Skip to content

Commit a164916

Browse files
committed
get film tile to work with KernelAbstraction
1 parent ecb3f2d commit a164916

File tree

11 files changed

+477
-121
lines changed

11 files changed

+477
-121
lines changed

docs/code/TraceMakie.jl

Lines changed: 87 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Makie, Trace, ImageShow, Colors, FileIO, LinearAlgebra, GeometryBasics
2-
using AMDGPU
2+
using AMDGPU, GLMakie
3+
34
ArrayType = ROCArray
45

56
function to_spectrum(data::Colorant)
@@ -123,19 +124,17 @@ end
123124

124125
function to_trace_camera(scene::Makie.Scene, film)
125126
cc = scene.camera_controls
126-
fov = cc.fov[]
127-
view = Trace.look_at(
128-
Point3f(cc.eyeposition[]), Point3f(cc.lookat[]), Vec3f(cc.upvector[]),
129-
)
130-
return Trace.PerspectiveCamera(
131-
view, Trace.Bounds2(Point2f(-1.0f0), Point2f(1.0f0)),
132-
0.0f0, 1.0f0, 0.0f0, 1.0f6, Float32(fov),
133-
film
134-
)
135-
end
136-
137-
function render_scene(scene::Makie.Scene)
138-
return render_scene(c -> Trace.WhittedIntegrator(c, Trace.UniformSampler(8), 5), scene)
127+
return lift(scene, cc.eyeposition, cc.lookat, cc.upvector, cc.fov) do eyeposition, lookat, upvector, fov
128+
view = Trace.look_at(
129+
Point3f(eyeposition), Point3f(lookat), Vec3f(upvector),
130+
)
131+
return Trace.PerspectiveCamera(
132+
view, Trace.Bounds2(Point2f(-1.0f0), Point2f(1.0f0)),
133+
0.0f0, 1.0f0, 0.0f0, 1.0f6, Float32(fov),
134+
film
135+
)
136+
end
137+
return
139138
end
140139

141140
function convert_scene(scene::Makie.Scene)
@@ -170,7 +169,14 @@ end
170169

171170
function render_whitted(mscene::Makie.Scene; samples_per_pixel=8, max_depth=5)
172171
scene, camera, film = convert_scene(mscene)
173-
integrator = Trace.WhittedIntegrator(camera, Trace.UniformSampler(samples_per_pixel), max_depth)
172+
integrator = Trace.WhittedIntegrator(camera[], Trace.UniformSampler(samples_per_pixel), max_depth)
173+
integrator(scene, film)
174+
return reverse(film.framebuffer, dims=1)
175+
end
176+
177+
function render_sppm(mscene::Makie.Scene; search_radius=0.075f0, max_depth=5, iterations=100)
178+
scene, camera, film = convert_scene(mscene)
179+
integrator = Trace.SPPMIntegrator(camera[], search_radius, max_depth, iterations, film)
174180
integrator(scene, film)
175181
return reverse(film.framebuffer, dims=1)
176182
end
@@ -182,41 +188,57 @@ function render_gpu(mscene::Makie.Scene, ArrayType; samples_per_pixel=8, max_dep
182188
res = Int.((film.resolution...,))
183189
gpu_img = ArrayType(zeros(RGBf, res))
184190
GC.@preserve preserve begin
185-
Trace.launch_trace_image!(gpu_img, camera, gpu_scene, Int32(samples_per_pixel), Int32(max_depth))
191+
Trace.launch_trace_image!(gpu_img, camera[], gpu_scene, Int32(samples_per_pixel), Int32(max_depth), Int32(0))
186192
end
187193
return Array(gpu_img)
188194
end
189195

190-
glass = Trace.GlassMaterial(
191-
Trace.ConstantTexture(Trace.RGBSpectrum(1.0f0)),
192-
Trace.ConstantTexture(Trace.RGBSpectrum(1.0f0)),
193-
Trace.ConstantTexture(0.0f0),
194-
Trace.ConstantTexture(0.0f0),
195-
Trace.ConstantTexture(1.25f0),
196-
true,
197-
)
198-
mirror = Trace.MirrorMaterial(Trace.ConstantTexture(Trace.RGBSpectrum(1.0f0)))
199-
plastic = Trace.PlasticMaterial(
200-
Trace.ConstantTexture(Trace.RGBSpectrum(0.6399999857f0, 0.6399999857f0, 0.6399999857f0)),
201-
Trace.ConstantTexture(Trace.RGBSpectrum(0.1000000015f0, 0.1000000015f0, 0.1000000015f0)),
202-
Trace.ConstantTexture(0.010408001f0),
203-
true,
204-
)
205-
catmesh = load(Makie.assetpath("cat.obj"))
196+
function render(w::Whitten5, scene)
197+
198+
end
199+
200+
function render_interactive(mscene::Makie.Scene, ArrayType; max_depth=5)
201+
scene, camera, film = convert_scene(mscene)
202+
preserve = []
203+
gpu_scene = Trace.to_gpu(ArrayType, scene; preserve=preserve)
204+
res = Int.((film.resolution...,))
205+
gpu_img = ArrayType(zeros(RGBf, res))
206+
s = Scene(size=res)
207+
imgp = image!(s, -1..1, -1..1, Array(gpu_img))
208+
display(GLMakie.Screen(), mscene)
209+
display(GLMakie.Screen(), s)
210+
cam_start = camera[]
211+
n_iter = Int32(1)
212+
Base.errormonitor(@async while isopen(s)
213+
GC.@preserve preserve begin
214+
if cam_start != camera[]
215+
cam_start = camera[]
216+
gpu_img .= RGBf(0, 0, 0)
217+
end
218+
Trace.launch_trace_image!(gpu_img, camera[], gpu_scene, Int32(1), Int32(max_depth), n_iter)
219+
n_iter += Int32(1)
220+
end
221+
imgp[3] = Array(gpu_img)
222+
sleep(1/10)
223+
end)
224+
return Array(gpu_img)
225+
end
206226

207227
begin
228+
catmesh = load(Makie.assetpath("cat.obj"))
208229
scene = Scene(size=(1024, 1024);
209230
lights=[AmbientLight(RGBf(0.7, 0.6, 0.6)), PointLight(Vec3f(0, 1, 0.5), RGBf(1.3, 1.3, 1.3))]
210231
)
211232
cam3d!(scene)
212233
mesh!(scene, catmesh, color=load(Makie.assetpath("diffusemap.png")))
213234
center!(scene)
214-
@time render_whitted(scene)
235+
# @time render_whitted(scene)
215236
# 1.024328 seconds (16.94 M allocations: 5.108 GiB, 46.19% gc time, 81 lock conflicts)
216237
# 0.913530 seconds (16.93 M allocations: 5.108 GiB, 42.52% gc time, 57 lock conflicts)
217238
# 0.416158 seconds (75.58 k allocations: 88.646 MiB, 2.44% gc time, 16 lock conflicts)
218239
@time render_gpu(scene, ArrayType)
219240
# 0.135438 seconds (76.03 k allocations: 82.406 MiB, 8.57% gc time)
241+
# render_interactive(scene, ArrayType; max_depth=5)
220242
end
221243

222244
begin
@@ -236,24 +258,31 @@ begin
236258
# 0.976180 seconds (443.12 k allocations: 107.841 MiB, 6.60% gc time, 12 lock conflicts)
237259
@time render_gpu(scene, ArrayType)
238260
# 0.236231 seconds (443.48 k allocations: 101.598 MiB, 3.92% gc time)
261+
# render_interactive(scene, ArrayType; max_depth=5)
239262
end
240263

241-
model = load(joinpath(@__DIR__, "..", "src", "assets", "models", "caustic-glass.ply"))
242264
begin
265+
model = load(joinpath(@__DIR__, "..", "src", "assets", "models", "caustic-glass.ply"))
243266
glass = Trace.GlassMaterial(
244-
Trace.ConstantTexture(Trace.RGBSpectrum(1.0f0)),
245-
Trace.ConstantTexture(Trace.RGBSpectrum(1.0f0)),
267+
Trace.ConstantTexture(Trace.RGBSpectrum(0.9f0)),
268+
Trace.ConstantTexture(Trace.RGBSpectrum(0.88f0)),
246269
Trace.ConstantTexture(0.0f0),
247270
Trace.ConstantTexture(0.0f0),
248-
Trace.ConstantTexture(1.25f0),
271+
Trace.ConstantTexture(1.4f0),
249272
true,
250273
)
251274
plastic = Trace.PlasticMaterial(
252-
Trace.ConstantTexture(Trace.RGBSpectrum(0.6399999857f0, 0.6399999857f0, 0.6399999857f0)),
275+
Trace.ConstantTexture(Trace.RGBSpectrum(0.6399999857f0, 0.6399999857f0, 0.5399999857f0)),
253276
Trace.ConstantTexture(Trace.RGBSpectrum(0.1000000015f0, 0.1000000015f0, 0.1000000015f0)),
254277
Trace.ConstantTexture(0.010408001f0),
255278
true,
256279
)
280+
plastic_ceil = Trace.PlasticMaterial(
281+
Trace.ConstantTexture(Trace.RGBSpectrum(0.3399999857f0, 0.6399999857f0, 0.8399999857f0)),
282+
Trace.ConstantTexture(Trace.RGBSpectrum(1.4f0)),
283+
Trace.ConstantTexture(0.000408001f0),
284+
true,
285+
)
257286
scene = Scene(size=(1024, 1024); lights=[
258287
AmbientLight(RGBf(1, 1, 1)),
259288
PointLight(Vec3f(4, 4, 10), RGBf(150, 150, 150)),
@@ -265,12 +294,30 @@ begin
265294
mesh!(scene, model, material=glass)
266295
mini, maxi = extrema(Rect3f(decompose(Point, model)))
267296
floorrect = Rect3f(Vec3f(-10, mini[2], -10), Vec3f(20, -1, 20))
268-
mesh!(scene, floorrect, material=plastic)
297+
mesh!(scene, floorrect, material=plastic_ceil)
298+
ceiling = Rect3f(Vec3f(-25, 11, -25), Vec3f(50, -1, 50))
299+
mesh!(scene, ceiling, material=plastic)
269300
center!(scene)
270301
update_cam!(scene, Vec3f(-1.6, 6.2, 0.2), Vec3f(-3.6, 2.5, 2.4), Vec3f(0, 1, 0))
271302

272303
@time render_whitted(scene)
273304
# 9.820304 seconds (1.69 M allocations: 235.165 MiB, 0.51% gc time, 3 lock conflicts)
274-
@time render_gpu(scene, ArrayType)
305+
# @time render_gpu(scene, ArrayType)
275306
# 6.128600 seconds (1.70 M allocations: 228.875 MiB, 1.09% gc time)
307+
# @time render_sppm(scene; iterations=500)
308+
# @time colorbuffer(scene; backend=RPRMakie)
309+
# 6.321123 seconds (10.09 k allocations: 66.559 MiB, 0.15% gc time)
310+
# render_interactive(scene, ArrayType; max_depth=5)
276311
end
312+
313+
@time begin
314+
tscene, tcamera, tfilm = convert_scene(scene)
315+
w = Whitten5(tfilm; samples_per_pixel=8)
316+
end;
317+
begin
318+
@time launch_trace_image!(w, tcamera[], tscene)
319+
Trace.to_framebuffer!(tfilm, 1.0f0)
320+
tfilm.framebuffer
321+
end
322+
323+
# img = render_sppm(scene; iterations=1)

docs/code/basic-scene.jl

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,21 @@ begin
7070
)
7171
end
7272

73-
begin
74-
integrator = Trace.WhittedIntegrator(cam, Trace.UniformSampler(8), 5)
75-
@time integrator(scene, film)
76-
img = reverse(film.framebuffer, dims=1)
77-
end
73+
# begin
74+
# Trace.clear!(film)
75+
# integrator = Trace.WhittedIntegrator(cam, Trace.UniformSampler(8), 5)
76+
# @time integrator(scene, film)
77+
# img = reverse(film.framebuffer, dims=1)
78+
# end
79+
80+
# begin
81+
# resolution = Point2f(1024)
82+
# Trace.clear!(film)
83+
# @time render_scene(scene, film, cam)
84+
# Trace.to_framebuffer!(film, 1.0f0)
85+
# film.framebuffer
86+
# end
87+
7888

7989
# 6.296157 seconds (17.64 k allocations: 19.796 MiB, 0.13% gc time, 45 lock conflicts)
8090
# After more GPU optimizations

docs/code/rpr-comparison.jl

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using RPRMakie
2+
3+
function Plastic(; kw...)
4+
return (type=:Uber,
5+
color=to_color(:yellow), reflection_color=Vec4f(1),
6+
reflection_weight=Vec4f(1), reflection_roughness=Vec4f(0),
7+
reflection_anisotropy=Vec4f(0), reflection_anisotropy_rotation=Vec4f(0),
8+
reflection_metalness=Vec4f(0), reflection_ior=Vec4f(1.5), refraction_weight=Vec4f(0),
9+
coating_weight=Vec4f(0), sheen_weight=Vec4f(0), emission_weight=Vec3f(0),
10+
transparency=Vec4f(0), reflection_mode=UInt(RPR.RPR_UBER_MATERIAL_IOR_MODE_PBR),
11+
emission_mode=UInt(RPR.RPR_UBER_MATERIAL_EMISSION_MODE_SINGLESIDED),
12+
coating_mode=UInt(RPR.RPR_UBER_MATERIAL_IOR_MODE_PBR), sss_multiscatter=false,
13+
refraction_thin_surface=false, kw...
14+
)
15+
end
16+
17+
function Glass(; kw...)
18+
return (type=:Uber,
19+
reflection_color=Vec4f(0.9), reflection_weight=Vec4f(1.0),
20+
reflection_roughness=Vec4f(0.0), reflection_anisotropy=Vec4f(0.0),
21+
reflection_anisotropy_rotation=Vec4f(0.0), reflection_mode=1,
22+
reflection_ior=Vec4f(1.5), refraction_color=Vec4f(0.9), refraction_weight=Vec4f(1.0),
23+
refraction_roughness=Vec4f(0.0), refraction_ior=Vec4f(1.5),
24+
refraction_thin_surface=false, refraction_absorption_color=Vec4f(0.6, 0.8, 0.6, 0.0),
25+
refraction_absorption_distance=Vec4f(150), refraction_caustics=true,
26+
coating_weight=Vec4f(0), sheen_weight=Vec4f(0), emission_weight=Vec4f(0),
27+
transparency=Vec4f(0), kw...
28+
)
29+
end
30+
begin
31+
glass = Glass(color=RGBf(0.8f0, 0.2f0, 0.2f0))
32+
plastic = Plastic(color=RGBf(0.9f0, 0.9f0, 0.9f0), reflection_ior=1.2, reflection_roughness=0.1)
33+
plastic_ceil = Plastic(color=RGBf(0.33, 0.63, 0.83))
34+
radiance = 500
35+
scene = Scene(size=(1024, 1024); lights=[
36+
AmbientLight(RGBf(0.6, 0.6, 0.6)),
37+
PointLight(Vec3f(4, 4, 10), RGBf(150, 150, 150)),
38+
PointLight(Vec3f(-3, 10, 2.5), RGBf(60, 60, 60)),
39+
PointLight(Vec3f(0, 3, 0.5), RGBf(40, 40, 40))
40+
])
41+
cam3d!(scene)
42+
cm = scene.camera_controls
43+
mesh!(scene, model, material=glass)
44+
mini, maxi = extrema(Rect3f(decompose(Point, model)))
45+
floorrect = Rect3f(Vec3f(-10, mini[2], -10), Vec3f(20, -1, 20))
46+
mesh!(scene, floorrect, material=plastic_ceil)
47+
ceiling = Rect3f(Vec3f(-20, 12, -20), Vec3f(40, -1, 40))
48+
mesh!(scene, ceiling, material=plastic)
49+
center!(scene)
50+
update_cam!(scene, Vec3f(-1.6, 6.2, 0.2), Vec3f(-3.6, 2.5, 2.4), Vec3f(0, 1, 0))
51+
52+
@time colorbuffer(scene; backend=RPRMakie, iterations=100)
53+
end

src/bounds.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,22 @@ end
3333

3434
function Base.length(b::Bounds2)::Int64
3535
δ = ceil.(b.p_max .- b.p_min .+ 1f0)
36-
Int64(δ[1] * δ[2])
36+
u_int32(δ[1] * δ[2])
3737
end
3838

3939
function Base.iterate(
40-
b::Bounds2, i::Integer = 1,
41-
)::Union{Nothing,Tuple{Point2f,Integer}}
40+
b::Bounds2, i::Integer = Int32(1),
41+
)::Union{Nothing,Tuple{Point2f,Int32}}
4242
i > length(b) && return nothing
4343

44-
j = i - 1
44+
j = i - Int32(1)
4545
δ = b.p_max .- b.p_min .+ 1f0
46-
b.p_min .+ Point2f(j % δ[1], j ÷ δ[1]), i + 1
46+
b.p_min .+ Point2f(j % δ[1], j ÷ δ[1]), i + Int32(1)
4747
end
4848

4949
# Index through 8 corners.
5050
function corner(b::Bounds3, c::Integer)
51-
c -= 1
51+
c -= Int32(1)
5252
Point3f(
5353
b[(c&1)+1][1],
5454
b[(c & 2) != 0 ? 2 : 1][2],

src/film.jl

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ function FilmTile(f::Film, sample_bounds::Bounds2, radius)
130130
end
131131

132132
function reset!(tile::FilmTile)
133+
133134
tile.pixels.contrib_sum .= (RGBSpectrum(0f0),)
134135
tile.pixels.filter_weight_sum .= 0f0
135136
end
@@ -147,13 +148,13 @@ end
147148

148149
function filter_offset!(offsets, start, stop, discrete_point, inv_filter_radius, filter_table_width)
149150
@inbounds for (i, x) in enumerate(Int(start):Int(stop))
150-
fx = abs((x - discrete_point[1]) * inv_filter_radius * filter_table_width)
151+
fx = abs((x - discrete_point) * inv_filter_radius * filter_table_width)
151152
offsets[i] = clamp(ceil(fx), 1, filter_table_width) # TODO is clipping ok?
152153
end
153154
end
154155

155156
@inline function filter_offset(x, discrete_point, inv_filter_radius, filter_table_width)
156-
fx = abs((x - discrete_point[1]) * inv_filter_radius * filter_table_width)
157+
fx = abs((x - discrete_point) * inv_filter_radius * filter_table_width)
157158
return clamp(u_int32(ceil(fx)), Int32(1), Int32(filter_table_width)) # TODO is clipping ok?
158159
end
159160

@@ -187,8 +188,8 @@ function add_sample!(
187188
p0 = Int32.(max.(p0, max.(t.bounds.p_min, Point2{Int32}(1))))
188189
p1 = Int32.(min.(p1, t.bounds.p_max))
189190
# Precompute x & y filter offsets.
190-
offsets_x = filter_offsets(p0[1], p1[1], discrete_point, t.inv_filter_radius[1], t.filter_table_width)
191-
offsets_y = filter_offsets(p0[2], p1[2], discrete_point, t.inv_filter_radius[2], t.filter_table_width)
191+
offsets_x = filter_offsets(p0[1], p1[1], discrete_point[1], t.inv_filter_radius[1], t.filter_table_width)
192+
offsets_y = filter_offsets(p0[2], p1[2], discrete_point[2], t.inv_filter_radius[2], t.filter_table_width)
192193
# Loop over filter support & add sample to pixel array.
193194
pixels = t.pixels
194195
contrib_sum = pixels.contrib_sum
@@ -245,12 +246,18 @@ function set_image!(f::Film, spectrum::Matrix{S}) where {S<:Spectrum}
245246
f.pixels.splat_xyz .= (Point3f(0.0f0),)
246247
end
247248

248-
function to_framebuffer!(film::Film, splat_scale::Float32 = 1f0)
249-
image = film.framebuffer
250-
xyz = film.pixels.xyz
251-
filter_weight_sum = film.pixels.filter_weight_sum
252-
splat_xyz = film.pixels.splat_xyz
253-
@inbounds for idx in eachindex(film.pixels)
249+
function clear!(film::Film)
250+
film.pixels.xyz .= (Point3f(0),)
251+
film.pixels.filter_weight_sum .= 0.0f0
252+
film.pixels.splat_xyz .= (Point3f(0),)
253+
end
254+
255+
function to_framebuffer!(image, pixels, scale=1f0, splat_scale::Float32=1.0f0)
256+
image .= RGB{Float32}(0.0f0, 0.0f0, 0.0f0)
257+
xyz = pixels.xyz
258+
filter_weight_sum = pixels.filter_weight_sum
259+
splat_xyz = pixels.splat_xyz
260+
@inbounds for idx in eachindex(pixels)
254261
rgb = XYZ_to_RGB(xyz[idx])
255262
# Normalize pixel with weight sum.
256263
fws = filter_weight_sum[idx]
@@ -261,16 +268,22 @@ function to_framebuffer!(film::Film, splat_scale::Float32 = 1f0)
261268
# Add splat value at pixel & scale.
262269
splat_rgb = XYZ_to_RGB(splat_xyz[idx])
263270
rgb = rgb .+ splat_scale .* splat_rgb
264-
rgb = rgb .* film.scale
271+
rgb = rgb .* scale
265272
rgb = map(rgb) do c
266-
c = ifelse(isfinite(c), c, 0.0f0)
267-
return clamp(c, 0.0f0, 1.0f0)
273+
return ifelse(isfinite(c), c, 0.0f0)
268274
end
269275
image[idx] = RGB(rgb...)
270276
end
277+
return image
278+
end
279+
280+
function to_framebuffer!(film::Film, splat_scale::Float32 = 1f0)
281+
image = film.framebuffer
282+
to_framebuffer!(image, film.pixels, film.scale, splat_scale)
271283
end
272284

273285
function save(film::Film, splat_scale::Float32 = 1f0)
274286
to_framebuffer!(film, splat_scale)
275287
FileIO.save(film.filename, @view film.framebuffer[end:-1:begin, :])
288+
film.framebuffer
276289
end

0 commit comments

Comments
 (0)