[我已经使用julia编程语言编写了路径跟踪器,但我认为它很慢

问题描述 投票:0回答:1

如何改善我的代码?这是最耗时的功能:

@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)。 。

julia raytracing
1个回答
1
投票

首先,

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.