Raytracer 2 We start with some bits we missed in the previous - - PowerPoint PPT Presentation

raytracer 2
SMART_READER_LITE
LIVE PREVIEW

Raytracer 2 We start with some bits we missed in the previous - - PowerPoint PPT Presentation

Raytracer 2 We start with some bits we missed in the previous lecture General camera in word coordinates (we positioned in (0,0,0) in the previous slides Computing refraction term without trigo (by means of dot products) Some


slide-1
SLIDE 1

Raytracer 2

  • We start with some bits we missed in the

previous lecture

– General camera in word coordinates (we positioned in (0,0,0) in the previous slides – Computing refraction term without trigo (by means of dot products)

  • Some ray tracer acceleration techniques
  • Overview of the basic version of the algorithm

– To make your life a bit easier during the ex.

slide-2
SLIDE 2

Eye LUV Coordinates

(Gram-Schmidt Ortho-normalization) lookat eye up u v l l = (lookat - eye)/||(lookat - eye)|| v = (l × up)/||(l × up)|| u = v × l

slide-3
SLIDE 3

Pixels in World Coords

  • aspect ratio a = w/h
  • focal length d = 1/tan(fovy/2)

ll = eye + d l – a v – u eye dl

  • av
  • u

ll fovy

for (j = 0; j < VRES; j++) { for (i = 0; i < HRES; i++) { p = ll + 2av (double)i/HRES + 2u (double)j/VRES; color = TraceRay(Ray(eye, p - eye)); plot(i,j,color); } } for (j = 0; j < VRES; j++) { for (i = 0; i < HRES; i++) { p = ll + 2av (double)i/HRES + 2u (double)j/VRES; color = TraceRay(Ray(eye, p - eye)); plot(i,j,color); } }

slide-4
SLIDE 4

Refract (using dot products)

Snell’s Law: ηi sin θi = ηt sin θt Let η =ηi /ηt = sin θt / sin θi Let m = (cos θi n - i) / sin θi Then… t = sin θt m - cos θt n = (sin θt / sin θi) (cos θi n - i) - cos θt n = (η cos θi - cos θt )n - η i

( )

i n i n i n t η η η − ⋅ − − − ⋅ = ) ) ( 1 ( 1 ) (

2 2

cos θi n - i i n

  • n

θi θt t = ? m

i t t

θ η θ θ

2 2 2

sin 1 sin 1 cos − = − =

Ray refract(Ray r) { double ni = dot(n,-r.d); double eta = current_index/new_index; return Ray((x,eta*ni - sqrt(1 - eta*eta*(1-ni*ni)))*n + eta*r.d); } Ray refract(Ray r) { double ni = dot(n,-r.d); double eta = current_index/new_index; return Ray((x,eta*ni - sqrt(1 - eta*eta*(1-ni*ni)))*n + eta*r.d); } Can be negative for grazing angles when η >1, say when going from glass to air, resulting in total internal reflection (no refraction). Can be negative for grazing angles when η >1, say when going from glass to air, resulting in total internal reflection (no refraction).

cos θi n

slide-5
SLIDE 5

Ray Tracing Acceleration

slide-6
SLIDE 6

Bounding Volume Hierarchies

  • The basic concept of a bounding volume hierarchy is a complex object in a

hierarchy of simpler ones

  • This works much like the hierarchical culling we looked at in the scene

graph lecture

  • For example, if one were using spheres as their bounding volume, we could

enclose the entire scene in one big sphere

  • Within that sphere are several other spheres, each containing more

spheres, until we finally get to the bottom level where spheres contain actual geometry like triangles

  • To test a ray against the scene, we traverse the hierarchy from the top level
  • When a sphere is hit, we test the spheres it contains, and ultimately the

triangles/primitives within

  • In general, a bounding volume hierarchy can reduce the ray intersection

time from O(n) to O(log n), where n is the number of primitives in the scene

  • This reduction from linear to logarithmic performance makes a huge

difference and makes it possible to construct scenes with millions of primitives

slide-7
SLIDE 7

Sphere Hierarchies

  • The sphere hierarchy makes for a good example of the concept, but in

practice, sphere hierarchies are not often used for ray tracing

  • One reason is that it is not clear how to automatically group an arbitrary set
  • f triangles into some number of spheres, so various heuristic options exist
  • Also, as the spheres are likely to overlap a lot, they end up triggering a lot
  • f redundant intersection tests
slide-8
SLIDE 8

Octrees

  • The octree starts by placing a cube around the entire scene
  • If the cube contains more than some specified number of primitives

(say, 10), then it is split equally into 8 cubes, which are then recursively tested and possibly resplit

  • The octree is a more regular structure than the sphere tree and

provides a clear rule for subdivision and no overlap between cells

  • This makes it a better choice usually, but still not ideal

Note: the drawing is actually a 2D quadtree, but the octree is a 3D extension of this concept

slide-9
SLIDE 9

KD Trees

  • The KD tree starts by placing a box (not necessarily a cube) around the entire scene
  • If the box contains too many primitives, it is split, as with the octree
  • However, the KD tree only splits the box into two boxes, that need not be equal
  • The split can take place on the x, y, or z place at some arbitrary point within the box
  • This makes the KD tree a little bit more adaptable to irregular geometry and able to

customize a tighter fit

  • In general, KD trees tend to be pretty good for ray tracing
  • Their main drawback is that the tree depth can get rather deep, causing the ray

intersection to spend a lot of time traversing the tree itself, rather than testing intersections with primitives

slide-10
SLIDE 10

BSP Trees

  • The BSP tree (binary space partitioning) is much like the KD tree in

that it continually splits space into two (not necessarily equal) halves

  • Unlike the KD tree which is limited to xyz axis splitting, the BSP tree

allows the splitting plane to be placed anywhere in the volume and aligned in any direction

  • This makes it a much more difficult problem to choose the location
  • f the splitting plane, and so many heuristics exist
  • In practice, BSP trees tend to perform well for ray tracing, much like

KD trees

slide-11
SLIDE 11

Uniform Grids

  • One can also subdivide space into a uniform grid, instead of hierarchically
  • This is fast for certain situations, but gets too expensive in terms of memory

for large complex scenes

  • It also tends to loose its performance advantages in situations where

primitives have a large variance in size and location (which is common)

  • As a result, they are not really a practical general purpose acceleration

structure for ray tracing, although they are useful in certain situations

slide-12
SLIDE 12

Hierarchical Grids

One can also make a hierarchical grid Start with a uniform grid, but subdivide any cell that

contains too many primitives into a smaller grid

An octree is an example of a hierarchical grid limited to

2x2x2 subdivision

A more general hierarchical grid could support

subdivision into any number of cells

Hierarchical grids tend to perform very well in ray

tracing, especially for highly detailed geometry of relatively uniform size (such as the triangles in a tessellated surface)

slide-13
SLIDE 13

Ray Tracing Acceleration Techniques

Acceleration Techniques Faster Intersections Fewer Rays Generalized Rays Fewer ray-object intersections Faster ray-object intersections Volume hierarchies Spatial subdivision Directional techniques Bounding volumes Efficient surfaces Adaptive tree-depth Adaptive sampling Beam tracing Cone tracing Pencil tracing

slide-14
SLIDE 14

Ray tracer pseudo-code

slide-15
SLIDE 15

Generating Rays

Trace a ray for each pixel in the image

plane

renderImage(){ for each pixel i, j in the image ray.setStart(0, 0, 0); // ro ray.setDir ((.5 + i) * tan(fovx)* 2 / m, (.5 + j) * tan(fovy)* 2 / n, 1.0); // rd ray.normalize(); image[i][j] = rayTrace(ray); }

slide-16
SLIDE 16

Recursive ray evaluation

rayTrace(ray) { hitObject(ray, p, n, triangle); color = object color; if(object is light) return(color); else return(lighting(p, n, color)); }

slide-17
SLIDE 17

Finding Intersections

Check all triangles, keep the closest

intersection

hitObject(ray) { for each triangle in scene does ray intersect triangle? if(intersected and was closer) save that intersection if(intersected) return intersection point and normal }

slide-18
SLIDE 18

Calculating surface color

lighting(point) { color = ambient color; for each light if(hitObject(shadow ray)) color += lightcolor * dot(shadow ray, n); color += rayTrace(reflection) * pow(dot(reflection, ray), shininess); return(color); }

slide-19
SLIDE 19

Putting It All Together

The main program

main() { triangles = readTriangles(); image = renderImage(triangles); writeImage(image); }