Ray tracing Tutorial Lukas Herzberger
Agenda Ray tracing algorithm (lab 4a) Intersection tests Ray tracing algorithm (lab 4b) Hints & common mistakes
Agenda Ray tracing algorithm (lab 4a) Intersection tests Ray tracing algorithm (lab 4b) Hints & common mistakes
Ray tracing algorithm For each pixel on image: Construct camera ray Find first object hit by ray and its surface normal Set pixel color to value computed from hit point, light and normal
Useful data structures Scene: holds our geometry, camera, light sources Ray: origin + direction (vec3 / vec4) SceneObject: geometry, material, transform implementint an intersection function (could also be in an Intersection class if you want to separate data and functionality) IntersectionRecord: containing information about our intersection tests, like - t distance between ray s origin and intersection point - normal the surface normal at the intersection point - object the object that was hit
Ray tracing algorithm List<SceneObject> objectlist for (y=0; y < image.height; ++y) for (x=0; x < image.width; ++x) ray = camera.constructeyeray(x,y) color = trace(ray, objectlist) image.setcolor(x,y,color)
Constructing camera rays Ray: origin & direction Camera/Eye/Viewing ray: origin = camera s position ray-direction =? For pixel (x,y) find point p on image plane ray-direction = normalize( p - camera.position )
Constructing camera rays Some hints: field of view(fov) is in degrees but most math libraries use radians! Find camera s base vectors: - viewing direction = lookat - position - right = viewing direction X scene.up -!!!up = right X viewing direction Find width/height of our image plane using fov: tan(alpha) = opposite / adjacent opposite = adjacent * tan(alpha)
Ray tracing algorithm List<SceneObject> objectlist for (y=0; y < image.height; ++y) for (x=0; x < image.width; ++x) ray = camera.constructeyeray(x,y) color = trace(ray, objectlist) image.setcolor(x,y,color)
Tracing a ray Find closest intersection Determine color of our intersection point
Tracing a ray trace(ray,objectlist) for(sceneobject object in objectlist) result = object.intersect(ray) //determine smallest result.t > 0! if (no intersection) return backgroundcolor else return result.color
What this will give us:
Adding illumination For each intersection: find exact point & normal use normal, object s material and light direction to shade point using a local illumination model (e.g. Phong, Blinn-Phong, Cook-Torrance, etc.)
Adding illumination trace(ray,objectlist) for(sceneobject object in objectlist) result = object.intersect(ray) //determine smallest result.t > 0! if (no intersection) return backgroundcolor else //determine intersection point Vec4 ip = ray.origin + result.t*ray.direction Vec4 normal = result.normal Vec4 color = shade(ray,object,ip,normal,light) return color
Multiple light sources else //determine intersection point Vec4 ip = ray.origin + result.t*ray.direction Vec4 normal = result.normal Vec4 color; for (LightSource light in lightsources) color += shade(ray,object,ip,normal,light) return color
Shadows For each light source: cast Shadow ray from intersection point to light source if ray hits anything between intersection point and light source the point is not affected by this light source directly -> ignore this light source!
What this will give us:
Agenda Ray tracing algorithm (non-recursive) Intersection tests Ray tracing algorithm (recursive) Hints & common mistakes
Intersection tests A ray is defined as: X = e + t d e origin d direction t > 0 We want to find points that lie on this ray!
Intersection tests: Sphere A sphere is defined as: In vector form: When we plug in our ray we get:
Intersection tests: Sphere Ray plugged into our sphere equation: After rearranging the terms: We can now see that this is a very simple problem:
Intersection tests: Sphere Our problem: in the form of: When we solve after t we get:
Intersection tests: Sphere When we look at our equation once again, we can see that we can still optimize some things: Calculating square roots is quite expensive Just looking at the discriminant will tell us, if the test will be successful or not: disc. > 0 : two intersections disc. = 0 : one intersection disc. < 0 : no intersection > return false!
Intersection tests: Triangle Having a triangle with a, b and c as its vertices, we can say that an intersection will occur when: But only if β > 0, γ > 0 and β + γ < 1 To solve this and get all three unknowns t, β and γ we ll have to set up a system of equations
Intersection tests: Triangle Our problem: Our system of equations: Rewritten as standard linear equations:
Intersection tests: Triangle Our problem: Solution after Cramer s rule (with A being A s determinant):
Intersection tests: Triangle Let s look at this again with some dummy values and see what Cramer s rule gives us: Linear system with dummy values
Intersection tests: Triangles To make our intersection test cheaper, we have to keep all conditions in mind that have to be fulfilled! t > 0 (and t < t from an earlier intersection test) β > 0 γ > 0 β + γ < 1
Agenda Ray tracing algorithm (non-recursive) Intersection tests Ray tracing algorithm (recursive) Hints & common mistakes
Our Raytracer vs recursive Raytracer
What do we need? Recursion! For every intersection point: Create reflected AND refracted rays! Recursively trace those rays! Stop recursion after max. bounces!
Tracing those rays trace(ray,objectlist, depth) //perform intersection and shading as before... if depth >= maxbounces return color //depending on object's material properties, cast new rays if (object.transmittance > 0) ray.origin = ip ray.direction = calculatetransmittancedirection() colortrans = trace(ray,objectlist, depth+1) if (object.reflectance > 0) ray.origin = ip ray.direction = calculatereflectancedirection() colorrefl = trace(ray,objectlist, depth+1) finalcolor = r*colorrefl + t*colortrans + (1-r-t)*color return finalcolor
Agenda Ray tracing algorithm (non-recursive) Intersection tests Ray tracing algorithm (recursive) Hints & common mistakes
Hints and common mistakes Normalize your vectors! Rays should not hit their own origin! Translate the origin in the its own direction by a very small number (epsilon) before testing for intersections! There is only one ambient light source in the scene! For all other light sources only calculate the diffuse and specular term! Make use of homogenous coordinates but make sure that you separate vectors(w=0) from points(w=1)! You can t translate a vector!
Hints and common mistakes Don t transform your objects - transform your rays! Use the inverse of your transformation matrix to transform your ray s origin and direction! Don t normalize your ray s direction after that! Use the inverse transpose to transform the normal!
Hints and common mistakes Check out this awesome book: Peter Shirley, Michael Ashikhmin, Steve Marschner, Fundamentals of Computer Graphics, 3rd edition, AK Peters/CRC Press 2009
Questions?