Add more shared C++/JavaScript docs and add JavaScript wrapping guide
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / docs / content / shader-effect.js
1 /**
2  *
3
4 ## Shader Effects API
5
6 Shader effects provide a visual effect for actors.
7
8 You can create a type-registered shader effect by its type name.
9 ```
10 // create a new shader effect
11 var shader = new dali.ShaderEffect("BlindEffect");
12 ```
13
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:
17 ```
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;
27 uniform   vec4  uColor;
28 varying   vec2  vTexCoord;
29 ```
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:
32 ```
33 void main()
34 {
35     gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);
36     vTexCoord = aTexCoord;
37 }
38 ```
39 For an Image fragment shader the default attributes and uniforms are:
40 ```
41 precision mediump float;
42 uniform   sampler2D sTexture;
43 uniform   sampler2D sEffect;
44 uniform   vec4      uColor;
45 varying   vec2      vTexCoord;
46 ```
47 The custom shader is expected to output the fragment color.
48 The basic fragment shader for images would contain:
49 ```
50 void main()
51 {
52   gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;
53 }
54 ```
55 The API supports functionality such as:
56
57 + new dali.{{#crossLink "ShaderEffect/ShaderEffect:method"}}{{/crossLink}}
58 + {{#crossLink "ShaderEffect/setUniform:method"}}{{/crossLink}}
59
60 ### Example of using a custom uniform to brighten an Image (Fragment Shader)
61   
62 ![ ](../assets/img/shaders/fragment-shader-color.png)
63   
64 ```
65 createColorEffect = function()
66 {
67   
68   // add uColorShift to the pixel color
69   
70   var fragShader =
71     "uniform lowp vec4 uColorShift; \
72     \
73     void main()             \
74     {                  \
75       gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor + uColorShift; \
76     }"
77   
78     var shaderOptions = {
79         geometryType: "image",
80         fragmentShader: fragShader
81     };
82   
83   // create a new shader effect
84     var shader = new dali.ShaderEffect(shaderOptions);
85   
86   // add the color shift uniform so we can modify and animate it
87     shader.setUniform("uColorShift", [0.0, 0.0, 0.0, 0]);
88     return shader;
89 }
90 // create an image actor and add an image to it
91 var image = new dali.ResourceImage( { url: getImageDirectory() +"gallery-medium-50.jpg"});
92 var imageActor = new dali.ImageActor( image );
93 imageActor.parentOrigin = dali.CENTER;
94 dali.stage.add( imageActor );
95   
96 var colorShift = createColorEffect();
97   
98 colorShift.setUniform( "uColorShift", [0.5,0.5,0.5,0.0] );  // increase RGB by 50%
99   
100 imageActor.setShaderEffect( colorShift );
101 ```
102
103 For an example of animating we can just do:
104 ```
105 var shaderAnim = new dali.Animation(10);
106   
107 var animOptions = {
108     alpha: "doubleEaseInOutSine60",
109 };
110   
111 // animate the color uniform to full white
112 shaderAnim.animateTo( colorShift, "uColorShift", dali.COLOR_WHITE, animOptions);
113   
114 shaderAnim.play();
115 ```
116 Like all animatable properties we can also use keyframes to animate the value.
117 * * *
118
119 ### Example of animating a custom uniform to perform a mask operation (Fragment Shader)
120
121 In this example we are using the OpenGL discard function to draw an image with a circular mask.
122   
123 ![ ](../assets/img/shaders/fragment-shader-reveal.png)
124   
125 ```
126 createRevealEffect = function()
127 {
128 // texture co-ordinate is from 0..1
129 // we shift the texture co-ordinate to -0.5 to 0.5 to center it
130 // then work out the radius from the centre, using ( a^2 + b^2) = c^2
131 // we use the dot product to perform the a^2 + b^2
132 // then just perform uRadius * uRadius to workout c^2
133   
134     var fragShader =
135       " uniform lowp float uRadius; \
136       \
137        void main()             \
138        {                  \
139          lowp vec2 pos= vec2(vTexCoord.x-0.5,vTexCoord.y-0.5);    \
140          lowp float radius = dot(pos, pos ) ; \
141          if( radius > (uRadius*uRadius) )\
142            discard; \
143          gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor ; \
144        }"
145
146       var shaderOptions = {
147           geometryType: "image",
148           fragmentShader: fragShader
149       };
150   
151     // create a new shader effect
152       var shader = new dali.ShaderEffect(shaderOptions);
153   
154       // set the uniform
155       shader.setUniform("uRadius",0.0);
156       return shader;
157 }
158 // create an image actor and add an image to it
159 var filename = getImageDirectory() +"gallery-medium-50.jpg;
160 var image = new dali.ResourceImage( {url: filename });
161 var imageActor = new dali.ImageActor( image );
162 imageActor.parentOrigin = dali.CENTER;
163 dali.stage.add( imageActor );
164   
165 var revealEffect = createRevealEffect();
166   
167 imageActor.setShaderEffect( revealEffect );
168   
169 var shaderAnim = new dali.Animation(5);
170   
171 var animOptions = {
172           alpha: "easeInOutSine",
173       };
174   
175 // animate up to radius = 0.5 ( a full circle )
176 // if we go to 1.0 then it will go to a full box
177 shaderAnim.animateTo( revealEffect, "uRadius", 0.5,animOptions);
178 shaderAnim.play();
179 ```
180 * * *
181 ### Example of paper twisting in the wind with color (Vertex + Fragment Shader)
182   
183 ![ ](../assets/img/shaders/vertex-shader.png)
184   
185
186 The example does the following:
187
188 + Creates a varying variable called vColor in the vertex shader.
189  + The vColor is set to the position of the vertex, so the color changes depending on its position
190 + Create a uniform called uOffset which modifies the xPosition of each vertex, creating a twist effect
191
192 An ImageActor normally only has 4 vertices ( quad ). To allow the image to twist and bend we need it to have more
193 vertices. To do this we can break the image into a grid using the gridX and gridY geometry hints.
194   
195 ![ ](../assets/img/shaders/shader-grid-hint.png)
196   
197 ```
198 createTwistEffect = function()
199 {
200
201     // do some maths on the x-position to move it based on y,z pos + uOffset
202     var vertexShader =
203     " \
204       varying lowp vec4  vColor; \
205       uniform lowp float uOffset; \
206       \
207       void main() \
208       {   \
209         vec4 pos = uProjection * uModelView * vec4(aPosition, 1.0); \
210         pos.x= 3*pos.z*(sin(1.57+uOffset+pos.y/1000.0)); \
211         gl_Position =pos; \
212           vColor = pos/500.0;\
213           vTexCoord = aTexCoord; \
214     }"
215   
216     // add the vColor to the pixel color to tint it
217     var fragShader =
218       " \
219        varying lowp vec4 vColor; \
220        void main()               \
221        {                         \
222          gl_FragColor = texture2D( sTexture, vTexCoord ) *uColor + vColor*0.2;  \
223        }"
224   
225     var shaderOptions = {
226           geometryType: "image",
227           vertexShader: vertexShader,
228           fragmentShader: fragShader,
229           geometryHints: ["grid"]
230     };
231   
232     // create a new shader effect
233     var shader = new dali.ShaderEffect(shaderOptions);
234   
235     // set the uniform
236     shader.setUniform("uOffset",0.0);
237     return shader;
238 }
239   
240
241 dali.stage.setBackgroundColor( dali.COLOR_WHITE);
242
243 var image = new dali.ResourceImage( { url:getImageDirectory() +"gallery-medium-50.jpg"});
244 var imageActor = new dali.ImageActor( image );
245 imageActor.parentOrigin = dali.CENTER;
246 imageActor.setCullFace( dali.CULL_FACE_DISABLE ); // disable face culling so we can see both sides
247 dali.stage.add( imageActor );
248   
249 // start it of tilted around the y-axis
250 imageActor.orientation=new dali.Rotation(90, 0, 1, 0);
251   
252 var twistEffect = createTwistEffect();
253 imageActor.setShaderEffect( twistEffect );
254   
255 var shaderAnim = new dali.Animation(1);
256 var animOptions = {
257           alpha: "bounce",
258           duration:20
259       };
260 shaderAnim.animateTo( twistEffect, "uOffset",20,animOptions);
261   
262 shaderAnim.play();
263 ```
264 Note: In order for fade and color animations to work, the fragment shader needs to multiply the fragment color
265 with the uniform color "uColor" of the node
266
267 @class ShaderEffect
268 */