Skip to content

Instantly share code, notes, and snippets.

@miura1729
Created October 14, 2013 07:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save miura1729/6972107 to your computer and use it in GitHub Desktop.
Save miura1729/6972107 to your computer and use it in GitHub Desktop.
Result of profiling for ao-render.rb with IV reader inlining.
0000 0.00000 # AO render benchmark
0001 0.00000 # Original program (C) Syoyo Fujita in Javascript (and other languages)
0002 0.00000 # http://lucille.atso-net.jp/blog/?p=642
0003 0.00000 # http://lucille.atso-net.jp/blog/?p=711
0004 0.00000 # Ruby(yarv2llvm) version by Hideki Miura
0005 0.00000 # mruby version by Hideki Miura
0006 0.00000 #
0007 0.00000
0008 0.00011 IMAGE_WIDTH = 64
0009 0.00004 IMAGE_HEIGHT = 64
0010 0.00004 NSUBSAMPLES = 2
0011 0.00004 NAO_SAMPLES = 8
0012 0.00000
0013 0.00000 module Rand
0014 0.00000 # Use xorshift
0015 0.00009 @@x = 123456789
0016 0.00004 @@y = 362436069
0017 0.00004 @@z = 521288629
0018 0.00004 @@w = 88675123
0019 0.00064 BNUM = 1 << 29
0020 0.00010 BNUMF = BNUM.to_f
0021 0.00069 def self.rand
0022 3.03462 x = @@x
0023 77.46124 t = x ^ ((x & 0xfffff) << 11)
0024 9.10506 w = @@w
0025 42.73082 @@x, @@y, @@z = @@y, @@z, w
0026 133.42250 w = @@w = (w ^ (w >> 19) ^ (t ^ (t >> 8)))
0027 55.80279 (w % BNUM) / BNUMF
0028 0.00025 end
0029 0.00036 end
0030 0.00000
0031 0.00000 class Vec
0032 0.00000 def initialize(x, y, z)
0033 185.81640 @x = x
0034 26.56755 @y = y
0035 59.83972 @z = z
0036 0.00496 end
0037 0.00000
0038 1.51039 def x=(v); @x = v; end
0039 1.42103 def y=(v); @y = v; end
0040 1.40543 def z=(v); @z = v; end
0041 0.03414 def x; @x; end
0042 0.03082 def y; @y; end
0043 0.02891 def z; @z; end
0044 0.00000
0045 0.00000 def vadd(b)
0046 0.00000 Vec.new(@x + b.x, @y + b.y, @z + b.z)
0047 0.00005 end
0048 0.00000
0049 0.00000 def vsub(b)
0050 260.69928 Vec.new(@x - b.x, @y - b.y, @z - b.z)
0051 4.42458 end
0052 0.00000
0053 0.00000 def vcross(b)
0054 1.23898 Vec.new(@y * b.z - @z * b.y,
0055 1.18159 @z * b.x - @x * b.z,
0056 1.95895 @x * b.y - @y * b.x)
0057 0.00033 end
0058 0.00000
0059 0.00000 def vdot(b)
0060 533.90740 r = @x * b.x + @y * b.y + @z * b.z
0061 55.53106 r
0062 0.00502 end
0063 0.00000
0064 0.00000 def vlength
0065 8.04718 Math.sqrt(@x * @x + @y * @y + @z * @z)
0066 0.20165 end
0067 0.00000
0068 0.00000 def vnormalize
0069 0.91699 len = vlength
0070 6.70841 v = Vec.new(@x, @y, @z)
0071 1.65682 if len > 1.0e-17 then
0072 3.70383 v.x = v.x / len
0073 3.65232 v.y = v.y / len
0074 3.73124 v.z = v.z / len
0075 0.00000 end
0076 0.80847 v
0077 0.05999 end
0078 0.00053 end
0079 0.00000
0080 0.00000
0081 0.00000 class Sphere
0082 0.00000 def initialize(center, radius)
0083 0.00022 @center = center
0084 0.00009 @radius = radius
0085 0.00008 end
0086 0.00000
0087 0.00005 def center; @center; end
0088 0.00005 def radius; @radius; end
0089 0.00000
0090 0.00000 def intersect(ray, isect)
0091 42.53879 rs = ray.org.vsub(@center)
0092 52.63690 b = rs.vdot(ray.dir)
0093 83.93571 c = rs.vdot(rs) - (@radius * @radius)
0094 63.94486 d = b * b - c
0095 39.71742 if d > 0.0 then
0096 7.25402 t = - b - Math.sqrt(d)
0097 0.00000
0098 5.10274 if t > 0.0 and t < isect.t then
0099 0.80388 isect.t = t
0100 0.86797 isect.hit = true
0101 3.46617 isect.pl = Vec.new(ray.org.x + ray.dir.x * t,
0102 2.82193 ray.org.y + ray.dir.y * t,
0103 5.00883 ray.org.z + ray.dir.z * t)
0104 1.17367 n = isect.pl.vsub(@center)
0105 26.83837 isect.n = n.vnormalize
0106 0.00000 end
0107 0.00000 end
0108 0.00048 end
0109 0.00039 end
0110 0.00000
0111 0.00000 class Plane
0112 0.00000 def initialize(p, n)
0113 0.00007 @p = p
0114 0.00003 @n = n
0115 0.00007 end
0116 0.00000
0117 0.00000 def intersect(ray, isect)
0118 17.60948 d = -@p.vdot(@n)
0119 18.45908 v = ray.dir.vdot(@n)
0120 2.11162 v0 = v
0121 13.19376 if v < 0.0 then
0122 0.99738 v0 = -v
0123 0.00000 end
0124 12.52805 if v0 < 1.0e-17 then
0125 0.00645 return
0126 0.00000 end
0127 0.00000
0128 43.30654 t = -(ray.org.vdot(@n) + d) / v
0129 0.00000
0130 16.82027 if t > 0.0 and t < isect.t then
0131 1.07429 isect.hit = true
0132 1.12348 isect.t = t
0133 1.13136 isect.n = @n
0134 13.10180 isect.pl = Vec.new(ray.org.x + t * ray.dir.x,
0135 3.80998 ray.org.y + t * ray.dir.y,
0136 6.29063 ray.org.z + t * ray.dir.z)
0137 0.00000 end
0138 0.05198 end
0139 0.00037 end
0140 0.00000
0141 0.00000 class Ray
0142 0.00000 def initialize(org, dir)
0143 28.42958 @org = org
0144 8.07495 @dir = dir
0145 0.00080 end
0146 0.00000
0147 0.01819 def org; @org; end
0148 0.00005 def org=(v); @org = v; end
0149 0.01780 def dir; @dir; end
0150 0.00007 def dir=(v); @dir = v; end
0151 0.00037 end
0152 0.00000
0153 0.00000 class Isect
0154 0.00000 def initialize
0155 28.09686 @t = 10000000.0
0156 6.37966 @hit = false
0157 46.83183 @pl = Vec.new(0.0, 0.0, 0.0)
0158 50.43594 @n = Vec.new(0.0, 0.0, 0.0)
0159 0.00058 end
0160 0.00000
0161 0.01094 def t; @t; end
0162 1.13621 def t=(v); @t = v; end
0163 0.00096 def hit; @hit; end
0164 1.09971 def hit=(v); @hit = v; end
0165 0.02018 def pl; @pl; end
0166 1.11426 def pl=(v); @pl = v; end
0167 0.02027 def n; @n; end
0168 1.13262 def n=(v); @n = v; end
0169 0.00037 end
0170 0.00000
0171 0.00000 def clamp(f)
0172 0.00000 i = f * 255.5
0173 0.00000 if i > 255.0 then
0174 0.00000 i = 255.0
0175 0.00000 end
0176 0.00000 if i < 0.0 then
0177 0.00000 i = 0.0
0178 0.00000 end
0179 0.00000 i.to_i
0180 0.00005 end
0181 0.00000
0182 0.00000 def otherBasis(basis, n)
0183 0.85249 basis[2] = Vec.new(n.x, n.y, n.z)
0184 1.02600 basis[1] = Vec.new(0.0, 0.0, 0.0)
0185 0.00000
0186 0.60668 if n.x < 0.6 and n.x > -0.6 then
0187 0.36581 basis[1].x = 1.0
0188 0.04291 elsif n.y < 0.6 and n.y > -0.6 then
0189 0.02509 basis[1].y = 1.0
0190 0.01891 elsif n.z < 0.6 and n.z > -0.6 then
0191 0.01342 basis[1].z = 1.0
0192 0.00000 else
0193 0.00000 basis[1].x = 1.0
0194 0.00000 end
0195 0.00000
0196 0.74152 basis[0] = basis[1].vcross(basis[2])
0197 0.55756 basis[0] = basis[0].vnormalize
0198 0.00000
0199 0.69038 basis[1] = basis[2].vcross(basis[0])
0200 0.62596 basis[1] = basis[1].vnormalize
0201 0.03907 end
0202 0.00000
0203 0.00000 class Scene
0204 0.00000 def initialize
0205 0.00030 @spheres = Array.new
0206 0.00050 @spheres[0] = Sphere.new(Vec.new(-2.0, 0.0, -3.5), 0.5)
0207 0.00029 @spheres[1] = Sphere.new(Vec.new(-0.5, 0.0, -3.0), 0.5)
0208 0.00028 @spheres[2] = Sphere.new(Vec.new(1.0, 0.0, -2.2), 0.5)
0209 0.00039 @plane = Plane.new(Vec.new(0.0, -0.5, 0.0), Vec.new(0.0, 1.0, 0.0))
0210 0.00007 end
0211 0.00000
0212 0.00000 def ambient_occlusion(isect)
0213 0.58336 basis = Array.new(3)
0214 0.29472 otherBasis(basis, isect.n)
0215 0.00000
0216 0.02210 ntheta = NAO_SAMPLES
0217 0.03194 nphi = NAO_SAMPLES
0218 0.03787 eps = 0.0001
0219 0.03927 occlusion = 0.0
0220 0.00000
0221 0.67276 p0 = Vec.new(isect.pl.x + eps * isect.n.x,
0222 0.64251 isect.pl.y + eps * isect.n.y,
0223 1.15228 isect.pl.z + eps * isect.n.z)
0224 0.02379 nphi.times do |j|
0225 0.25462 ntheta.times do |i|
0226 9.97940 r = Rand::rand
0227 24.48799 phi = 2.0 * 3.14159265 * Rand::rand
0228 53.11522 x = Math.cos(phi) * Math.sqrt(1.0 - r)
0229 50.49768 y = Math.sin(phi) * Math.sqrt(1.0 - r)
0230 17.65417 z = Math.sqrt(r)
0231 0.00000
0232 84.80468 rx = x * basis[0].x + y * basis[1].x + z * basis[2].x
0233 85.50154 ry = x * basis[0].y + y * basis[1].y + z * basis[2].y
0234 84.74682 rz = x * basis[0].z + y * basis[1].z + z * basis[2].z
0235 0.00000
0236 42.39302 raydir = Vec.new(rx, ry, rz)
0237 40.69797 ray = Ray.new(p0, raydir)
0238 0.00000
0239 34.27505 occisect = Isect.new
0240 20.82296 @spheres[0].intersect(ray, occisect)
0241 19.79685 @spheres[1].intersect(ray, occisect)
0242 19.81074 @spheres[2].intersect(ray, occisect)
0243 12.20606 @plane.intersect(ray, occisect)
0244 8.85399 if occisect.hit then
0245 2.37550 occlusion = occlusion + 1.0
0246 0.00000 else
0247 7.95925 0.0
0248 0.00000 end
0249 1.72566 end
0250 0.15946 end
0251 0.00000
0252 0.88870 occlusion = (ntheta.to_f * nphi.to_f - occlusion) / (ntheta.to_f * nphi.to_f)
0253 1.07865 Vec.new(occlusion, occlusion, occlusion)
0254 0.02879 end
0255 0.00000
0256 0.00000 def render(w, h, nsubsamples)
0257 0.00001 cnt = 0
0258 0.00006 nsf = nsubsamples.to_f
0259 0.00002 h.times do |y|
0260 0.00050 w.times do |x|
0261 0.29591 rad = Vec.new(0.0, 0.0, 0.0)
0262 0.00000
0263 0.00000 # Subsmpling
0264 0.01735 nsubsamples.times do |v|
0265 0.03242 nsubsamples.times do |u|
0266 0.34523 cnt = cnt + 1
0267 0.27618 wf = w.to_f
0268 0.33101 hf = h.to_f
0269 0.32649 xf = x.to_f
0270 0.30959 yf = y.to_f
0271 0.29973 uf = u.to_f
0272 0.30919 vf = v.to_f
0273 0.00000
0274 1.57241 px = (xf + (uf / nsf) - (wf / 2.0)) / (wf / 2.0)
0275 1.82467 py = -(yf + (vf / nsf) - (hf / 2.0)) / (hf / 2.0)
0276 0.00000
0277 1.28896 eye = Vec.new(px, py, -1.0).vnormalize
0278 0.00000
0279 2.08854 ray = Ray.new(Vec.new(0.0, 0.0, 0.0), eye)
0280 0.00000
0281 0.78791 isect = Isect.new
0282 0.65789 @spheres[0].intersect(ray, isect)
0283 0.63139 @spheres[1].intersect(ray, isect)
0284 0.62806 @spheres[2].intersect(ray, isect)
0285 0.36207 @plane.intersect(ray, isect)
0286 0.26900 if isect.hit then
0287 0.16645 col = ambient_occlusion(isect)
0288 0.60018 rad.x = rad.x + col.x
0289 0.50080 rad.y = rad.y + col.y
0290 0.58354 rad.z = rad.z + col.z
0291 0.00000 else
0292 0.13064 0.0
0293 0.00000 end
0294 0.20815 end
0295 0.07247 end
0296 0.00000
0297 0.22218 r = rad.x / (nsf * nsf)
0298 0.23100 g = rad.y / (nsf * nsf)
0299 0.24130 b = rad.z / (nsf * nsf)
0300 0.00000 #printf("%c", clamp(r))
0301 0.00000 #printf("%c", clamp(g))
0302 0.00000 #printf("%c", clamp(b))
0303 0.01053 end
0304 0.00076 end
0305 0.00009 end
0306 0.00036 end
0307 0.00000
0308 0.00000 # File.open("ao.ppm", "w") do |fp|
0309 0.00016 printf("P6\n")
0310 0.00027 printf("%d %d\n", IMAGE_WIDTH, IMAGE_HEIGHT)
0311 0.00016 printf("255\n", IMAGE_WIDTH, IMAGE_HEIGHT)
0312 0.01123 Scene.new.render(IMAGE_WIDTH, IMAGE_HEIGHT, NSUBSAMPLES)
0313 0.00000 # Scene.new.render(256, 256, 2)
0314 0.00000 # end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment