SkSL in Cavalry

Ian Waters
Cavalry Animation
Published in
4 min readMay 13, 2020
https://www.shadertoy.com/view/4lf3Rj

If you don’t have Cavalry yet, head to Scene Group to sign-up and download the free beta.

As of PR14 you can use SkSL shader code directly in Cavalry. SkSL is a flavour of GLSL created by the Skia team at Google. It’s very similar and converting existing shaders should only take a couple of minutes.

The main differences are:
Vectors are named <base type><columns> E.g vec2 becomes float2
Matrices are named <base type><columns>x<rows>. E.g mat2 becomes float2x2.
• The signature for the main method is:
void main(float2 fragCoord, inout half4 fragColor)
Use fragCoord not gl_FragCoord.
Use fragColor not gl_FragColor.
• The fragColor is of type half4, so you may need to cast to that.
• Defines don’t appear to be allowed.

More details on the differences can be found here: https://github.com/google/skia/blob/master/src/sksl/README

Please note, the first tech preview of our SkSL shader (May 2020) can only take float uniforms. We will be expanding this functionality soon. As this is a preview, there may be file breaking changes to this Shader as we progress with its development.

To add a uniform, simply click the Add button on the SkSL shader UI in the Attribute Editor.

Click Add to add a Uniform.

For those who need a refresher, or a place to start, here are a few demo shaders of increasing complexity. All the shaders below are based on examples from www.thebookofshaders.com.

The Shadertoy Wiki is also another useful page: https://shadertoy.fandom.com/wiki/Shadertoy_Wikia

Flat colour:

Uniforms required: 0

void main(float2 fragCoord, inout half4 fragColor) {
fragColor = half4(0.385,0.775,1.000,1.000);
}

Cycling colour:

Uniforms required: 1 (time)

uniform float u_time;float3 colorA = float3(0.86,0.25,0.18);
float3 colorB = float3(0.01,0.96,0.94);
void main(float2 fragCoord, inout half4 fragColor) {
float3 color = float3(0.0);
float percent = abs(sin(u_time*.01));
// Mix uses percent (a value from 0–1) to
// mix the two colors
color = mix(colorA, colorB, percent);
fragColor = half4(color,1.0);
}

Pixels:

Zooming pixels.

Uniforms required: 3 (resolution.x, resolution.y, time)

uniform float2 u_resolution;
uniform float u_time;
float random (float2 st) {
return fract(sin(dot(st.xy , float2(12.9898,78.233))) * 43758.5453);
}
void main(float2 fragCoord, inout half4 fragColor) {
float2 st = fragCoord/u_resolution.xy;
st *=max(1.0, u_time); // Scale the coordinate system
float2 ipos = floor(st); // get the integer coords
float2 fpos = fract(st); // get the fractional coords
// Assign a random value based on the integer coord
float3 color = float3(random( ipos ));
// Uncomment to see the subdivided grid
// color = vec3(fpos,0.0);
fragColor = half4(color,1.0);
}

Fractal Brownian motion

FBM Noise.

Uniforms required: 3 (resolution.x, resolution.y, time)

uniform float2 u_resolution;
uniform float u_time;
float random (in float2 _st) {
return fract(sin(dot(_st.xy,
float2(12.9898,78.233)))*
43758.5453123);
}
// Based on Morgan McGuire @morgan3d
// https://www.shadertoy.com/view/4dS3Wd
float noise (in float2 _st) {
float2 i = floor(_st);
float2 f = fract(_st);
// Four corners in 2D of a tile
float a = random(i);
float b = random(i + float2(1.0, 0.0));
float c = random(i + float2(0.0, 1.0));
float d = random(i + float2(1.0, 1.0));
float2 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 ( in float2 _st) {
float v = 0.0;
float a = 0.5;
float2 shift = float2(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(_st);
_st = rot * _st * 2.0 + shift;
a *= 0.5;
}
return v;
}
void main(float2 fragCoord, inout half4 fragColor) {
float2 st = fragCoord.xy/u_resolution.xy*3.;
// st += st * abs(sin(u_time*0.1)*3.0);
float3 color = float3(0.0);
float2 q = float2(0.);
q.x = fbm( st + 0.00*u_time);
q.y = fbm( st + float2(1.0));
float2 r = float2(0.);
r.x = fbm( st + 1.0*q + float2(1.7,9.2)+ 0.15*u_time );
r.y = fbm( st + 1.0*q + float2(8.3,2.8)+ 0.126*u_time);
float f = fbm(st+r);
color = mix(float3(0.101961,0.619608,0.666667),
float3(0.666667,0.666667,0.498039),
clamp((f*f)*4.0,0.0,1.0));
color = mix(color,
float3(0,0,0.164706),
clamp(length(q),0.0,1.0));
color = mix(color,
float3(0.666667,1,1),
clamp(length(r.x),0.0,1.0));
fragColor = half4((f*f*f+.6*f*f+.5*f)*color,1.);
}
https://www.shadertoy.com/view/XlfGRj
https://www.shadertoy.com/view/4tdSWr

--

--

Ian Waters
Cavalry Animation

Co-creator of Cavalry. CTO of Scene Group. Ex-Animator with a background in Interaction Design.