Skip to content

Commit

Permalink
Take texel shape into account for sample environment map
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Oct 18, 2024
1 parent aaa15a5 commit 8aa5985
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 4 deletions.
2 changes: 1 addition & 1 deletion blade-helpers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub use hud::{populate_debug_selection, ExposeHud};
pub fn default_ray_config() -> blade_render::RayConfig {
blade_render::RayConfig {
num_environment_samples: 1,
environment_importance_sampling: false,
environment_importance_sampling: true,
tap_count: 2,
tap_radius: 20,
tap_confidence_near: 15,
Expand Down
9 changes: 8 additions & 1 deletion blade-render/code/env-importance.inc.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@ struct EnvImportantSample {
pdf: f32,
}

// Returns the range of values proportional to the area, given the texel Y
fn compute_latitude_area_bounds(texel_y: i32, dim: u32) -> vec2<f32> {
return cos(vec2<f32>(vec2<i32>(texel_y, texel_y + 1)) / f32(dim) * PI);
}

fn compute_texel_solid_angle(itc: vec2<i32>, dim: vec2<u32>) -> f32 {
//Note: this has to agree with `map_equirect_uv_to_dir`
let meridian_solid_angle = 4.0 * PI / f32(dim.x);
let meridian_part = 0.5 * (cos(PI * f32(itc.y) / f32(dim.y)) - cos(PI * f32(itc.y + 1) / f32(dim.y)));
let bounds = compute_latitude_area_bounds(itc.y, dim.y);
let meridian_part = 0.5 * (bounds.x - bounds.y);
return meridian_solid_angle * meridian_part;
}

Expand Down
7 changes: 5 additions & 2 deletions blade-render/code/ray-trace.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,11 @@ fn sample_light_from_environment(rng: ptr<function, RandomState>) -> LightSample
// sample the incoming radiance
ls.radiance = textureLoad(env_map, es.pixel, 0).xyz;
// for determining direction - offset randomly within the texel
// Note: this only works if the texels are sufficiently small
ls.uv = (vec2<f32>(es.pixel) + vec2<f32>(random_gen(rng), random_gen(rng))) / vec2<f32>(dim);
// this offset has to be uniformly distributed across the surface of the texel
let u = (f32(es.pixel.x) + random_gen(rng)) / f32(dim.x);
let bounds = compute_latitude_area_bounds(es.pixel.y, dim.y);
let v = acos(mix(bounds.x, bounds.y, random_gen(rng))) / PI;
ls.uv = vec2<f32>(u, v);
return ls;
}

Expand Down

0 comments on commit 8aa5985

Please sign in to comment.