2 * Fragment shader for textured quad
4 varying mediump vec2 vTexCoord;
5 varying mediump vec2 vRayCastCoord;
7 uniform mediump float uRadius;
8 uniform mediump float uAdjuster;
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
15 // signed distance function
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 )
22 return distance( point, sphereCenter ) - radius;
25 // Simulate a simple spot light ( there's no ambient light in this example)
26 mediump vec4 lightSphere( mediump vec3 point, mediump vec3 sphereCenter )
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 );
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 );
34 // calculate the dot product to give us the intensity of the light bouncing off the surface
35 mediump float value = dot( normal , lightDirection);
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);
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.
48 // For this example the vRayCastCoord is currently set to the range -1 to 1 by the Vertex Shader
57 // |_______|______|(1,1)
59 mediump vec3 pixelPosition = vec3( vRayCastCoord, 0.0 );
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;
64 // We are going to assume there is a virtual camera infront of the plane of projection
71 // Camera---->| (SPHERE)
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
81 mediump vec3 cameraPos = vec3( 0.0, 0.0, CAMERA_Z_POSITION );
83 // calculate the ray direction from the camera to the pixel on the quad
84 mediump vec3 rayDirection = normalize( pixelPosition - cameraPos );
86 // uncomment to visualize the normalized ray direction vector
87 // gl_FragColor = vec4( rayDirection, 1.0 ); return;
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
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
99 mediump vec3 hitPoint = pixelPosition;
103 for( int i = 0; i < steps ; ++i )
105 // calculate the shortest distance between our hitPoint and the sphere
106 mediump float distance = distanceToSphere( hitPoint, spherePosition, sphereRadius );
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 )
113 gl_FragColor = lightSphere( hitPoint, spherePosition );
117 // move the hit point along by the distance to the spin the direction of the ray
118 hitPoint += rayDirection * distance;
121 // no hit, color the pixel based on it's x,y position
122 gl_FragColor = vec4(pixelPosition.x,pixelPosition.y,0.5,1);