Skip to content

Commit 08af848

Browse files
committed
simplify some integrators
1 parent 3051a73 commit 08af848

4 files changed

Lines changed: 203 additions & 249 deletions

File tree

src/artic/technique/simpleguidedpathtracer.art

Lines changed: 64 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,35 @@
11
struct SGPTRayPayload {
2-
inv_bsdf_pdf: f32, // Inverse BSDF pdf
3-
inv_guided_pdf: f32, // Inverse Guided pdf
4-
contrib: Color, // Current contribution
5-
depth: i32, // Current depth
6-
eta: f32, // Current eta (n1 / n2)
7-
gen_technique: i32, // Technique which generated the previous vertex (0=BSDF, 1=Guiding)
2+
inv_pdf: f32, // Inverse pdf
3+
contrib: Color, // Current contribution
4+
depth: i32, // Current depth
5+
eta: f32, // Current eta (n1 / n2)
6+
gen_technique: i32, // Technique which generated the previous vertex (0=BSDF, 1=Guiding)
87
}
98

109
fn @write_sgptraypayload(payload: RayPayload, pt: SGPTRayPayload) -> () {
11-
payload.set(0, pt.inv_bsdf_pdf);
12-
payload.set(1, pt.inv_guided_pdf);
13-
payload.set(2, pt.contrib.r);
14-
payload.set(3, pt.contrib.g);
15-
payload.set(4, pt.contrib.b);
16-
payload.set(5, pt.depth as f32);
17-
payload.set(6, pt.eta);
18-
payload.set(7, pt.gen_technique as f32);
10+
payload.set(0, pt.inv_pdf);
11+
payload.set(1, pt.contrib.r);
12+
payload.set(2, pt.contrib.g);
13+
payload.set(3, pt.contrib.b);
14+
payload.set(4, pt.depth as f32);
15+
payload.set(5, pt.eta);
16+
payload.set(6, pt.gen_technique as f32);
1917
}
2018

2119
fn @unwrap_sgptraypayload(payload: RayPayload) = SGPTRayPayload {
22-
inv_bsdf_pdf = payload.get(0),
23-
inv_guided_pdf = payload.get(1),
24-
contrib = make_color(payload.get(2), payload.get(3), payload.get(4), 1),
25-
depth = payload.get(5) as i32,
26-
eta = payload.get(6),
27-
gen_technique = payload.get(7) as i32,
20+
inv_pdf = payload.get(0),
21+
contrib = make_color(payload.get(1), payload.get(2), payload.get(3), 1),
22+
depth = payload.get(4) as i32,
23+
eta = payload.get(5),
24+
gen_technique = payload.get(6) as i32,
2825
};
2926

3027
fn @init_sgpt_raypayload(payload: RayPayload) = write_sgptraypayload(payload, SGPTRayPayload {
31-
inv_bsdf_pdf = 0,
32-
inv_guided_pdf = 0,
33-
contrib = color_builtins::white,
34-
depth = 1,
35-
eta = 1,
36-
gen_technique = 0
28+
inv_pdf = 0,
29+
contrib = color_builtins::white,
30+
depth = 1,
31+
eta = 1,
32+
gen_technique = 0
3733
});
3834

3935
struct SimpleGuidingTechnique {
@@ -42,13 +38,9 @@ struct SimpleGuidingTechnique {
4238
prob: fn () -> f32 // Probability to use this guider
4339
}
4440

45-
fn @make_sgpt_renderer(device: Device, max_path_len: i32, min_path_len: i32, spi: i32, light_selector: LightSelector, clamp_value: f32, enable_nee: bool, enable_aovs: bool, guider: SimpleGuidingTechnique) -> Technique {
41+
fn @make_sgpt_renderer(_device: Device, max_path_len: i32, min_path_len: i32, _spi: i32, light_selector: LightSelector, clamp_value: f32, enable_nee: bool, _enable_aovs: bool, guider: SimpleGuidingTechnique) -> Technique {
4642
let offset : f32 = 0.001;
4743

48-
let aov_bsdf = if enable_aovs { device.load_aov_image("BSDF Weights", spi, 0) } else { make_empty_aov_image(0, 0) };
49-
let aov_guided = if enable_aovs { device.load_aov_image("Guided Weights", spi, 0) } else { make_empty_aov_image(0, 0) };
50-
let aov_nee = if enable_aovs { device.load_aov_image("NEE Weights", spi, 0) } else { make_empty_aov_image(0, 0) };
51-
5244
let handle_color = make_std_color_handler(clamp_value);
5345

5446
fn @on_shadow( ctx: ShadingContext
@@ -129,25 +121,11 @@ fn @make_sgpt_renderer(device: Device, max_path_len: i32, min_path_len: i32, spi
129121
let pt = unwrap_sgptraypayload(payload);
130122
let dot = -vec3_dot(ctx.ray.dir, ctx.surf.local.col(2));
131123
if dot > flt_eps { // Only contribute proper aligned directions
132-
let emit = mat.emission(ctx);
133-
let pdf_s = emit.pdf.as_solid(dot, ctx.hit.distance * ctx.hit.distance);
134-
135-
let mis_denom = 1 + if pt.gen_technique == 0 { safe_div(pt.inv_bsdf_pdf, pt.inv_guided_pdf) } else { safe_div(pt.inv_guided_pdf, pt.inv_bsdf_pdf) };
136-
let mis = if enable_nee {
137-
let inv_pdf_b = if pt.gen_technique == 0 { pt.inv_bsdf_pdf } else { pt.inv_guided_pdf }; // The actual (inverse) pdf used for the previous vertex
138-
let pdf_l_s = light_selector.pdf(mat.light, ctx.ray.org) * pdf_s;
139-
1 / (mis_denom + inv_pdf_b * pdf_l_s)
140-
} else {
141-
1 / mis_denom
142-
};
124+
let emit = mat.emission(ctx);
125+
let pdf_s = emit.pdf.as_solid(dot, ctx.hit.distance * ctx.hit.distance);
126+
let mis = if enable_nee { 1 / (1 + pt.inv_pdf * light_selector.pdf(mat.light, ctx.ray.org) * pdf_s) } else { 1:f32 };
143127

144128
let contrib = handle_color(color_mulf(color_mul(pt.contrib, emit.intensity), mis));
145-
146-
if pt.gen_technique == 0 {
147-
aov_bsdf.splat(ctx.pixel, contrib);
148-
} else {
149-
aov_guided.splat(ctx.pixel, contrib);
150-
}
151129

152130
return(make_option(contrib))
153131
}
@@ -168,29 +146,18 @@ fn @make_sgpt_renderer(device: Device, max_path_len: i32, min_path_len: i32, spi
168146
if light.infinite && !light.delta {
169147
inflights += 1;
170148

171-
let emit = light.emission(ctx);
149+
let emit = light.emission(ctx);
150+
if is_black_eps(emit, flt_eps) { continue() }
151+
172152
let pdf = light.pdf_direct(ctx.ray, make_invalid_surface_element());
173153
let pdf_s = pdf.as_solid(1, 1/* We assume infinite lights are always given in solid angle measure */);
174-
175-
let mis_denom = 1 + if pt.gen_technique == 0 { safe_div(pt.inv_bsdf_pdf, pt.inv_guided_pdf) } else { safe_div(pt.inv_guided_pdf, pt.inv_bsdf_pdf) };
176-
let mis = if enable_nee {
177-
let inv_pdf_b = if pt.gen_technique == 0 { pt.inv_bsdf_pdf } else { pt.inv_guided_pdf }; // The actual (inverse) pdf used for the previous vertex
178-
let pdf_l_s = light_selector.pdf(light, ctx.ray.org) * pdf_s;
179-
1 / (mis_denom + inv_pdf_b * pdf_l_s)
180-
} else {
181-
1 / mis_denom
182-
};
154+
let mis = if enable_nee { 1 / (1 + pt.inv_pdf * light_selector.pdf(light, ctx.ray.org) * pdf_s) } else { 1:f32 };
183155

184156
color = color_add(color, handle_color(color_mulf(color_mul(pt.contrib, emit), mis)));
185157
}
186158
}
187159

188160
if inflights > 0 {
189-
if pt.gen_technique == 0 {
190-
aov_bsdf.splat(ctx.pixel, color);
191-
} else {
192-
aov_guided.splat(ctx.pixel, color);
193-
}
194161
make_option(color)
195162
} else {
196163
Option[Color]::None
@@ -221,25 +188,29 @@ fn @make_sgpt_renderer(device: Device, max_path_len: i32, min_path_len: i32, spi
221188
return(Option[Ray]::None)
222189
}
223190

224-
let inv_guided_pdf = 1 / (g_prob * pdf_g_s);
225-
let mat_eval = mat.bsdf.eval(in_dir, out_dir);
191+
let full_pdf = (1 - g_prob) * mat.bsdf.pdf(in_dir, out_dir) + g_prob * pdf_g_s;
192+
let inv_pdf = 1 / full_pdf;
193+
let mat_eval = mat.bsdf.eval(in_dir, out_dir);
226194

227-
let contrib = color_mul(pt.contrib, color_mulf(mat_eval, inv_guided_pdf));
195+
let contrib = color_mul(pt.contrib, color_mulf(mat_eval, inv_pdf));
228196
let rr_prob = if pt.depth + 1 > min_path_len { russian_roulette_pbrt(color_mulf(contrib, pt.eta * pt.eta), 0.95) } else { 1.0 };
229197
if rnd.next_f32() >= rr_prob {
230198
return(Option[Ray]::None)
231199
}
232200

233-
let inv_bsdf_pdf = safe_div(1, (1 - g_prob) * mat.bsdf.pdf(in_dir, out_dir));
234-
let new_contrib = color_mulf(contrib, 1 / rr_prob);
201+
let new_contrib = color_mulf(contrib, 1 / rr_prob);
202+
203+
// This might happen due to wrong hemisphere, texture, etc
204+
if color_average(new_contrib) <= flt_eps {
205+
return(Option[Ray]::None)
206+
}
235207

236208
write_sgptraypayload(payload, SGPTRayPayload {
237-
inv_bsdf_pdf = inv_bsdf_pdf,
238-
inv_guided_pdf = inv_guided_pdf,
239-
contrib = new_contrib,
240-
depth = pt.depth + 1,
241-
eta = pt.eta, // * mat_sample.eta (TODO)
242-
gen_technique = 1 /* Guiding */
209+
inv_pdf = inv_pdf,
210+
contrib = new_contrib,
211+
depth = pt.depth + 1,
212+
eta = pt.eta, // * mat_sample.eta (TODO)
213+
gen_technique = 1 /* Guiding */
243214
});
244215
make_option(
245216
make_ray(ctx.surf.point, in_dir, offset, flt_max, ray_flag_bounce)
@@ -252,23 +223,29 @@ fn @make_sgpt_renderer(device: Device, max_path_len: i32, min_path_len: i32, spi
252223
return(Option[Ray]::None)
253224
}
254225

255-
let contrib = color_mul(pt.contrib, mat_sample.color/* Pdf and cosine are already applied!*/);
226+
let full_pdf = if mat_sample.is_delta { mat_sample.pdf } else { (1 - g_prob) * mat_sample.pdf + g_prob * guider.pdf(mat_sample.in_dir, out_dir) };
227+
let inv_pdf = 1/ full_pdf;
228+
let mat_eval = color_mulf(mat_sample.color, mat_sample.pdf);
229+
230+
let contrib = color_mul(pt.contrib, color_mulf(mat_eval, inv_pdf));
256231
let rr_prob = if pt.depth + 1 > min_path_len { russian_roulette_pbrt(color_mulf(contrib, pt.eta * pt.eta), 0.95) } else { 1.0 };
257232
if rnd.next_f32() >= rr_prob {
258233
return(Option[Ray]::None)
259234
}
260235

261-
let inv_bsdf_pdf = if mat_sample.is_delta { 0 } else { 1 / ((1 - g_prob) * mat_sample.pdf) };
262-
let inv_guided_pdf = if mat_sample.is_delta { 0 } else { safe_div(1, g_prob * guider.pdf(mat_sample.in_dir, out_dir)) };
263236
let new_contrib = color_mulf(contrib, 1 / (rr_prob * (1 - g_prob)));
237+
238+
// This might happen due to wrong hemisphere, texture, etc
239+
if color_average(new_contrib) <= flt_eps {
240+
return(Option[Ray]::None)
241+
}
264242

265243
write_sgptraypayload(payload, SGPTRayPayload {
266-
inv_bsdf_pdf = inv_bsdf_pdf,
267-
inv_guided_pdf = inv_guided_pdf,
268-
contrib = new_contrib,
269-
depth = pt.depth + 1,
270-
eta = pt.eta * mat_sample.eta,
271-
gen_technique = 0 /* BSDF */
244+
inv_pdf = inv_pdf,
245+
contrib = new_contrib,
246+
depth = pt.depth + 1,
247+
eta = pt.eta * mat_sample.eta,
248+
gen_technique = 0 /* BSDF */
272249
});
273250
make_option(
274251
make_ray(ctx.surf.point, mat_sample.in_dir, offset, flt_max, ray_flag_bounce)
@@ -279,20 +256,11 @@ fn @make_sgpt_renderer(device: Device, max_path_len: i32, min_path_len: i32, spi
279256
}
280257
}
281258

282-
fn @on_shadow_miss( ctx: ShadingContext
283-
, _shader: MaterialShader
284-
, _: RayPayload
285-
, color: Color) -> Option[Color] {
286-
aov_nee.splat(ctx.pixel, color);
287-
make_option(color)
288-
}
289-
290259
make_empty_technique().{
291-
on_hit = on_hit,
292-
on_miss = on_miss,
293-
on_shadow = on_shadow,
294-
on_bounce = on_bounce,
295-
on_shadow_miss = if enable_aovs { on_shadow_miss } else { TechniqueNoShadowMissFunction },
260+
on_hit = on_hit,
261+
on_miss = on_miss,
262+
on_shadow = on_shadow,
263+
on_bounce = on_bounce
296264
}
297265
}
298266

0 commit comments

Comments
 (0)