Plasma
This is a Shadertoy example. Because of the way this docs are built, its housed in a minimal Indigo project for built purposes, but the shader code isn't run because it's incompatible with Indigo, so all you get is a black screen.
This example is a port of 'Plasma' by Jolle, and you can view it here: https://www.shadertoy.com/view/XsVSDz
The GLSL Output
This is the shadertoy compatible GLSL code that Ultraviolet manufactures, note that this shader is in two parts, Buffer A and Image:
Buffer A
const float pi=3.1415927;
void mainImage(out vec4 fragColor,in vec2 fragCoord){
float i=fragCoord.x/iResolution.x;
vec3 t=(iTime+iMouse.y)/vec3(63.0,78.0,45.0);
vec3 cs=cos(((i*pi)*2.0)+((vec3(0.0,1.0,-0.5))*pi)+t);
fragColor=vec4(0.5+(0.5*cs),1.0);
}
Image
const vec2 vp=vec2(320.0,200.0);
void mainImage(out vec4 fragColor,in vec2 fragCoord){
float t=(iTime*10.0)+iMouse.x;
vec2 uv=fragCoord.xy/iResolution.xy;
vec2 p0=(uv-0.5)*vp;
vec2 hvp=vp*0.5;
vec2 p1d=((vec2(cos(t/98.0),sin(t/178.0)))*hvp)-p0;
vec2 p2d=((vec2(sin((-t)/124.0),cos((-t)/104.0)))*hvp)-p0;
vec2 p3d=((vec2(cos((-t)/165.0),cos(t/45.0)))*hvp)-p0;
float sum=0.25+(0.5*(cos(length(p1d)/30.0))+(cos(length(p2d)/20.0))+(sin(length(p3d)/25.0))*(sin(p3d.x/20.0))*(sin(p3d.y/15.0)));
fragColor=texture(iChannel0,vec2(fract(sum),0.0));
}
Example Links
Ultraviolet Shadertoy code
Reminder: The live demo will not work, below is the Shadertoy compatible code.
Unlike the default example, this example produces two shaders: 1. A shader that produces a buffer (bufferA) 2. A shader that produces the final image (image)
If you were to render Bufffer A, you'd see that it produces a noise image, which is then used as a reference source in order to produce the final plasma effect.
object ShaderToyExample:
inline def bufferA =
Shader[ShaderToyEnv, Unit] { env =>
@const val pi: Float = 3.1415926435f
def mainImage(fragColor: vec4, fragCoord: vec2): vec4 =
val i: Float = fragCoord.x / env.iResolution.x
val t: vec3 = (env.iTime + env.iMouse.y) / vec3(63.0f, 78.0f, 45.0f)
val cs: vec3 = cos(i * pi * 2.0f + vec3(0.0f, 1.0f, -0.5f) * pi + t)
vec4(0.5f + 0.5f * cs, 1.0f)
}
inline def image =
Shader[ShaderToyEnv, Unit] { env =>
@const val vp: vec2 = vec2(320.0, 200.0)
def mainImage(fragColor: vec4, fragCoord: vec2): vec4 =
val t: Float = env.iTime * 10.0f + env.iMouse.x
val uv: vec2 = fragCoord.xy / env.iResolution.xy
val p0: vec2 = (uv - 0.5f) * vp
val hvp: vec2 = vp * 0.5f
val p1d: vec2 = vec2(cos(t / 98.0f), sin(t / 178.0f)) * hvp - p0
val p2d: vec2 = vec2(sin(-t / 124.0f), cos(-t / 104.0f)) * hvp - p0
val p3d: vec2 = vec2(cos(-t / 165.0f), cos(t / 45.0f)) * hvp - p0
val sum: Float = 0.25f + 0.5f * (cos(length(p1d) / 30.0f) +
cos(length(p2d) / 20.0f) +
sin(length(p3d) / 25.0f) * sin(p3d.x / 20.0f) * sin(p3d.y / 15.0f))
texture2D(env.iChannel0, vec2(fract(sum), 0))
}
Then to get the code for the two shaders as a String so that we might print or output them somewhere, we can do the following:
object Output:
val bufferACode: String =
ShaderToyExample.bufferA.toGLSL[ShaderToy].toOutput.code
val imageCode: String =
ShaderToyExample.image.toGLSL[ShaderToy].toOutput.code