A few questions about ray tracing with opengl

I need to do a limited form of ray tracing. I do not need reflection. I only need to change the color of the pixel, depending on how it passes the object, and refraction. I also need to check only the intersection of rays 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 about the origin of the beam. How to get its location? Right now, I'm just playing around until it looks right, but if I change the width or height of the screen, I have to play until it looks right.

My second question is about the intersection between the beam and the disk. I do this by first checking to see if the ray crosses the plane, and then if the intersection point is within the radius of the disk. My code is as follows:

 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 the body [count] .radius is less than or equal to the z-position of the radial origin, then nothing appears. So

 if(det>0) { if(distance(det*ray.direction,bodies[count].position)<=.76) { return vec4(1.0,0.0,0.0,1.0); } } 

leads to the appearance of visible disks, and when using the actual radius, nothing happens.

+7
source share
3 answers

As for your second question: do not use distance, use the square of the distance. This speeds up the processing, and I suspect that this may solve your problem.

+3
source
  • The origin of the beam is really up to you, but I recommend that you specify a start point so that the positions of the pixels are approximately equidistant from the origin and objects.

  • Be careful with the direction of the beam, which means that the objects you are trying to see must be in front of the camera. (The rays that are sent must hit objects.)

+1
source

The intersection point of the beam and the plane is calculated as follows:

 dist = dot( plane_origin - ray.origin, plane_NV ) / dot( ray.direction, plane_NV ); plane_isect = ray.origin + ray.direction * dist; 

Your intersectPlane function correctly calculates the distance from the beginning of the ray to the point of intersection of the plane, but you do not calculate the intersection point before comparing it to the center of the disks.

To check if the intersection point is in radius, you should do the following:

 vec3 plane_isect = ray.origin + det * ray.direction; if ( distance( plane_isect, bodies[count].position ) <= bodies[count].radius ) 

Adapt your code as follows:

 det = intersectPlane( ray, bodies[count].position, vec3(0,0,1) ); if ( det>0 ) { vec3 plane_isect = ray.origin + det * ray.direction; if ( distance( plane_isect, bodies[count].position ) <= bodies[count].radius ) { return vec4(1.0,0.0,0.0,1.0); } } 
+1
source

All Articles