# File benchmark/bm_ao_render.rb, line 204 def initialize @spheres = Array.new @spheres[0] = Sphere.new(Vec.new(-2.0, 0.0, -3.5), 0.5) @spheres[1] = Sphere.new(Vec.new(-0.5, 0.0, -3.0), 0.5) @spheres[2] = Sphere.new(Vec.new(1.0, 0.0, -2.2), 0.5) @plane = Plane.new(Vec.new(0.0, -0.5, 0.0), Vec.new(0.0, 1.0, 0.0)) end
# File benchmark/bm_ao_render.rb, line 212 def ambient_occlusion(isect) basis = Array.new(3) otherBasis(basis, isect.n) ntheta = NAO_SAMPLES nphi = NAO_SAMPLES eps = 0.0001 occlusion = 0.0 p0 = Vec.new(isect.pl.x + eps * isect.n.x, isect.pl.y + eps * isect.n.y, isect.pl.z + eps * isect.n.z) nphi.times do ntheta.times do r = Rand::rand phi = 2.0 * 3.14159265 * Rand::rand x = Math.cos(phi) * Math.sqrt(1.0 - r) y = Math.sin(phi) * Math.sqrt(1.0 - r) z = Math.sqrt(r) rx = x * basis[0].x + y * basis[1].x + z * basis[2].x ry = x * basis[0].y + y * basis[1].y + z * basis[2].y rz = x * basis[0].z + y * basis[1].z + z * basis[2].z raydir = Vec.new(rx, ry, rz) ray = Ray.new(p0, raydir) occisect = Isect.new @spheres[0].intersect(ray, occisect) @spheres[1].intersect(ray, occisect) @spheres[2].intersect(ray, occisect) @plane.intersect(ray, occisect) if occisect.hit occlusion = occlusion + 1.0 else 0.0 end end end occlusion = (ntheta.to_f * nphi.to_f - occlusion) / (ntheta.to_f * nphi.to_f) Vec.new(occlusion, occlusion, occlusion) end
# File benchmark/bm_ao_render.rb, line 256 def render(w, h, nsubsamples) cnt = 0 nsf = nsubsamples.to_f h.times do |y| w.times do |x| rad = Vec.new(0.0, 0.0, 0.0) # Subsmpling nsubsamples.times do |v| nsubsamples.times do |u| cnt = cnt + 1 wf = w.to_f hf = h.to_f xf = x.to_f yf = y.to_f uf = u.to_f vf = v.to_f px = (xf + (uf / nsf) - (wf / 2.0)) / (wf / 2.0) py = -(yf + (vf / nsf) - (hf / 2.0)) / (hf / 2.0) eye = Vec.new(px, py, -1.0).vnormalize ray = Ray.new(Vec.new(0.0, 0.0, 0.0), eye) isect = Isect.new @spheres[0].intersect(ray, isect) @spheres[1].intersect(ray, isect) @spheres[2].intersect(ray, isect) @plane.intersect(ray, isect) if isect.hit col = ambient_occlusion(isect) rad.x = rad.x + col.x rad.y = rad.y + col.y rad.z = rad.z + col.z else 0.0 end end end r = rad.x / (nsf * nsf) g = rad.y / (nsf * nsf) b = rad.z / (nsf * nsf) printf("%c", clamp(r)) printf("%c", clamp(g)) printf("%c", clamp(b)) end end end