SkSL Shader
Intro
SkSL ("Skia Shading Language") is a variant of GLSL which is used as Skia's internal shading language. With some minor modifications, GLSL code from sites like https://www.shadertoy.com/ can be converted for use in Cavalry.
For more detail on the differences between GLSL and SkSL see the Skia documentation.
Note - the SkSL shader currently only takes float uniforms.
UI
Blend Mode - See Blend Modes.
Shader Code - Paste/edit SkSL code here.
Inputs - Click the +
button to to choose a uniform type and add one. Uniforms can be renamed by right clicking on an attribute and choosing Rename.... This name can then be used as a variable in the SkSL code.
Examples
Several examples can be loaded via the Create > Demo Scenes > Custom Shaders
menu.
- Create a Rectangle.
- In the Attribute Editor, open the Fill tab.
- On the Shaders attribute, right click > Add Shader > SkSL Shader.
- Double click the SkSL Shader to load its Attribute Editor UI.
- Copy and paste the example code below into the Shader Code attribute.
- Right click on the n0 uniform, choose Rename... and rename to Time.
- Click the
+
button to create a new uniform and choose Add Double 2 (float2). - Rename it to Resolution.
- Ensure all uniform values are greater than 0.
A blue flame will appear on the Rectangle. Try connecting a Behaviour (Noise, Sound etc) into an input. For example, connect a Frame Behaviour to the Time uniform. 😎
// Created by Anatole Duprat - XT95/2013
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
float noise(vec3 p) //Thx to Las^Mercury
{
vec3 i = floor(p);
vec4 a = dot(i, vec3(1., 57., 21.)) + vec4(0., 57., 21., 78.);
vec3 f = cos((p-i)*acos(-1.))*(-.5)+.5;
a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
a.xy = mix(a.xz, a.yw, f.y);
return mix(a.x, a.y, f.z);
}
float sphere(vec3 p, vec4 spr)
{
return length(spr.xyz-p) - spr.w;
}
float flame(vec3 p)
{
float d = sphere(p*vec3(1.,.3,1.), vec4(.0,-1.,.0,1.));
return d + (noise(p+vec3(.0,Time*0.1,.0)) + noise(p*3.)*.5)*.25*(p.y) ;
}
float scene(vec3 p)
{
return min(100.-length(p) , abs(flame(p)) );
}
vec4 raymarch(vec3 org, vec3 dir)
{
float d = 0.0, glow = 0.0, eps = 0.02;
vec3 p = org;
bool glowed = false;
for(int i=0; i<64; i++)
{
d = scene(p) + eps;
p += d * dir;
if( d>eps )
{
if(flame(p) < .0)
glowed=true;
if(glowed)
glow = float(i)/64.;
}
}
return vec4(p,glow);
}
half4 main(vec2 fragCoord)
{
vec2 uv = 2.0 * fragCoord.xy / Resolution.xy;
uv.x *= Resolution.x/Resolution.y;
vec3 org = vec3(0., -4.5, 4.);
vec3 dir = normalize(vec3(uv.x*1.6, -uv.y, -1.5));
vec4 p = raymarch(org, dir);
float glow = p.w;
half4 col = mix(half4(1.,.5,.1,1.), half4(0.1,.5,1.,1.), p.y*.02+.4);
return half4(mix(half4(0.), col, pow(glow*2.,4.)));
}
Flat colour
- Delete the default
n0
uniform. To do this, right click on the attribute and choose Delete Selected Attribute. - Use the
+
button to add a Color (half4) uniform. - Paste the code below into the Shader Code input:
half4 main(float2 fragCoord) {
return n0;
} - Adjust the color values on the uniform.
Cycling colour
- Rename the existing n0 uniform to Time. To do this, right click on the attribute and choose Rename....
- Paste the code below into the Shader Code input:
vec3 colorA = vec3(0.149,0.141,0.912);
vec3 colorB = vec3(1.000,0.833,0.224);
half4 main(vec2 fragCoord) {
vec3 color = vec3(0.0);
float percent = abs(sin(Time*.01));// Mix uses percent (a value from 0–1) to
// mix the two colors
color = mix(colorA, colorB, percent);
return half4(color,1.0);
} - Scrub the Time uniform.
Pixels
- Rename the existing n0 uniform to Time. To do this, right click on the attribute and choose Rename....
- Use the
+
button and choose Add Double 2 (float2) to add a new uniform. - Rename the uniform to Resolution.
- Paste the code below into the Shader Code input:
float random (vec2 uv) {
return fract(sin(dot(uv.xy , vec2(12.9898,78.233))) * 43758.5453);
}
half4 main(vec2 fragCoord) {
vec2 uv = fragCoord / Resolution.xy;
uv *= max(1.0, Time); // Scale the coordinate system by 10
vec2 ipos = floor(uv); // get the integer coords
vec2 fpos = fract(uv); // get the fractional coords
// Assign a random value based on the integer coord
vec3 color = vec3(random(ipos));
return half4(color,1.0);
} - Increase the uniform's values.
Fractal Brownian motion
- Rename the existing n0 uniform to Time. To do this, right click on the attribute and choose Rename....
- Use the
+
button and choose Add Double 2 (float2) to add a new uniform. - Rename the uniform to Resolution.
- Paste the code below into the Shader Code input:
float random (vec2 uv) {
return fract(sin(dot(uv.xy, vec2(12.9898,78.233))) * 43758.5453123);
}
// Based on Morgan McGuire @morgan3d
// https://www.shadertoy.com/view/4dS3Wd
float noise (vec2 uv) {
vec2 i = floor(uv);
// Four corners in 2D of a tile
vec2 f = fract(uv);
float a = random(i);
float b = random(i + vec2(1.0, 0.0));
float c = random(i + vec2(0.0, 1.0));
float d = random(i + vec2(1.0, 1.0));
vec2 u = (f * f * (3.0 - 2.0 * f));
return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
float fbm (vec2 uv) {
float v = 0.0;
float a = 0.5;
vec2 shift = vec2(100.0);
// Rotate to reduce axial bias
float2x2 rot = float2x2(cos(0.5), sin(0.5), -sin(0.5), cos(0.50));
for (int i = 0; i < 5; ++i) {
v += a * noise(uv);
uv = rot * uv * 2.0 + shift;
a *= 0.5;
}
return v;
}
half4 main(vec2 fragCoord) {
float2 uv = fragCoord.xy/Resolution.xy*3.;
// uv += uv * abs(sin(Time*0.1)*3.0);
vec3 color = vec3(0.0);vec2 q = vec2(0.);
q.x = fbm( uv + 0.00*Time);
q.y = fbm( uv + vec2(1.0));vec2 r = vec2(0.);
r.x = fbm( uv + 1.0*q + vec2(1.7,9.2)+ 0.15*Time );
r.y = fbm( uv + 1.0*q + vec2(8.3,2.8)+ 0.126*Time);
float f = fbm(uv+r);
color = mix(vec3(0.101961,0.619608,0.666667), vec3(0.666667,0.666667,0.498039),
clamp((f*f)*4.0,0.0,1.0));
color = mix(color,
vec3(0,0,0.164706), clamp(length(q),0.0,1.0));
color = mix(color,vec3(0.666667,1,1),clamp(length(r.x),0.0,1.0));
return half4((f*f*f+.6*f*f+.5*f)*color,1.);
} - Increase the uniform's values.
The Material Sampler does not currently support SkSL Shaders.