Shader compilation tool for dali-toolkit
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / graphics / shaders / motion-blur-effect.vert
1 precision mediump float;
2
3 attribute vec2 aPosition;
4
5 uniform mat4 uMvpMatrix;
6 uniform mat4 uModelView;
7 uniform mat4 uViewMatrix;
8 uniform mat4 uProjection;
9 uniform vec3 uSize;
10
11 uniform mat4 uModelLastFrame;
12 float timeDelta = 0.0167;
13
14 uniform float uGeometryStretchFactor;
15 uniform float uSpeedScalingFactor;
16
17 // outputs
18 varying vec2 vModelSpaceCenterToPos;
19 varying vec2 vScreenSpaceVelocityVector;
20 varying float vSpeed;
21 varying vec2 vTexCoord;
22
23 void main()
24 {
25   // get view space position of vertex this frame and last frame
26   vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);
27   vertexPosition.xyz *= uSize;
28
29   vec4 viewSpaceVertex = uModelView * vertexPosition;
30   vec4 viewSpaceVertexLastFrame = (uViewMatrix * uModelLastFrame) * vertexPosition;
31   float reciprocalTimeDelta = 1.0 / timeDelta;
32
33   // work out vertex's last movement in view space
34   vec3 viewSpacePosDelta = viewSpaceVertex.xyz - viewSpaceVertexLastFrame.xyz;
35
36   // get clip space position of vertex this frame and last frame
37   vec4 clipSpaceVertex = uMvpMatrix * vertexPosition;
38   vec4 clipSpaceVertexLastFrame = uProjection * viewSpaceVertexLastFrame;
39
40   // decide how much this vertex is 'trailing', i.e. at the back of the object relative to its direction of motion. We do this
41   // by assuming the objects model space origin is at its center and taking the dot product of the vector from center to vertex with the motion direction
42   float t = 0.0;
43   float posDeltaLength = length(viewSpacePosDelta);
44   if(posDeltaLength > 0.001) // avoid div by 0 if object has barely moved
45   {
46     vec4 viewSpaceCenterToPos = uModelView * vec4(vertexPosition.xy, 0.0, 0.0);
47     float centerToVertexDist = length(viewSpaceCenterToPos);
48     if(centerToVertexDist > 0.001) // avoid div by 0 if object has vertex at model space origin
49     {
50       vec3 viewSpacePosDeltaNormalised = viewSpacePosDelta / posDeltaLength;
51       vec3 viewSpaceCenterToPosNormalised = viewSpaceCenterToPos.xyz / centerToVertexDist;
52       t = (dot(viewSpacePosDeltaNormalised, viewSpaceCenterToPosNormalised) * 0.5 ) + 0.5; // scale and bias from [-1..1] to [0..1]
53     }
54   }
55   // output vertex position lerped with its last position, based on how much it is trailing,
56   // this stretches the geom back along where it has just been, giving a warping effect
57   // Note: we must take account of time delta to convert position delta into a velocity, so changes are smooth (take into account frame time correctly)
58   gl_Position = mix(clipSpaceVertexLastFrame, clipSpaceVertex, t * uGeometryStretchFactor * reciprocalTimeDelta);
59
60   // work out vertex's last movement in normalised device coordinates [-1..1] space, i.e. perspective divide
61   vec2 ndcVertex = clipSpaceVertex.xy / clipSpaceVertex.w;
62   vec2 ndcVertexLastFrame = clipSpaceVertexLastFrame.xy / clipSpaceVertexLastFrame.w;
63   // scale and bias so that a value of 1.0 corresponds to screen size (NDC is [-1..1] = 2)
64   vScreenSpaceVelocityVector = ((ndcVertex - ndcVertexLastFrame) * 0.5 * reciprocalTimeDelta);
65   vScreenSpaceVelocityVector.y = -vScreenSpaceVelocityVector.y; // TODO negated due to y being inverted in our coordinate system?
66   // calculate a scaling factor proportional to velocity, which we can use to tweak how things look
67   vSpeed = length(vScreenSpaceVelocityVector) * uSpeedScalingFactor;
68   vSpeed = clamp(vSpeed, 0.0, 1.0);
69
70   // provide fragment shader with vector from center of object to pixel (assumes the objects model space origin is at its center and verts have same z)
71   vModelSpaceCenterToPos = viewSpaceVertex.xy;
72
73   vec2 texCoord = aPosition + vec2(0.5);
74   vTexCoord = texCoord;
75 }