summaryrefslogtreecommitdiff
path: root/examples/shader-toy/example-effect.slang
diff options
context:
space:
mode:
Diffstat (limited to 'examples/shader-toy/example-effect.slang')
-rw-r--r--examples/shader-toy/example-effect.slang93
1 files changed, 93 insertions, 0 deletions
diff --git a/examples/shader-toy/example-effect.slang b/examples/shader-toy/example-effect.slang
new file mode 100644
index 000000000..966894a87
--- /dev/null
+++ b/examples/shader-toy/example-effect.slang
@@ -0,0 +1,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;
+ }
+}