6 Shader effects provide a visual effect for actors.
8 You can create a type-registered shader effect by its type name.
10 // create a new shader effect
11 var shader = new dali.ShaderEffect("BlindEffect");
14 Alternatively you can create a Custom shader by providing the vertex and fragment shader code as strings.
15 Each shader is provided with default uniforms and attributes.
16 For a vertex shader this part contains the following code:
18 precision highp float;
19 attribute vec3 aPosition;
20 attribute vec2 aTexCoord;
21 uniform mat4 uMvpMatrix;
22 uniform mat4 uModelMatrix;
23 uniform mat4 uViewMatrix;
24 uniform mat4 uModelView;
25 uniform mat3 uNormalMatrix;
26 uniform mat4 uProjection;
28 varying vec2 vTexCoord;
30 The custom shader part is expected to output the vertex position and texture coordinate.
31 A basic custom vertex shader would contain the following code:
35 gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);
36 vTexCoord = aTexCoord;
39 For an Image fragment shader the default attributes and uniforms are:
41 precision mediump float;
42 uniform sampler2D sTexture;
43 uniform sampler2D sEffect;
45 varying vec2 vTexCoord;
47 The custom shader is expected to output the fragment color.
48 The basic fragment shader for images would contain:
52 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;
55 The API supports functionality such as:
57 + new dali.{{#crossLink "ShaderEffect/ShaderEffect:method"}}{{/crossLink}}
58 + {{#crossLink "ShaderEffect/setUniform:method"}}{{/crossLink}}
60 ### Example of using a custom uniform to brighten an Image (Fragment Shader)
62 <img src="../assets/img/fragment-shader-color.png">
64 createColorEffect = function()
67 // add uColorShift to the pixel color
70 "uniform lowp vec4 uColorShift; \
74 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor + uColorShift; \
78 geometryType: "image",
79 fragmentShader: fragShader
82 // create a new shader effect
83 var shader = new dali.ShaderEffect(shaderOptions);
85 // add the color shift uniform so we can modify and animate it
86 shader.setUniform("uColorShift", [0.0, 0.0, 0.0, 0]);
89 // create an image actor and add an image to it
90 var image = new dali.ResourceImage( { url: getImageDirectory() +"gallery-medium-50.jpg"});
91 var imageActor = new dali.ImageActor( image );
92 imageActor.parentOrigin = dali.CENTER;
93 dali.stage.add( imageActor );
95 var colorShift = createColorEffect();
97 colorShift.setUniform( "uColorShift", [0.5,0.5,0.5,0.0] ); // increase RGB by 50%
99 imageActor.setShaderEffect( colorShift );
102 For an example of animating we can just do:
104 var shaderAnim = new dali.Animation(10);
107 alpha: "doubleEaseInOutSine60",
110 // animate the color uniform to full white
111 shaderAnim.animateTo( colorShift, "uColorShift", dali.COLOR_WHITE, animOptions);
115 Like all animatable properties we can also use keyframes to animate the value.
118 ### Example of animating a custom uniform to perform a mask operation (Fragment Shader)
120 In this example we are using the OpenGL discard function to draw an image with a circular mask.
122 <img src="../assets/img/fragment-shader-reveal.png">
124 createRevealEffect = function()
126 // texture co-ordinate is from 0..1
127 // we shift the texture co-ordinate to -0.5 to 0.5 to center it
128 // then work out the radius from the centre, using ( a^2 + b^2) = c^2
129 // we use the dot product to perform the a^2 + b^2
130 // then just perform uRadius * uRadius to workout c^2
133 " uniform lowp float uRadius; \
137 lowp vec2 pos= vec2(vTexCoord.x-0.5,vTexCoord.y-0.5); \
138 lowp float radius = dot(pos, pos ) ; \
139 if( radius > (uRadius*uRadius) )\
141 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor ; \
144 var shaderOptions = {
145 geometryType: "image",
146 fragmentShader: fragShader
149 // create a new shader effect
150 var shader = new dali.ShaderEffect(shaderOptions);
153 shader.setUniform("uRadius",0.0);
156 // create an image actor and add an image to it
157 var filename = getImageDirectory() +"gallery-medium-50.jpg;
158 var image = new dali.ResourceImage( {url: filename });
159 var imageActor = new dali.ImageActor( image );
160 imageActor.parentOrigin = dali.CENTER;
161 dali.stage.add( imageActor );
163 var revealEffect = createRevealEffect();
165 imageActor.setShaderEffect( revealEffect );
167 var shaderAnim = new dali.Animation(5);
170 alpha: "easeInOutSine",
173 // animate up to radius = 0.5 ( a full circle )
174 // if we go to 1.0 then it will go to a full box
175 shaderAnim.animateTo( revealEffect, "uRadius", 0.5,animOptions);
179 ### Example of paper twisting in the wind with color (Vertex + Fragment Shader)
181 <img src="../assets/img/vertex-shader.png"><br>
183 The example does the following:
185 + Creates a varying variable called vColor in the vertex shader.
186 + The vColor is set to the position of the vertex, so the color changes depending on its position
187 + Create a uniform called uOffset which modifies the xPosition of each vertex, creating a twist effect
189 An ImageActor normally only has 4 vertices ( quad ). To allow the image to twist and bend we need it to have more
190 vertices. To do this we can break the image into a grid using the gridX and gridY geometry hints.
192 <img src="../assets/img/shader-grid-hint.png">
195 createTwistEffect = function()
198 // do some maths on the x-position to move it based on y,z pos + uOffset
201 varying lowp vec4 vColor; \
202 uniform lowp float uOffset; \
206 vec4 pos = uProjection * uModelView * vec4(aPosition, 1.0); \
207 pos.x= 3*pos.z*(sin(1.57+uOffset+pos.y/1000.0)); \
210 vTexCoord = aTexCoord; \
213 // add the vColor to the pixel color to tint it
216 varying lowp vec4 vColor; \
219 gl_FragColor = texture2D( sTexture, vTexCoord ) *uColor + vColor*0.2; \
222 var shaderOptions = {
223 geometryType: "image",
224 vertexShader: vertexShader,
225 fragmentShader: fragShader,
226 geometryHints: ["grid"]
229 // create a new shader effect
230 var shader = new dali.ShaderEffect(shaderOptions);
233 shader.setUniform("uOffset",0.0);
238 dali.stage.setBackgroundColor( dali.COLOR_WHITE);
240 var image = new dali.ResourceImage( { url:getImageDirectory() +"gallery-medium-50.jpg"});
241 var imageActor = new dali.ImageActor( image );
242 imageActor.parentOrigin = dali.CENTER;
243 imageActor.setCullFace( dali.CULL_FACE_DISABLE ); // disable face culling so we can see both sides
244 dali.stage.add( imageActor );
246 // start it of tilted around the y-axis
247 imageActor.orientation=new dali.Rotation(90, 0, 1, 0);
249 var twistEffect = createTwistEffect();
250 imageActor.setShaderEffect( twistEffect );
252 var shaderAnim = new dali.Animation(1);
257 shaderAnim.animateTo( twistEffect, "uOffset",20,animOptions);
261 Note: In order for fade and color animations to work, the fragment shader needs to multiply the fragment color
262 with the uniform color "uColor" of the node