I need to do a limited form of ray tracing. I do not need reflections. I only need to change the color of a pixel, depending on how it passes by an object, and refraction. I also only need to test for intersections between the ray and spheres and disks, nothing else.
This is the main function in my shader:
void main(void)
{
Ray ray;
ray.origin=vec3(0.5,0.5,.75);
ray.direction=vec3(gl_FragCoord.x/width,gl_FragCoord.y/height,-gl_FragCoord.z)-ray.origin;
ray.direction=normalize(ray.direction);
gl_FragColor=trace(ray);
}
My first question is regarding the origin of the ray. How do I get its location? Right now, I just fiddle around until it looks right, but if I change the width or height of the screen I have to play around until it looks right.
My second question is about the intersection between a ray and a disk. I do this by first checking to see if the ray intersects a plane and then if the intersection point is within the radius of the disk. My code looks like this
float intersectPlane(Ray ray,vec3 point,vec3 normal)
{
return dot(point-ray.origin,normal)/dot(ray.direction,normal);
}
...
det=intersectPlane(ray,bodies[count].position,vec3(0,0,1));
if(det>0)
{
if(distance(det*ray.direction,bodies[count].position)<=bodies[count].radius)
{
return vec4(1.0,0.0,0.0,1.0);
}
}
The problem is that if bodies[count].radius is less than or equal to the z-position of the ray's origin then nothing shows up. So
if(det>0)
{
if(distance(det*ray.direction,bodies[count].position)<=.76)
{
return vec4(1.0,0.0,0.0,1.0);
}
}
results in visible disks, while using the actual radius results in nothing.