Skip to content

Commit 71be078

Browse files
committed
Merge master into optimize-draw-arrange
2 parents bd7ffe5 + 7cb7362 commit 71be078

276 files changed

Lines changed: 4629 additions & 2167 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ mono_crash.*
2121

2222
# Build results
2323
[Dd]ebug/
24+
!crates/renderide/src/config/types/debug/
25+
!crates/renderide/src/config/types/debug/*.rs
2426
[Dd]ebugPublic/
2527
[Rr]elease/
2628
[Rr]eleases/

crates/renderide/assets/xr/bindings/valve_index_controller.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ path = "/user/hand/right/input/trigger/click"
3636

3737
[[binding]]
3838
action = "left_squeeze"
39-
path = "/user/hand/left/input/squeeze/value"
39+
path = "/user/hand/left/input/squeeze/force"
4040
[[binding]]
4141
action = "right_squeeze"
42-
path = "/user/hand/right/input/squeeze/value"
42+
path = "/user/hand/right/input/squeeze/force"
4343

4444
[[binding]]
4545
action = "left_thumbstick"

crates/renderide/build_support/shader.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ mod model;
2424
mod modules;
2525
#[path = "shader/parallel.rs"]
2626
mod parallel;
27-
#[path = "../src/shader_package/schema.rs"]
27+
#[path = "../src/materials/shader_package/schema.rs"]
2828
mod shader_package_schema;
2929
#[path = "shader/source.rs"]
3030
mod source;

crates/renderide/build_support/shader/emit.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,37 +205,37 @@ pub struct EmbeddedShaderReflection {
205205
fn embedded_shader_lookup_fn_defs() -> &'static str {
206206
r#"/// Flattened WGSL for `stem` from the runtime shader package.
207207
pub fn embedded_target_wgsl(stem: &str) -> Option<&'static str> {
208-
crate::shader_package::target_wgsl(stem)
208+
crate::materials::shader_package::target_wgsl(stem)
209209
}
210210
211211
/// Declared render passes for `stem`, parsed from package TOML metadata.
212212
pub fn embedded_target_passes(stem: &str) -> &'static [crate::materials::MaterialPassDesc] {
213-
crate::shader_package::material_passes(stem)
213+
crate::materials::shader_package::material_passes(stem)
214214
}
215215
216216
/// Shader default render queue for `stem`, parsed from package TOML metadata.
217217
pub fn embedded_target_default_render_queue(stem: &str) -> i32 {
218-
crate::shader_package::material_default_render_queue(stem)
218+
crate::materials::shader_package::material_default_render_queue(stem)
219219
}
220220
221221
/// Required device features for `stem`, parsed from package TOML metadata.
222222
pub fn embedded_target_required_features(stem: &str) -> wgpu::Features {
223-
crate::shader_package::target_required_features(stem)
223+
crate::materials::shader_package::target_required_features(stem)
224224
}
225225
226226
/// Declared texture fallbacks for `stem`, parsed from package TOML metadata.
227227
pub fn embedded_target_texture_defaults(stem: &str) -> &'static [EmbeddedTextureDefault] {
228-
crate::shader_package::material_texture_defaults(stem)
228+
crate::materials::shader_package::material_texture_defaults(stem)
229229
}
230230
231231
/// Declared material uniform fallbacks for `stem`, parsed from package TOML metadata.
232232
pub fn embedded_target_material_defaults(stem: &str) -> &'static [EmbeddedMaterialDefault] {
233-
crate::shader_package::material_uniform_defaults(stem)
233+
crate::materials::shader_package::material_uniform_defaults(stem)
234234
}
235235
236236
/// Stable reflection metadata for `stem`, reflected from WGSL with Naga at runtime.
237237
pub fn embedded_target_reflection(stem: &str) -> EmbeddedShaderReflection {
238-
crate::shader_package::material_reflection(stem)
238+
crate::materials::shader_package::material_reflection(stem)
239239
}
240240
"#
241241
}
@@ -410,7 +410,7 @@ mod tests {
410410
assert!(!embedded.contains("pub fn embedded_target_desc"));
411411
assert!(embedded.contains("pub fn embedded_target_reflection"));
412412
assert!(embedded.contains("macro_rules! embedded_wgsl"));
413-
assert!(embedded.contains("crate::shader_package::target_wgsl"));
413+
assert!(embedded.contains("crate::materials::shader_package::target_wgsl"));
414414
assert!(!embedded.contains("wgsl body"));
415415
assert!(!embedded.contains("pub const OUTLINE_DEFAULT_WGSL"));
416416
Ok(())

crates/renderide/shaders/materials/billboardunlit.wgsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ fn vs_main(
378378
}
379379

380380
fn main_st(view_layer: u32) -> vec4<f32> {
381-
if (kw_RIGHT_EYE_ST() && view_layer != 0u) {
381+
if (kw_RIGHT_EYE_ST() && rg::view_layer_is_right_eye(view_layer)) {
382382
return mat._RightEye_ST;
383383
}
384384
return mat._Tex_ST;

crates/renderide/shaders/materials/reflection.wgsl

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Unity `Shader "Reflection"`: samples a host-provided 2D reflection texture in screen space,
22
//! optionally distorted by a tangent-space normal map. **Not a grab pass** -- `_ReflectionTex` is a
33
//! regular `sampler2D`, populated by the host with whatever reflection RT (planar, cubemap-projected,
4-
//! etc.) is available. Multi-view eye separation is handled by the renderer's per-eye render pass,
5-
//! not the side-by-side `eyeIndex` texture-coordinate offset Unity needs for single-pass stereo.
4+
//! etc.) is available. VR camera portals render left/right mirror eyes into side-by-side halves of
5+
//! the same host render texture, matching Unity's non-single-pass fallback.
66
//!
77
//! Froox variant bits populate `_RenderideVariantBits`; this shader decodes Reflection's
88
//! shader-specific keyword bits locally. `_OFFSET_TEXTURE` is reserved in the bit table so the
@@ -60,6 +60,7 @@ struct VertexOutput {
6060
@builtin(position) clip_pos: vec4<f32>,
6161
@location(0) screen_uv: vec3<f32>,
6262
@location(1) uv: vec2<f32>,
63+
@location(2) @interpolate(flat) view_layer: u32,
6364
}
6465

6566
@vertex
@@ -80,33 +81,54 @@ fn vs_main(
8081
let vp = mv::select_view_proj(d, 0u);
8182
#endif
8283
let clip = vp * world_p;
84+
#ifdef MULTIVIEW
85+
let view_layer = view_idx;
86+
let screen_y = (clip.y + clip.w) * 0.5;
87+
#else
88+
let view_layer = 0u;
89+
let screen_y = (clip.w - clip.y) * 0.5;
90+
#endif
8391
var out: VertexOutput;
8492
out.clip_pos = clip;
85-
// Equivalent of Unity's ComputeNonStereoScreenPos: ((clip.xy * vec2(1, -1) + clip.w) * 0.5, w)
86-
// packed into xy/z so the fragment can do uv/w to get [0..1] screen UV.
93+
// Unity ComputeNonStereoScreenPos with the projection sign matching the active target path.
8794
out.screen_uv = vec3<f32>(
8895
(clip.x + clip.w) * 0.5,
89-
(clip.w - clip.y) * 0.5,
96+
screen_y,
9097
clip.w,
9198
);
9299
out.uv = uvu::apply_st(uv, mat._NormalMap_ST);
100+
out.view_layer = view_layer;
93101
return out;
94102
}
95103

104+
fn projected_reflection_uv(screen_uv: vec3<f32>) -> vec2<f32> {
105+
return screen_uv.xy / max(screen_uv.z, 1e-4);
106+
}
107+
108+
fn reflection_texture_uv(screen: vec2<f32>, view_layer: u32) -> vec2<f32> {
109+
var uv = screen;
110+
#ifdef MULTIVIEW
111+
uv.x = uv.x * 0.5 + f32(view_layer) * 0.5;
112+
#endif
113+
return uv;
114+
}
115+
96116
//#pass type=forward blend=material_filter a2c=cutout
97117
@fragment
98118
fn fs_main(
99119
@location(0) screen_uv: vec3<f32>,
100120
@location(1) uv: vec2<f32>,
121+
@location(2) @interpolate(flat) view_layer: u32,
101122
) -> @location(0) vec4<f32> {
102-
var screen = screen_uv.xy / max(screen_uv.z, 1e-4);
123+
var screen = projected_reflection_uv(screen_uv);
103124
if (kw_NORMALMAP()) {
104125
let bump = nd::decode_ts_normal_with_placeholder_sample(
105126
ts::sample_tex_2d(_NormalMap, _NormalMap_sampler, uv, mat._NormalMap_LodBias),
106127
1.0,
107128
);
108129
screen = screen + bump.xy * mat._Distort;
109130
}
131+
screen = reflection_texture_uv(screen, view_layer);
110132
var col = textureSample(_ReflectionTex, _ReflectionTex_sampler, screen);
111133
if (kw_COLOR()) {
112134
col = col * mat._Color;

crates/renderide/shaders/materials/unlit.wgsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ fn vs_main(
105105
}
106106

107107
fn main_texture_st(view_layer: u32) -> vec4<f32> {
108-
if (kw_RIGHT_EYE_ST() && view_layer != 0u) {
108+
if (kw_RIGHT_EYE_ST() && rg::view_layer_is_right_eye(view_layer)) {
109109
return mat._RightEye_ST;
110110
}
111111
return mat._Tex_ST;

crates/renderide/shaders/modules/frame/globals.wgsl

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
//! layout at pipeline creation for storage-backed frame resources.
88
//!
99
//! CPU packing must match [`crate::gpu::frame_globals::FrameGpuUniforms`],
10-
//! [`crate::backend::light_gpu::GpuLight`], and [`crate::backend::cluster_gpu`] cluster buffers.
10+
//! [`crate::backend::light_gpu::GpuLight`], [`crate::gpu::GpuLightCookieRect`], and
11+
//! [`crate::backend::cluster_gpu`] cluster buffers.
1112

1213
#define_import_path renderide::frame::globals
1314

@@ -26,12 +27,13 @@
2627
@group(0) @binding(10) var reflection_probe_specular_sampler: sampler;
2728
@group(0) @binding(11) var ibl_dfg_lut: texture_2d<f32>;
2829
@group(0) @binding(12) var<storage, read> reflection_probes: array<ft::GpuReflectionProbe>;
29-
@group(0) @binding(13) var light_cookie_2d_atlas: texture_2d_array<f32>;
30-
@group(0) @binding(14) var light_cookie_point_atlas: texture_2d_array<f32>;
30+
@group(0) @binding(13) var light_cookie_2d_atlas: texture_2d<f32>;
31+
@group(0) @binding(14) var light_cookie_point_atlas: texture_2d<f32>;
3132
@group(0) @binding(15) var light_cookie_sampler: sampler;
3233
@group(0) @binding(16) var<storage, read> shadow_views: array<ft::GpuShadowView>;
3334
@group(0) @binding(17) var shadow_atlas: texture_depth_2d_array;
3435
@group(0) @binding(18) var shadow_sampler: sampler_comparison;
36+
@group(0) @binding(19) var<storage, read> light_cookie_rects: array<ft::GpuLightCookieRect>;
3537

3638
/// View index encoded in a material varying.
3739
fn view_index_from_layer(view_layer: u32) -> u32 {
@@ -43,10 +45,19 @@ fn draw_index_from_layer(view_layer: u32) -> u32 {
4345
return view_layer >> 1u;
4446
}
4547

48+
/// Returns true when the encoded material view layer targets the right eye.
49+
fn view_layer_is_right_eye(view_layer: u32) -> bool {
50+
#ifdef MULTIVIEW
51+
return view_index_from_layer(view_layer) != 0u;
52+
#else
53+
return false;
54+
#endif
55+
}
56+
4657
/// World-space camera position for the current view layer.
4758
fn camera_world_pos_for_view(view_layer: u32) -> vec3<f32> {
4859
#ifdef MULTIVIEW
49-
if (view_index_from_layer(view_layer) != 0u) {
60+
if (view_layer_is_right_eye(view_layer)) {
5061
return frame.camera_world_pos_right.xyz;
5162
}
5263
#endif
@@ -65,7 +76,7 @@ fn stereo_center_camera_world_pos() -> vec3<f32> {
6576
/// World -> view-space Z coefficients for the current view layer.
6677
fn view_space_z_coeffs_for_view(view_layer: u32) -> vec4<f32> {
6778
#ifdef MULTIVIEW
68-
if (view_index_from_layer(view_layer) != 0u) {
79+
if (view_layer_is_right_eye(view_layer)) {
6980
return frame.view_space_z_coeffs_right;
7081
}
7182
#endif
@@ -75,7 +86,7 @@ fn view_space_z_coeffs_for_view(view_layer: u32) -> vec4<f32> {
7586
/// View -> world-space Y coefficients for the current view layer.
7687
fn view_to_world_y_coeffs_for_view(view_layer: u32) -> vec4<f32> {
7788
#ifdef MULTIVIEW
78-
if (view_index_from_layer(view_layer) != 0u) {
89+
if (view_layer_is_right_eye(view_layer)) {
7990
return frame.view_to_world_y_coeffs_right;
8091
}
8192
#endif
@@ -85,7 +96,7 @@ fn view_to_world_y_coeffs_for_view(view_layer: u32) -> vec4<f32> {
8596
/// Projection coefficients for the current view layer.
8697
fn proj_params_for_view(view_layer: u32) -> vec4<f32> {
8798
#ifdef MULTIVIEW
88-
if (view_index_from_layer(view_layer) != 0u) {
99+
if (view_layer_is_right_eye(view_layer)) {
89100
return frame.proj_params_right;
90101
}
91102
#endif
@@ -95,7 +106,7 @@ fn proj_params_for_view(view_layer: u32) -> vec4<f32> {
95106
/// Projection matrix for the current view layer.
96107
fn projection_for_view(view_layer: u32) -> mat4x4<f32> {
97108
#ifdef MULTIVIEW
98-
if (view_index_from_layer(view_layer) != 0u) {
109+
if (view_layer_is_right_eye(view_layer)) {
99110
return frame.proj_right;
100111
}
101112
#endif
@@ -105,7 +116,7 @@ fn projection_for_view(view_layer: u32) -> mat4x4<f32> {
105116
/// Projection flags for the current view layer.
106117
fn projection_flags_for_view(view_layer: u32) -> u32 {
107118
#ifdef MULTIVIEW
108-
if (view_index_from_layer(view_layer) != 0u) {
119+
if (view_layer_is_right_eye(view_layer)) {
109120
return frame.frame_tail.z;
110121
}
111122
#endif
@@ -174,7 +185,8 @@ fn retain_globals_additive(color: vec4<f32>) -> vec4<f32> {
174185
f32(cluster_light_indices[0u] & 255u) * 1e-10;
175186
let probe_touch = reflection_probes[0u].params.x * 1e-10;
176187
let cookie_touch =
177-
textureSampleLevel(light_cookie_2d_atlas, light_cookie_sampler, vec2<f32>(0.5), 0, 0.0).r * 1e-10 +
178-
textureSampleLevel(light_cookie_point_atlas, light_cookie_sampler, vec2<f32>(0.5), 0, 0.0).r * 1e-10;
188+
textureSampleLevel(light_cookie_2d_atlas, light_cookie_sampler, vec2<f32>(0.5), 0.0).r * 1e-10 +
189+
textureSampleLevel(light_cookie_point_atlas, light_cookie_sampler, vec2<f32>(0.5), 0.0).r * 1e-10 +
190+
light_cookie_rects[0u].origin_scale.x * 1e-10;
179191
return color + vec4<f32>(vec3<f32>(f32(lit) * 1e-10 + cluster_touch + probe_touch + cookie_touch), 0.0);
180192
}

crates/renderide/shaders/modules/frame/types.wgsl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ struct GpuShadowView {
5555
light_params: vec4<f32>,
5656
}
5757

58+
struct GpuLightCookieRect {
59+
origin_scale: vec4<f32>,
60+
}
61+
5862
struct GpuReflectionProbe {
5963
/// World-space AABB minimum; `.w` stores the sanitized blend distance.
6064
box_min: vec4<f32>,

crates/renderide/shaders/modules/lighting/light_cookies.wgsl

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,16 @@ fn wrap_cookie_uv(uv: vec2<f32>, bits: u32) -> vec2<f32> {
3939
);
4040
}
4141

42+
fn atlas_cookie_uv(rect_index: u32, uv: vec2<f32>) -> vec2<f32> {
43+
let rect = rg::light_cookie_rects[rect_index].origin_scale;
44+
return rect.xy + uv * rect.zw;
45+
}
46+
4247
fn sample_2d_cookie(light: ft::GpuLight, uv: vec2<f32>) -> f32 {
4348
return textureSample(
4449
rg::light_cookie_2d_atlas,
4550
rg::light_cookie_sampler,
46-
wrap_cookie_uv(uv, light.cookie_reserved),
47-
i32(light.cookie_layer),
51+
atlas_cookie_uv(light.cookie_layer, wrap_cookie_uv(uv, light.cookie_reserved)),
4852
).r;
4953
}
5054

@@ -114,8 +118,12 @@ fn point_cookie_multiplier(light: ft::GpuLight, world_pos: vec3<f32>) -> f32 {
114118
dot(from_light, light.direction),
115119
) * inverseSqrt(len_sq);
116120
let face_uv = cube_face_uv(local);
117-
let layer = light.cookie_layer + u32(face_uv.z);
118-
return textureSample(rg::light_cookie_point_atlas, rg::light_cookie_sampler, face_uv.xy, i32(layer)).r;
121+
let rect_index = light.cookie_layer + u32(face_uv.z);
122+
return textureSample(
123+
rg::light_cookie_point_atlas,
124+
rg::light_cookie_sampler,
125+
atlas_cookie_uv(rect_index, face_uv.xy),
126+
).r;
119127
}
120128

121129
fn multiplier(light: ft::GpuLight, world_pos: vec3<f32>) -> f32 {

0 commit comments

Comments
 (0)