如何改善我的代码?这是最耗时的功能:
@timeit to function intersect(surface::Surfaces, ray::Ray)
if typeof(surface) == xyRect
t = (surface.z - ray.s.z)/ray.d.z
if surface.x1 < ray.s.x + t*ray.d.x < surface.x2 && surface.y1 < ray.s.y + t*ray.d.y < surface.y2 && t > 0
t
else
Inf
end
elseif typeof(surface) == xzRect
t = (surface.y - ray.s.y)/ray.d.y
if surface.x1 < ray.s.x + t*ray.d.x < surface.x2 && surface.z1 < ray.s.z + t*ray.d.z < surface.z2 && t > 0
t
else
Inf
end
elseif typeof(surface) == yzRect
t = (surface.x - ray.s.x)/ray.d.x
if surface.y1 < ray.s.y + t*ray.d.y < surface.y2 && surface.z1 < ray.s.z + t*ray.d.z < surface.z2 && t > 0
t
else
Inf
end
elseif typeof(surface) == Sphere
a = dot(ray.d, ray.d)
b = 2dot(ray.d, ray.s - surface.center)
c = dot(ray.s - surface.center, ray.s - surface.center) - surface.radius*surface.radius
Δ = b*b - 4*a*c
if Δ > 0
Δ = sqrt(Δ)
t1 = 0.5(-b-Δ)/a
t2 = 0.5(-b+Δ)/a
if t1 > 0
surface.normal = normalize(ray.s + t1*ray.d - surface.center)
t1
elseif t2 > 0
surface.normal = normalize(ray.s + t2*ray.d - surface.center)
t2
else
Inf
end
else
Inf
end
end
end
@timeit to function nearest(surfaces::Array{Surfaces, 1}, ray::Ray, tMin::Float64)
hitSurface = Empty(Vec3(0,0,0), Vec3(0,0,0), Vec3(0,0,0))
for surface in surfaces
t = intersect(surface, ray)
if t < tMin
tMin = t
hitSurface = surface
end
end
tMin, hitSurface
end
@timeit to function trace(surfaces::Array{Surfaces, 1}, ray::Ray, depth::Int64, maxDepth::Int64)
if depth >= maxDepth
return Vec3(0,0,0)
end
t, material = nearest(surfaces, ray, Inf)
if typeof(material) == Empty
return Vec3(0,0,0)
end
if material.isLight == true
return material.emittance
end
ρ = material.reflectance
BRDF = ρ/Π
n = material.normal
R = hemiRand(n)
In = trace(surfaces, Ray(ray.s + t*ray.d, R), depth+1, maxDepth)
return Π*BRDF*In
end
@timeit to function render(surfaces::Array{Surfaces, 1},camera::Camera,xRes::Int64,yRes::Int64,numSamples::Int64,maxDepth::Int64)
n = normalize(camera.N)
e = camera.eye
c = e - camera.distance*n
θ = camera.fov*(π/180)
H = 2*camera.distance*tan(θ/2)
W = H*camera.aspect
u = normalize(cross(camera.v_up,n))
v = cross(n,u)
img = zeros(3, xRes, yRes)
pixHeight = H/yRes
pixWidth = W/xRes
L = c - 0.5*W*u - 0.5*H*v
for i=1:xRes
for j=1:yRes
cl = Vec3(0,0,0)
for s=1:numSamples
pt = L + (i-rand())*pixWidth*u + (yRes-j+rand())*pixHeight*v
cl = cl + trace(surfaces, Ray(e, pt-e), 0, maxDepth)
end
cl = gamma(clamp(cl/convert(Float64, numSamples)))
img[:,j,i] = [cl.x, cl.y, cl.z]
end
end
img
end
──────────────────────────────── ──────────────────时间分配──────────────────────────────────────托特/实测%:137s / 5.25%1.72GiB / 84.7%
部分ncalls时间%tot平均分配%tot平均──────────────────────────────────────────── ────────────────轨迹609k 14.6s 203%23.9μs2.96GiB 203%5.09KiB渲染1 7.21s 100%7.21s 1.46GiB 100%1.46GiB最接近531k 4.12s 57.2%7.76μs909MiB 61.0%1.75KiB相交3.72M 2.82s 39.1%758ns 695MiB 46.6%196BhemiRand 449k 833ms 11.6%1.85μs158MiB 10.6%368B归一化484k 362ms 5.02%748ns 59.1MiB 3.96%128B-1.79M 201ms 2.79%112ns 54.6MiB 3.66%32.0B点2.08M 197ms 2.73%94.7ns 0.00B 0.00%0.00B* 1.70M 191ms 2.65%112ns 52.0MiB 3.49%32.0B/ 1.09M 132ms 1.83%121ns 33.4MiB 2.24%32.0B+ 964k 107ms 1.49%111ns 29.4MiB 1.97%32.0B交叉899k 107ms 1.49%119ns 27.4MiB 1.84%32.0B伽玛160k 33.2ms 0.46%208ns 4.88MiB 0.33%32.0B钳位160k 17.3ms 0.24%108ns 0.00B 0.00%0.00B──────────────────────────────────────────── ────────────────
Ray,Vec3和对象的定义如下:
mutable struct Vec3
x::Float64
y::Float64
z::Float64
end
struct Ray
s::Vec3
d::Vec3
end
struct yzRect
x; y1; y2; z1; z2::Float64
normal; emittance; reflectance::Vec3
isLight::Bool
end
struct xyRect
z; x1; x2; y1; y2::Float64
normal; emittance; reflectance::Vec3
isLight::Bool
end
struct yzRect
x; y1; y2; z1; z2::Float64
normal; emittance; reflectance::Vec3
isLight::Bool
end
mutable struct Sphere
radius::Float64
center; normal; emittance; reflectance::Vec3
isLight::Bool
end
如何改善我的代码?这是最耗时的函数:如果typeof(surface)== xyRect t =(surface.z-ray.sz)/ray.dz ..,则@timeit要进行交集(surface :: Surfaces,ray :: Ray)。 。
首先,