[macruby-changes] [4145] MacRuby/trunk/perf/perf_algo.rb
source_changes at macosforge.org
source_changes at macosforge.org
Tue May 25 01:24:47 PDT 2010
Revision: 4145
http://trac.macosforge.org/projects/ruby/changeset/4145
Author: lsansonetti at apple.com
Date: 2010-05-25 01:24:44 -0700 (Tue, 25 May 2010)
Log Message:
-----------
added the AO bench into the algo perf suite
Modified Paths:
--------------
MacRuby/trunk/perf/perf_algo.rb
Modified: MacRuby/trunk/perf/perf_algo.rb
===================================================================
--- MacRuby/trunk/perf/perf_algo.rb 2010-05-25 01:55:01 UTC (rev 4144)
+++ MacRuby/trunk/perf/perf_algo.rb 2010-05-25 08:24:44 UTC (rev 4145)
@@ -64,3 +64,292 @@
end
perf_test('mandelbrot') { mandelbrot }
+
+module AOBench
+ # AO render benchmark
+ # Original program (C) Syoyo Fujita in Javascript (and other languages)
+ # http://lucille.atso-net.jp/blog/?p=642
+ # http://lucille.atso-net.jp/blog/?p=711
+ # Ruby(yarv2llvm) version by Hideki Miura
+ # http://github.com/miura1729/yarv2llvm/blob/a888d8ce6855e70b630a8673d4cfe075a8e44f0e/sample/ao-render.rb
+ # Modified by Tomoyuki Chikanaga
+ #
+
+ IMAGE_WIDTH = 64 # original value: 256
+ IMAGE_HEIGHT = 64 # original value: 256
+ NSUBSAMPLES = 2
+ NAO_SAMPLES = 6 # original value: 8
+
+ class Vec
+ def initialize(x, y, z)
+ @x = x
+ @y = y
+ @z = z
+ end
+
+ attr_accessor :x, :y, :z
+
+ def vadd(b)
+ Vec.new(@x + b.x, @y + b.y, @z + b.z)
+ end
+
+ def vsub(b)
+ Vec.new(@x - b.x, @y - b.y, @z - b.z)
+ end
+
+ def vcross(b)
+ Vec.new(@y * b.z - @z * b.y,
+ @z * b.x - @x * b.z,
+ @x * b.y - @y * b.x)
+ end
+
+ def vdot(b)
+ @x * b.x + @y * b.y + @z * b.z
+ end
+
+ def vlength
+ Math.sqrt(@x * @x + @y * @y + @z * @z)
+ end
+
+ def vnormalize!
+ len = vlength
+ if len > 1.0e-17
+ r_len = 1.0 / len
+ @x *= r_len
+ @y *= r_len
+ @z *= r_len
+ end
+ self
+ end
+ end
+
+ class Sphere
+ def initialize(center, radius)
+ @center = center
+ @radius_2 = radius * radius
+ end
+
+ def intersect(ray, isect)
+ rs = ray.org.vsub(@center)
+ b = rs.vdot(ray.dir)
+ c = rs.vdot(rs) - @radius_2
+ d = b * b - c
+ if d > 0.0
+ t = - b - Math.sqrt(d)
+
+ isect.cross(self, ray, t)
+ end
+ nil
+ end
+
+ def normal_vec(pos)
+ pos.vsub(@center).vnormalize!
+ end
+ end
+
+ class Plane
+ def initialize(p, n)
+ @p = p
+ @n = n
+ end
+
+ def intersect(ray, isect)
+ d = - at p.vdot(@n)
+ v = ray.dir.vdot(@n)
+ v0 = v
+ if v < 0.0
+ v0 = -v
+ end
+ if v0 < 1.0e-17
+ return
+ end
+
+ t = -(ray.org.vdot(@n) + d) / v
+
+ isect.cross(self, ray, t)
+ nil
+ end
+
+ def normal_vec(pos)
+ @n
+ end
+ end
+
+ class Ray
+ def initialize(org, dir)
+ @org = org
+ @dir = dir
+ end
+ attr_reader :org, :dir
+ end
+
+ class Isect
+ def initialize
+ @t = Float::MAX
+ @hit = false
+ @pl = Vec.new(0.0, 0.0, 0.0)
+ @normal = Vec.new(0.0, 0.0, 0.0)
+ end
+
+ attr_reader :normal
+
+ def hit?
+ @hit
+ end
+
+ def cross(geom, ray, dist)
+ if 0.0 < dist and dist < @t
+ @hit = true
+ @t = dist
+ @pl = Vec.new(ray.org.x + ray.dir.x * dist,
+ ray.org.y + ray.dir.y * dist,
+ ray.org.z + ray.dir.z * dist)
+ @normal = geom.normal_vec(@pl)
+ end
+ nil
+ end
+
+ def surface(eps)
+ Vec.new(@pl.x + eps * @normal.x,
+ @pl.y + eps * @normal.y,
+ @pl.z + eps * @normal.z)
+ end
+ end
+
+ def self.clamp(f)
+ i = f * 255.5
+ if i > 255.0
+ i = 255.0
+ end
+ if i < 0.0
+ i = 0.0
+ end
+ i.round
+ end
+
+ def self.otherBasis(basis, n)
+ basis[2] = Vec.new(n.x, n.y, n.z)
+ basis[1] = Vec.new(0.0, 0.0, 0.0)
+
+ if n.x < 0.6 and n.x > -0.6
+ basis[1].x = 1.0
+ elsif n.y < 0.6 and n.y > -0.6
+ basis[1].y = 1.0
+ elsif n.z < 0.6 and n.z > -0.6
+ basis[1].z = 1.0
+ else
+ basis[1].x = 1.0
+ end
+
+ basis[0] = basis[1].vcross(basis[2])
+ basis[0].vnormalize!
+
+ basis[1] = basis[2].vcross(basis[0])
+ basis[1].vnormalize!
+ end
+
+ class Scene
+ 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
+
+ def ambient_occlusion(isect)
+ basis = Array.new
+ AOBench.otherBasis(basis, isect.normal)
+
+ ntheta = NAO_SAMPLES
+ nphi = NAO_SAMPLES
+ eps = 0.0001
+ occlusion = 0.0
+
+ p0 = isect.surface(eps)
+ nphi.times do |j|
+ ntheta.times do |i|
+ r = rand
+ rr = Math.sqrt(1.0 - r)
+ phi = 2.0 * Math::PI * rand
+ x = Math.cos(phi) * rr
+ y = Math.sin(phi) * rr
+ 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 * nphi - occlusion).to_f / (ntheta * nphi)
+
+ occlusion
+ end
+
+ def render(w, h, nsubsamples)
+ cnt = 0
+ pixbuf = []
+ nsf = nsubsamples.to_f
+ nsf_2 = nsf * nsf
+ h.times do |y|
+ w.times do |x|
+ rad = 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)
+ eye.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?
+ rad += ambient_occlusion(isect)
+ end
+ end
+ end
+
+ pixbuf << AOBench.clamp(rad / nsf_2)
+ end
+ end
+ end
+ end
+
+ def self.test
+ Scene.new.render(IMAGE_WIDTH, IMAGE_HEIGHT, NSUBSAMPLES)
+ end
+end
+
+perf_test('ao_bench') { AOBench.test }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100525/0c1af069/attachment.html>
More information about the macruby-changes
mailing list