OpenGL Logo

Shader Resource

available from Version 1.10+

Overview

Spark provides many powerful capabilities for the creation of Visually Rich applications - with animations, image masking, clipping and other technologies. The addition the Shader Resource provides near limitless visual effects capabilities - allowing OpenGL shader (programable pipeline) power to be leveraged in Spark applications.

The Shader Resource will allow application developers to harness GPU performance to provide "next-level" visuals.

SVG Logo

Shader Resource

Spark now supports OpenGL Shaders via the shaderResource. Shaders are written in GLSL - GL Shader language.


Creating the Shader Resource

The following example shows how to create a Shader Resource -

var tintShader = scene.create({ t: 'shaderResource', fragment: frag_src, vertex: vert_src, uniforms: { s_texture: "sampler2D", u_time: "float" u_color: "vec4" } });
GLSL Shader creation

We pass the Shader Resource frag_src and vert_src which are GLSL either URL's to source code, or Data URL's. Additionally, we declare uniforms that we will use.

In this case,

  • s_texture   an image bound to
  • u_time         a floating-point time value
  • u_color       an RGBA color value value.


Using the Shader Resource

tintShader.ready .then( (resolve) => { image.effect = { name: "My Color Tint", shader: tintShader, uniforms: { u_color: [1.0, 1.0, 0.0, 1.0] // YELLOW // #ff0 } }; }, (reject) => { console.log("SHADER ERROR: " + tintShader.loadStatus.glError ); });

Shader Config JSON

The Shader Resource will return a promise to indicate when it's ready. The promise will resolve when the shader code is downloaded and compiled successfullly by OpenGL.

In the case of an error, the promise will reject, and additional details will be available through loadStatus.glError.

When it's ready, the Shader Resource is attached to the .effect property of our Image object image.

It can be attached to any Spark object:-    object, rectangle, image   etc.

The configuration for our Shader Resource is assigned as a JSON object as shown above.

We configure uniform values here also.


Shader Configuration

3 methods of configuration are available.

  • Direct Uniform Configuration
  • Configuration Object - SINGLE
  • Configuration Objects - ARRAY

Direct Uniform Configuration

Using the uniform variable name directly on the Shader Resource object.

NOTE:   Direct assignment uniforms should be considered volatile.

For example:-

myShader.ready.then( () => { myShader.u_color = [1.0, 1.0, 0.0, 1.0] // YELLOW // #ff0 });

Configuration Object - SINGLE

For a Single shader pass - use a SINGLE JSON configuration object with the 'shader' Shader Resource object and 'uniforms' to the Spark object via .effect.

For example:-

image.effect = { name: "My Color Tint", shader: tintShader, uniforms: { u_color1: [1.0, 1.0, 0.0, 1.0] // YELLOW // #ff0 u_color2: [1.0, 0.0, 1.0, 1.0] // MAGENTA // #f0f } };

Configuration Objects - ARRAY

For Multiple shader passes - use an ARRAY of JSON configuration objects with the 'shader' Shader Resource object and 'uniforms' to the Spark object via .effect.

For example:-

image.effect = [ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { name: "Pass 1", shader: blurShader, uniforms: { u_kernelRadius: kernelRadius, u_direction: [blurAmount, 0] // HORIZONTAL } }, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { name: "Pass 2", shader: blurShader, uniforms: { u_kernelRadius: kernelRadius, u_direction: [0, blurAmount] // VERTICAL } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ];

Inline Source Code

Using Data URL's - the shader source code can be embedded in the Javascript source - and remove the need for extra files / downloads.

var src = `data:text/plain, varying vec2 v_uv; uniform vec4 u_color; uniform sampler2D s_texture; void main(void) { // Pixels from Source texture... vec4 px = texture2D(s_texture, v_uv); vec3 clr = u_color.rgb * px.a; // pre-multiplied Alpha // Mix image and colors... vec4 mixed = mix( px, vec4(clr, 1.0), 0.5); // lerp mixed.a *= px.a; // pre-multiplied Alpha gl_FragColor = vec4(mixed); } `; // <<<<<<<< NOTE THE BACK TICK
GLSL Source as a Javascript string

NOTE:   The use of back ticks    >> ` code ` <<   in JS code to capture source code as a string.

There is quite a bit going on above. The code creates a Javascript string as a Data URL capturing fragment shader code which blends source pixels with a color assigned by the uniform   u_color


Internal Variables

NOTE:   The following GLSL variables are provided by Spark - their names are reserved and should be avoided.

u_texture
u_resolution
u_time

The texture of the Spark object upon which the shader is applied.
The resolution / dimensions of the object upon which the shader is applied.
A monotonic increasing, floating-point clock value.

Flattened Composition - u_texture

The Shader Resource will provide a texture of flattened/compositied of the Object and its Children to which shader is applied.

In this case the blue background rounded rectangle or image, text and logo image are rendered to a texture bound to u_texture.

This texture is accessed in Shader code via u_texture and may be used in fragment operations.

Shader Resource Exploded
Components

The resulting texture u_texture can use in fragment sampling operations.

Shader Resource View
Flattened/Compositied

Capability

The following code shows how to test the supported capability of Shader Resource in Spark releases.

if( scene.capabilities == undefined || scene.capabilities.graphics == undefined || scene.capabilities.graphics.shaders == undefined ) { console.log("Oh NO ... Shader Resource is not supported in this build."); }

Versions

The following code shows how to check the version of Shader Resource in Spark releases.

if( scene.capabilities.graphics.shaders == 1 ) { // confirming the Shader Resource capabilities }

Further Reading

A great resource for Shader inspiration is   Shadertoy.com

It's an open-source gallery of MANY many Fragment Shaders.