Skip to content

Commit 5d79574

Browse files
committed
Fixed some bias issues
1 parent 6ee8aee commit 5d79574

File tree

5 files changed

+27
-23
lines changed

5 files changed

+27
-23
lines changed

scenes/many_point_lights_scene.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
22
"technique": {
33
"type": "path",
4-
"max_depth": 64
4+
"max_depth": 64,
5+
"light_selector": "simple"
56
},
67
"camera": {
78
"type": "perspective",

src/artic/impl/light_hierarchy.art

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ mod light_hierarchy {
4747
1:f32
4848
};
4949

50-
entry.flux * cos_d / math_builtins::fmax[f32](0.0001, dist2)
50+
all::safe_div(entry.flux * cos_d, dist2)
5151
}
5252

5353
fn @get_left_prop(left: LightHierarchyEntry, right: LightHierarchyEntry, pos: Vec3) -> f32 {
5454
let cl = get_entry_cost(left, pos);
5555
let cr = get_entry_cost(right, pos);
56-
cl / (cl + cr)
56+
1 / (1 + cr/cl)
5757
}
5858

5959
fn @random_select_left(rnd: &mut RndState, left: LightHierarchyEntry, right: LightHierarchyEntry, pos: Vec3) -> (bool, f32) {
@@ -65,9 +65,11 @@ mod light_hierarchy {
6565
let mut pdf = 1:f32;
6666
let mut entry = load_entry(0, data);
6767
while !entry.is_leaf {
68-
let (is_left, prop) = random_select_left(rnd, load_entry(entry.id, data), load_entry(entry.id+1, data), pos);
68+
let left = load_entry(entry.id, data);
69+
let right = load_entry(entry.id+1, data);
70+
let (is_left, prop) = random_select_left(rnd, left, right, pos);
6971

70-
entry = load_entry(all::select(is_left, entry.id, entry.id+1), data);
72+
entry = all::select(is_left, left, right);
7173
pdf *= all::select(is_left, prop, 1-prop);
7274
}
7375

@@ -82,19 +84,14 @@ mod light_hierarchy {
8284
let left = load_entry(entry.id, data);
8385
let right = load_entry(entry.id+1, data);
8486
let prop = get_left_prop(left, right, pos);
87+
let is_left = (code & 0x1) == 0;
8588

86-
if (code & 0x1) == 0 {
87-
entry = left;
88-
pdf *= prop;
89-
} else {
90-
entry = right;
91-
pdf *= 1 - prop;
92-
}
93-
89+
entry = all::select(is_left, left, right);
90+
pdf *= all::select(is_left, prop, 1-prop);
9491
code >>= 1;
9592
}
9693

97-
all::select(entry.id == light.id, pdf, 0:f32)
94+
pdf
9895
}
9996
}
10097

src/artic/impl/light_selector.art

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ fn @make_uniform_light_selector(infinite_lights: LightTable, finite_lights: Ligh
4747
fn @make_cdf_light_selector(infinite_lights: LightTable, finite_lights: LightTable, sampler: cdf::CDF1D) -> LightSelector {
4848
if infinite_lights.count == 0 {
4949
LightSelector {
50-
count = sampler.func_size,
50+
count = finite_lights.count,
5151
sample = @|rnd,_| { let s = sampler.sample_discrete(randf(rnd)); (finite_lights.get(s.off), s.pdf) },
5252
pdf = @|light,_| sampler.pdf_discrete(light.id).pdf,
5353
infinites = infinite_lights,
@@ -57,7 +57,7 @@ fn @make_cdf_light_selector(infinite_lights: LightTable, finite_lights: LightTab
5757
let pdf_infinite_lights = 1 / (infinite_lights.count as f32);
5858
let infinite_ratio = 0.5:f32;
5959
LightSelector {
60-
count = infinite_lights.count + sampler.func_size,
60+
count = infinite_lights.count + finite_lights.count,
6161
sample = @|rnd,_| {
6262
let q = randf(rnd);
6363
if q < infinite_ratio {
@@ -92,7 +92,7 @@ fn @make_hierarchy_light_selector(infinite_lights: LightTable, finite_lights: Li
9292
let infinite_ratio = 0.5:f32;
9393
let hierarchy = make_light_hierarchy(finite_lights, data);
9494
LightSelector {
95-
count = finite_lights.count,
95+
count = infinite_lights.count + finite_lights.count,
9696
sample = @|rnd, from_pos| {
9797
let q = randf(rnd);
9898
if q < infinite_ratio {

src/artic/render/light.art

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,10 @@ struct LightTable {
9797
get: fn (i32) -> Light
9898
}
9999

100-
fn @make_empty_light_table() = LightTable {
101-
count = 0,
100+
/// Set count, but return no valid light. Useful for miss shaders
101+
fn @make_proxy_light_table(count: i32) = LightTable {
102+
count = count,
102103
get = @|_| make_null_light(0)
103104
};
105+
106+
fn @make_empty_light_table() = make_proxy_light_table(0);

src/backend/runtime/loader/LoaderLight.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ std::string LoaderLight::generate(ShadingTree& tree, bool skipFinite)
109109
stream << generateInfinite(tree);
110110

111111
if (skipFinite)
112-
stream << " let finite_lights = make_empty_light_table();" << std::endl;
112+
stream << " let finite_lights = make_proxy_light_table(" << finiteLightCount() << ");" << std::endl;
113113
else
114114
stream << generateFinite(tree);
115115

@@ -409,17 +409,20 @@ std::string LoaderLight::generateLightSelector(std::string type, ShadingTree& tr
409409
{
410410
const std::string uniformSelector = " let light_selector = make_uniform_light_selector(infinite_lights, finite_lights);";
411411

412+
// If there is just a none or just a single light, do not bother with fancy selectors
413+
if (lightCount() <= 1)
414+
return uniformSelector;
415+
412416
std::stringstream stream;
413417

414-
const bool fallbackLS = lightCount() <= 1;
415-
if (!fallbackLS && type == "hierarchy") {
418+
if (type == "hierarchy") {
416419
auto hierarchy = LightHierarchy::setup(mFiniteLights, tree);
417420
if (hierarchy.empty()) {
418421
stream << uniformSelector << std::endl;
419422
} else {
420423
stream << " let light_selector = make_hierarchy_light_selector(infinite_lights, finite_lights, device.load_buffer(\"" << hierarchy.u8string() << "\"));" << std::endl;
421424
}
422-
} else if (!fallbackLS && type == "simple") {
425+
} else if (type == "simple") {
423426
auto cdf = generateLightSelectionCDF(tree);
424427
if (cdf.empty()) {
425428
stream << uniformSelector << std::endl;

0 commit comments

Comments
 (0)