6 Shader effects provide a visual effect for actors.
8 For a Custom shader you can provide the vertex and fragment shader code as strings.
9 Each shader is provided with default uniforms and attributes.
10 For a vertex shader this part contains the following code:
12 precision highp float;
13 attribute vec3 aPosition;
14 attribute vec2 aTexCoord;
15 uniform mat4 uMvpMatrix;
16 uniform mat4 uModelMatrix;
17 uniform mat4 uViewMatrix;
18 uniform mat4 uModelView;
19 uniform mat3 uNormalMatrix;
20 uniform mat4 uProjection;
22 varying vec2 vTexCoord;
24 The custom shader part is expected to output the vertex position and texture coordinate.
25 A basic custom vertex shader would contain the following code:
29 gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);
30 vTexCoord = aTexCoord;
33 For an Image fragment shader the default attributes and uniforms are:
35 precision mediump float;
36 uniform sampler2D sTexture;
37 uniform sampler2D sEffect;
39 varying vec2 vTexCoord;
41 The custom shader is expected to output the fragment color.
42 The basic fragment shader for images would contain:
46 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;
49 The API supports functionality such as:
51 + new dali.{{#crossLink "ShaderEffect/ShaderEffect:method"}}{{/crossLink}}
52 + {{#crossLink "ShaderEffect/setUniform:method"}}{{/crossLink}}
54 ### Example of using a custom uniform to brighten an Image (Fragment Shader)
56 <img src="../assets/img/fragment-shader-color.png">
58 createColorEffect = function()
61 // add uColorShift to the pixel color
64 "uniform lowp vec4 uColorShift; \
68 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor + uColorShift; \
72 geometryType: "image",
73 fragmentShader: fragShader
76 // create a new shader effect
77 var shader = new dali.ShaderEffect(shaderOptions);
79 // add the color shift uniform so we can modify and animate it
80 shader.setUniform("uColorShift", [0.0, 0.0, 0.0, 0]);
83 // create an image actor and add an image to it
84 var image = new dali.ResourceImage( { url: getImageDirectory() +"gallery-medium-50.jpg"});
85 var imageActor = new dali.ImageActor( image );
86 imageActor.parentOrigin = dali.CENTER;
87 dali.stage.add( imageActor );
89 var colorShift = createColorEffect();
91 colorShift.setUniform( "uColorShift", [0.5,0.5,0.5,0.0] ); // increase RGB by 50%
93 imageActor.setShaderEffect( colorShift );
96 For an example of animating we can just do:
98 var shaderAnim = new dali.Animation(10);
101 alpha: "doubleEaseInOutSine60",
104 // animate the color uniform to full white
105 shaderAnim.animateTo( colorShift, "uColorShift", dali.COLOR_WHITE, animOptions);
109 Like all animatable properties we can also use keyframes to animate the value.
112 ### Example of animating a custom uniform to perform a mask operation (Fragment Shader)
114 In this example we are using the OpenGL discard function to draw an image with a circular mask.
116 <img src="../assets/img/fragment-shader-reveal.png">
118 createRevealEffect = function()
120 // texture co-ordinate is from 0..1
121 // we shift the texture co-ordinate to -0.5 to 0.5 to center it
122 // then work out the radius from the centre, using ( a^2 + b^2) = c^2
123 // we use the dot product to perform the a^2 + b^2
124 // then just perform uRadius * uRadius to workout c^2
127 " uniform lowp float uRadius; \
131 lowp vec2 pos= vec2(vTexCoord.x-0.5,vTexCoord.y-0.5); \
132 lowp float radius = dot(pos, pos ) ; \
133 if( radius > (uRadius*uRadius) )\
135 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor ; \
138 var shaderOptions = {
139 geometryType: "image",
140 fragmentShader: fragShader
143 // create a new shader effect
144 var shader = new dali.ShaderEffect(shaderOptions);
147 shader.setUniform("uRadius",0.0);
150 // create an image actor and add an image to it
151 var filename = getImageDirectory() +"gallery-medium-50.jpg;
152 var image = new dali.ResourceImage( {url: filename });
153 var imageActor = new dali.ImageActor( image );
154 imageActor.parentOrigin = dali.CENTER;
155 dali.stage.add( imageActor );
157 var revealEffect = createRevealEffect();
159 imageActor.setShaderEffect( revealEffect );
161 var shaderAnim = new dali.Animation(5);
164 alpha: "easeInOutSine",
167 // animate up to radius = 0.5 ( a full circle )
168 // if we go to 1.0 then it will go to a full box
169 shaderAnim.animateTo( revealEffect, "uRadius", 0.5,animOptions);
173 ### Example of paper twisting in the wind with color (Vertex + Fragment Shader)
175 <img src="../assets/img/vertex-shader.png"><br>
177 The example does the following:
179 + Creates a varying variable called vColor in the vertex shader.
180 + The vColor is set to the position of the vertex, so the color changes depending on its position
181 + Create a uniform called uOffset which modifies the xPosition of each vertex, creating a twist effect
183 An ImageActor normally only has 4 vertices ( quad ). To allow the image to twist and bend we need it to have more
184 vertices. To do this we can break the image into a grid using the gridX and gridY geometry hints.
186 <img src="../assets/img/shader-grid-hint.png">
189 createTwistEffect = function()
192 // do some maths on the x-position to move it based on y,z pos + uOffset
195 varying lowp vec4 vColor; \
196 uniform lowp float uOffset; \
200 vec4 pos = uProjection * uModelView * vec4(aPosition, 1.0); \
201 pos.x= 3*pos.z*(sin(1.57+uOffset+pos.y/1000.0)); \
204 vTexCoord = aTexCoord; \
207 // add the vColor to the pixel color to tint it
210 varying lowp vec4 vColor; \
213 gl_FragColor = texture2D( sTexture, vTexCoord ) *uColor + vColor*0.2; \
216 var shaderOptions = {
217 geometryType: "image",
218 vertexShader: vertexShader,
219 fragmentShader: fragShader,
220 geometryHints: ["grid"]
223 // create a new shader effect
224 var shader = new dali.ShaderEffect(shaderOptions);
227 shader.setUniform("uOffset",0.0);
232 dali.stage.setBackgroundColor( dali.COLOR_WHITE);
234 var image = new dali.ResourceImage( { url:getImageDirectory() +"gallery-medium-50.jpg"});
235 var imageActor = new dali.ImageActor( image );
236 imageActor.parentOrigin = dali.CENTER;
237 imageActor.setCullFace( dali.CULL_FACE_DISABLE ); // disable face culling so we can see both sides
238 dali.stage.add( imageActor );
240 // start it of tilted around the y-axis
241 imageActor.rotation=new dali.Rotation(90, 0, 1, 0);
243 var twistEffect = createTwistEffect();
244 imageActor.setShaderEffect( twistEffect );
246 var shaderAnim = new dali.Animation(1);
251 shaderAnim.animateTo( twistEffect, "uOffset",20,animOptions);
255 Note: In order for fade and color animations to work, the fragment shader needs to multiply the fragment color
256 with the uniform color "uColor" of the node