1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
// example-effect.slang
// This file provides an example of how a shader
// toy effect can be compiled as a Slang module.
//
// Every effect will depend on the module that
// defines out shader toy infrastructure:
//
import shader_toy;
// The `shader_toy` module defines the interface
// that each effect must implement, and our
// specific effect will be a type that implements
// the interface:
//
struct ExampleEffect : IShaderToyImageShader
{
// Our goal is that we can mostly just copy-paste
// the code for an effect from shadertoy.com into
// this file, and have something that works.
//
// Due to limitations in compatibility between
// GLSL and Slang, that won't always work, but
// it still helps to note where the original
// GLSL code begins/ends.
// Note: the verison of this file that is checked
// in uses a placeholder effect so that this file
// does not need to concern itself with the license
// terms of particular effects on shadertoy.com.
// BEGIN GLSL
float rand(float n)
{
return fract(sin(n) * 43758.5453123);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
float screenScale = length(iResolution.xy);
vec2 uv = fragCoord / screenScale;
float frequency = 5.0f;
vec2 pos = (uv + iTime*vec2(0.25f, 0.0f)) * frequency;
vec2 center = floor(pos + vec2(0.5));
float r0 = rand(center.x*3.0f + center.y*7.0f);
float r1 = rand(center.x*7.0f + center.y*13.0f);
float r2 = rand(center.x*13.0f + center.y*3.0f);
float p = mix(0.0f, 4.0f, r0);
float f = mix(5.0f, 8.0f, r1);
float a = 0.5f * (1.0f + cos(iTime*f + p));
float rad0 = mix(0.1, 0.4, r2);
float rad1 = mix(0.2, 0.9, r0);
float radius = 0.5f*mix(rad0, rad1, a);
vec2 delta = pos - center;
float distance = length(delta);
fragColor.xyz = vec3(r0, r1, r2);
fragColor.w = 1.0f;
if(distance > radius) fragColor.xyz = vec3(0.25f);
}
// END GLSL
// The GLSL logic for the effect above might have included
// "global" declarations (which become fields since things
// are wrapped in a `struct`) with initializer, and we
// need a way for the code that uses an effect like this
// to get an instance that has been properly initialized.
//
// Right now, the `IShaderToyImageShader` interface requires
// a factory function `getDefault()`, so we will implement
// that here.
//
static This getDefault()
{
// Note: this code does not need to be updated for different
// GLSL effects, since it will default-initialize whatever
// members the `This` types has.
//
This value = {};
return value;
}
}
|