Skip to content

Commit c113489

Browse files
committed
make li(...) iterative (normal raytracing broken)
1 parent 4cdcce2 commit c113489

File tree

7 files changed

+239
-112
lines changed

7 files changed

+239
-112
lines changed

src/gpu-support.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,14 @@ function to_gpu(ArrayType, m::Trace.UberMaterial; preserve=[])
3333
no_tex_s = typeof(Kr)()
3434
Kd = Trace.no_texture(m.Kd) ? no_tex_s : to_gpu(ArrayType, m.Kd; preserve=preserve)
3535
end
36-
f_tex = to_gpu(ArrayType, Trace.Texture(ArrayType(zeros(Float32, 1, 1))); preserve=preserve)
36+
f_tex = to_gpu(ArrayType, Trace.Texture(zeros(Float32, 1, 1)); preserve=preserve)
3737
no_tex_f = typeof(f_tex)()
3838
return Trace.UberMaterial(
3939
Kd,
4040
Trace.no_texture(m.Ks) ? no_tex_s : to_gpu(ArrayType, m.Ks; preserve=preserve),
4141
Trace.no_texture(m.Kr) ? no_tex_s : to_gpu(ArrayType, m.Kr; preserve=preserve),
4242
Trace.no_texture(m.Kt) ? no_tex_s : to_gpu(ArrayType, m.Kt; preserve=preserve),
43+
4344
Trace.no_texture(m.σ) ? no_tex_f : to_gpu(ArrayType, m.σ; preserve=preserve),
4445
Trace.no_texture(m.roughness) ? no_tex_f : to_gpu(ArrayType, m.roughness; preserve=preserve),
4546
Trace.no_texture(m.u_roughness) ? no_tex_f : to_gpu(ArrayType, m.u_roughness; preserve=preserve),

src/integrators/sampler.jl

Lines changed: 119 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ function get_material(scene::Scene, shape::Triangle)
8181
get_material(scene.aggregate, shape)
8282
end
8383

84+
using KernelAbstractions.Extras.LoopInfo: @unroll
85+
8486
function li(
8587
sampler, max_depth, ray::RayDifferentials, scene::Scene, depth::Int64,
8688
)::RGBSpectrum
@@ -138,13 +140,121 @@ function li(
138140
l
139141
end
140142

143+
144+
function only_light(lights, ray)
145+
l = RGBSpectrum(0.0f0)
146+
Base.Cartesian.@nexprs 8 i -> begin
147+
if i <= length(lights)
148+
light = lights[i]
149+
l += le(light, ray)
150+
end
151+
end
152+
return l
153+
end
154+
155+
function li_iterative(scene, sampler, ray, lights)
156+
l = RGBSpectrum(0.0f0)
157+
srf = RGBSpectrum(1.0f0)
158+
stf = RGBSpectrum(1.0f0)
159+
i = Int32(0)
160+
max_depth = Int32(3)
161+
reflect = false
162+
transmit = false
163+
recursion_depth = Int32(0)
164+
last_ray = ray
165+
while i max_depth
166+
i += Int32(1)
167+
if reflect && i == max_depth
168+
# i = recursion_depth
169+
reflect = false
170+
srf = RGBSpectrum(1.0f0)
171+
ray = last_ray
172+
end
173+
if transmit && i == max_depth
174+
# i = recursion_depth
175+
transmit = false
176+
stf = RGBSpectrum(1.0f0)
177+
end
178+
l *= srf
179+
l *= stf
180+
# Find closest ray intersection or return background radiance.
181+
hit, shape, si = intersect!(scene, ray)
182+
if !hit
183+
l = only_light(lights, ray)
184+
break
185+
end
186+
f, _ray, bsdf = li_norec(shape, sampler, ray, scene, si)
187+
l += f
188+
if _ray !== ray
189+
last_ray = ray
190+
ray = _ray
191+
192+
continue
193+
end
194+
# Trace rays for specular reflection & refraction.
195+
srf, rayr = specular_reflect(bsdf, sampler, ray, si)
196+
if rayr !== ray
197+
last_ray = ray
198+
ray = rayr
199+
reflect = true
200+
# recursion_depth = i
201+
continue
202+
end
203+
stf, rayt = specular_transmit(bsdf, sampler, ray, si)
204+
if rayt !== ray
205+
ray = rayt
206+
transmit = true
207+
recursion_depth = i
208+
continue
209+
end
210+
end
211+
return l
212+
end
213+
214+
function li_norec(
215+
shape, sampler, ray::RayDifferentials, scene::Scene, si::SurfaceInteraction
216+
)
217+
218+
l = RGBSpectrum(0.0f0)
219+
lights = scene.lights
220+
bsdf = BSDF()
221+
# Compute emmited & reflected light at ray intersection point.
222+
# Initialize common variables for Whitted integrator.
223+
core = si.core
224+
n = si.shading.n
225+
wo = core.wo
226+
# Compute scattering functions for surface interaction.
227+
si = compute_differentials(si, ray)
228+
m = get_material(scene, shape)
229+
if m.type === NO_MATERIAL
230+
return l, RayDifferentials(spawn_ray(si, ray.d)), bsdf
231+
end
232+
bsdf = m(si, false, Radiance)
233+
# Compute emitted light if ray hit an area light source.
234+
l += le(si, wo)
235+
# Add contribution of each light source.
236+
Base.Cartesian.@nexprs 8 i -> begin
237+
if i <= length(lights)
238+
light = lights[i]
239+
sampled_li, wi, pdf, visibility_tester = sample_li(
240+
light, core, get_2d(sampler),
241+
)
242+
if !(is_black(sampled_li) || pdf 0.0f0)
243+
f = bsdf(wo, wi)
244+
if !is_black(f) && unoccluded(visibility_tester, scene)
245+
l += f * sampled_li * abs(wi n) / pdf
246+
end
247+
end
248+
end
249+
end
250+
return l, ray, bsdf
251+
end
252+
141253
@inline function specular_reflect(
142-
bsdf, sampler, max_depth, ray::RayDifferentials,
143-
si::SurfaceInteraction, scene::Scene, depth::Int64,
254+
bsdf, sampler, ray::RayDifferentials, si::SurfaceInteraction
144255
)
145256

146257
# Compute specular reflection direction `wi` and BSDF value.
147-
148258
wo = si.core.wo
149259
type = BSDF_REFLECTION | BSDF_SPECULAR
150260
wi, f, pdf, sampled_type = sample_f(
@@ -153,7 +263,7 @@ end
153263
# Return contribution of specular reflection.
154264
ns = si.shading.n
155265
if !(pdf > 0f0 && !is_black(f) && abs(wi ns) != 0f0)
156-
return RGBSpectrum(0f0)
266+
return RGBSpectrum(1f0), ray
157267
end
158268
# # Compute ray differential for specular reflection.
159269
rd = RayDifferentials(spawn_ray(si, wi))
@@ -179,12 +289,12 @@ end
179289
ry_direction = wi - ∂wo∂y + 2f0 * (wo ns) * ∂n∂y + ∂dn∂y * ns
180290
rd = RayDifferentials(rd, rx_origin=rx_origin, ry_origin=ry_origin, rx_direction=rx_direction, ry_direction=ry_direction)
181291
end
182-
return f * li(sampler, max_depth, rd, scene, depth + 1) * abs(wi ns) / pdf
292+
return f * abs(wi ns) / pdf, rd
183293
end
184294

185295
@inline function specular_transmit(
186-
bsdf, sampler, max_depth, ray::RayDifferentials,
187-
surface_intersect::SurfaceInteraction, scene::Scene, depth::Int64,
296+
bsdf, sampler, ray::RayDifferentials,
297+
surface_intersect::SurfaceInteraction
188298
)
189299

190300
# Compute specular reflection direction `wi` and BSDF value.
@@ -196,7 +306,7 @@ end
196306

197307
ns = surface_intersect.shading.n
198308
if !(pdf > 0f0 && !is_black(f) && abs(wi ns) != 0f0)
199-
return RGBSpectrum(0f0)
309+
return RGBSpectrum(1f0), ray
200310
end
201311
# TODO shift in ray direction instead of normal?
202312
rd = RayDifferentials(spawn_ray(surface_intersect, wi))
@@ -236,5 +346,5 @@ end
236346
ry_direction = wi - η * ∂wo∂y + μ * ∂n∂y + ∂μ∂y * ns
237347
rd = RayDifferentials(rd, rx_origin=rx_origin, ry_origin=ry_origin, rx_direction=rx_direction, ry_direction=ry_direction)
238348
end
239-
f * li(sampler, max_depth, rd, scene, depth + 1) * abs(wi ns) / pdf
349+
f * abs(wi ns) / pdf, rd
240350
end

src/materials/uber-material.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,14 @@ FresnelConductor(ni, nt, k) = Fresnel(ni, nt, k, FRESNEL_CONDUCTOR)
3434
FresnelDielectric(ni::Float32, nt::Float32) = Fresnel(RGBSpectrum(ni), RGBSpectrum(nt), RGBSpectrum(0.0f0), FRESNEL_DIELECTRIC)
3535
FresnelNoOp() = Fresnel(RGBSpectrum(0.0f0), RGBSpectrum(0.0f0), RGBSpectrum(0.0f0), FRESNEL_NO_OP)
3636

37-
function (f::Fresnel)(cos_θi::Float32)
38-
if f.type === FRESNEL_CONDUCTOR
39-
return fresnel_conductor(cos_θi, f.ηi, f.ηt, f.k)
40-
elseif f.type === FRESNEL_DIELECTRIC
37+
function (f::Fresnel)(cos_θi::Float32)::Float32
38+
# if f.type === FRESNEL_CONDUCTOR
39+
# return fresnel_conductor(cos_θi, f.ηi, f.ηt, f.k)
40+
# else
41+
if f.type === FRESNEL_DIELECTRIC
4142
return fresnel_dielectric(cos_θi, f.ηi[1], f.ηt[1])
4243
end
43-
return RGBSpectrum(1.0f0)
44+
return 1f0
4445
end
4546

4647

src/reflection/bxdf.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,5 @@ function fresnel_conductor(
9292
t3 = cos_θi2 * a2_plus_b2 + sin_θi2 * sin_θi2
9393
t4 = t2 * sin_θi2
9494
r_parallel = r_perp * (t3 - t4) / (t3 + t4)
95-
0.5f0 * (r_parallel + r_perp)
95+
return 0.5f0 * (r_parallel + r_perp)
9696
end

src/spectrum.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ lerp(c1::C, c2::C, t::Float32) where C<:Spectrum = (1f0 - t) * c1 + t * c2
3333
Base.getindex(c::C, i) where C<:Spectrum = c.c[i]
3434

3535
function Base.clamp(
36-
c::C, low::Float32 = 0f0, high::Float32 = Inf32,
37-
) where C<:Spectrum
36+
c::C, low::Float32 = 0f0, high::Float32 = Inf32,
37+
) where C<:Spectrum
3838
C(clamp.(c.c, low, high))
3939
end
4040

src/textures/basic.jl

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,10 @@ function Base.convert(::Type{Texture{ElType,N,T}}, ::NoTexture) where {ElType,N,
2626
end
2727

2828
function (c::Texture{T})(si::SurfaceInteraction)::T where {T<:TextureType}
29-
if c.isconst
30-
return c.const_value
31-
else
32-
uv = Vec2f(1f0 - si.uv[2], si.uv[1])
33-
s = unsafe_trunc.(Int32, size(c.data))
34-
idx = map(x -> unsafe_trunc(Int32, x), Int32(1) .+ ((s .- Int32(1)) .* uv))
35-
idx = clamp.(idx, Int32(1), s)
36-
@inbounds return c.data[idx...]
37-
end
29+
c.isconst && return c.const_value
30+
uv = Vec2f(1f0 - si.uv[2], si.uv[1])
31+
s = unsafe_trunc.(Int32, size(c.data))
32+
idx = map(x -> unsafe_trunc(Int32, x), Int32(1) .+ ((s .- Int32(1)) .* uv))
33+
idx = clamp.(idx, Int32(1), s)
34+
@inbounds return c.data[idx...]
3835
end

0 commit comments

Comments
 (0)