2010, Dr. Lawlor, CS 481/681, CS, UAF

- The general approach in modern graphics to drawing objects is to combine a small amount of per-vertex or texture data with a huge amount of arithmetic inside a pixel shader. Contrast this with the traditional polygon-rendering approach, where most of the data and work is per-vertex, and almost nothing happens per pixel.
- Yes, you can store arbitrary floating-point data in a texture.
- You can also store conventional images in a texture, and render into textures.

- One way to draw arbitrary objects inside a pixel shader is via raytracing: substitute the ray equation (P=C+t*D) into the object's equation (for example, length(P)==r), and solve for the ray-object intersection distance t. Throw away intersections behind the camera or farther away than other closer objects.
- We figured out how to raytrace arbitrary quadric objects, which can be transformed by an arbitrary matrix and still remain quadrics.

- The easiest way to render multiple objects
is to output a depth at each pixel (gl_FragDepth), and just keep the
color (gl_FragColor) for the closest object. This is called the
"Z-buffer" method, and it has the huge advantage that the outputs from
utterly unrelated rendering algorithms can be mixed together (e.g.,
raytracing and conventional polygons).

- One trick for speeding up raytracers is to build a bounding volume hierarchy: if
a ray misses the root bounding sphere, you don't need to check any of
the recursive child bounding spheres. There's even a whole class
of geometry called iterated function systems that consists solely of
recursive child bounding volumes!

- Once you've found an object intersection, you compute lighting.
- Classic lighting is a combination of diffuse Lambertian
illumination (clamp(dot(N,L),0.0,1.0)) and/or specular highlights
(pow(dot(N,H),500.0)). You just need a normal to compute these.

- In a raytracer, shadows can be computed by shooting a "shadow ray" from the object intersection toward the light source--if you hit anything along that ray, it will shadow you.
- In a raytracer, mirrored objects can be computed via recursive raytracing:
shoot a second "reflected ray" and (recursively) figure out the color
of what it hits. It's easy enough to transform recursion into
iteration, to run directly in a pixel shader (modern GPUs do not
support recursion). You can support refraction in the same way.

- The atmosphere
also interacts with light, by scattering out geometry light and
scattering in light from the sky, causing distant objects to get
bluer. You can even compute closed-form planetary atmosphere scattering, via my(?) method using an approximation to "erf".