Skip to content

Commit 543e892

Browse files
committed
Add unmodified aobench benchmark
1 parent 1db71db commit 543e892

File tree

1 file changed

+297
-0
lines changed

1 file changed

+297
-0
lines changed

bench/classic/aobench.rb

Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
# coding: US-ASCII
2+
3+
# AO render benchmark
4+
# Original program (C) Syoyo Fujita in Javascript (and other languages)
5+
# https://code.google.com/p/aobench/
6+
# Ruby(yarv2llvm) version by Hideki Miura
7+
#
8+
9+
IMAGE_WIDTH = 256
10+
IMAGE_HEIGHT = 256
11+
NSUBSAMPLES = 2
12+
NAO_SAMPLES = 8
13+
14+
srand(0)
15+
16+
class Vec
17+
def initialize(x, y, z)
18+
@x = x
19+
@y = y
20+
@z = z
21+
end
22+
23+
attr_accessor :x, :y, :z
24+
25+
def vadd(b)
26+
Vec.new(@x + b.x, @y + b.y, @z + b.z)
27+
end
28+
29+
def vsub(b)
30+
Vec.new(@x - b.x, @y - b.y, @z - b.z)
31+
end
32+
33+
def vcross(b)
34+
Vec.new(@y * b.z - @z * b.y,
35+
@z * b.x - @x * b.z,
36+
@x * b.y - @y * b.x)
37+
end
38+
39+
def vdot(b)
40+
@x * b.x + @y * b.y + @z * b.z
41+
end
42+
43+
def vlength
44+
Math.sqrt(@x * @x + @y * @y + @z * @z)
45+
end
46+
47+
def vnormalize
48+
len = vlength
49+
v = Vec.new(@x, @y, @z)
50+
if len > 1.0e-17 then
51+
v.x = v.x / len
52+
v.y = v.y / len
53+
v.z = v.z / len
54+
end
55+
v
56+
end
57+
end
58+
59+
60+
class Sphere
61+
def initialize(center, radius)
62+
@center = center
63+
@radius = radius
64+
end
65+
66+
attr_reader :center, :radius
67+
68+
def intersect(ray, isect)
69+
rs = ray.org.vsub(@center)
70+
b = rs.vdot(ray.dir)
71+
c = rs.vdot(rs) - (@radius * @radius)
72+
d = b * b - c
73+
if d > 0.0 then
74+
t = - b - Math.sqrt(d)
75+
76+
if t > 0.0 and t < isect.t then
77+
isect.t = t
78+
isect.hit = true
79+
isect.pl = Vec.new(ray.org.x + ray.dir.x * t,
80+
ray.org.y + ray.dir.y * t,
81+
ray.org.z + ray.dir.z * t)
82+
n = isect.pl.vsub(@center)
83+
isect.n = n.vnormalize
84+
else
85+
0.0
86+
end
87+
end
88+
nil
89+
end
90+
end
91+
92+
class Plane
93+
def initialize(p, n)
94+
@p = p
95+
@n = n
96+
end
97+
98+
def intersect(ray, isect)
99+
d = -@p.vdot(@n)
100+
v = ray.dir.vdot(@n)
101+
v0 = v
102+
if v < 0.0 then
103+
v0 = -v
104+
end
105+
if v0 < 1.0e-17 then
106+
return
107+
end
108+
109+
t = -(ray.org.vdot(@n) + d) / v
110+
111+
if t > 0.0 and t < isect.t then
112+
isect.hit = true
113+
isect.t = t
114+
isect.n = @n
115+
isect.pl = Vec.new(ray.org.x + t * ray.dir.x,
116+
ray.org.y + t * ray.dir.y,
117+
ray.org.z + t * ray.dir.z)
118+
end
119+
nil
120+
end
121+
end
122+
123+
class Ray
124+
def initialize(org, dir)
125+
@org = org
126+
@dir = dir
127+
end
128+
129+
attr_accessor :org, :dir
130+
end
131+
132+
class Isect
133+
def initialize
134+
@t = 10000000.0
135+
@hit = false
136+
@pl = Vec.new(0.0, 0.0, 0.0)
137+
@n = Vec.new(0.0, 0.0, 0.0)
138+
end
139+
140+
attr_accessor :t, :hit, :pl, :n
141+
end
142+
143+
def clamp(f)
144+
i = f * 255.5
145+
if i > 255.0 then
146+
i = 255.0
147+
end
148+
if i < 0.0 then
149+
i = 0.0
150+
end
151+
i.to_i
152+
end
153+
154+
def otherBasis(basis, n)
155+
basis[2] = Vec.new(n.x, n.y, n.z)
156+
basis[1] = Vec.new(0.0, 0.0, 0.0)
157+
158+
if n.x < 0.6 and n.x > -0.6 then
159+
basis[1].x = 1.0
160+
elsif n.y < 0.6 and n.y > -0.6 then
161+
basis[1].y = 1.0
162+
elsif n.z < 0.6 and n.z > -0.6 then
163+
basis[1].z = 1.0
164+
else
165+
basis[1].x = 1.0
166+
end
167+
168+
basis[0] = basis[1].vcross(basis[2])
169+
basis[0] = basis[0].vnormalize
170+
171+
basis[1] = basis[2].vcross(basis[0])
172+
basis[1] = basis[1].vnormalize
173+
end
174+
175+
class Scene
176+
def initialize
177+
@spheres = Array.new
178+
@spheres[0] = Sphere.new(Vec.new(-2.0, 0.0, -3.5), 0.5)
179+
@spheres[1] = Sphere.new(Vec.new(-0.5, 0.0, -3.0), 0.5)
180+
@spheres[2] = Sphere.new(Vec.new(1.0, 0.0, -2.2), 0.5)
181+
@plane = Plane.new(Vec.new(0.0, -0.5, 0.0), Vec.new(0.0, 1.0, 0.0))
182+
end
183+
184+
def ambient_occlusion(isect)
185+
basis = Array.new
186+
otherBasis(basis, isect.n)
187+
188+
ntheta = NAO_SAMPLES
189+
nphi = NAO_SAMPLES
190+
eps = 0.0001
191+
occlusion = 0.0
192+
193+
p0 = Vec.new(isect.pl.x + eps * isect.n.x,
194+
isect.pl.y + eps * isect.n.y,
195+
isect.pl.z + eps * isect.n.z)
196+
nphi.times do |j|
197+
ntheta.times do |i|
198+
r = rand
199+
phi = 2.0 * 3.14159265 * rand
200+
x = Math.cos(phi) * Math.sqrt(1.0 - r)
201+
y = Math.sin(phi) * Math.sqrt(1.0 - r)
202+
z = Math.sqrt(r)
203+
204+
rx = x * basis[0].x + y * basis[1].x + z * basis[2].x
205+
ry = x * basis[0].y + y * basis[1].y + z * basis[2].y
206+
rz = x * basis[0].z + y * basis[1].z + z * basis[2].z
207+
208+
raydir = Vec.new(rx, ry, rz)
209+
ray = Ray.new(p0, raydir)
210+
211+
occisect = Isect.new
212+
@spheres[0].intersect(ray, occisect)
213+
@spheres[1].intersect(ray, occisect)
214+
@spheres[2].intersect(ray, occisect)
215+
@plane.intersect(ray, occisect)
216+
if occisect.hit then
217+
occlusion = occlusion + 1.0
218+
else
219+
0.0
220+
end
221+
end
222+
end
223+
224+
occlusion = (ntheta.to_f * nphi.to_f - occlusion) / (ntheta.to_f * nphi.to_f)
225+
226+
Vec.new(occlusion, occlusion, occlusion)
227+
end
228+
229+
def render(w, h, nsubsamples)
230+
cnt = 0
231+
nsf = nsubsamples.to_f
232+
h.times do |y|
233+
w.times do |x|
234+
rad = Vec.new(0.0, 0.0, 0.0)
235+
236+
# Subsampling
237+
nsubsamples.times do |v|
238+
nsubsamples.times do |u|
239+
240+
cnt = cnt + 1
241+
wf = w.to_f
242+
hf = h.to_f
243+
xf = x.to_f
244+
yf = y.to_f
245+
uf = u.to_f
246+
vf = v.to_f
247+
248+
px = (xf + (uf / nsf) - (wf / 2.0)) / (wf / 2.0)
249+
py = -(yf + (vf / nsf) - (hf / 2.0)) / (hf / 2.0)
250+
251+
eye = Vec.new(px, py, -1.0).vnormalize
252+
253+
ray = Ray.new(Vec.new(0.0, 0.0, 0.0), eye)
254+
255+
isect = Isect.new
256+
@spheres[0].intersect(ray, isect)
257+
@spheres[1].intersect(ray, isect)
258+
@spheres[2].intersect(ray, isect)
259+
@plane.intersect(ray, isect)
260+
if isect.hit then
261+
col = ambient_occlusion(isect)
262+
rad.x = rad.x + col.x
263+
rad.y = rad.y + col.y
264+
rad.z = rad.z + col.z
265+
end
266+
end
267+
end
268+
269+
r = rad.x / (nsf * nsf)
270+
g = rad.y / (nsf * nsf)
271+
b = rad.z / (nsf * nsf)
272+
printf("%c", clamp(r))
273+
printf("%c", clamp(g))
274+
printf("%c", clamp(b))
275+
end
276+
nil
277+
end
278+
279+
nil
280+
end
281+
end
282+
283+
alias printf_orig printf
284+
def printf *args
285+
# $fp.printf(*args)
286+
end
287+
288+
# File.open("ao.ppm", "w") do |fp|
289+
# $fp = fp
290+
printf("P6\n")
291+
printf("%d %d\n", IMAGE_WIDTH, IMAGE_HEIGHT)
292+
printf("255\n")
293+
Scene.new.render(IMAGE_WIDTH, IMAGE_HEIGHT, NSUBSAMPLES)
294+
# end
295+
296+
undef printf
297+
alias printf printf_orig

0 commit comments

Comments
 (0)