index.html
html · 139 lines · part of Raytracer 001 - 3 spheres with normals · raw
<html>
<title>WebGL Fragment Shader Canvas</title>
<script src="webgl_fragment_framework.001.js"></script>
<script id="shader" type="x-shader/x-fragment">
#ifdef GL_ES
precision mediump float;
#endif
varying vec3 vPosition;
uniform float uTime;
uniform vec2 uMousePos;
vec3 ray;
vec3 dir;
vec4 sphere_pos[3];
vec3 sphere_col[3];
float intersectSphere( in vec3 ray, in vec3 dir, in vec3 sphere_pos, in float radius )
{
float x = sphere_pos.x;
float y = sphere_pos.y;
float z = sphere_pos.z;
float a, b, c, d, t1, t2;
a = dir.x * dir.x + dir.y * dir.y + dir.z * dir.z;
b = 2.0 * (dir.x * (ray.x - x) + dir.y * (ray.y - y) + dir.z * (ray.z - z));
c = (ray.x - x) * (ray.x - x) + (ray.y - y) * (ray.y - y) + (ray.z - z) * (ray.z - z) - radius * radius;
d = b * b - 4.0 * a * c;
if( d <= 0.0 ) return 0.0;
d = sqrt(d);
t2 = (-b + d) / (2.0 * a);
t1 = (-b - d) / (2.0 * a);
if( t1 > t2 ) return t2;
return t1;
}
int intersect( in vec3 ray, in vec3 dir, out vec3 col, out vec3 pos, out vec3 normal, out vec3 reflection )
{
float max_t = 9999999.0;
int found_i = -1;
for( int i = 0; i<3; i++ )
{
float t = intersectSphere( ray, dir, sphere_pos[i].xyz, sphere_pos[i].w );
if( t > 0.0001 && t < max_t )
{
max_t = t;
found_i = i;
}
}
if( found_i == -1 )
{
col = vec3( 0.0, 0.0, 0.0 );
pos = vec3( 0.0 );
normal = vec3( 0.0 );
reflection = vec3( 0.0 );
return -1;
}
for( int i = 0; i<3; i++ )
{
if( found_i == i )
{
pos = ray + max_t * dir;
normal = (pos - sphere_pos[i].xyz) / sphere_pos[i].w;
reflection = dir - 2.0*normal*dot( dir, normal );
col = sphere_col[i];
}
}
return found_i;
}
void main(void)
{
sphere_pos[0] = vec4(-1.0,0.0,4.0,0.5);
sphere_col[0] = vec3(0.5,0.0,1.0);
sphere_pos[1] = vec4(1.0,0.5,3.0,0.25);
sphere_col[1] = vec3(1.0,0.75,1.0);
sphere_pos[2] = vec4(0.2,-0.75,3.5,0.75);
sphere_col[2] = vec3(0.0,-0.75,1.0);
ray = vec3( 0.0, 0.0, 0.0 );
dir = normalize( vPosition );
vec3 col;
vec3 pos;
vec3 normal;
vec3 reflection;
int sphere_index = intersect( ray, dir, col, pos, normal, reflection );
gl_FragColor = vec4( normal*0.5 + 0.5, 1.0 );
}
</script>
<body onload="webgl_init( 'canvas', 'shader', 'status' )" bgcolor="#000000">
<table cellspacing="0" cellpadding="0" border="0" width="100%" height="100%"><tr><td align="center" valign="middle">
<table cellspacing="0" cellpadding="0" border="0" width="640">
<tr>
<td style="padding:8px;background:#555555;color:#FFFFFF;font-family:arial;font-size:11px;font-weight:bold">
<div>WebGL Fragment Shader Raytracer - 3 Spheres - Basic intersection test and normal calculation</div>
</td>
</tr>
<tr>
<td><canvas id="canvas" width="640" height="640" style="border:5px solid #FFFFFF"></canvas></td>
</tr><tr>
<td style="padding:8px;background:#555555;color:#FFFFFF;font-family:arial;font-size:11px;font-weight:bold">
<div id="status"> </div>
</td>
</tr>
</table>
</td></tr></table>
</body>
</html>