Created
October 14, 2013 07:32
-
-
Save miura1729/6972107 to your computer and use it in GitHub Desktop.
Result of profiling for ao-render.rb with IV reader inlining.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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