diff options
Diffstat (limited to 'examples/shader-toy/example-effect.slang')
| -rw-r--r-- | examples/shader-toy/example-effect.slang | 93 |
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; + } +} |
