Skip to content

Commit 50f8643

Browse files
committed
chore: Consolidate raytracer shader code
1 parent f154cd5 commit 50f8643

File tree

4 files changed

+31
-133
lines changed

4 files changed

+31
-133
lines changed

app/src/rendering/renderer.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ impl Renderer {
272272
} else {
273273
self.frames_till_next_raytracer_compute -= 1;
274274
}
275+
} else {
276+
self.frames_till_next_raytracer_compute = 0;
275277
}
276278

277279
Ok(())

app/src/shaders/probe_lighting/updater.wesl

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,10 @@ import super::util::{
33
ProbeGridConfig,
44
probe_index_to_world_pos,
55
probe_index_to_tex_coords,
6-
world_to_texture_coords,
76
};
87
import super::super::raytracer::util::{
98
sample_radiance_with_lighting,
10-
trace_triangles,
11-
get_interpolated_color_from_hit,
12-
get_triangle_data,
13-
get_interpolated_color,
14-
Ray,
15-
HitInfo,
16-
Material,
17-
Vertex,
18-
Triangle,
19-
FLT_MAX,
20-
SUN_INTENSITY,
21-
materials,
22-
material_stride,
23-
vertices,
24-
vertex_stride,
25-
vertex_normal_offset,
26-
vertex_material_offset,
27-
indices,
9+
MAX_BOUNCES
2810
};
2911

3012
@group(3) @binding(0) var probe_atlas_l0: texture_storage_3d<rgba32float, write>;
@@ -87,7 +69,7 @@ fn project_to_sh(probe_pos: vec3f, probe_index: u32) -> SHCoefficients {
8769

8870
// Use probe position and sample index for unique bounce seeds
8971
let bounce_seed = f32(probe_index) * 0.1 + fi * 0.01;
90-
let radiance = sample_radiance_with_lighting(probe_pos, direction, bounce_seed);
72+
let radiance = sample_radiance_with_lighting(probe_pos, direction, MAX_BOUNCES, bounce_seed).rgb;
9173

9274
// L0 basis function (constant)
9375
let y00 = SH_C0;
@@ -109,7 +91,7 @@ fn project_to_sh(probe_pos: vec3f, probe_index: u32) -> SHCoefficients {
10991
}
11092

11193
// Apply a small normalization factor to prevent excessive brightness
112-
let normalization_factor = 0.5;
94+
let normalization_factor = 1.0;
11395
coeffs.l0 *= normalization_factor;
11496
coeffs.l1x *= normalization_factor;
11597
coeffs.l1y *= normalization_factor;

app/src/shaders/raytracer/compute.wesl

Lines changed: 9 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,11 @@ import super::super::util::{
33
decodeRGBA,
44
};
55
import super::util::{
6-
create_ray,
7-
get_triangle_intersection_mt,
8-
get_interpolated_color,
9-
get_sky_color,
10-
random_in_hemisphere,
11-
get_triangle_data,
12-
get_vertex,
13-
get_material,
14-
Ray,
15-
HitInfo,
16-
SceneParams,
17-
Material,
18-
Vertex,
19-
Triangle,
6+
sample_radiance_with_lighting,
207
MAX_BOUNCES,
218
MAX_LOW_FRAME_BOUNCES,
229
LOW_BOUNCE_FRAMES,
2310
CLEAR_COLOR,
24-
FLT_MAX,
25-
SUN_INTENSITY,
26-
materials,
27-
material_stride,
28-
vertices,
29-
vertex_stride,
30-
vertex_normal_offset,
31-
vertex_material_offset,
32-
indices,
33-
sun_direction,
3411
};
3512

3613
@group(3) @binding(0) @if(wasm) var result: texture_storage_2d<r32float, read_write>;
@@ -41,39 +18,16 @@ import super::util::{
4118

4219

4320

44-
fn trace_triangles(ray: Ray) -> HitInfo {
45-
let num_triangles = u32(arrayLength(&indices) / 3u);
4621

47-
var nearest_hit_info: HitInfo;
48-
nearest_hit_info.did_hit = false;
49-
nearest_hit_info.t = FLT_MAX;
5022

51-
for (var i: u32 = 0u; i < num_triangles; i = i + 1u) {
52-
let triangle: Triangle = get_triangle_data(i);
53-
let hit_info: HitInfo = get_triangle_intersection_mt(triangle, ray);
54-
55-
if hit_info.did_hit {
56-
if hit_info.t < nearest_hit_info.t {
57-
nearest_hit_info = hit_info;
58-
nearest_hit_info.i = i;
59-
}
60-
}
61-
}
62-
63-
return nearest_hit_info;
23+
fn get_camera_position(uv: vec2f) -> vec3f {
24+
return (camera_to_world * vec4f(0.0, 0.0, 0.0, 1.0)).xyz;
6425
}
6526

66-
fn get_interpolated_color_from_hit(hit_info: HitInfo) -> vec4f {
67-
let triangle: Triangle = get_triangle_data(hit_info.i);
68-
return vec4f(get_interpolated_color(hit_info, triangle), 1.0);
69-
}
70-
71-
fn create_camera_ray(uv: vec2f) -> Ray {
72-
let origin: vec3f = (camera_to_world * vec4f(0.0, 0.0, 0.0, 1.0)).xyz;
27+
fn get_camera_direction(uv: vec2f) -> vec3f {
7328
var direction = (camera_inverse_projection * vec4f(uv, 0.0, 1.0)).xyz;
7429
direction = (camera_to_world * vec4f(direction, 0.0)).xyz;
75-
direction = normalize(direction);
76-
return create_ray(origin, direction);
30+
return normalize(direction);
7731
}
7832

7933
@compute
@@ -103,9 +57,6 @@ fn main(@builtin(global_invocation_id) id: vec3u) {
10357
// Reference: https://github.com/gfx-rs/wgpu?tab=readme-ov-file#coordinate-systems
10458
let uv = ((vec2f(id.xy) + 0.5) / dims * 2.0 - 1.0) * vec2f(1.0, -1.0);
10559

106-
// Get a ray for the UVs
107-
var ray: Ray = create_camera_ray(uv);
108-
10960
// Load the previous frame's color
11061
var prev_color: vec4f;
11162
@if(wasm) {
@@ -114,55 +65,15 @@ fn main(@builtin(global_invocation_id) id: vec3u) {
11465
prev_color = textureLoad(result, coords);
11566
}
11667

117-
let scene_params = SceneParams(
118-
material_stride,
119-
vertex_stride,
120-
vertex_normal_offset,
121-
vertex_material_offset,
122-
sun_direction,
123-
);
124-
125-
// Trace the ray against the triangles
126-
var ray_color: vec4f = vec4f(0.0);
127-
var ray_throughput: vec4f = vec4f(1.0);
128-
68+
12969
var max_bounces = MAX_BOUNCES;
13070
if frame_count < LOW_BOUNCE_FRAMES {
13171
max_bounces = MAX_LOW_FRAME_BOUNCES;
13272
}
13373

134-
for (var bounce = 0u; bounce <= max_bounces; bounce += 1u) {
135-
if bounce == max_bounces {
136-
// Set ray color as black if the ray has bounced too many times
137-
ray_color = vec4f(0.0);
138-
break;
139-
}
140-
141-
let hit_info: HitInfo = trace_triangles(ray);
142-
if hit_info.did_hit {
143-
let tri_color = get_interpolated_color_from_hit(hit_info);
144-
ray_color += tri_color * ray_throughput;
145-
ray_throughput *= tri_color;
146-
147-
// Use frame number in random seed for temporal variation
148-
ray = create_ray(
149-
hit_info.p + hit_info.normal * 0.001, // Move the origin slightly to avoid self-intersection
150-
random_in_hemisphere(hit_info.normal, hit_info.p + vec3f(f32(frame_count) * 0.1))
151-
);
152-
} else {
153-
if bounce == 0u {
154-
// If ray misses all triangles, return the sky color
155-
ray_color = get_sky_color(ray, scene_params);
156-
} else {
157-
let ray_sun_intensity = max(0.0, dot(scene_params.sun_direction, ray.direction)) * SUN_INTENSITY;
158-
ray_color *= ray_sun_intensity * ray_throughput;
159-
}
160-
161-
break;
162-
}
163-
}
164-
165-
ray_color = clamp(ray_color, vec4f(0.0), vec4f(1.0));
74+
var camera_position = get_camera_position(uv);
75+
var camera_direction = get_camera_direction(uv);
76+
var ray_color: vec4f = sample_radiance_with_lighting(camera_position, camera_direction, max_bounces, f32(frame_count) * 0.1);
16677

16778
// Blend with previous frame
16879
let blend_factor = 1.0 / pow(f32(frame_count + 1), 1.05);

app/src/shaders/raytracer/util.wesl

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const MAX_BOUNCES: u32 = 8u;
22
const MAX_LOW_FRAME_BOUNCES: u32 = 2u;
3-
const LOW_BOUNCE_FRAMES: u32 = 8u;
3+
const LOW_BOUNCE_FRAMES: u32 = 4u;
44
const CLEAR_COLOR: vec4f = vec4f(0.0, 0.0, 0.0, 1.0);
55
const FLT_MAX: f32 = 1e12;
66
const K_EPSILON: f32 = 1e-6;
@@ -213,7 +213,7 @@ fn get_interpolated_color_from_hit(hit_info: HitInfo) -> vec4f {
213213
return vec4f(get_interpolated_color(hit_info, triangle), 1.0);
214214
}
215215

216-
fn sample_radiance_with_lighting(origin: vec3f, direction: vec3f, bounce_seed: f32) -> vec3f {
216+
fn sample_radiance_with_lighting(origin: vec3f, direction: vec3f, max_bounces: u32, bounce_seed: f32) -> vec4f {
217217
let scene_params = SceneParams(
218218
material_stride,
219219
vertex_stride,
@@ -226,32 +226,35 @@ fn sample_radiance_with_lighting(origin: vec3f, direction: vec3f, bounce_seed: f
226226
var ray_color = vec4f(0.0);
227227
var ray_throughput = vec4f(1.0);
228228

229-
for (var bounce = 0u; bounce < 3u; bounce++) {
230-
let hit_info = trace_triangles(ray);
229+
for (var bounce = 0u; bounce <= max_bounces; bounce += 1u) {
230+
if bounce == max_bounces {
231+
// Set ray color as black if the ray has bounced too many times
232+
ray_color = vec4f(0.0);
233+
break;
234+
}
231235

236+
let hit_info: HitInfo = trace_triangles(ray);
232237
if hit_info.did_hit {
233-
let surface_color = get_interpolated_color_from_hit(hit_info);
238+
let tri_color = get_interpolated_color_from_hit(hit_info);
239+
ray_color += tri_color * ray_throughput;
240+
ray_throughput *= tri_color;
234241

235-
ray_color += surface_color * ray_throughput;
236-
ray_throughput *= surface_color;
237-
238-
// Generate next bounce ray
239-
let seed = origin + vec3f(bounce_seed, f32(bounce), 0.0);
240242
ray = create_ray(
241-
hit_info.p + hit_info.normal * 0.001,
242-
random_in_hemisphere(hit_info.normal, seed)
243+
hit_info.p + hit_info.normal * 0.001, // Move the origin slightly to avoid self-intersection
244+
random_in_hemisphere(hit_info.normal, hit_info.p + bounce_seed)
243245
);
244246
} else {
245-
// Hit sky - add sun and ambient lighting
246247
if bounce == 0u {
248+
// If ray misses all triangles, return the sky color
247249
ray_color = get_sky_color(ray, scene_params);
248250
} else {
249251
let ray_sun_intensity = max(0.0, dot(scene_params.sun_direction, ray.direction)) * SUN_INTENSITY;
250252
ray_color *= ray_sun_intensity * ray_throughput;
251253
}
254+
252255
break;
253256
}
254257
}
255258

256-
return clamp(ray_color.rgb, vec3f(0.0), vec3f(1.0));
259+
return clamp(ray_color, vec4f(0.0), vec4f(1.0));
257260
}

0 commit comments

Comments
 (0)