DALi Version 1.3.45
[platform/core/uifw/dali-demo.git] / resources / shaders / raymarch_sphere_shaded.fsh
1 /*
2  * Fragment shader for textured quad
3  */
4 varying mediump vec2 vTexCoord;
5 varying mediump vec2 vRayCastCoord;
6
7 uniform mediump float uRadius;
8 uniform mediump float uAdjuster;
9
10 #define CAMERA_Z_POSITION 1.0  // gives us a FOV of 90 degrees if Plane of projection is at Z = 0 with size 2x2
11 #define SPHERE_Z_POSITION -1.0 // Sphere placed behind Plane of projection
12 #define SPHERE_RADIUS 0.5
13
14
15 // signed distance function
16 // returns
17 // < 0 if inside sphere
18 // 0 == on sphere surface
19 // > 1 if outside sphere
20 mediump float distanceToSphere( mediump vec3 point, mediump vec3 sphereCenter, mediump float radius )
21 {
22   return distance( point, sphereCenter ) - radius;
23 }
24
25 // Simulate a simple spot light ( there's no ambient light in this example)
26 mediump vec4 lightSphere( mediump vec3 point, mediump vec3 sphereCenter )
27 {
28    // the normal = direction of the vector from the sphere center to the point on the surface of the sphere
29    mediump vec3 normal = normalize( point - sphereCenter );
30
31    // Animate the light around the sphere in a circular motion
32    mediump vec3 lightDirection = vec3( sin(uAdjuster)+uRadius, cos ( uAdjuster )+uRadius, CAMERA_Z_POSITION  );
33
34    // calculate the dot product to give us the intensity of the light bouncing off the surface
35    mediump float value =  dot( normal , lightDirection);
36
37    // add a purple tint to the final color by adjust green channel by 0.84
38    return vec4( value, value * 0.843, value , 1.0);
39
40 }
41
42 void main()
43 {
44   // The fragment shader is called for every pixel that is to be drawn for our
45   // quad geometry ( 2 triangles ). The size and number of pixels drawn is
46   // determined by the size / position of the quad and the DALi camera position.
47   //
48   // For this example the vRayCastCoord is currently set to the range -1 to 1 by the Vertex Shader
49   //
50   // (-1,-1)
51   //    |--------------|
52   //    |       |      |
53   //    |       |      |
54   //    |_____(0,0)____|
55   //    |       |      |
56   //    |       |      |
57   //    |_______|______|(1,1)
58
59   mediump vec3 pixelPosition = vec3( vRayCastCoord, 0.0 );
60
61   // uncomment line below to see red / green colors only visible when x > 0, or y > 0
62   // gl_FragColor = vec4( pixelPosition, 1.0 ); return;
63
64   // We are going to assume there is a virtual camera infront of the plane of projection
65   // Side view:
66   //                projection
67   //                  plane (2x2)
68   //                  /|
69   //                /  |
70   //              /    |      /----\
71   //        Camera---->|     (SPHERE)
72   //              \    |      \----/
73   //                \  |
74   //                  \|
75   //      z=1        z=0     z  = -1
76   //
77   //
78   //  Why z=1 for camera? Our projection plane is at z = 0, with plane size 2x2 which gives a 90 degree FOV
79   // from the camera to the projection plane
80   //
81   mediump vec3 cameraPos = vec3( 0.0, 0.0, CAMERA_Z_POSITION );
82
83   // calculate the ray direction from the camera to the pixel on the quad
84   mediump vec3 rayDirection = normalize(  pixelPosition - cameraPos );
85
86   // uncomment to visualize the normalized ray direction vector
87   // gl_FragColor = vec4( rayDirection, 1.0 ); return;
88
89   // Setup the position on radius of our virtual sphere
90   mediump vec3 spherePosition = vec3( 0.0, 0.0, SPHERE_Z_POSITION );
91   mediump float sphereRadius = SPHERE_RADIUS + uRadius ; // use uRadius to animate radius from small to large
92
93   // We have the direction of the ray from the camera, now see if it
94   // hits our sphere using ray marching
95   // starting at a pixel position 0 on our projection plane, step in the direction
96   // of ray from the camera to see if it hits our sphere
97   // The concept of ray marching is the step size = minimum distance to an object
98
99   mediump vec3 hitPoint = pixelPosition;
100
101   int steps = 5;
102
103   for( int i = 0; i < steps ; ++i )
104   {
105       // calculate the shortest distance between our hitPoint and the sphere
106       mediump float distance = distanceToSphere( hitPoint, spherePosition, sphereRadius );
107
108       // if the distance < 0 then were inside the sphere
109       // if the distance > 0 then were outside the sphere
110       // if we're close to the edge of the sphere, then draw it
111       if( distance < 0.01 )
112       {
113         gl_FragColor = lightSphere(  hitPoint, spherePosition );
114         return;
115       }
116
117       // move the hit point along by the distance to the spin the direction of the ray
118       hitPoint +=  rayDirection * distance;
119
120   }
121   // no hit, color the pixel based on it's x,y position
122   gl_FragColor = vec4(pixelPosition.x,pixelPosition.y,0.5,1);
123
124 }