In Files

  • benchmark/bm_ao_render.rb

Scene

Public Class Methods

new() click to toggle source
 
               # 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
            

Public Instance Methods

ambient_occlusion(isect) click to toggle source
 
               # 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 |j|
    ntheta.times do |i|
      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 then
        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
            
render(w, h, nsubsamples) click to toggle source
 
               # 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 then
            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