Suppose we have a basic ray tracer where we send a shadow and reflection ray.
The basic code (where rgb colors geometric vectors are vec3) will look like:
vec3 rayColor(ray r, int depth) {
vec3 color(0)
if (depth > maxDepth) return color
if (hitsScene(r)) { // somehow this passes back state like hitpoint p
if (Rs > 0) { // Rs is rgb specular reflectance
ray s(p, reflect(r, N))
color += rayColor(s, depth+1)
}
if (Rd > 0) { //Rd is rgb diffuse reflectance
ray shadow(p, L) // L is the direction to the one light
if (not hitsScene(shadow)) {
color += Rd*lightColor*max(0, dot(N,L) )
}
}
}
else
color = background(r)
return color
}
The three spheres we add to get fuzzy effect. |
vec3 rayColor(ray r, int depth) {
vec3 color(0)
if (depth > maxDepth) return color
if (hitsScene(r)) { // somehow this passes back state like hitpoint p
if (Rs > 0) { // Rs is rgb specular reflectance
// radius_specular is a material parameter where 0 = perfect
ray s(p, reflect(r, N)+ radius_specular*rs())
color += rayColor(s, depth+1)
}
if (Rd > 0) { //Rd is rgb diffuse reflectance
ray shadow(p, L + radius_shadow*rs()) // L is the direction to the one light
if (not hitsScene(shadow)) {
color += Rd*lightColor*max(0, dot(N,L) )
}
ray diffuse(p, N + rs()) // assumes N is unit length
color += Rd*rayColor(diffuse, depth+1)
}
}
else
color = background(r)
return color
}
2 comments:
The code can't seem to decide if rs is a variable or a function.
Trying to force a world-space endpoint into the ray definition doesn't seem helpful, especially given that the original code doesn't do it. I think it would be clearer if rs was a parameterless function (e.g., it returned a random vector in the unit sphere centered at the origin). Then you could use:
ray shadow(p, L + rs() * radius_diffuse)
Alternatively, mention that the 2-parameter form could be used as an alias for a direction perturbation function:
#define perturbDirection rs
ray shadow(p, perturbDirection(L, radius_diffuse))
You are right; that code will be much cleaner! Thanks!
The comment above will not make a lot of sense once I change the blog post to reflect the suggestion: for those that want to see what the fuss was if the rs(center, radius) function is used (as it was in the original blog post) with the ray endpoint as the "center" the code is much uglier.
Post a Comment