From af296b0d38461eb6bed91aa3e70554b17158945b Mon Sep 17 00:00:00 2001 From: Baplar Date: Fri, 5 Jun 2026 21:03:14 +0200 Subject: [PATCH 1/5] Setup generic keyword to render any material as billboard particles --- .../shaders/materials/billboardunlit.wgsl | 214 +--------- .../renderide/shaders/materials/fresnel.wgsl | 12 +- .../shaders/materials/fresnellerp.wgsl | 12 +- .../shaders/materials/furfx-2.0-10layer.wgsl | 81 ++-- .../shaders/materials/furfx-2.0-20layer.wgsl | 151 ++++--- .../shaders/materials/furfx-3.0-10layer.wgsl | 81 ++-- .../shaders/materials/furfx-3.0-20layer.wgsl | 151 ++++--- .../materials/furfx-3.0-shell-10layer.wgsl | 74 ++-- .../materials/furfx-3.0-shell-20layer.wgsl | 144 +++++-- .../materials/furfx-advanced-10layer.wgsl | 81 ++-- .../materials/furfx-advanced-20layer.wgsl | 144 +++++-- .../materials/furfx-advanced-40layer.wgsl | 284 ++++++++++---- .../materials/furfx-advanced-5layer.wgsl | 39 +- .../furfx-advanced-shell-10layer.wgsl | 74 ++-- .../furfx-advanced-shell-20layer.wgsl | 137 +++++-- .../furfx-advanced-shell-40layer.wgsl | 277 +++++++++---- .../furfx-advanced-shell-5layer.wgsl | 32 +- .../materials/furfx-basic-10layer.wgsl | 81 ++-- .../materials/furfx-basic-20layer.wgsl | 144 +++++-- .../materials/furfx-basic-40layer.wgsl | 284 ++++++++++---- .../shaders/materials/furfx-basic-5layer.wgsl | 39 +- .../furfx-selfshadow-blend-10layer.wgsl | 81 ++-- .../furfx-selfshadow-blend-20layer.wgsl | 144 +++++-- .../furfx-selfshadow-noblend-10layer.wgsl | 81 ++-- .../furfx-selfshadow-noblend-20layer.wgsl | 144 +++++-- .../shaders/materials/pbscolormask.wgsl | 12 +- .../materials/pbscolormaskspecular.wgsl | 12 +- .../shaders/materials/pbscolorsplat.wgsl | 12 +- .../materials/pbscolorsplatspecular.wgsl | 12 +- .../shaders/materials/pbsdualsided.wgsl | 12 +- .../materials/pbsdualsidedspecular.wgsl | 12 +- .../materials/pbsdualsidedtransparent.wgsl | 12 +- .../pbsdualsidedtransparentspecular.wgsl | 12 +- .../shaders/materials/pbsintersect.wgsl | 12 +- .../materials/pbsintersectspecular.wgsl | 12 +- .../renderide/shaders/materials/pbslerp.wgsl | 12 +- .../shaders/materials/pbslerpspecular.wgsl | 12 +- .../shaders/materials/pbsmetallic.wgsl | 11 +- .../shaders/materials/pbsmultiuv.wgsl | 11 +- .../shaders/materials/pbsmultiuvspecular.wgsl | 11 +- .../renderide/shaders/materials/pbsrim.wgsl | 12 +- .../shaders/materials/pbsrimspecular.wgsl | 12 +- .../shaders/materials/pbsrimtransparent.wgsl | 12 +- .../materials/pbsrimtransparentspecular.wgsl | 12 +- .../materials/pbsrimtransparentzwrite.wgsl | 12 +- .../pbsrimtransparentzwritespecular.wgsl | 12 +- .../renderide/shaders/materials/pbsslice.wgsl | 12 +- .../shaders/materials/pbsslicespecular.wgsl | 12 +- .../materials/pbsslicetransparent.wgsl | 12 +- .../pbsslicetransparentspecular.wgsl | 12 +- .../shaders/materials/pbsspecular.wgsl | 11 +- .../shaders/materials/pbsstencil.wgsl | 12 +- .../shaders/materials/pbsstencilspecular.wgsl | 12 +- .../materials/pbsvertexcolortransparent.wgsl | 12 +- .../pbsvertexcolortransparentspecular.wgsl | 12 +- crates/renderide/shaders/materials/unlit.wgsl | 17 +- .../shaders/materials/unlitdistancelerp.wgsl | 22 +- .../shaders/materials/xstoon2.0-cutout.wgsl | 11 +- .../xstoon2.0-cutouta2c-outlined.wgsl | 21 +- .../materials/xstoon2.0-cutouta2c.wgsl | 11 +- .../materials/xstoon2.0-cutouta2cmasked.wgsl | 11 +- .../xstoon2.0-dithered-outlined.wgsl | 21 +- .../shaders/materials/xstoon2.0-dithered.wgsl | 11 +- .../shaders/materials/xstoon2.0-fade.wgsl | 11 +- .../shaders/materials/xstoon2.0-outlined.wgsl | 21 +- .../materials/xstoon2.0-transparent.wgsl | 11 +- .../shaders/materials/xstoon2.0.wgsl | 11 +- .../shaders/materials/xstoon2.0_outlined.wgsl | 21 +- .../xstoon2.0_wireframeoverride.wgsl | 11 +- .../xstoon2.0_wireframeoverride_a2c.wgsl | 11 +- .../shaders/modules/billboard/vertex.wgsl | 369 ++++++++++++++++++ .../shaders/modules/fur/classic_advanced.wgsl | 6 + .../shaders/modules/fur/classic_basic.wgsl | 6 + .../modules/fur/classic_selfshadow.wgsl | 6 + .../renderide/shaders/modules/fur/common.wgsl | 33 +- .../renderide/shaders/modules/fur/modern.wgsl | 6 + .../shaders/modules/xiexe/toon2/main.wgsl | 17 + .../shaders/modules/xiexe/toon2/surface.wgsl | 42 ++ crates/renderide/src/assets/mesh/gpu_mesh.rs | 9 - .../src/assets/mesh/gpu_mesh/demand.rs | 20 +- .../src/assets/mesh/gpu_mesh/hints.rs | 4 - .../mesh/gpu_mesh/tangent_generation.rs | 42 -- .../mesh/gpu_mesh/update/extended_streams.rs | 57 +-- .../assets/mesh/gpu_mesh/update/in_place.rs | 1 - .../mesh/gpu_mesh/update/in_place_buffers.rs | 40 +- .../assets/mesh/gpu_mesh/update/queries.rs | 16 +- .../src/assets/mesh/gpu_mesh/upload.rs | 27 +- .../assets/mesh/gpu_mesh/upload/accounting.rs | 1 - .../mesh/gpu_mesh/upload/derived_streams.rs | 20 +- .../mesh/gpu_mesh/upload/extended_streams.rs | 39 +- .../assets/mesh/gpu_mesh/upload/generated.rs | 18 - crates/renderide/src/assets/mesh/layout.rs | 9 +- .../src/assets/mesh/layout/streams.rs | 8 +- .../src/backend/asset_transfers/mesh_task.rs | 4 +- .../src/backend/facade/graph_access/warmup.rs | 74 ++-- crates/renderide/src/gpu_pools/pools/mesh.rs | 8 +- crates/renderide/src/materials.rs | 4 - .../src/materials/embedded/stem_metadata.rs | 12 +- .../embedded/stem_metadata/vertex_streams.rs | 27 +- .../src/materials/render_buffer_shader.rs | 251 ------------ crates/renderide/src/particles/point.rs | 12 +- crates/renderide/src/particles/tests.rs | 4 +- crates/renderide/src/particles/upload.rs | 12 +- .../encode/vertex_binding.rs | 45 +-- .../world_mesh_forward/material_batch.rs | 26 +- .../world_mesh/draw_prep/collect/candidate.rs | 6 +- .../src/world_mesh/draw_prep/tests.rs | 4 +- .../renderide/src/world_mesh/materials/key.rs | 4 +- .../src/world_mesh/materials/resolve.rs | 209 +--------- .../renderide/src/world_mesh/test_fixtures.rs | 2 +- 110 files changed, 3087 insertions(+), 1977 deletions(-) create mode 100644 crates/renderide/shaders/modules/billboard/vertex.wgsl delete mode 100644 crates/renderide/src/materials/render_buffer_shader.rs diff --git a/crates/renderide/shaders/materials/billboardunlit.wgsl b/crates/renderide/shaders/materials/billboardunlit.wgsl index fa352f364..29e8d1601 100644 --- a/crates/renderide/shaders/materials/billboardunlit.wgsl +++ b/crates/renderide/shaders/materials/billboardunlit.wgsl @@ -22,6 +22,7 @@ //#mat_default _OffsetTex_LodBias float 0.0 //#mat_default _MaskTex_LodBias float 0.0 +#import renderide::billboard::vertex as bv #import renderide::core::texture_sampling as ts #import renderide::core::uv as uvu #import renderide::core::math as rmath @@ -69,10 +70,8 @@ const BILLBOARDUNLIT_KW_VERTEX_HDRSRGBALPHA_COLOR: u32 = 1u << 12u; const BILLBOARDUNLIT_KW_VERTEX_LINEAR_COLOR: u32 = 1u << 13u; const BILLBOARDUNLIT_KW_VERTEX_SRGB_COLOR: u32 = 1u << 14u; const BILLBOARDUNLIT_KW_VERTEXCOLORS: u32 = 1u << 15u; -const BILLBOARDUNLIT_KW_RENDER_BUFFER: u32 = 1u << 16u; -const BILLBOARDUNLIT_KW_SIMPLE_LIT: u32 = 1u << 17u; -const BILLBOARDUNLIT_KW_UNLIT_MASK_TEXTURE_CLIP: u32 = 1u << 18u; -const BILLBOARDUNLIT_KW_UNLIT_MASK_TEXTURE_MUL: u32 = 1u << 19u; +const BILLBOARDUNLIT_KW_UNLIT_MASK_TEXTURE_CLIP: u32 = 1u << 16u; +const BILLBOARDUNLIT_KW_UNLIT_MASK_TEXTURE_MUL: u32 = 1u << 17u; @group(1) @binding(0) var mat: BillboardUnlitMaterial; @group(1) @binding(1) var _Tex: texture_2d; @@ -122,10 +121,6 @@ fn kw_POINT_SIZE() -> bool { return bb_kw(BILLBOARDUNLIT_KW_POINT_SIZE); } -fn kw_RENDER_BUFFER() -> bool { - return bb_kw(BILLBOARDUNLIT_KW_RENDER_BUFFER); -} - fn kw_POLARUV() -> bool { return bb_kw(BILLBOARDUNLIT_KW_POLARUV); } @@ -154,174 +149,12 @@ fn kw_VERTEXCOLORS() -> bool { return bb_kw(BILLBOARDUNLIT_KW_VERTEXCOLORS); } -fn kw_SIMPLE_LIT() -> bool { - return bb_kw(BILLBOARDUNLIT_KW_SIMPLE_LIT); -} - struct VertexOutput { @builtin(position) clip_pos: vec4, @location(0) uv: vec2, @location(1) color: vec4, @location(2) @interpolate(flat) view_layer: u32, @location(3) fog_coord: f32, - @location(4) world_p: vec3, - @location(5) n: vec3, -} - -struct RenderBufferBillboardBasis { - right: vec3, - up: vec3, -} - -fn billboard_size(pointdata: vec3, model: mat4x4) -> vec2 { - if (kw_RENDER_BUFFER()) { - return max(abs(pointdata.xy), vec2(1e-6, 1e-6)) * mb::model_uniform_scale(model); - } - return mb::billboard_size(pointdata, mat._PointSize.xy, model, kw_POINT_SIZE()); -} - -fn rotate_render_buffer_axes(angle: f32, right: vec3, up: vec3) -> RenderBufferBillboardBasis { - let c = cos(angle); - let s = sin(angle); - return RenderBufferBillboardBasis(right * c - up * s, right * s + up * c); -} - -fn view_plane_basis(view_layer: u32, roll: f32, allow_roll: bool) -> RenderBufferBillboardBasis { - let view_up = rmath::safe_normalize(rg::view_to_world_y_coeffs_for_view(view_layer).xyz, vec3(0.0, 1.0, 0.0)); - let to_camera = rg::orthographic_view_dir_for_view(view_layer); - var right = rmath::safe_normalize(cross(view_up, to_camera), vec3(1.0, 0.0, 0.0)); - var up = rmath::safe_normalize(cross(to_camera, right), view_up); - if (allow_roll && abs(roll) > 1e-4) { - let rotated = rotate_render_buffer_axes(roll, right, up); - right = rotated.right; - up = rotated.up; - } - return RenderBufferBillboardBasis(right, up); -} - -fn facing_basis(center_world: vec3, view_layer: u32, roll: f32, allow_roll: bool) -> RenderBufferBillboardBasis { - let view_up = rmath::safe_normalize(rg::view_to_world_y_coeffs_for_view(view_layer).xyz, vec3(0.0, 1.0, 0.0)); - let to_camera = rg::view_dir_for_world_pos(center_world, view_layer); - var right = rmath::safe_normalize(cross(view_up, to_camera), vec3(1.0, 0.0, 0.0)); - var up = rmath::safe_normalize(cross(to_camera, right), view_up); - if (allow_roll && abs(roll) > 1e-4) { - let rotated = rotate_render_buffer_axes(roll, right, up); - right = rotated.right; - up = rotated.up; - } - return RenderBufferBillboardBasis(right, up); -} - -fn direction_stretch_particle_basis( - d: dt::PerDrawUniforms, - center_world: vec3, - point_forward_upz: vec4, - view_layer: u32, -) -> RenderBufferBillboardBasis { - let to_camera = rg::view_dir_for_world_pos(center_world, view_layer); - let velocity_world = mv::model_vector(d, point_forward_upz.xyz); - let velocity_in_plane = velocity_world - to_camera * dot(velocity_world, to_camera); - let view_up = rg::view_to_world_y_coeffs_for_view(view_layer).xyz; - let view_up_in_plane = view_up - to_camera * dot(view_up, to_camera); - var up = rmath::safe_normalize( - velocity_in_plane, - rmath::safe_normalize(view_up_in_plane, vec3(0.0, 1.0, 0.0)), - ); - let right = rmath::safe_normalize(cross(up, to_camera), vec3(1.0, 0.0, 0.0)); - up = rmath::safe_normalize(cross(to_camera, right), up); - return RenderBufferBillboardBasis(right, up); -} - -fn local_particle_basis( - d: dt::PerDrawUniforms, - pointdata: vec3, - point_forward_upz: vec4, - point_up_xy: vec2, -) -> RenderBufferBillboardBasis { - let raw_forward = rmath::safe_normalize(point_forward_upz.xyz, vec3(0.0, 0.0, 1.0)); - let raw_up = rmath::safe_normalize(vec3(point_up_xy, point_forward_upz.w), vec3(0.0, 1.0, 0.0)); - let world_forward = rmath::safe_normalize(mv::model_vector(d, raw_forward), vec3(0.0, 0.0, 1.0)); - let world_up = rmath::safe_normalize(mv::model_vector(d, raw_up), vec3(0.0, 1.0, 0.0)); - var right = rmath::safe_normalize(cross(world_forward, world_up), vec3(1.0, 0.0, 0.0)); - var up = rmath::safe_normalize(cross(right, world_forward), world_up); - if (abs(pointdata.z) > 1e-4) { - let rotated = rotate_render_buffer_axes(pointdata.z, right, up); - right = rotated.right; - up = rotated.up; - } - return RenderBufferBillboardBasis(right, up); -} - -fn render_buffer_billboard_basis( - d: dt::PerDrawUniforms, - center_world: vec3, - pointdata: vec3, - point_forward_upz: vec4, - point_up_xy: vec2, - view_layer: u32, -) -> RenderBufferBillboardBasis { - let alignment = pd::particle_alignment(d); - if (alignment == 1u) { - return facing_basis(center_world, view_layer, pointdata.z, false); - } - if (alignment == 2u || alignment == 3u) { - return local_particle_basis(d, pointdata, point_forward_upz, point_up_xy); - } - if (alignment == 4u) { - return direction_stretch_particle_basis(d, center_world, point_forward_upz, view_layer); - } - return view_plane_basis(view_layer, pointdata.z, true); -} - -fn ndc_xy(clip: vec4) -> vec2 { - return clip.xy / max(abs(clip.w), 1e-6); -} - -fn screen_clamped_billboard_size( - d: dt::PerDrawUniforms, - center_world: vec3, - axes: RenderBufferBillboardBasis, - size: vec2, - vp: mat4x4, -) -> vec2 { - let min_size = pd::particle_min_screen_size(d); - let max_size = pd::particle_max_screen_size(d); - if (min_size <= 0.0 && max_size <= 0.0) { - return size; - } - let viewport = max(rg::viewport_size(), vec2(1.0, 1.0)); - let center_ndc = ndc_xy(vp * vec4(center_world, 1.0)); - let right_ndc = ndc_xy(vp * vec4(center_world + axes.right * size.x, 1.0)); - let up_ndc = ndc_xy(vp * vec4(center_world + axes.up * size.y, 1.0)); - let right_pixels = length((right_ndc - center_ndc) * viewport * 0.5); - let up_pixels = length((up_ndc - center_ndc) * viewport * 0.5); - let screen_fraction = max(right_pixels, up_pixels) / max(min(viewport.x, viewport.y), 1.0); - if (screen_fraction <= 1e-6) { - return size; - } - var scale = 1.0; - if (min_size > 0.0 && screen_fraction < min_size) { - scale = max(scale, min_size / screen_fraction); - } - if (max_size > 0.0 && screen_fraction * scale > max_size) { - scale = max_size / screen_fraction; - } - return max(size * scale, vec2(1e-6, 1e-6)); -} - -fn render_buffer_billboard_unit_corner(vertex_index: u32) -> vec2 { - let corner = vertex_index % 4u; - return vec2( - select(0.0, 1.0, (corner & 1u) != 0u), - select(0.0, 1.0, (corner & 2u) != 0u), - ); -} - -fn billboard_corner_for_vertex(pos: vec3, uv: vec2, vertex_index: u32) -> vec2 { - if (kw_RENDER_BUFFER()) { - return render_buffer_billboard_unit_corner(vertex_index) * 2.0 - vec2(1.0, 1.0); - } - return mb::billboard_corner(pos, uv); } @vertex @@ -332,14 +165,13 @@ fn vs_main( @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, - @location(1) pointdata_in: vec4, + @location(1) pointdata: vec4, @location(2) uv: vec2, @location(3) color: vec4, @location(4) point_forward_upz: vec4, @location(5) point_up_xy: vec2, ) -> VertexOutput { let d = pd::get_draw(instance_index); - let pointdata = pointdata_in.xyz; #ifdef MULTIVIEW let layer = view_idx; #else @@ -351,29 +183,28 @@ fn vs_main( #else let vp = mv::select_view_proj(d, 0u); #endif - let center_world = mv::world_position(d, pos).xyz; - let use_rotation = kw_POINT_ROTATION() && abs(pointdata.z) > 1e-4; - let fallback_axes = mb::billboard_axes(center_world, pointdata, layer, use_rotation); - var axes = RenderBufferBillboardBasis(fallback_axes.right, fallback_axes.up); - if (kw_RENDER_BUFFER()) { - axes = render_buffer_billboard_basis(d, center_world, pointdata, point_forward_upz, point_up_xy, layer); - } - let corner = billboard_corner_for_vertex(pos.xyz, uv, vertex_index); - let unclamped_size = billboard_size(pointdata, d.model); - var size = unclamped_size; - if (kw_RENDER_BUFFER()) { - size = screen_clamped_billboard_size(d, center_world, axes, unclamped_size, vp); - } - let world_p = center_world + axes.right * (corner.x * size.x) + axes.up * (corner.y * size.y); var out: VertexOutput; + var world_p: vec3; + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + let render_billboard_vertex = bv::render_buffer_billboard_vertex( + d, layer, pos, vertex_index, pointdata, point_forward_upz, point_up_xy, + ); + world_p = render_billboard_vertex.world_pos.xyz; + } else { + let center_world = mv::world_position(d, pos).xyz; + let use_rotation = kw_POINT_ROTATION() && abs(pointdata.z) > 1e-4; + let fallback_axes = mb::billboard_axes(center_world, pointdata.xyz, layer, use_rotation); + let axes = bv::RenderBufferBillboardBasis(fallback_axes.right, fallback_axes.up); + let corner = mb::billboard_corner(pos.xyz, uv); + let size = mb::billboard_size(pointdata.xyz, mat._PointSize.xy, d.model, kw_POINT_SIZE()); + world_p = center_world + axes.right * (corner.x * size.x) + axes.up * (corner.y * size.y); + } out.clip_pos = vp * vec4(world_p, 1.0); out.uv = uv; out.color = color; out.view_layer = layer; out.fog_coord = rfog::coord_from_world_pos(world_p, layer); - out.world_p = world_p; - out.n = rmath::safe_normalize(cross(axes.right, axes.up), vec3(0.0, 0.0, 1.0)); return out; } @@ -491,12 +322,5 @@ fn fs_main( col = vec4(col.rgb, ma::alpha_intensity(col.a, col.rgb)); } - if (kw_SIMPLE_LIT()) { - let n = two_sided_geometric_normal(in.n, front_facing); - let base = clamp(col.rgb, vec3(0.0), vec3(1.0)); - let lit = dl::shade_clustered_diffuse(in.clip_pos.xy, in.world_p, n, base, in.view_layer); - col = vec4(lit, col.a); - } - return rg::retain_globals_additive(rfog::apply_rgba(col, in.fog_coord)); } diff --git a/crates/renderide/shaders/materials/fresnel.wgsl b/crates/renderide/shaders/materials/fresnel.wgsl index b38229d07..839a3b3c0 100644 --- a/crates/renderide/shaders/materials/fresnel.wgsl +++ b/crates/renderide/shaders/materials/fresnel.wgsl @@ -16,6 +16,7 @@ //#mat_default _PolarPow float 1.0 //#mat_default _Cutoff float 0.5 +#import renderide::billboard::vertex as bv #import renderide::frame::globals as rg #import renderide::pbs::normal as pnorm #import renderide::material::alpha as ma @@ -122,6 +123,7 @@ fn vertex_color_to_linear(color: vec4) -> vec4 { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -130,12 +132,18 @@ fn vs_main( @location(2) uv: vec2, @location(3) color: vec4, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldColorVertexOutput { #ifdef MULTIVIEW - return mv::world_color_vertex_main(instance_index, view_idx, pos, n, t, uv, color); + let view_layer = view_idx; #else - return mv::world_color_vertex_main(instance_index, 0u, pos, n, t, uv, color); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_color_vertex_main(instance_index, view_layer, pos, n, t, uv, color, vertex_index, uv1); + } else { + return mv::world_color_vertex_main(instance_index, view_layer, pos, n, t, uv, color); + } } //#pass type=forward diff --git a/crates/renderide/shaders/materials/fresnellerp.wgsl b/crates/renderide/shaders/materials/fresnellerp.wgsl index e61da5c7c..4adfe73d3 100644 --- a/crates/renderide/shaders/materials/fresnellerp.wgsl +++ b/crates/renderide/shaders/materials/fresnellerp.wgsl @@ -19,6 +19,7 @@ //#mat_default _NearColor0 vec4 1.0 1.0 1.0 1.0 //#mat_default _NearColor1 vec4 0.8 0.8 0.8 0.8 +#import renderide::billboard::vertex as bv #import renderide::frame::globals as rg #import renderide::pbs::normal as pnorm #import renderide::material::fresnel as mf @@ -97,6 +98,7 @@ fn kw_TEXTURE() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -104,12 +106,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv); + } } fn compute_lerp(uv: vec2) -> f32 { diff --git a/crates/renderide/shaders/materials/furfx-2.0-10layer.wgsl b/crates/renderide/shaders/materials/furfx-2.0-10layer.wgsl index f8435cd7e..567e73408 100644 --- a/crates/renderide/shaders/materials/furfx-2.0-10layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-2.0-10layer.wgsl @@ -28,13 +28,14 @@ #import renderide::fur::modern as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, t, uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, t, uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -42,17 +43,20 @@ fn vs_l_00( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -60,17 +64,20 @@ fn vs_l_01( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.1); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -78,17 +85,20 @@ fn vs_l_02( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.2); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -96,17 +106,20 @@ fn vs_l_03( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.3); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -114,17 +127,20 @@ fn vs_l_04( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.4); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -132,17 +148,20 @@ fn vs_l_05( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.5); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -150,17 +169,20 @@ fn vs_l_06( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.6); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -168,17 +190,20 @@ fn vs_l_07( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.7); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -186,17 +211,20 @@ fn vs_l_08( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.8); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -204,17 +232,20 @@ fn vs_l_09( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.9); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -222,12 +253,14 @@ fn vs_l_10( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 1.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 1.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 1.0); } //#pass type=forward vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-2.0-20layer.wgsl b/crates/renderide/shaders/materials/furfx-2.0-20layer.wgsl index 9c54fe196..b5f59d70f 100644 --- a/crates/renderide/shaders/materials/furfx-2.0-20layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-2.0-20layer.wgsl @@ -28,13 +28,14 @@ #import renderide::fur::modern as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, t, uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, t, uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -42,17 +43,20 @@ fn vs_l_00( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -60,17 +64,20 @@ fn vs_l_01( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.05); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.05); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.05); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -78,17 +85,20 @@ fn vs_l_02( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.1); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -96,17 +106,20 @@ fn vs_l_03( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.15); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.15); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.15); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -114,17 +127,20 @@ fn vs_l_04( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.2); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -132,17 +148,20 @@ fn vs_l_05( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.25); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -150,17 +169,20 @@ fn vs_l_06( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.3); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -168,17 +190,20 @@ fn vs_l_07( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.35); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.35); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.35); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -186,17 +211,20 @@ fn vs_l_08( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.4); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -204,17 +232,20 @@ fn vs_l_09( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.45); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.45); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.45); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -222,17 +253,20 @@ fn vs_l_10( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.5); } @vertex fn vs_l_11( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -240,17 +274,20 @@ fn vs_l_11( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.55); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.55); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.55); } @vertex fn vs_l_12( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -258,17 +295,20 @@ fn vs_l_12( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.6); } @vertex fn vs_l_13( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -276,17 +316,20 @@ fn vs_l_13( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.65); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.65); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.65); } @vertex fn vs_l_14( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -294,17 +337,20 @@ fn vs_l_14( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.7); } @vertex fn vs_l_15( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -312,17 +358,20 @@ fn vs_l_15( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.75); } @vertex fn vs_l_16( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -330,17 +379,20 @@ fn vs_l_16( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.8); } @vertex fn vs_l_17( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -348,17 +400,20 @@ fn vs_l_17( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.85); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.85); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.85); } @vertex fn vs_l_18( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -366,17 +421,20 @@ fn vs_l_18( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.9); } @vertex fn vs_l_19( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -384,17 +442,20 @@ fn vs_l_19( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.95); } @vertex fn vs_l_20( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -402,12 +463,14 @@ fn vs_l_20( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 1.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 1.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 1.0); } //#pass type=forward vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-3.0-10layer.wgsl b/crates/renderide/shaders/materials/furfx-3.0-10layer.wgsl index 3aa418f72..18c03ef6a 100644 --- a/crates/renderide/shaders/materials/furfx-3.0-10layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-3.0-10layer.wgsl @@ -28,13 +28,14 @@ #import renderide::fur::modern as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, t, uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, t, uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -42,17 +43,20 @@ fn vs_l_00( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -60,17 +64,20 @@ fn vs_l_01( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.1); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -78,17 +85,20 @@ fn vs_l_02( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.2); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -96,17 +106,20 @@ fn vs_l_03( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.3); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -114,17 +127,20 @@ fn vs_l_04( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.4); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -132,17 +148,20 @@ fn vs_l_05( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.5); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -150,17 +169,20 @@ fn vs_l_06( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.6); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -168,17 +190,20 @@ fn vs_l_07( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.7); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -186,17 +211,20 @@ fn vs_l_08( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.8); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -204,17 +232,20 @@ fn vs_l_09( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.9); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -222,12 +253,14 @@ fn vs_l_10( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 1.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 1.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 1.0); } //#pass type=forward vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-3.0-20layer.wgsl b/crates/renderide/shaders/materials/furfx-3.0-20layer.wgsl index 960a3fc00..0e0f9152c 100644 --- a/crates/renderide/shaders/materials/furfx-3.0-20layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-3.0-20layer.wgsl @@ -28,13 +28,14 @@ #import renderide::fur::modern as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, t, uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, t, uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -42,17 +43,20 @@ fn vs_l_00( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -60,17 +64,20 @@ fn vs_l_01( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.05); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.05); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.05); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -78,17 +85,20 @@ fn vs_l_02( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.1); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -96,17 +106,20 @@ fn vs_l_03( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.15); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.15); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.15); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -114,17 +127,20 @@ fn vs_l_04( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.2); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -132,17 +148,20 @@ fn vs_l_05( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.25); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -150,17 +169,20 @@ fn vs_l_06( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.3); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -168,17 +190,20 @@ fn vs_l_07( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.35); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.35); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.35); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -186,17 +211,20 @@ fn vs_l_08( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.4); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -204,17 +232,20 @@ fn vs_l_09( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.45); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.45); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.45); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -222,17 +253,20 @@ fn vs_l_10( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.5); } @vertex fn vs_l_11( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -240,17 +274,20 @@ fn vs_l_11( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.55); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.55); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.55); } @vertex fn vs_l_12( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -258,17 +295,20 @@ fn vs_l_12( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.6); } @vertex fn vs_l_13( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -276,17 +316,20 @@ fn vs_l_13( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.65); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.65); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.65); } @vertex fn vs_l_14( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -294,17 +337,20 @@ fn vs_l_14( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.7); } @vertex fn vs_l_15( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -312,17 +358,20 @@ fn vs_l_15( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.75); } @vertex fn vs_l_16( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -330,17 +379,20 @@ fn vs_l_16( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.8); } @vertex fn vs_l_17( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -348,17 +400,20 @@ fn vs_l_17( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.85); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.85); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.85); } @vertex fn vs_l_18( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -366,17 +421,20 @@ fn vs_l_18( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.9); } @vertex fn vs_l_19( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -384,17 +442,20 @@ fn vs_l_19( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.95); } @vertex fn vs_l_20( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -402,12 +463,14 @@ fn vs_l_20( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 1.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 1.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 1.0); } //#pass type=forward vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-3.0-shell-10layer.wgsl b/crates/renderide/shaders/materials/furfx-3.0-shell-10layer.wgsl index ccd75ce2b..43355d7c9 100644 --- a/crates/renderide/shaders/materials/furfx-3.0-shell-10layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-3.0-shell-10layer.wgsl @@ -27,13 +27,14 @@ #import renderide::fur::modern as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, t, uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, t, uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -41,17 +42,20 @@ fn vs_l_00( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.1); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -59,17 +63,20 @@ fn vs_l_01( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.2); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -77,17 +84,20 @@ fn vs_l_02( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.3); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -95,17 +105,20 @@ fn vs_l_03( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.4); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -113,17 +126,20 @@ fn vs_l_04( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.5); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -131,17 +147,20 @@ fn vs_l_05( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.6); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -149,17 +168,20 @@ fn vs_l_06( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.7); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -167,17 +189,20 @@ fn vs_l_07( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.8); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -185,17 +210,20 @@ fn vs_l_08( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.9); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -203,12 +231,14 @@ fn vs_l_09( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 1.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 1.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 1.0); } //#pass type=forward vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-3.0-shell-20layer.wgsl b/crates/renderide/shaders/materials/furfx-3.0-shell-20layer.wgsl index f18cf7b6c..bfe08ef68 100644 --- a/crates/renderide/shaders/materials/furfx-3.0-shell-20layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-3.0-shell-20layer.wgsl @@ -27,13 +27,14 @@ #import renderide::fur::modern as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, t, uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, t, uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -41,17 +42,20 @@ fn vs_l_00( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.05); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.05); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.05); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -59,17 +63,20 @@ fn vs_l_01( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.1); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -77,17 +84,20 @@ fn vs_l_02( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.15); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.15); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.15); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -95,17 +105,20 @@ fn vs_l_03( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.2); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -113,17 +126,20 @@ fn vs_l_04( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.25); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -131,17 +147,20 @@ fn vs_l_05( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.3); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -149,17 +168,20 @@ fn vs_l_06( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.35); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.35); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.35); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -167,17 +189,20 @@ fn vs_l_07( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.4); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -185,17 +210,20 @@ fn vs_l_08( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.45); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.45); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.45); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -203,17 +231,20 @@ fn vs_l_09( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.5); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -221,17 +252,20 @@ fn vs_l_10( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.55); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.55); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.55); } @vertex fn vs_l_11( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -239,17 +273,20 @@ fn vs_l_11( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.6); } @vertex fn vs_l_12( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -257,17 +294,20 @@ fn vs_l_12( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.65); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.65); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.65); } @vertex fn vs_l_13( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -275,17 +315,20 @@ fn vs_l_13( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.7); } @vertex fn vs_l_14( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -293,17 +336,20 @@ fn vs_l_14( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.75); } @vertex fn vs_l_15( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -311,17 +357,20 @@ fn vs_l_15( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.8); } @vertex fn vs_l_16( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -329,17 +378,20 @@ fn vs_l_16( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.85); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.85); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.85); } @vertex fn vs_l_17( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -347,17 +399,20 @@ fn vs_l_17( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.9); } @vertex fn vs_l_18( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -365,17 +420,20 @@ fn vs_l_18( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 0.95); } @vertex fn vs_l_19( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -383,12 +441,14 @@ fn vs_l_19( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, t, uv0, 1.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, t, uv0, 1.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, t, uv0, uv1, 1.0); } //#pass type=forward vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-advanced-10layer.wgsl b/crates/renderide/shaders/materials/furfx-advanced-10layer.wgsl index 130216f33..c4edba085 100644 --- a/crates/renderide/shaders/materials/furfx-advanced-10layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-advanced-10layer.wgsl @@ -24,195 +24,228 @@ #import renderide::fur::classic_advanced as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.05); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.05); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.05); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.15); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.15); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.15); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.35); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.35); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.35); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.45); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.45); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.45); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.55); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.55); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.55); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.65); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.65); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.65); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.75); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.85); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.85); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.85); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.95); } //#pass type=forward name=forward_alpha_blend_zwrite blend=alpha zwrite=on ztest=main color_mask=rgba offset=0,0 vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-advanced-20layer.wgsl b/crates/renderide/shaders/materials/furfx-advanced-20layer.wgsl index 8e9fe9d47..4b12dd7bb 100644 --- a/crates/renderide/shaders/materials/furfx-advanced-20layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-advanced-20layer.wgsl @@ -24,348 +24,408 @@ #import renderide::fur::classic_advanced as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.05); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.05); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.05); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.1); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.15); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.15); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.15); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.2); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.3); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.35); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.35); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.35); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.4); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.45); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.45); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.45); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.5); } @vertex fn vs_l_11( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.55); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.55); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.55); } @vertex fn vs_l_12( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.6); } @vertex fn vs_l_13( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.65); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.65); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.65); } @vertex fn vs_l_14( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.7); } @vertex fn vs_l_15( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.75); } @vertex fn vs_l_16( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.8); } @vertex fn vs_l_17( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.85); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.85); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.85); } @vertex fn vs_l_18( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.9); } @vertex fn vs_l_19( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.95); } //#pass type=forward name=forward_alpha_blend_zwrite blend=alpha zwrite=on ztest=main color_mask=rgba offset=0,0 vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-advanced-40layer.wgsl b/crates/renderide/shaders/materials/furfx-advanced-40layer.wgsl index 4c7324a4c..0e925c3e5 100644 --- a/crates/renderide/shaders/materials/furfx-advanced-40layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-advanced-40layer.wgsl @@ -24,688 +24,808 @@ #import renderide::fur::classic_advanced as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.05); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.05); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.05); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.075); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.075); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.075); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.1); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.125); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.125); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.125); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.15); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.15); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.15); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.175); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.175); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.175); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.2); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.225); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.225); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.225); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_11( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.275); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.275); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.275); } @vertex fn vs_l_12( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.3); } @vertex fn vs_l_13( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.325); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.325); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.325); } @vertex fn vs_l_14( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.35); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.35); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.35); } @vertex fn vs_l_15( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.375); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.375); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.375); } @vertex fn vs_l_16( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.4); } @vertex fn vs_l_17( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.425); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.425); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.425); } @vertex fn vs_l_18( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.45); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.45); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.45); } @vertex fn vs_l_19( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.475); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.475); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.475); } @vertex fn vs_l_20( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.5); } @vertex fn vs_l_21( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.525); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.525); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.525); } @vertex fn vs_l_22( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.55); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.55); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.55); } @vertex fn vs_l_23( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.575); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.575); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.575); } @vertex fn vs_l_24( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.6); } @vertex fn vs_l_25( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.625); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.625); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.625); } @vertex fn vs_l_26( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.65); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.65); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.65); } @vertex fn vs_l_27( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.675); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.675); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.675); } @vertex fn vs_l_28( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.7); } @vertex fn vs_l_29( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.725); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.725); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.725); } @vertex fn vs_l_30( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.75); } @vertex fn vs_l_31( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.775); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.775); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.775); } @vertex fn vs_l_32( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.8); } @vertex fn vs_l_33( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.825); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.825); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.825); } @vertex fn vs_l_34( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.85); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.85); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.85); } @vertex fn vs_l_35( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.875); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.875); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.875); } @vertex fn vs_l_36( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.9); } @vertex fn vs_l_37( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.925); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.925); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.925); } @vertex fn vs_l_38( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.95); } @vertex fn vs_l_39( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.975); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.975); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.975); } //#pass type=forward name=forward_alpha_blend_zwrite blend=alpha zwrite=on ztest=main color_mask=rgba offset=0,0 vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-advanced-5layer.wgsl b/crates/renderide/shaders/materials/furfx-advanced-5layer.wgsl index 41fa000e7..317caaf04 100644 --- a/crates/renderide/shaders/materials/furfx-advanced-5layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-advanced-5layer.wgsl @@ -24,93 +24,108 @@ #import renderide::fur::classic_advanced as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.5); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.75); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.95); } //#pass type=forward name=forward_alpha_blend_zwrite blend=alpha zwrite=on ztest=main color_mask=rgba offset=0,0 vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-advanced-shell-10layer.wgsl b/crates/renderide/shaders/materials/furfx-advanced-shell-10layer.wgsl index 40a6b9880..de06ee139 100644 --- a/crates/renderide/shaders/materials/furfx-advanced-shell-10layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-advanced-shell-10layer.wgsl @@ -24,178 +24,208 @@ #import renderide::fur::classic_advanced as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.05); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.05); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.05); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.15); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.15); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.15); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.35); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.35); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.35); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.45); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.45); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.45); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.55); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.55); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.55); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.65); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.65); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.65); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.75); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.85); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.85); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.85); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.95); } //#pass type=forward name=forward_alpha_blend_zwrite blend=alpha zwrite=on ztest=main color_mask=rgba offset=0,0 vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-advanced-shell-20layer.wgsl b/crates/renderide/shaders/materials/furfx-advanced-shell-20layer.wgsl index 79a291666..f6f19a83e 100644 --- a/crates/renderide/shaders/materials/furfx-advanced-shell-20layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-advanced-shell-20layer.wgsl @@ -24,331 +24,388 @@ #import renderide::fur::classic_advanced as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.05); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.05); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.05); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.1); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.15); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.15); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.15); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.2); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.3); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.35); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.35); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.35); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.4); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.45); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.45); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.45); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.5); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.55); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.55); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.55); } @vertex fn vs_l_11( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.6); } @vertex fn vs_l_12( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.65); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.65); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.65); } @vertex fn vs_l_13( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.7); } @vertex fn vs_l_14( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.75); } @vertex fn vs_l_15( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.8); } @vertex fn vs_l_16( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.85); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.85); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.85); } @vertex fn vs_l_17( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.9); } @vertex fn vs_l_18( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.95); } //#pass type=forward name=forward_alpha_blend_zwrite blend=alpha zwrite=on ztest=main color_mask=rgba offset=0,0 vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-advanced-shell-40layer.wgsl b/crates/renderide/shaders/materials/furfx-advanced-shell-40layer.wgsl index f9c1f6b3c..566a5c0c5 100644 --- a/crates/renderide/shaders/materials/furfx-advanced-shell-40layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-advanced-shell-40layer.wgsl @@ -24,671 +24,788 @@ #import renderide::fur::classic_advanced as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.05); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.05); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.05); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.075); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.075); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.075); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.1); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.125); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.125); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.125); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.15); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.15); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.15); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.175); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.175); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.175); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.2); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.225); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.225); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.225); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.275); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.275); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.275); } @vertex fn vs_l_11( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.3); } @vertex fn vs_l_12( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.325); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.325); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.325); } @vertex fn vs_l_13( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.35); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.35); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.35); } @vertex fn vs_l_14( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.375); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.375); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.375); } @vertex fn vs_l_15( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.4); } @vertex fn vs_l_16( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.425); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.425); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.425); } @vertex fn vs_l_17( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.45); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.45); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.45); } @vertex fn vs_l_18( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.475); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.475); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.475); } @vertex fn vs_l_19( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.5); } @vertex fn vs_l_20( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.525); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.525); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.525); } @vertex fn vs_l_21( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.55); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.55); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.55); } @vertex fn vs_l_22( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.575); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.575); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.575); } @vertex fn vs_l_23( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.6); } @vertex fn vs_l_24( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.625); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.625); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.625); } @vertex fn vs_l_25( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.65); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.65); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.65); } @vertex fn vs_l_26( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.675); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.675); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.675); } @vertex fn vs_l_27( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.7); } @vertex fn vs_l_28( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.725); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.725); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.725); } @vertex fn vs_l_29( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.75); } @vertex fn vs_l_30( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.775); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.775); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.775); } @vertex fn vs_l_31( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.8); } @vertex fn vs_l_32( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.825); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.825); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.825); } @vertex fn vs_l_33( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.85); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.85); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.85); } @vertex fn vs_l_34( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.875); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.875); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.875); } @vertex fn vs_l_35( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.9); } @vertex fn vs_l_36( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.925); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.925); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.925); } @vertex fn vs_l_37( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.95); } @vertex fn vs_l_38( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.975); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.975); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.975); } //#pass type=forward name=forward_alpha_blend_zwrite blend=alpha zwrite=on ztest=main color_mask=rgba offset=0,0 vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-advanced-shell-5layer.wgsl b/crates/renderide/shaders/materials/furfx-advanced-shell-5layer.wgsl index bd84c77c6..23438107d 100644 --- a/crates/renderide/shaders/materials/furfx-advanced-shell-5layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-advanced-shell-5layer.wgsl @@ -24,76 +24,88 @@ #import renderide::fur::classic_advanced as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.5); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.75); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.95); } //#pass type=forward name=forward_alpha_blend_zwrite blend=alpha zwrite=on ztest=main color_mask=rgba offset=0,0 vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-basic-10layer.wgsl b/crates/renderide/shaders/materials/furfx-basic-10layer.wgsl index cd3bee0d0..b9ac69f97 100644 --- a/crates/renderide/shaders/materials/furfx-basic-10layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-basic-10layer.wgsl @@ -20,195 +20,228 @@ #import renderide::fur::classic_basic as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.05); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.05); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.05); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.15); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.15); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.15); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.35); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.35); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.35); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.45); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.45); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.45); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.55); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.55); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.55); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.65); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.65); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.65); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.75); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.85); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.85); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.85); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.95); } //#pass type=forward name=forward_alpha_blend_zwrite blend=alpha zwrite=on ztest=main color_mask=rgba offset=0,0 vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-basic-20layer.wgsl b/crates/renderide/shaders/materials/furfx-basic-20layer.wgsl index 86142af88..abf5ba3fb 100644 --- a/crates/renderide/shaders/materials/furfx-basic-20layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-basic-20layer.wgsl @@ -20,348 +20,408 @@ #import renderide::fur::classic_basic as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.05); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.05); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.05); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.1); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.15); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.15); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.15); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.2); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.3); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.35); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.35); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.35); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.4); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.45); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.45); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.45); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.5); } @vertex fn vs_l_11( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.55); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.55); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.55); } @vertex fn vs_l_12( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.6); } @vertex fn vs_l_13( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.65); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.65); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.65); } @vertex fn vs_l_14( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.7); } @vertex fn vs_l_15( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.75); } @vertex fn vs_l_16( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.8); } @vertex fn vs_l_17( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.85); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.85); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.85); } @vertex fn vs_l_18( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.9); } @vertex fn vs_l_19( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.95); } //#pass type=forward name=forward_alpha_blend_zwrite blend=alpha zwrite=on ztest=main color_mask=rgba offset=0,0 vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-basic-40layer.wgsl b/crates/renderide/shaders/materials/furfx-basic-40layer.wgsl index 43cd26a83..7acf8bb3b 100644 --- a/crates/renderide/shaders/materials/furfx-basic-40layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-basic-40layer.wgsl @@ -20,688 +20,808 @@ #import renderide::fur::classic_basic as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.05); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.05); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.05); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.075); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.075); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.075); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.1); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.125); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.125); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.125); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.15); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.15); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.15); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.175); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.175); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.175); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.2); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.225); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.225); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.225); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_11( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.275); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.275); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.275); } @vertex fn vs_l_12( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.3); } @vertex fn vs_l_13( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.325); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.325); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.325); } @vertex fn vs_l_14( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.35); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.35); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.35); } @vertex fn vs_l_15( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.375); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.375); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.375); } @vertex fn vs_l_16( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.4); } @vertex fn vs_l_17( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.425); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.425); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.425); } @vertex fn vs_l_18( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.45); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.45); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.45); } @vertex fn vs_l_19( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.475); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.475); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.475); } @vertex fn vs_l_20( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.5); } @vertex fn vs_l_21( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.525); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.525); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.525); } @vertex fn vs_l_22( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.55); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.55); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.55); } @vertex fn vs_l_23( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.575); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.575); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.575); } @vertex fn vs_l_24( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.6); } @vertex fn vs_l_25( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.625); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.625); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.625); } @vertex fn vs_l_26( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.65); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.65); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.65); } @vertex fn vs_l_27( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.675); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.675); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.675); } @vertex fn vs_l_28( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.7); } @vertex fn vs_l_29( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.725); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.725); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.725); } @vertex fn vs_l_30( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.75); } @vertex fn vs_l_31( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.775); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.775); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.775); } @vertex fn vs_l_32( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.8); } @vertex fn vs_l_33( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.825); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.825); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.825); } @vertex fn vs_l_34( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.85); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.85); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.85); } @vertex fn vs_l_35( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.875); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.875); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.875); } @vertex fn vs_l_36( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.9); } @vertex fn vs_l_37( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.925); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.925); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.925); } @vertex fn vs_l_38( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.95); } @vertex fn vs_l_39( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.975); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.975); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.975); } //#pass type=forward name=forward_alpha_blend_zwrite blend=alpha zwrite=on ztest=main color_mask=rgba offset=0,0 vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-basic-5layer.wgsl b/crates/renderide/shaders/materials/furfx-basic-5layer.wgsl index f29b1df12..3441b0a19 100644 --- a/crates/renderide/shaders/materials/furfx-basic-5layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-basic-5layer.wgsl @@ -20,93 +20,108 @@ #import renderide::fur::classic_basic as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.5); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.75); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.95); } //#pass type=forward name=forward_alpha_blend_zwrite blend=alpha zwrite=on ztest=main color_mask=rgba offset=0,0 vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-selfshadow-blend-10layer.wgsl b/crates/renderide/shaders/materials/furfx-selfshadow-blend-10layer.wgsl index 07fa1c40c..b964fb958 100644 --- a/crates/renderide/shaders/materials/furfx-selfshadow-blend-10layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-selfshadow-blend-10layer.wgsl @@ -25,195 +25,228 @@ #import renderide::fur::classic_selfshadow as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.1); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.2); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.3); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.4); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.5); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.6); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.7); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.8); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.9); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 1.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 1.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 1.0); } //#pass type=forward name=forward_alpha_blend_zwrite blend=alpha zwrite=on ztest=main color_mask=rgba offset=0,0 vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-selfshadow-blend-20layer.wgsl b/crates/renderide/shaders/materials/furfx-selfshadow-blend-20layer.wgsl index 8d2151f59..2e0d47b5b 100644 --- a/crates/renderide/shaders/materials/furfx-selfshadow-blend-20layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-selfshadow-blend-20layer.wgsl @@ -25,348 +25,408 @@ #import renderide::fur::classic_selfshadow as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.05); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.05); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.05); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.1); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.15); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.15); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.15); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.2); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.3); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.35); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.35); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.35); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.4); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.45); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.45); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.45); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.5); } @vertex fn vs_l_11( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.55); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.55); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.55); } @vertex fn vs_l_12( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.6); } @vertex fn vs_l_13( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.65); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.65); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.65); } @vertex fn vs_l_14( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.7); } @vertex fn vs_l_15( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.75); } @vertex fn vs_l_16( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.8); } @vertex fn vs_l_17( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.85); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.85); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.85); } @vertex fn vs_l_18( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.9); } @vertex fn vs_l_19( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.95); } //#pass type=forward name=forward_alpha_blend_zwrite blend=alpha zwrite=on ztest=main color_mask=rgba offset=0,0 vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-selfshadow-noblend-10layer.wgsl b/crates/renderide/shaders/materials/furfx-selfshadow-noblend-10layer.wgsl index 623340947..69bf7373d 100644 --- a/crates/renderide/shaders/materials/furfx-selfshadow-noblend-10layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-selfshadow-noblend-10layer.wgsl @@ -25,195 +25,228 @@ #import renderide::fur::classic_selfshadow as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.1); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.2); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.3); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.4); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.5); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.6); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.7); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.8); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.9); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 1.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 1.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 1.0); } //#pass type=forward vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/furfx-selfshadow-noblend-20layer.wgsl b/crates/renderide/shaders/materials/furfx-selfshadow-noblend-20layer.wgsl index af721e7ef..52f0005ca 100644 --- a/crates/renderide/shaders/materials/furfx-selfshadow-noblend-20layer.wgsl +++ b/crates/renderide/shaders/materials/furfx-selfshadow-noblend-20layer.wgsl @@ -25,348 +25,408 @@ #import renderide::fur::classic_selfshadow as fur #import renderide::fur::common as furc -fn vertex_at(instance_index: u32, view_idx: u32, pos: vec4, n: vec4, uv0: vec2, fur_multiplier: f32) -> furc::VertexOutput { - return fur::vertex_main(instance_index, view_idx, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, fur_multiplier); +fn vertex_at(instance_index: u32, view_idx: u32, vertex_index: u32, pos: vec4, n: vec4, uv0: vec2, uv1: vec2, fur_multiplier: f32) -> furc::VertexOutput { + return fur::vertex_main(instance_index, view_idx, vertex_index, pos, n, vec4(1.0, 0.0, 0.0, 1.0), uv0, uv1, fur_multiplier); } @vertex fn vs_l_00( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.0); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.0); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.0); } @vertex fn vs_l_01( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.05); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.05); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.05); } @vertex fn vs_l_02( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.1); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.1); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.1); } @vertex fn vs_l_03( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.15); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.15); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.15); } @vertex fn vs_l_04( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.2); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.2); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.2); } @vertex fn vs_l_05( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.25); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.25); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.25); } @vertex fn vs_l_06( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.3); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.3); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.3); } @vertex fn vs_l_07( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.35); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.35); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.35); } @vertex fn vs_l_08( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.4); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.4); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.4); } @vertex fn vs_l_09( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.45); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.45); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.45); } @vertex fn vs_l_10( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.5); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.5); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.5); } @vertex fn vs_l_11( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.55); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.55); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.55); } @vertex fn vs_l_12( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.6); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.6); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.6); } @vertex fn vs_l_13( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.65); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.65); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.65); } @vertex fn vs_l_14( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.7); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.7); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.7); } @vertex fn vs_l_15( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.75); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.75); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.75); } @vertex fn vs_l_16( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.8); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.8); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.8); } @vertex fn vs_l_17( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.85); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.85); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.85); } @vertex fn vs_l_18( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.9); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.9); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.9); } @vertex fn vs_l_19( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, + @location(5) uv1: vec2, ) -> furc::VertexOutput { #ifdef MULTIVIEW - return vertex_at(instance_index, view_idx, pos, n, uv0, 0.95); + let view_layer = view_idx; #else - return vertex_at(instance_index, 0u, pos, n, uv0, 0.95); + let view_layer = 0u; #endif + return vertex_at(instance_index, view_layer, vertex_index, pos, n, uv0, uv1, 0.95); } //#pass type=forward vs=vs_l_00 diff --git a/crates/renderide/shaders/materials/pbscolormask.wgsl b/crates/renderide/shaders/materials/pbscolormask.wgsl index e765b605b..5b0a1874c 100644 --- a/crates/renderide/shaders/materials/pbscolormask.wgsl +++ b/crates/renderide/shaders/materials/pbscolormask.wgsl @@ -23,6 +23,7 @@ //#mat_default _NormalScale float 1.0 //#mat_default _Glossiness float 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::material::color as mcolor #import renderide::mesh::vertex as mv @@ -207,6 +208,7 @@ fn sample_surface(uv0: vec2, world_n: vec3, world_t: vec4) -> Sur @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -214,12 +216,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } /// Forward-base pass: ambient + directional lighting + emission. diff --git a/crates/renderide/shaders/materials/pbscolormaskspecular.wgsl b/crates/renderide/shaders/materials/pbscolormaskspecular.wgsl index cc7c84abf..4ea7241f0 100644 --- a/crates/renderide/shaders/materials/pbscolormaskspecular.wgsl +++ b/crates/renderide/shaders/materials/pbscolormaskspecular.wgsl @@ -20,6 +20,7 @@ //#mat_default _NormalScale float 1.0 //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::material::color as mcolor #import renderide::mesh::vertex as mv @@ -193,6 +194,7 @@ fn sample_surface(uv0: vec2, world_n: vec3, world_t: vec4) -> Sur @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -200,12 +202,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } /// Forward-base pass: ambient + directional lighting + emission. diff --git a/crates/renderide/shaders/materials/pbscolorsplat.wgsl b/crates/renderide/shaders/materials/pbscolorsplat.wgsl index b53c45817..51b5e9160 100644 --- a/crates/renderide/shaders/materials/pbscolorsplat.wgsl +++ b/crates/renderide/shaders/materials/pbscolorsplat.wgsl @@ -38,6 +38,7 @@ //#mat_default _Glossiness3 float 0.5 //#mat_default _HeightTransitionRange float 0.1 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::mesh::vertex as mv #import renderide::pbs::normal as pnorm @@ -237,6 +238,7 @@ fn sample_surface(uv0: vec2, world_n: vec3, world_t: vec4) -> Sur @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -244,12 +246,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward diff --git a/crates/renderide/shaders/materials/pbscolorsplatspecular.wgsl b/crates/renderide/shaders/materials/pbscolorsplatspecular.wgsl index 4cb836591..2ff460ec7 100644 --- a/crates/renderide/shaders/materials/pbscolorsplatspecular.wgsl +++ b/crates/renderide/shaders/materials/pbscolorsplatspecular.wgsl @@ -37,6 +37,7 @@ //#mat_default _SpecularColor3 vec4 0.5 0.5 0.5 0.5 //#mat_default _HeightTransitionRange float 0.1 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::mesh::vertex as mv #import renderide::pbs::normal as pnorm @@ -237,6 +238,7 @@ fn sample_surface(uv0: vec2, world_n: vec3, world_t: vec4) -> Sur @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -244,12 +246,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward diff --git a/crates/renderide/shaders/materials/pbsdualsided.wgsl b/crates/renderide/shaders/materials/pbsdualsided.wgsl index 556b61e71..e25e64e83 100644 --- a/crates/renderide/shaders/materials/pbsdualsided.wgsl +++ b/crates/renderide/shaders/materials/pbsdualsided.wgsl @@ -18,6 +18,7 @@ //#mat_default _AlphaClip float 0.5 //#mat_default _Glossiness float 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::mesh::vertex as mv #import renderide::pbs::lighting as plight @@ -147,6 +148,7 @@ fn sample_surface( @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -155,12 +157,18 @@ fn vs_main( @location(2) uv0: vec2, @location(3) color: vec4, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldColorVertexOutput { #ifdef MULTIVIEW - return mv::world_color_vertex_main(instance_index, view_idx, pos, n, t, uv0, color); + let view_layer = view_idx; #else - return mv::world_color_vertex_main(instance_index, 0u, pos, n, t, uv0, color); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_color_vertex_main(instance_index, view_layer, pos, n, t, uv0, color, vertex_index, uv1); + } else { + return mv::world_color_vertex_main(instance_index, view_layer, pos, n, t, uv0, color); + } } //#pass type=forward name=forward_two_sided cull=material(off) offset=material(0,0) diff --git a/crates/renderide/shaders/materials/pbsdualsidedspecular.wgsl b/crates/renderide/shaders/materials/pbsdualsidedspecular.wgsl index 42e21a847..149834330 100644 --- a/crates/renderide/shaders/materials/pbsdualsidedspecular.wgsl +++ b/crates/renderide/shaders/materials/pbsdualsidedspecular.wgsl @@ -17,6 +17,7 @@ //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 //#mat_default _AlphaClip float 0.5 +#import renderide::billboard::vertex as bv #import renderide::mesh::vertex as mv #import renderide::pbs::lighting as plight #import renderide::pbs::sampling as psamp @@ -152,6 +153,7 @@ fn sample_surface( @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -160,12 +162,18 @@ fn vs_main( @location(2) uv0: vec2, @location(3) color: vec4, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldColorVertexOutput { #ifdef MULTIVIEW - return mv::world_color_vertex_main(instance_index, view_idx, pos, n, t, uv0, color); + let view_layer = view_idx; #else - return mv::world_color_vertex_main(instance_index, 0u, pos, n, t, uv0, color); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_color_vertex_main(instance_index, view_layer, pos, n, t, uv0, color, vertex_index, uv1); + } else { + return mv::world_color_vertex_main(instance_index, view_layer, pos, n, t, uv0, color); + } } //#pass type=forward name=forward_two_sided cull=material(off) offset=material(0,0) diff --git a/crates/renderide/shaders/materials/pbsdualsidedtransparent.wgsl b/crates/renderide/shaders/materials/pbsdualsidedtransparent.wgsl index 241bb8cd2..3fc700788 100644 --- a/crates/renderide/shaders/materials/pbsdualsidedtransparent.wgsl +++ b/crates/renderide/shaders/materials/pbsdualsidedtransparent.wgsl @@ -18,6 +18,7 @@ //#mat_default _NormalScale float 1.0 //#mat_default _Glossiness float 0.5 +#import renderide::billboard::vertex as bv #import renderide::mesh::vertex as mv #import renderide::pbs::lighting as plight #import renderide::pbs::sampling as psamp @@ -151,6 +152,7 @@ fn sample_surface( @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -159,12 +161,18 @@ fn vs_main( @location(2) uv0: vec2, @location(3) color: vec4, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldColorVertexOutput { #ifdef MULTIVIEW - return mv::world_color_vertex_main(instance_index, view_idx, pos, n, t, uv0, color); + let view_layer = view_idx; #else - return mv::world_color_vertex_main(instance_index, 0u, pos, n, t, uv0, color); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_color_vertex_main(instance_index, view_layer, pos, n, t, uv0, color, vertex_index, uv1); + } else { + return mv::world_color_vertex_main(instance_index, view_layer, pos, n, t, uv0, color); + } } fn shade( diff --git a/crates/renderide/shaders/materials/pbsdualsidedtransparentspecular.wgsl b/crates/renderide/shaders/materials/pbsdualsidedtransparentspecular.wgsl index bef5b2ab5..da9c27062 100644 --- a/crates/renderide/shaders/materials/pbsdualsidedtransparentspecular.wgsl +++ b/crates/renderide/shaders/materials/pbsdualsidedtransparentspecular.wgsl @@ -20,6 +20,7 @@ //#mat_default _NormalScale float 1.0 //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 +#import renderide::billboard::vertex as bv #import renderide::mesh::vertex as mv #import renderide::pbs::lighting as plight #import renderide::pbs::sampling as psamp @@ -167,6 +168,7 @@ fn sample_surface( @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -175,12 +177,18 @@ fn vs_main( @location(2) uv0: vec2, @location(3) color: vec4, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldColorVertexOutput { #ifdef MULTIVIEW - return mv::world_color_vertex_main(instance_index, view_idx, pos, n, t, uv0, color); + let view_layer = view_idx; #else - return mv::world_color_vertex_main(instance_index, 0u, pos, n, t, uv0, color); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_color_vertex_main(instance_index, view_layer, pos, n, t, uv0, color, vertex_index, uv1); + } else { + return mv::world_color_vertex_main(instance_index, view_layer, pos, n, t, uv0, color); + } } fn shade( diff --git a/crates/renderide/shaders/materials/pbsintersect.wgsl b/crates/renderide/shaders/materials/pbsintersect.wgsl index 7945b7e7c..0bfb9295e 100644 --- a/crates/renderide/shaders/materials/pbsintersect.wgsl +++ b/crates/renderide/shaders/materials/pbsintersect.wgsl @@ -22,6 +22,7 @@ //#mat_default _NormalScale float 1.0 //#mat_default _Glossiness float 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::mesh::vertex as mv #import renderide::pbs::families::intersect as pint @@ -71,6 +72,7 @@ fn pbs_kw(mask: u32) -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -78,12 +80,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_transparent blend=transparent_material zwrite=material(off) cull=material(off) color_mask=material(rgba) offset=material(0,0) diff --git a/crates/renderide/shaders/materials/pbsintersectspecular.wgsl b/crates/renderide/shaders/materials/pbsintersectspecular.wgsl index 2bbaa1aee..609a5894b 100644 --- a/crates/renderide/shaders/materials/pbsintersectspecular.wgsl +++ b/crates/renderide/shaders/materials/pbsintersectspecular.wgsl @@ -19,6 +19,7 @@ //#mat_default _NormalScale float 1.0 //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::mesh::vertex as mv #import renderide::pbs::families::intersect as pint @@ -67,6 +68,7 @@ fn pbs_kw(mask: u32) -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -74,12 +76,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_transparent blend=transparent_material zwrite=material(off) cull=material(off) color_mask=material(rgba) offset=material(0,0) diff --git a/crates/renderide/shaders/materials/pbslerp.wgsl b/crates/renderide/shaders/materials/pbslerp.wgsl index 79ac8e05f..2587e8388 100644 --- a/crates/renderide/shaders/materials/pbslerp.wgsl +++ b/crates/renderide/shaders/materials/pbslerp.wgsl @@ -26,6 +26,7 @@ //#mat_default _Glossiness float 0.5 //#mat_default _Glossiness1 float 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::mesh::vertex as mv #import renderide::pbs::lighting as plight @@ -138,6 +139,7 @@ fn compute_lerp_factor(uv_lerp: vec2) -> f32 { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -145,12 +147,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward ztest=main diff --git a/crates/renderide/shaders/materials/pbslerpspecular.wgsl b/crates/renderide/shaders/materials/pbslerpspecular.wgsl index 72bd9f2bb..7553f154a 100644 --- a/crates/renderide/shaders/materials/pbslerpspecular.wgsl +++ b/crates/renderide/shaders/materials/pbslerpspecular.wgsl @@ -23,6 +23,7 @@ //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 //#mat_default _SpecularColor1 vec4 1.0 1.0 1.0 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::mesh::vertex as mv #import renderide::pbs::lighting as plight @@ -133,6 +134,7 @@ fn compute_lerp_factor(uv_lerp: vec2) -> f32 { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -140,12 +142,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward ztest=main diff --git a/crates/renderide/shaders/materials/pbsmetallic.wgsl b/crates/renderide/shaders/materials/pbsmetallic.wgsl index 2aca176ec..a88f3931e 100644 --- a/crates/renderide/shaders/materials/pbsmetallic.wgsl +++ b/crates/renderide/shaders/materials/pbsmetallic.wgsl @@ -30,6 +30,7 @@ //#mat_default _Cutoff float 0.5 //#mat_default _Glossiness float 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::mesh::vertex as mv #import renderide::pbs::detail as pdet @@ -227,6 +228,7 @@ fn sample_surface(uv0: vec2, uv1: vec2, world_pos: vec3, world_n: @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -237,10 +239,15 @@ fn vs_main( @location(5) uv1: vec2, ) -> mv::WorldUv2VertexOutput { #ifdef MULTIVIEW - return mv::world_uv2_vertex_main(instance_index, view_idx, pos, n, t, uv0, uv1); + let view_layer = view_idx; #else - return mv::world_uv2_vertex_main(instance_index, 0u, pos, n, t, uv0, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_uv2_vertex_main(instance_index, view_layer, pos, n, t, uv0, uv1, vertex_index); + } else { + return mv::world_uv2_vertex_main(instance_index, view_layer, pos, n, t, uv0, uv1); + } } //#pass type=forward diff --git a/crates/renderide/shaders/materials/pbsmultiuv.wgsl b/crates/renderide/shaders/materials/pbsmultiuv.wgsl index a080caf2e..c863f95d4 100644 --- a/crates/renderide/shaders/materials/pbsmultiuv.wgsl +++ b/crates/renderide/shaders/materials/pbsmultiuv.wgsl @@ -20,6 +20,7 @@ //#mat_default _AlphaClip float 0.5 //#mat_default _Glossiness float 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::mesh::vertex as mv #import renderide::pbs::normal as pnorm @@ -209,6 +210,7 @@ fn sample_surface( @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -221,10 +223,15 @@ fn vs_main( @location(7) uv3: vec2, ) -> mv::WorldUv4VertexOutput { #ifdef MULTIVIEW - return mv::world_uv4_vertex_main(instance_index, view_idx, pos, n, t, uv0, uv1, uv2, uv3); + let view_layer = view_idx; #else - return mv::world_uv4_vertex_main(instance_index, 0u, pos, n, t, uv0, uv1, uv2, uv3); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_uv4_vertex_main(instance_index, view_layer, pos, n, t, uv0, uv1, vertex_index); + } else { + return mv::world_uv4_vertex_main(instance_index, view_layer, pos, n, t, uv0, uv1, uv2, uv3); + } } /// Forward-base pass: clustered lighting (ambient + directional + local lights) + emission. diff --git a/crates/renderide/shaders/materials/pbsmultiuvspecular.wgsl b/crates/renderide/shaders/materials/pbsmultiuvspecular.wgsl index 42c8133a3..6ac291f0d 100644 --- a/crates/renderide/shaders/materials/pbsmultiuvspecular.wgsl +++ b/crates/renderide/shaders/materials/pbsmultiuvspecular.wgsl @@ -21,6 +21,7 @@ //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 //#mat_default _AlphaClip float 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::mesh::vertex as mv #import renderide::pbs::normal as pnorm @@ -203,6 +204,7 @@ fn sample_surface( @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -215,10 +217,15 @@ fn vs_main( @location(7) uv3: vec2, ) -> mv::WorldUv4VertexOutput { #ifdef MULTIVIEW - return mv::world_uv4_vertex_main(instance_index, view_idx, pos, n, t, uv0, uv1, uv2, uv3); + let view_layer = view_idx; #else - return mv::world_uv4_vertex_main(instance_index, 0u, pos, n, t, uv0, uv1, uv2, uv3); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_uv4_vertex_main(instance_index, view_layer, pos, n, t, uv0, uv1, vertex_index); + } else { + return mv::world_uv4_vertex_main(instance_index, view_layer, pos, n, t, uv0, uv1, uv2, uv3); + } } /// Forward-base pass: clustered lighting (ambient + directional + local lights) + emission. diff --git a/crates/renderide/shaders/materials/pbsrim.wgsl b/crates/renderide/shaders/materials/pbsrim.wgsl index 8f7348cad..5f8cd8961 100644 --- a/crates/renderide/shaders/materials/pbsrim.wgsl +++ b/crates/renderide/shaders/materials/pbsrim.wgsl @@ -20,6 +20,7 @@ //#mat_default _Glossiness float 0.5 //#mat_default _RimPower float 3.0 +#import renderide::billboard::vertex as bv #import renderide::frame::globals as rg #import renderide::material::fresnel as mf #import renderide::material::variant_bits as vb @@ -93,6 +94,7 @@ fn metallic_roughness(uv: vec2) -> vec2 { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -100,12 +102,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward diff --git a/crates/renderide/shaders/materials/pbsrimspecular.wgsl b/crates/renderide/shaders/materials/pbsrimspecular.wgsl index 704e4ca2d..3779732f7 100644 --- a/crates/renderide/shaders/materials/pbsrimspecular.wgsl +++ b/crates/renderide/shaders/materials/pbsrimspecular.wgsl @@ -19,6 +19,7 @@ //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 //#mat_default _RimPower float 3.0 +#import renderide::billboard::vertex as bv #import renderide::frame::globals as rg #import renderide::material::fresnel as mf #import renderide::material::variant_bits as vb @@ -77,6 +78,7 @@ fn sample_normal_world(uv_main: vec2, world_n: vec3, world_t: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward diff --git a/crates/renderide/shaders/materials/pbsrimtransparent.wgsl b/crates/renderide/shaders/materials/pbsrimtransparent.wgsl index 4e43701be..2e12073ba 100644 --- a/crates/renderide/shaders/materials/pbsrimtransparent.wgsl +++ b/crates/renderide/shaders/materials/pbsrimtransparent.wgsl @@ -20,6 +20,7 @@ //#mat_default _Glossiness float 0.5 //#mat_default _RimPower float 3.0 +#import renderide::billboard::vertex as bv #import renderide::frame::globals as rg #import renderide::material::fresnel as mf #import renderide::material::variant_bits as vb @@ -94,6 +95,7 @@ fn metallic_roughness(uv: vec2) -> vec2 { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -101,12 +103,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_transparent_cull_back blend=transparent_material zwrite=material(off) cull=back color_mask=material(rgba) diff --git a/crates/renderide/shaders/materials/pbsrimtransparentspecular.wgsl b/crates/renderide/shaders/materials/pbsrimtransparentspecular.wgsl index 4ffe880cc..aa90d22f5 100644 --- a/crates/renderide/shaders/materials/pbsrimtransparentspecular.wgsl +++ b/crates/renderide/shaders/materials/pbsrimtransparentspecular.wgsl @@ -22,6 +22,7 @@ //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 //#mat_default _RimPower float 3.0 +#import renderide::billboard::vertex as bv #import renderide::frame::globals as rg #import renderide::material::fresnel as mf #import renderide::material::variant_bits as vb @@ -77,6 +78,7 @@ fn sample_normal_world(uv_main: vec2, world_n: vec3, world_t: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_transparent_cull_back blend=transparent_material zwrite=material(off) cull=back color_mask=material(rgba) diff --git a/crates/renderide/shaders/materials/pbsrimtransparentzwrite.wgsl b/crates/renderide/shaders/materials/pbsrimtransparentzwrite.wgsl index d42eca709..36e995ce1 100644 --- a/crates/renderide/shaders/materials/pbsrimtransparentzwrite.wgsl +++ b/crates/renderide/shaders/materials/pbsrimtransparentzwrite.wgsl @@ -20,6 +20,7 @@ //#mat_default _Glossiness float 0.5 //#mat_default _RimPower float 3.0 +#import renderide::billboard::vertex as bv #import renderide::frame::globals as rg #import renderide::material::fresnel as mf #import renderide::material::variant_bits as vb @@ -80,6 +81,7 @@ fn sample_normal_world(uv_main: vec2, world_n: vec3, world_t: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } /// Depth-only prepass: writes nothing to color (`write=none`) but populates depth so the alpha-blended diff --git a/crates/renderide/shaders/materials/pbsrimtransparentzwritespecular.wgsl b/crates/renderide/shaders/materials/pbsrimtransparentzwritespecular.wgsl index f173c3d54..cb96db323 100644 --- a/crates/renderide/shaders/materials/pbsrimtransparentzwritespecular.wgsl +++ b/crates/renderide/shaders/materials/pbsrimtransparentzwritespecular.wgsl @@ -20,6 +20,7 @@ //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 //#mat_default _RimPower float 3.0 +#import renderide::billboard::vertex as bv #import renderide::frame::globals as rg #import renderide::material::fresnel as mf #import renderide::material::variant_bits as vb @@ -80,6 +81,7 @@ fn sample_normal_world(uv_main: vec2, world_n: vec3, world_t: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=depth_prepass blend=off zwrite=on ztest=material_froox(main) color_mask=0 cull=material(back) offset=material(0,0) stencil=material diff --git a/crates/renderide/shaders/materials/pbsslice.wgsl b/crates/renderide/shaders/materials/pbsslice.wgsl index 45c8173de..6de40ed73 100644 --- a/crates/renderide/shaders/materials/pbsslice.wgsl +++ b/crates/renderide/shaders/materials/pbsslice.wgsl @@ -27,6 +27,7 @@ //#mat_default _AlphaClip float 0.5 //#mat_default _Glossiness float 0.5 +#import renderide::billboard::vertex as bv #import renderide::mesh::vertex as mv #import renderide::material::variant_bits as vb #import renderide::pbs::families::slice as pslice @@ -106,6 +107,7 @@ fn sample_albedo_color(uv_main: vec2, edge_lerp: f32) -> vec4 { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -113,12 +115,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldObjectVertexOutput { #ifdef MULTIVIEW - return mv::world_object_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_object_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_object_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_object_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward cull=material(off) offset=material(0,0) diff --git a/crates/renderide/shaders/materials/pbsslicespecular.wgsl b/crates/renderide/shaders/materials/pbsslicespecular.wgsl index 9bfd1ee78..f65120a3a 100644 --- a/crates/renderide/shaders/materials/pbsslicespecular.wgsl +++ b/crates/renderide/shaders/materials/pbsslicespecular.wgsl @@ -25,6 +25,7 @@ //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 //#mat_default _AlphaClip float 0.5 +#import renderide::billboard::vertex as bv #import renderide::mesh::vertex as mv #import renderide::material::variant_bits as vb #import renderide::pbs::families::slice as pslice @@ -106,6 +107,7 @@ fn sample_albedo_color(uv_main: vec2, edge_lerp: f32) -> vec4 { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -113,12 +115,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldObjectVertexOutput { #ifdef MULTIVIEW - return mv::world_object_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_object_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_object_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_object_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward cull=material(off) offset=material(0,0) diff --git a/crates/renderide/shaders/materials/pbsslicetransparent.wgsl b/crates/renderide/shaders/materials/pbsslicetransparent.wgsl index 61df357e5..ff4b2523b 100644 --- a/crates/renderide/shaders/materials/pbsslicetransparent.wgsl +++ b/crates/renderide/shaders/materials/pbsslicetransparent.wgsl @@ -22,6 +22,7 @@ //#mat_default _NormalScale float 1.0 //#mat_default _Glossiness float 0.5 +#import renderide::billboard::vertex as bv #import renderide::mesh::vertex as mv #import renderide::material::variant_bits as vb #import renderide::pbs::families::slice as pslice @@ -100,6 +101,7 @@ fn sample_albedo_color(uv_main: vec2, edge_lerp: f32) -> vec4 { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -107,12 +109,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldObjectVertexOutput { #ifdef MULTIVIEW - return mv::world_object_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_object_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_object_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_object_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_transparent blend=transparent_material zwrite=material(off) cull=material(off) color_mask=material(rgba) offset=material(0,0) diff --git a/crates/renderide/shaders/materials/pbsslicetransparentspecular.wgsl b/crates/renderide/shaders/materials/pbsslicetransparentspecular.wgsl index 99531a0b6..0d82f956c 100644 --- a/crates/renderide/shaders/materials/pbsslicetransparentspecular.wgsl +++ b/crates/renderide/shaders/materials/pbsslicetransparentspecular.wgsl @@ -23,6 +23,7 @@ //#mat_default _NormalScale float 1.0 //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 +#import renderide::billboard::vertex as bv #import renderide::mesh::vertex as mv #import renderide::material::variant_bits as vb #import renderide::pbs::families::slice as pslice @@ -99,6 +100,7 @@ fn sample_albedo_color(uv_main: vec2, edge_lerp: f32) -> vec4 { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -106,12 +108,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldObjectVertexOutput { #ifdef MULTIVIEW - return mv::world_object_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_object_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_object_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_object_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_transparent blend=transparent_material zwrite=material(off) cull=material(off) color_mask=material(rgba) offset=material(0,0) diff --git a/crates/renderide/shaders/materials/pbsspecular.wgsl b/crates/renderide/shaders/materials/pbsspecular.wgsl index bfc4f0812..b3666cc38 100644 --- a/crates/renderide/shaders/materials/pbsspecular.wgsl +++ b/crates/renderide/shaders/materials/pbsspecular.wgsl @@ -31,6 +31,7 @@ //#mat_default _Cutoff float 0.5 //#mat_default _Glossiness float 0.5 +#import renderide::billboard::vertex as bv #import renderide::mesh::vertex as mv #import renderide::material::variant_bits as vb #import renderide::pbs::detail as pdet @@ -227,6 +228,7 @@ fn sample_surface(uv0: vec2, uv1: vec2, world_pos: vec3, world_n: @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -237,10 +239,15 @@ fn vs_main( @location(5) uv1: vec2, ) -> mv::WorldUv2VertexOutput { #ifdef MULTIVIEW - return mv::world_uv2_vertex_main(instance_index, view_idx, pos, n, t, uv0, uv1); + let view_layer = view_idx; #else - return mv::world_uv2_vertex_main(instance_index, 0u, pos, n, t, uv0, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_uv2_vertex_main(instance_index, view_layer, pos, n, t, uv0, uv1, vertex_index); + } else { + return mv::world_uv2_vertex_main(instance_index, view_layer, pos, n, t, uv0, uv1); + } } //#pass type=forward diff --git a/crates/renderide/shaders/materials/pbsstencil.wgsl b/crates/renderide/shaders/materials/pbsstencil.wgsl index 7ebc88930..ee31eaf3c 100644 --- a/crates/renderide/shaders/materials/pbsstencil.wgsl +++ b/crates/renderide/shaders/materials/pbsstencil.wgsl @@ -20,6 +20,7 @@ //#mat_default _NormalScale float 1.0 //#mat_default _Glossiness float 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::mesh::vertex as mv #import renderide::pbs::lighting as plight @@ -104,6 +105,7 @@ fn sample_normal_world(uv_main: vec2, world_n: vec3, world_t: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } fn shade( diff --git a/crates/renderide/shaders/materials/pbsstencilspecular.wgsl b/crates/renderide/shaders/materials/pbsstencilspecular.wgsl index f8cca976d..aab6782db 100644 --- a/crates/renderide/shaders/materials/pbsstencilspecular.wgsl +++ b/crates/renderide/shaders/materials/pbsstencilspecular.wgsl @@ -15,6 +15,7 @@ //#mat_default _NormalScale float 1.0 //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 +#import renderide::billboard::vertex as bv #import renderide::mesh::vertex as mv #import renderide::material::variant_bits as vb #import renderide::pbs::lighting as plight @@ -76,6 +77,7 @@ fn sample_normal_world(uv_main: vec2, world_n: vec3, world_t: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } fn shade( diff --git a/crates/renderide/shaders/materials/pbsvertexcolortransparent.wgsl b/crates/renderide/shaders/materials/pbsvertexcolortransparent.wgsl index 7a76fb1da..8a9b27eef 100644 --- a/crates/renderide/shaders/materials/pbsvertexcolortransparent.wgsl +++ b/crates/renderide/shaders/materials/pbsvertexcolortransparent.wgsl @@ -19,6 +19,7 @@ //#mat_default _AlphaClip float 0.5 //#mat_default _Glossiness float 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::core::math as rmath #import renderide::mesh::vertex as mv @@ -178,6 +179,7 @@ fn sample_surface(uv0: vec2, world_n: vec3, world_t: vec4, vertex @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -186,12 +188,18 @@ fn vs_main( @location(2) uv0: vec2, @location(3) color: vec4, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldColorVertexOutput { #ifdef MULTIVIEW - return mv::world_color_vertex_main(instance_index, view_idx, pos, n, t, uv0, color); + let view_layer = view_idx; #else - return mv::world_color_vertex_main(instance_index, 0u, pos, n, t, uv0, color); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_color_vertex_main(instance_index, view_layer, pos, n, t, uv0, color, vertex_index, uv1); + } else { + return mv::world_color_vertex_main(instance_index, view_layer, pos, n, t, uv0, color); + } } //#pass type=forward name=forward_transparent_cull_back blend=transparent_material zwrite=material(off) cull=back color_mask=material(rgba) diff --git a/crates/renderide/shaders/materials/pbsvertexcolortransparentspecular.wgsl b/crates/renderide/shaders/materials/pbsvertexcolortransparentspecular.wgsl index 61af43721..bc338b9c2 100644 --- a/crates/renderide/shaders/materials/pbsvertexcolortransparentspecular.wgsl +++ b/crates/renderide/shaders/materials/pbsvertexcolortransparentspecular.wgsl @@ -20,6 +20,7 @@ //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 //#mat_default _AlphaClip float 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::mesh::vertex as mv #import renderide::pbs::lighting as plight @@ -176,6 +177,7 @@ fn sample_surface(uv0: vec2, world_n: vec3, world_t: vec4, vertex @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -184,12 +186,18 @@ fn vs_main( @location(2) uv0: vec2, @location(3) color: vec4, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldColorVertexOutput { #ifdef MULTIVIEW - return mv::world_color_vertex_main(instance_index, view_idx, pos, n, t, uv0, color); + let view_layer = view_idx; #else - return mv::world_color_vertex_main(instance_index, 0u, pos, n, t, uv0, color); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_color_vertex_main(instance_index, view_layer, pos, n, t, uv0, color, vertex_index, uv1); + } else { + return mv::world_color_vertex_main(instance_index, view_layer, pos, n, t, uv0, color); + } } //#pass type=forward name=forward_transparent_cull_back blend=transparent_material zwrite=material(off) cull=back color_mask=material(rgba) diff --git a/crates/renderide/shaders/materials/unlit.wgsl b/crates/renderide/shaders/materials/unlit.wgsl index d6fb76d60..012cba859 100644 --- a/crates/renderide/shaders/materials/unlit.wgsl +++ b/crates/renderide/shaders/materials/unlit.wgsl @@ -21,6 +21,7 @@ //#mat_default _PolarPow float 1.0 //#mat_default _Cutoff float 0.5 +#import renderide::billboard::vertex as bv #import renderide::core::texture_sampling as ts #import renderide::frame::globals as rg #import renderide::material::alpha as ma @@ -79,16 +80,18 @@ struct VertexOutput { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, - @location(1) _n: vec4, + @location(1) n: vec4, @location(2) uv: vec2, @location(3) color: vec4, + @location(4) t: vec4, + @location(5) uv1: vec2, ) -> VertexOutput { let d = pd::get_draw(instance_index); - let world_p = mv::world_position(d, pos); #ifdef MULTIVIEW let view_layer = view_idx; #else @@ -96,6 +99,16 @@ fn vs_main( #endif let vp = mv::select_view_proj(d, view_layer); + var world_p: vec4; + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + let render_billboard_vertex = bv::render_buffer_billboard_vertex( + d, view_layer, pos, vertex_index, n, t, uv1, + ); + world_p = render_billboard_vertex.world_pos; + } else { + world_p = mv::world_position(d, pos); + } + var out: VertexOutput; out.clip_pos = vp * world_p; out.uv = uv; diff --git a/crates/renderide/shaders/materials/unlitdistancelerp.wgsl b/crates/renderide/shaders/materials/unlitdistancelerp.wgsl index 14c3dc0ce..a1429c599 100644 --- a/crates/renderide/shaders/materials/unlitdistancelerp.wgsl +++ b/crates/renderide/shaders/materials/unlitdistancelerp.wgsl @@ -14,6 +14,7 @@ //#mat_default _Transition float 0.1 //#mat_default _Cutoff float 0.5 +#import renderide::billboard::vertex as bv #import renderide::frame::globals as rg #import renderide::draw::per_draw as pd #import renderide::material::variant_bits as vb @@ -59,21 +60,34 @@ struct VertexOutput { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, - @location(1) _n: vec4, + @location(1) n: vec4, @location(2) uv: vec2, @location(3) color: vec4, + @location(4) t: vec4, + @location(5) uv1: vec2, ) -> VertexOutput { let d = pd::get_draw(instance_index); - let world_p = mv::world_position(d, pos); #ifdef MULTIVIEW - let vp = mv::select_view_proj(d, view_idx); + let view_layer = view_idx; #else - let vp = mv::select_view_proj(d, 0u); + let view_layer = 0u; #endif + let vp = mv::select_view_proj(d, view_layer); + + var world_p: vec4; + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + let render_billboard_vertex = bv::render_buffer_billboard_vertex( + d, view_layer, pos, vertex_index, n, t, uv1, + ); + world_p = render_billboard_vertex.world_pos; + } else { + world_p = mv::world_position(d, pos); + } var out: VertexOutput; out.clip_pos = vp * world_p; diff --git a/crates/renderide/shaders/materials/xstoon2.0-cutout.wgsl b/crates/renderide/shaders/materials/xstoon2.0-cutout.wgsl index f71f37a17..d6e956bca 100644 --- a/crates/renderide/shaders/materials/xstoon2.0-cutout.wgsl +++ b/crates/renderide/shaders/materials/xstoon2.0-cutout.wgsl @@ -38,6 +38,7 @@ //#mat_default _SSPower float 1.0 //#mat_default _SSScale float 1.0 +#import renderide::billboard::vertex as bv #import renderide::xiexe::toon2 as xs #import renderide::xiexe::toon2::base as xb #import renderide::xiexe::toon2::variant_bits as xvb @@ -48,6 +49,7 @@ const XIEE_KEYWORD_LAYOUT: u32 = xvb::XTOON_KEYWORD_LAYOUT_STATIC_VERTEXLIGHT; @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -59,10 +61,15 @@ fn vs_main( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xs::vertex_main(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xs::vertex_main(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xs::vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } //#pass type=forward diff --git a/crates/renderide/shaders/materials/xstoon2.0-cutouta2c-outlined.wgsl b/crates/renderide/shaders/materials/xstoon2.0-cutouta2c-outlined.wgsl index 32b8ce7f5..58ed7401d 100644 --- a/crates/renderide/shaders/materials/xstoon2.0-cutouta2c-outlined.wgsl +++ b/crates/renderide/shaders/materials/xstoon2.0-cutouta2c-outlined.wgsl @@ -39,6 +39,7 @@ //#mat_default _SSPower float 1.0 //#mat_default _SSScale float 1.0 +#import renderide::billboard::vertex as bv #import renderide::xiexe::toon2 as xs #import renderide::xiexe::toon2::base as xb #import renderide::xiexe::toon2::variant_bits as xvb @@ -50,6 +51,7 @@ const XIEE_KEYWORD_LAYOUT: u32 = xvb::XTOON_KEYWORD_LAYOUT_STATIC_VERTEXLIGHT; @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -61,15 +63,21 @@ fn vs_main( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xs::vertex_main(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xs::vertex_main(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xs::vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } @vertex fn vs_outline( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -81,10 +89,15 @@ fn vs_outline( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xo::vertex_outline(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xo::vertex_outline(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xo::vertex_outline(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } //#pass type=forward name=outline cull=front vs=vs_outline a2c=true diff --git a/crates/renderide/shaders/materials/xstoon2.0-cutouta2c.wgsl b/crates/renderide/shaders/materials/xstoon2.0-cutouta2c.wgsl index 8608f78dd..0a2e6ae7c 100644 --- a/crates/renderide/shaders/materials/xstoon2.0-cutouta2c.wgsl +++ b/crates/renderide/shaders/materials/xstoon2.0-cutouta2c.wgsl @@ -38,6 +38,7 @@ //#mat_default _SSPower float 1.0 //#mat_default _SSScale float 1.0 +#import renderide::billboard::vertex as bv #import renderide::xiexe::toon2 as xs #import renderide::xiexe::toon2::base as xb #import renderide::xiexe::toon2::variant_bits as xvb @@ -48,6 +49,7 @@ const XIEE_KEYWORD_LAYOUT: u32 = xvb::XTOON_KEYWORD_LAYOUT_STATIC_VERTEXLIGHT; @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -59,10 +61,15 @@ fn vs_main( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xs::vertex_main(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xs::vertex_main(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xs::vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } //#pass type=forward a2c=true diff --git a/crates/renderide/shaders/materials/xstoon2.0-cutouta2cmasked.wgsl b/crates/renderide/shaders/materials/xstoon2.0-cutouta2cmasked.wgsl index 7116df512..20f7bebfa 100644 --- a/crates/renderide/shaders/materials/xstoon2.0-cutouta2cmasked.wgsl +++ b/crates/renderide/shaders/materials/xstoon2.0-cutouta2cmasked.wgsl @@ -38,6 +38,7 @@ //#mat_default _SSPower float 1.0 //#mat_default _SSScale float 1.0 +#import renderide::billboard::vertex as bv #import renderide::xiexe::toon2 as xs #import renderide::xiexe::toon2::base as xb #import renderide::xiexe::toon2::variant_bits as xvb @@ -48,6 +49,7 @@ const XIEE_KEYWORD_LAYOUT: u32 = xvb::XTOON_KEYWORD_LAYOUT_STATIC_VERTEXLIGHT; @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -59,10 +61,15 @@ fn vs_main( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xs::vertex_main(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xs::vertex_main(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xs::vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } //#pass type=forward a2c=true diff --git a/crates/renderide/shaders/materials/xstoon2.0-dithered-outlined.wgsl b/crates/renderide/shaders/materials/xstoon2.0-dithered-outlined.wgsl index cb5d20afe..2087fedab 100644 --- a/crates/renderide/shaders/materials/xstoon2.0-dithered-outlined.wgsl +++ b/crates/renderide/shaders/materials/xstoon2.0-dithered-outlined.wgsl @@ -39,6 +39,7 @@ //#mat_default _SSPower float 1.0 //#mat_default _SSScale float 1.0 +#import renderide::billboard::vertex as bv #import renderide::xiexe::toon2 as xs #import renderide::xiexe::toon2::base as xb #import renderide::xiexe::toon2::variant_bits as xvb @@ -50,6 +51,7 @@ const XIEE_KEYWORD_LAYOUT: u32 = xvb::XTOON_KEYWORD_LAYOUT_STATIC_VERTEXLIGHT; @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -61,15 +63,21 @@ fn vs_main( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xs::vertex_main(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xs::vertex_main(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xs::vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } @vertex fn vs_outline( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -81,10 +89,15 @@ fn vs_outline( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xo::vertex_outline(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xo::vertex_outline(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xo::vertex_outline(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } //#pass type=forward name=outline cull=front vs=vs_outline diff --git a/crates/renderide/shaders/materials/xstoon2.0-dithered.wgsl b/crates/renderide/shaders/materials/xstoon2.0-dithered.wgsl index b71c2ae67..a88bfb4a4 100644 --- a/crates/renderide/shaders/materials/xstoon2.0-dithered.wgsl +++ b/crates/renderide/shaders/materials/xstoon2.0-dithered.wgsl @@ -38,6 +38,7 @@ //#mat_default _SSPower float 1.0 //#mat_default _SSScale float 1.0 +#import renderide::billboard::vertex as bv #import renderide::xiexe::toon2 as xs #import renderide::xiexe::toon2::base as xb #import renderide::xiexe::toon2::variant_bits as xvb @@ -48,6 +49,7 @@ const XIEE_KEYWORD_LAYOUT: u32 = xvb::XTOON_KEYWORD_LAYOUT_STATIC_VERTEXLIGHT; @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -59,10 +61,15 @@ fn vs_main( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xs::vertex_main(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xs::vertex_main(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xs::vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } //#pass type=forward diff --git a/crates/renderide/shaders/materials/xstoon2.0-fade.wgsl b/crates/renderide/shaders/materials/xstoon2.0-fade.wgsl index cd804bef7..22b94b3ba 100644 --- a/crates/renderide/shaders/materials/xstoon2.0-fade.wgsl +++ b/crates/renderide/shaders/materials/xstoon2.0-fade.wgsl @@ -38,6 +38,7 @@ //#mat_default _SSPower float 1.0 //#mat_default _SSScale float 1.0 +#import renderide::billboard::vertex as bv #import renderide::xiexe::toon2 as xs #import renderide::xiexe::toon2::base as xb #import renderide::xiexe::toon2::variant_bits as xvb @@ -48,6 +49,7 @@ const XIEE_KEYWORD_LAYOUT: u32 = xvb::XTOON_KEYWORD_LAYOUT_STATIC_VERTEXLIGHT; @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -59,10 +61,15 @@ fn vs_main( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xs::vertex_main(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xs::vertex_main(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xs::vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } //#pass type=forward name=forward_alpha_blend blend=alpha zwrite=off ztest=main color_mask=rgba offset=0,0 diff --git a/crates/renderide/shaders/materials/xstoon2.0-outlined.wgsl b/crates/renderide/shaders/materials/xstoon2.0-outlined.wgsl index a8d1e2234..29bb05353 100644 --- a/crates/renderide/shaders/materials/xstoon2.0-outlined.wgsl +++ b/crates/renderide/shaders/materials/xstoon2.0-outlined.wgsl @@ -43,6 +43,7 @@ //#mat_default _SSPower float 1.0 //#mat_default _SSScale float 1.0 +#import renderide::billboard::vertex as bv #import renderide::xiexe::toon2 as xs #import renderide::xiexe::toon2::base as xb #import renderide::xiexe::toon2::variant_bits as xvb @@ -54,6 +55,7 @@ const XIEE_KEYWORD_LAYOUT: u32 = xvb::XTOON_KEYWORD_LAYOUT_STATIC_VERTEXLIGHT; @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -65,15 +67,21 @@ fn vs_main( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xs::vertex_main(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xs::vertex_main(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xs::vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } @vertex fn vs_outline( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -85,10 +93,15 @@ fn vs_outline( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xo::vertex_outline(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xo::vertex_outline(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xo::vertex_outline(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } //#pass type=forward name=outline cull=front vs=vs_outline diff --git a/crates/renderide/shaders/materials/xstoon2.0-transparent.wgsl b/crates/renderide/shaders/materials/xstoon2.0-transparent.wgsl index ac91e7c87..4453d003d 100644 --- a/crates/renderide/shaders/materials/xstoon2.0-transparent.wgsl +++ b/crates/renderide/shaders/materials/xstoon2.0-transparent.wgsl @@ -38,6 +38,7 @@ //#mat_default _SSPower float 1.0 //#mat_default _SSScale float 1.0 +#import renderide::billboard::vertex as bv #import renderide::xiexe::toon2 as xs #import renderide::xiexe::toon2::base as xb #import renderide::xiexe::toon2::variant_bits as xvb @@ -48,6 +49,7 @@ const XIEE_KEYWORD_LAYOUT: u32 = xvb::XTOON_KEYWORD_LAYOUT_STATIC_VERTEXLIGHT; @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -59,10 +61,15 @@ fn vs_main( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xs::vertex_main(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xs::vertex_main(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xs::vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } //#pass type=forward name=forward_premultiplied_transparent blend=premul zwrite=off ztest=main color_mask=rgba offset=0,0 diff --git a/crates/renderide/shaders/materials/xstoon2.0.wgsl b/crates/renderide/shaders/materials/xstoon2.0.wgsl index 9d78f5566..e12e47d7a 100644 --- a/crates/renderide/shaders/materials/xstoon2.0.wgsl +++ b/crates/renderide/shaders/materials/xstoon2.0.wgsl @@ -37,6 +37,7 @@ //#mat_default _SSPower float 1.0 //#mat_default _SSScale float 1.0 +#import renderide::billboard::vertex as bv #import renderide::xiexe::toon2 as xs #import renderide::xiexe::toon2::base as xb #import renderide::xiexe::toon2::variant_bits as xvb @@ -46,6 +47,7 @@ const XIEE_ALPHA_MODE: u32 = 0u; @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -57,10 +59,15 @@ fn vs_main( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xs::vertex_main(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xs::vertex_main(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xs::vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } //#pass type=forward diff --git a/crates/renderide/shaders/materials/xstoon2.0_outlined.wgsl b/crates/renderide/shaders/materials/xstoon2.0_outlined.wgsl index e462e182d..2287ce18e 100644 --- a/crates/renderide/shaders/materials/xstoon2.0_outlined.wgsl +++ b/crates/renderide/shaders/materials/xstoon2.0_outlined.wgsl @@ -43,6 +43,7 @@ //#mat_default _SSPower float 1.0 //#mat_default _SSScale float 1.0 +#import renderide::billboard::vertex as bv #import renderide::xiexe::toon2 as xs #import renderide::xiexe::toon2::base as xb #import renderide::xiexe::toon2::variant_bits as xvb @@ -53,6 +54,7 @@ const XIEE_ALPHA_MODE: u32 = 0u; @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -64,15 +66,21 @@ fn vs_main( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xs::vertex_main(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xs::vertex_main(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xs::vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } @vertex fn vs_outline( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -84,10 +92,15 @@ fn vs_outline( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xo::vertex_outline(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xo::vertex_outline(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xo::vertex_outline(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } //#pass type=forward name=outline cull=front vs=vs_outline diff --git a/crates/renderide/shaders/materials/xstoon2.0_wireframeoverride.wgsl b/crates/renderide/shaders/materials/xstoon2.0_wireframeoverride.wgsl index f98885750..ce8833121 100644 --- a/crates/renderide/shaders/materials/xstoon2.0_wireframeoverride.wgsl +++ b/crates/renderide/shaders/materials/xstoon2.0_wireframeoverride.wgsl @@ -37,6 +37,7 @@ //#mat_default _SSPower float 1.0 //#mat_default _SSScale float 1.0 +#import renderide::billboard::vertex as bv #import renderide::mesh::wireframe as wf #import renderide::xiexe::toon2 as xs #import renderide::xiexe::toon2::base as xb @@ -48,6 +49,7 @@ const XIEE_KEYWORD_LAYOUT: u32 = xvb::XTOON_KEYWORD_LAYOUT_STATIC_VERTEXLIGHT; @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -59,10 +61,15 @@ fn vs_main( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xs::vertex_main(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xs::vertex_main(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xs::vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } //#pass type=forward cull=material(back) diff --git a/crates/renderide/shaders/materials/xstoon2.0_wireframeoverride_a2c.wgsl b/crates/renderide/shaders/materials/xstoon2.0_wireframeoverride_a2c.wgsl index 725e967a3..142a531dc 100644 --- a/crates/renderide/shaders/materials/xstoon2.0_wireframeoverride_a2c.wgsl +++ b/crates/renderide/shaders/materials/xstoon2.0_wireframeoverride_a2c.wgsl @@ -38,6 +38,7 @@ //#mat_default _SSPower float 1.0 //#mat_default _SSScale float 1.0 +#import renderide::billboard::vertex as bv #import renderide::frame::globals as rg #import renderide::mesh::wireframe as wf #import renderide::xiexe::toon2 as xs @@ -50,6 +51,7 @@ const XIEE_KEYWORD_LAYOUT: u32 = xvb::XTOON_KEYWORD_LAYOUT_STATIC_VERTEXLIGHT; @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -61,10 +63,15 @@ fn vs_main( @location(5) uv1: vec2, ) -> xb::VertexOutput { #ifdef MULTIVIEW - return xs::vertex_main(instance_index, view_idx, pos, n, uv0, color, tangent, uv1); + let view_layer = view_idx; #else - return xs::vertex_main(instance_index, 0u, pos, n, uv0, color, tangent, uv1); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(xb::mat._RenderideVariantBits)) { + return xs::billboard_vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1, vertex_index); + } else { + return xs::vertex_main(instance_index, view_layer, pos, n, uv0, color, tangent, uv1); + } } //#pass type=forward cull=material(back) a2c=true diff --git a/crates/renderide/shaders/modules/billboard/vertex.wgsl b/crates/renderide/shaders/modules/billboard/vertex.wgsl new file mode 100644 index 000000000..2bf5055be --- /dev/null +++ b/crates/renderide/shaders/modules/billboard/vertex.wgsl @@ -0,0 +1,369 @@ +//! Vertex generation methods for billboard materials + +#define_import_path renderide::billboard::vertex + +#import renderide::core::math as rmath +#import renderide::frame::globals as rg +#import renderide::draw::per_draw as pd +#import renderide::draw::types as dt +#import renderide::material::variant_bits as vb +#import renderide::mesh::billboard as mb +#import renderide::mesh::vertex as mv + +const BILLBOARD_KW_RENDER_BUFFER: u32 = 1u << 24u; + +struct RenderBufferBillboardBasis { + right: vec3, + up: vec3, +} + +struct RenderBufferBillboardVertex { + world_pos: vec4, + axes: RenderBufferBillboardBasis, + corner: vec2, + size: vec2, +} + +fn kw_RENDER_BUFFER(variant_bits: u32) -> bool { + return vb::enabled(variant_bits, BILLBOARD_KW_RENDER_BUFFER); +} + +fn render_buffer_billboard_vertex( + draw: dt::PerDrawUniforms, + view_layer: u32, + pos: vec4, + vertex_index: u32, + pointdata: vec4, + point_forward_upz: vec4, + point_up_xy: vec2, +) -> RenderBufferBillboardVertex { + let center_world = mv::world_position(draw, pos).xyz; + let axes = render_buffer_billboard_basis(draw, center_world, pointdata, point_forward_upz, point_up_xy, view_layer); + let corner = render_buffer_billboard_corner_for_vertex(vertex_index); + let unclamped_size = render_buffer_billboard_size(pointdata.xy, draw.model); + let vp = mv::select_view_proj(draw, view_layer); + let size = screen_clamped_billboard_size(draw, center_world, axes, unclamped_size, vp); + var vertex = RenderBufferBillboardVertex(vec4(0.0), axes, corner, size); + vertex.world_pos = vec4(billboard_center_world_to_world_pos(center_world, vertex), 1.0); + return vertex; +} + +fn billboard_center_world_to_world_pos(center_world: vec3, vertex: RenderBufferBillboardVertex) -> vec3 { + let axes = vertex.axes; + let corner = vertex.corner; + let size = vertex.size; + return center_world + axes.right * (corner.x * size.x) + axes.up * (corner.y * size.y); +} + +fn rotate_render_buffer_axes(angle: f32, right: vec3, up: vec3) -> RenderBufferBillboardBasis { + let c = cos(angle); + let s = sin(angle); + return RenderBufferBillboardBasis(right * c - up * s, right * s + up * c); +} + +fn view_plane_basis(view_layer: u32, roll: f32) -> RenderBufferBillboardBasis { + let view_up = rmath::safe_normalize(rg::view_to_world_y_coeffs_for_view(view_layer).xyz, vec3(0.0, 1.0, 0.0)); + let to_camera = rg::orthographic_view_dir_for_view(view_layer); + var right = rmath::safe_normalize(cross(view_up, to_camera), vec3(1.0, 0.0, 0.0)); + var up = rmath::safe_normalize(cross(to_camera, right), view_up); + if (abs(roll) > 1e-4) { + let rotated = rotate_render_buffer_axes(roll, right, up); + right = rotated.right; + up = rotated.up; + } + return RenderBufferBillboardBasis(right, up); +} + +fn facing_basis(center_world: vec3, view_layer: u32, roll: f32) -> RenderBufferBillboardBasis { + let view_up = rmath::safe_normalize(rg::view_to_world_y_coeffs_for_view(view_layer).xyz, vec3(0.0, 1.0, 0.0)); + let to_camera = rg::view_dir_for_world_pos(center_world, view_layer); + var right = rmath::safe_normalize(cross(view_up, to_camera), vec3(1.0, 0.0, 0.0)); + var up = rmath::safe_normalize(cross(to_camera, right), view_up); + if (abs(roll) > 1e-4) { + let rotated = rotate_render_buffer_axes(roll, right, up); + right = rotated.right; + up = rotated.up; + } + return RenderBufferBillboardBasis(right, up); +} + +fn direction_stretch_particle_basis( + draw: dt::PerDrawUniforms, + center_world: vec3, + point_forward_upz: vec4, + view_layer: u32, +) -> RenderBufferBillboardBasis { + let to_camera = rg::view_dir_for_world_pos(center_world, view_layer); + let velocity_world = mv::model_vector(draw, point_forward_upz.xyz); + let velocity_in_plane = velocity_world - to_camera * dot(velocity_world, to_camera); + let view_up = rg::view_to_world_y_coeffs_for_view(view_layer).xyz; + let view_up_in_plane = view_up - to_camera * dot(view_up, to_camera); + var up = rmath::safe_normalize( + velocity_in_plane, + rmath::safe_normalize(view_up_in_plane, vec3(0.0, 1.0, 0.0)), + ); + let right = rmath::safe_normalize(cross(up, to_camera), vec3(1.0, 0.0, 0.0)); + up = rmath::safe_normalize(cross(to_camera, right), up); + return RenderBufferBillboardBasis(right, up); +} + +fn local_particle_basis( + draw: dt::PerDrawUniforms, + roll: f32, + point_forward_upz: vec4, + point_up_xy: vec2, +) -> RenderBufferBillboardBasis { + let raw_forward = rmath::safe_normalize(point_forward_upz.xyz, vec3(0.0, 0.0, 1.0)); + let raw_up = rmath::safe_normalize(vec3(point_up_xy, point_forward_upz.w), vec3(0.0, 1.0, 0.0)); + let world_forward = rmath::safe_normalize(mv::model_vector(draw, raw_forward), vec3(0.0, 0.0, 1.0)); + let world_up = rmath::safe_normalize(mv::model_vector(draw, raw_up), vec3(0.0, 1.0, 0.0)); + var right = rmath::safe_normalize(cross(world_forward, world_up), vec3(1.0, 0.0, 0.0)); + var up = rmath::safe_normalize(cross(right, world_forward), world_up); + if (abs(roll) > 1e-4) { + let rotated = rotate_render_buffer_axes(roll, right, up); + right = rotated.right; + up = rotated.up; + } + return RenderBufferBillboardBasis(right, up); +} + +fn render_buffer_billboard_basis( + draw: dt::PerDrawUniforms, + center_world: vec3, + pointdata: vec4, + point_forward_upz: vec4, + point_up_xy: vec2, + view_layer: u32, +) -> RenderBufferBillboardBasis { + let alignment = pd::particle_alignment(draw); + if (alignment == 1u) { + return facing_basis(center_world, view_layer, pointdata.z); + } + if (alignment == 2u || alignment == 3u) { + return local_particle_basis(draw, pointdata.z, point_forward_upz, point_up_xy); + } + if (alignment == 4u) { + return direction_stretch_particle_basis(draw, center_world, point_forward_upz, view_layer); + } + return view_plane_basis(view_layer, pointdata.z); +} + +fn ndc_xy(clip: vec4) -> vec2 { + return clip.xy / max(abs(clip.w), 1e-6); +} + +fn screen_clamped_billboard_size( + draw: dt::PerDrawUniforms, + center_world: vec3, + axes: RenderBufferBillboardBasis, + size: vec2, + vp: mat4x4, +) -> vec2 { + let min_size = pd::particle_min_screen_size(draw); + let max_size = pd::particle_max_screen_size(draw); + if (min_size <= 0.0 && max_size <= 0.0) { + return size; + } + let viewport = max(rg::viewport_size(), vec2(1.0, 1.0)); + let center_ndc = ndc_xy(vp * vec4(center_world, 1.0)); + let right_ndc = ndc_xy(vp * vec4(center_world + axes.right * size.x, 1.0)); + let up_ndc = ndc_xy(vp * vec4(center_world + axes.up * size.y, 1.0)); + let right_pixels = length((right_ndc - center_ndc) * viewport * 0.5); + let up_pixels = length((up_ndc - center_ndc) * viewport * 0.5); + let screen_fraction = max(right_pixels, up_pixels) / max(min(viewport.x, viewport.y), 1.0); + if (screen_fraction <= 1e-6) { + return size; + } + var scale = 1.0; + if (min_size > 0.0 && screen_fraction < min_size) { + scale = max(scale, min_size / screen_fraction); + } + if (max_size > 0.0 && screen_fraction * scale > max_size) { + scale = max_size / screen_fraction; + } + return max(size * scale, vec2(1e-6, 1e-6)); +} + +fn render_buffer_billboard_unit_corner(vertex_index: u32) -> vec2 { + let corner = vertex_index % 4u; + return vec2( + select(0.0, 1.0, (corner & 1u) != 0u), + select(0.0, 1.0, (corner & 2u) != 0u), + ); +} + +fn render_buffer_billboard_size(scale: vec2, model: mat4x4) -> vec2 { + return max(abs(scale), vec2(1e-6, 1e-6)) * mb::model_uniform_scale(model); +} + +fn render_buffer_billboard_corner_for_vertex(vertex_index: u32) -> vec2 { + return render_buffer_billboard_unit_corner(vertex_index) * 2.0 - vec2(1.0, 1.0); +} + +///////////////////////////////////////// +/// renderide::mesh::vertex overloads /// +///////////////////////////////////////// + +fn world_color_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + t: vec4, + primary_uv: vec2, + color: vec4, + vertex_index: u32, + uv1: vec2, +) -> mv::WorldColorVertexOutput { + let draw = pd::get_draw(instance_index); + let vp = mv::select_view_proj(draw, view_idx); + + let render_billboard_vertex = render_buffer_billboard_vertex( + draw, view_idx, pos, vertex_index, n, t, uv1, + ); + let world_p = render_billboard_vertex.world_pos; + let axes = render_billboard_vertex.axes; + let billboard_t = axes.right; + let billboard_n = rmath::safe_normalize(cross(axes.right, axes.up), vec3(0.0, 0.0, 1.0)); + + var out: mv::WorldColorVertexOutput; + out.clip_pos = vp * world_p; + out.world_pos = world_p.xyz; + out.world_n = mv::world_normal_for_view(draw, vec4(billboard_n, 0.0), view_idx); + out.world_t = mv::world_tangent_for_view(draw, vec4(billboard_t, 0.0), view_idx); + out.color = color * dt::particle_color(draw); + out.primary_uv = primary_uv; + out.view_layer = mv::packed_view_layer(instance_index, view_idx); + return out; +} + +fn world_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + t: vec4, + primary_uv: vec2, + vertex_index: u32, + uv1: vec2, +) -> mv::WorldVertexOutput { + let draw = pd::get_draw(instance_index); + let vp = mv::select_view_proj(draw, view_idx); + + let render_billboard_vertex = render_buffer_billboard_vertex( + draw, view_idx, pos, vertex_index, n, t, uv1, + ); + let world_p = render_billboard_vertex.world_pos; + let axes = render_billboard_vertex.axes; + let billboard_t = axes.right; + let billboard_n = rmath::safe_normalize(cross(axes.right, axes.up), vec3(0.0, 0.0, 1.0)); + + var out: mv::WorldVertexOutput; + out.clip_pos = vp * world_p; + out.world_pos = world_p.xyz; + out.world_n = mv::world_normal_for_view(draw, vec4(billboard_n, 0.0), view_idx); + out.world_t = mv::world_tangent_for_view(draw, vec4(billboard_t, 0.0), view_idx); + out.primary_uv = primary_uv; + out.view_layer = mv::packed_view_layer(instance_index, view_idx); + return out; +} + +fn world_uv2_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + t: vec4, + primary_uv: vec2, + secondary_uv: vec2, + vertex_index: u32, +) -> mv::WorldUv2VertexOutput { + let draw = pd::get_draw(instance_index); + let vp = mv::select_view_proj(draw, view_idx); + + let render_billboard_vertex = render_buffer_billboard_vertex( + draw, view_idx, pos, vertex_index, n, t, secondary_uv, + ); + let world_p = render_billboard_vertex.world_pos; + let axes = render_billboard_vertex.axes; + let billboard_t = axes.right; + let billboard_n = rmath::safe_normalize(cross(axes.right, axes.up), vec3(0.0, 0.0, 1.0)); + + var out: mv::WorldUv2VertexOutput; + out.clip_pos = vp * world_p; + out.world_pos = world_p.xyz; + out.world_n = mv::world_normal_for_view(draw, vec4(billboard_n, 0.0), view_idx); + out.world_t = mv::world_tangent_for_view(draw, vec4(billboard_t, 0.0), view_idx); + out.primary_uv = primary_uv; + // secondary_uv actually is overriden, and the generated billboard has no seccondary UV map anyway + out.secondary_uv = primary_uv; + out.view_layer = mv::packed_view_layer(instance_index, view_idx); + return out; +} + +fn world_uv4_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + t: vec4, + primary_uv: vec2, + secondary_uv: vec2, + vertex_index: u32, +) -> mv::WorldUv4VertexOutput { + let draw = pd::get_draw(instance_index); + let vp = mv::select_view_proj(draw, view_idx); + + let render_billboard_vertex = render_buffer_billboard_vertex( + draw, view_idx, pos, vertex_index, n, t, secondary_uv, + ); + let world_p = render_billboard_vertex.world_pos; + let axes = render_billboard_vertex.axes; + let billboard_t = axes.right; + let billboard_n = rmath::safe_normalize(cross(axes.right, axes.up), vec3(0.0, 0.0, 1.0)); + + var out: mv::WorldUv4VertexOutput; + out.clip_pos = vp * world_p; + out.world_pos = world_p.xyz; + out.world_n = mv::world_normal_for_view(draw, vec4(billboard_n, 0.0), view_idx); + out.world_t = mv::world_tangent_for_view(draw, vec4(billboard_t, 0.0), view_idx); + // secondary_uv actually is overriden, and the generated billboard has no seccondary UV map anyway + out.uv_a = primary_uv; + out.uv_b = primary_uv; + out.uv_c = primary_uv; + out.uv_d = primary_uv; + out.view_layer = mv::packed_view_layer(instance_index, view_idx); + return out; +} + +fn world_object_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + t: vec4, + primary_uv: vec2, + vertex_index: u32, + uv1: vec2, +) -> mv::WorldObjectVertexOutput { + let draw = pd::get_draw(instance_index); + let vp = mv::select_view_proj(draw, view_idx); + + let render_billboard_vertex = render_buffer_billboard_vertex( + draw, view_idx, pos, vertex_index, n, t, uv1, + ); + let world_p = render_billboard_vertex.world_pos; + let axes = render_billboard_vertex.axes; + let billboard_t = axes.right; + let billboard_n = rmath::safe_normalize(cross(axes.right, axes.up), vec3(0.0, 0.0, 1.0)); + + var out: mv::WorldObjectVertexOutput; + out.clip_pos = vp * world_p; + out.world_pos = world_p.xyz; + out.object_pos = pos.xyz; + out.world_n = mv::world_normal_for_view(draw, vec4(billboard_n, 0.0), view_idx); + out.world_t = mv::world_tangent_for_view(draw, vec4(billboard_t, 0.0), view_idx); + out.primary_uv = primary_uv; + out.view_layer = mv::packed_view_layer(instance_index, view_idx); + return out; +} diff --git a/crates/renderide/shaders/modules/fur/classic_advanced.wgsl b/crates/renderide/shaders/modules/fur/classic_advanced.wgsl index 692b7d5d7..17da9fbe6 100644 --- a/crates/renderide/shaders/modules/fur/classic_advanced.wgsl +++ b/crates/renderide/shaders/modules/fur/classic_advanced.wgsl @@ -32,6 +32,7 @@ struct ClassicAdvancedMaterial { _NoiseTex_LodBias: f32, _Cube_LodBias: f32, _Cube_StorageVInverted: f32, + _RenderideVariantBits: u32, } @group(1) @binding(0) var mat: ClassicAdvancedMaterial; @@ -45,19 +46,23 @@ struct ClassicAdvancedMaterial { fn vertex_main( instance_index: u32, view_idx: u32, + vertex_index: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, + uv1: vec2, fur_multiplier: f32, ) -> furc::VertexOutput { return furc::fur_vertex_main( instance_index, view_idx, + vertex_index, pos, n, t, uv0, + uv1, mat._MainTex_ST, mat._NoiseTex_ST, fur_multiplier, @@ -65,6 +70,7 @@ fn vertex_main( mat._HairHardness, mat._ForceGlobal, mat._ForceLocal, + mat._RenderideVariantBits, ); } diff --git a/crates/renderide/shaders/modules/fur/classic_basic.wgsl b/crates/renderide/shaders/modules/fur/classic_basic.wgsl index 6ee1ea38d..10ad5e318 100644 --- a/crates/renderide/shaders/modules/fur/classic_basic.wgsl +++ b/crates/renderide/shaders/modules/fur/classic_basic.wgsl @@ -25,6 +25,7 @@ struct ClassicBasicMaterial { _SkinAlpha: f32, _MainTex_LodBias: f32, _NoiseTex_LodBias: f32, + _RenderideVariantBits: u32, } @group(1) @binding(0) var mat: ClassicBasicMaterial; @@ -36,19 +37,23 @@ struct ClassicBasicMaterial { fn vertex_main( instance_index: u32, view_idx: u32, + vertex_index: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, + uv1: vec2, fur_multiplier: f32, ) -> furc::VertexOutput { return furc::fur_vertex_main( instance_index, view_idx, + vertex_index, pos, n, t, uv0, + uv1, mat._MainTex_ST, mat._NoiseTex_ST, fur_multiplier, @@ -56,6 +61,7 @@ fn vertex_main( mat._HairHardness, mat._ForceGlobal, mat._ForceLocal, + mat._RenderideVariantBits, ); } diff --git a/crates/renderide/shaders/modules/fur/classic_selfshadow.wgsl b/crates/renderide/shaders/modules/fur/classic_selfshadow.wgsl index d0c69c44b..e5c21dead 100644 --- a/crates/renderide/shaders/modules/fur/classic_selfshadow.wgsl +++ b/crates/renderide/shaders/modules/fur/classic_selfshadow.wgsl @@ -33,6 +33,7 @@ struct ClassicSelfShadowMaterial { _NoiseTex_LodBias: f32, _Cube_LodBias: f32, _Cube_StorageVInverted: f32, + _RenderideVariantBits: u32, } @group(1) @binding(0) var mat: ClassicSelfShadowMaterial; @@ -46,19 +47,23 @@ struct ClassicSelfShadowMaterial { fn vertex_main( instance_index: u32, view_idx: u32, + vertex_index: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, + uv1: vec2, fur_multiplier: f32, ) -> furc::VertexOutput { return furc::fur_vertex_main( instance_index, view_idx, + vertex_index, pos, n, t, uv0, + uv1, mat._MainTex_ST, mat._NoiseTex_ST, fur_multiplier, @@ -66,6 +71,7 @@ fn vertex_main( mat._HairHardness, mat._ForceGlobal, mat._ForceLocal, + mat._RenderideVariantBits, ); } diff --git a/crates/renderide/shaders/modules/fur/common.wgsl b/crates/renderide/shaders/modules/fur/common.wgsl index dba38c9c3..1371fa4a2 100644 --- a/crates/renderide/shaders/modules/fur/common.wgsl +++ b/crates/renderide/shaders/modules/fur/common.wgsl @@ -2,9 +2,11 @@ #define_import_path renderide::fur::common +#import renderide::billboard::vertex as bv #import renderide::draw::per_draw as pd #import renderide::frame::globals as rg #import renderide::mesh::vertex as mv +#import renderide::core::math as rmath #import renderide::core::uv as uvu struct VertexOutput { @@ -45,10 +47,12 @@ fn projected_local_force(force_local: vec4, view_idx: u32) -> vec3 { fn fur_vertex_main( instance_index: u32, view_idx: u32, + vertex_index: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, + uv1: vec2, main_st: vec4, noise_st: vec4, fur_multiplier: f32, @@ -56,17 +60,38 @@ fn fur_vertex_main( hair_hardness: f32, force_global: vec4, force_local: vec4, + variant_bits: u32, ) -> VertexOutput { let draw = pd::get_draw(instance_index); - let world_n = mv::world_normal(draw, n); - let world_t = mv::world_tangent(draw, t); - let base_world_pos = mv::world_position(draw, pos).xyz; + var base_world_pos: vec3; + var world_n: vec3; + var world_t: vec4; + var billboard_vertex: bv::RenderBufferBillboardVertex; + if (bv::kw_RENDER_BUFFER(variant_bits)) { + billboard_vertex = bv::render_buffer_billboard_vertex( + draw, view_idx, pos, vertex_index, n, t, uv1, + ); + base_world_pos = billboard_vertex.world_pos.xyz; + let axes = billboard_vertex.axes; + let billboard_t = axes.right; + let billboard_n = rmath::safe_normalize(cross(axes.right, axes.up), vec3(0.0, 0.0, 1.0)); + world_n = mv::world_normal(draw, vec4(billboard_n, 0.0)); + world_t = mv::world_tangent(draw, vec4(billboard_t, 0.0)); + } else { + base_world_pos = mv::world_position(draw, pos).xyz; + world_n = mv::world_normal(draw, n); + world_t = mv::world_tangent(draw, t); + } + let shell_offset = n.xyz * fur_length * fur_multiplier * hair_hardness; let force_scale = fur_multiplier * fur_multiplier * fur_length; let local_force_offset = projected_local_force(force_local, view_idx) * force_scale; let shell_model_pos = pos.xyz + shell_offset + local_force_offset; let shell_pos = vec4(shell_model_pos, pos.w); - let shell_world_pos = mv::world_position(draw, shell_pos).xyz; + var shell_world_pos = mv::world_position(draw, shell_pos).xyz; + if (bv::kw_RENDER_BUFFER(variant_bits)) { + shell_world_pos = bv::billboard_center_world_to_world_pos(shell_world_pos, billboard_vertex); + } let global_force = clamp(force_global.xyz, vec3(-1.0), vec3(1.0)); let global_force_offset = global_force * force_scale; let world_p = shell_world_pos + global_force_offset; diff --git a/crates/renderide/shaders/modules/fur/modern.wgsl b/crates/renderide/shaders/modules/fur/modern.wgsl index c483e0d56..2f9eec767 100644 --- a/crates/renderide/shaders/modules/fur/modern.wgsl +++ b/crates/renderide/shaders/modules/fur/modern.wgsl @@ -40,6 +40,7 @@ struct ModernFurMaterial { _NoiseTex_LodBias: f32, _Cube_LodBias: f32, _Cube_StorageVInverted: f32, + _RenderideVariantBits: u32, } @group(1) @binding(0) var mat: ModernFurMaterial; @@ -55,19 +56,23 @@ struct ModernFurMaterial { fn vertex_main( instance_index: u32, view_idx: u32, + vertex_index: u32, pos: vec4, n: vec4, t: vec4, uv0: vec2, + uv1: vec2, fur_multiplier: f32, ) -> furc::VertexOutput { return furc::fur_vertex_main( instance_index, view_idx, + vertex_index, pos, n, t, uv0, + uv1, mat._MainTex_ST, mat._NoiseTex_ST, fur_multiplier, @@ -75,6 +80,7 @@ fn vertex_main( mat._HairHardness, mat._ForceGlobal, mat._ForceLocal, + mat._RenderideVariantBits, ); } diff --git a/crates/renderide/shaders/modules/xiexe/toon2/main.wgsl b/crates/renderide/shaders/modules/xiexe/toon2/main.wgsl index 64ad6848c..d3732985e 100644 --- a/crates/renderide/shaders/modules/xiexe/toon2/main.wgsl +++ b/crates/renderide/shaders/modules/xiexe/toon2/main.wgsl @@ -35,6 +35,23 @@ fn vertex_main( return xsurf::vertex_main(instance_index, view_idx, pos, n, uv_primary, color, tangent, uv_secondary); } +/// Forward-pass vertex entry point for billboard rendering. +/// Thin wrapper around `surface::billboard_vertex_main` so +/// dispatcher shaders depend only on this aggregator namespace. +fn billboard_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + uv_primary: vec2, + color: vec4, + tangent: vec4, + uv_secondary: vec2, + vertex_index: u32, +) -> xb::VertexOutput { + return xsurf::billboard_vertex_main(instance_index, view_idx, pos, n, uv_primary, color, tangent, uv_secondary, vertex_index); +} + /// Forward (lit) fragment entry. Samples the surface (with the dual-sided back-face /// normal flip enabled), runs the alpha-mode dispatch, and shades through the cluster /// light walk. diff --git a/crates/renderide/shaders/modules/xiexe/toon2/surface.wgsl b/crates/renderide/shaders/modules/xiexe/toon2/surface.wgsl index 10458b72a..b183628b6 100644 --- a/crates/renderide/shaders/modules/xiexe/toon2/surface.wgsl +++ b/crates/renderide/shaders/modules/xiexe/toon2/surface.wgsl @@ -15,6 +15,8 @@ #import renderide::pbs::normal as pnorm #import renderide::core::normal_decode as nd #import renderide::core::uv as uvu +#import renderide::billboard::vertex as bv +#import renderide::core::math as rmath /// Forward-pass vertex transform. Builds the world-space TBN, applies the per-eye VP, /// and forwards UVs / vertex color unchanged. Outline extrusion lives in @@ -51,6 +53,46 @@ fn vertex_main( return out; } +/// Forward-pass vertex transform for billboard particle rendering. +/// Same structure as `vertex_main`, but using billboard point data +/// to generate quad vertices on the fly. +fn billboard_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + uv_primary: vec2, + color: vec4, + tangent: vec4, + uv_secondary: vec2, + vertex_index: u32, +) -> xb::VertexOutput { + let d = pd::get_draw(instance_index); + + let render_billboard_vertex = bv::render_buffer_billboard_vertex( + d, view_idx, pos, vertex_index, n, tangent, uv_secondary, + ); + let world_p = render_billboard_vertex.world_pos; + let axes = render_billboard_vertex.axes; + let billboard_t = axes.right; + let billboard_n = rmath::safe_normalize(cross(axes.right, axes.up), vec3(0.0, 0.0, 1.0)); + let vp = xb::view_projection_for_draw(d, view_idx); + + var out: xb::VertexOutput; + out.clip_pos = vp * world_p; + out.world_pos = world_p.xyz; + out.world_n = mv::world_normal_for_view(d, vec4(billboard_n, 0.0), view_idx).xyz; + out.world_t = mv::world_tangent_for_view(d, vec4(billboard_t, 0.0), view_idx).xyz; + out.world_b = rmath::safe_normalize(cross(out.world_n, out.world_t), vec3(0.0, 0.0, 1.0)); + out.uv_primary = uv_primary; + out.uv_secondary = uv_primary; + out.color = color; + out.obj_pos = xb::safe_normalize(pos.xyz, vec3(0.0, 0.0, 1.0)); + out.view_layer = mv::packed_view_layer(instance_index, view_idx); + return out; +} + + /// Builds a perturbed TBN from the interpolated geometry frame for a selected keyword layout. fn decode_normal_world_for_layout( uv_normal: vec2, diff --git a/crates/renderide/src/assets/mesh/gpu_mesh.rs b/crates/renderide/src/assets/mesh/gpu_mesh.rs index be4367b27..d6f830c04 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh.rs @@ -155,8 +155,6 @@ pub struct GpuMesh { pub color_buffer: Option>, /// `vec4` tangent stream for shaders using extended vertex inputs. pub tangent_buffer: Option>, - /// Raw `vec4` tangent payload for UI shaders that use the tangent semantic as data. - pub raw_tangent_buffer: Option>, /// Tangent fallback policy used for the current tangent stream. pub tangent_fallback_mode: EmbeddedTangentFallbackMode, /// `vec2` UV1 stream for shaders using extended vertex inputs. @@ -297,7 +295,6 @@ pub(super) fn extended_vertex_stream_source_from_raw( pub(super) fn extended_vertex_stream_bytes(mesh: &GpuMesh) -> u64 { [ mesh.tangent_buffer.as_ref(), - mesh.raw_tangent_buffer.as_ref(), mesh.uv1_buffer.as_ref(), mesh.uv2_buffer.as_ref(), mesh.uv3_buffer.as_ref(), @@ -327,7 +324,6 @@ fn rebuildable_derived_stream_mask( } if source.has_compact_extended_payload { mask |= MeshDerivedStreamMask::TANGENT - | MeshDerivedStreamMask::RAW_TANGENT | MeshDerivedStreamMask::UV1 | MeshDerivedStreamMask::UV2 | MeshDerivedStreamMask::UV3; @@ -364,9 +360,6 @@ impl GpuMesh { if self.tangent_buffer.is_some() { mask |= MeshDerivedStreamMask::TANGENT; } - if self.raw_tangent_buffer.is_some() { - mask |= MeshDerivedStreamMask::RAW_TANGENT; - } if self.uv1_buffer.is_some() { mask |= MeshDerivedStreamMask::UV1; } @@ -436,7 +429,6 @@ impl GpuMesh { uv0_buffer: None, color_buffer: None, tangent_buffer: None, - raw_tangent_buffer: None, tangent_fallback_mode: EmbeddedTangentFallbackMode::default(), uv1_buffer: None, uv2_buffer: None, @@ -544,7 +536,6 @@ impl GpuMesh { uv0_buffer: derived.uv0_buffer, color_buffer: derived.color_buffer, tangent_buffer: derived.tangent_buffer, - raw_tangent_buffer: derived.raw_tangent_buffer, tangent_fallback_mode: EmbeddedTangentFallbackMode::default(), uv1_buffer: derived.uv1_buffer, uv2_buffer: derived.uv2_buffer, diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/demand.rs b/crates/renderide/src/assets/mesh/gpu_mesh/demand.rs index d3007190f..2a2741a01 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/demand.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/demand.rs @@ -21,18 +21,18 @@ impl MeshDerivedStreamMask { pub(crate) const COLOR: Self = Self(1 << 3); /// Sanitized geometric tangent stream. pub(crate) const TANGENT: Self = Self(1 << 4); - /// Raw tangent payload stream. - pub(crate) const RAW_TANGENT: Self = Self(1 << 5); /// Compact UV1 stream. - pub(crate) const UV1: Self = Self(1 << 6); + pub(crate) const UV1: Self = Self(1 << 5); /// Compact UV2 stream. - pub(crate) const UV2: Self = Self(1 << 7); + pub(crate) const UV2: Self = Self(1 << 6); /// Compact UV3 stream. - pub(crate) const UV3: Self = Self(1 << 8); + pub(crate) const UV3: Self = Self(1 << 7); /// Packed UV0-UV3 stream for wide low UV inputs. - pub(crate) const WIDE_UV_LOW: Self = Self(1 << 9); + pub(crate) const WIDE_UV_LOW: Self = Self(1 << 8); /// Packed UV4-UV7 stream for high UV inputs. - pub(crate) const WIDE_UV_HIGH: Self = Self(1 << 10); + pub(crate) const WIDE_UV_HIGH: Self = Self(1 << 9); + /// Billboard direction stream replacing tangent and uv1. + pub(crate) const BILLBOARD: Self = Self(1 << 10); /// Streams affected when interleaved vertex data changes. pub(crate) const VERTEX_DERIVED: Self = Self( Self::POSITION.0 @@ -40,12 +40,12 @@ impl MeshDerivedStreamMask { | Self::UV0.0 | Self::COLOR.0 | Self::TANGENT.0 - | Self::RAW_TANGENT.0 | Self::UV1.0 | Self::UV2.0 | Self::UV3.0 | Self::WIDE_UV_LOW.0 - | Self::WIDE_UV_HIGH.0, + | Self::WIDE_UV_HIGH.0 + | Self::BILLBOARD.0, ); /// Streams affected when index order changes. pub(crate) const INDEX_DERIVED: Self = Self(Self::TANGENT.0); @@ -53,7 +53,7 @@ impl MeshDerivedStreamMask { pub(crate) const DRAWABLE_PRIMARY: Self = Self(Self::POSITION.0 | Self::NORMAL.0); /// Streams produced by generated particle meshes in steady state. pub(crate) const GENERATED_PARTICLE: Self = - Self(Self::POSITION.0 | Self::NORMAL.0 | Self::UV0.0 | Self::COLOR.0); + Self(Self::POSITION.0 | Self::NORMAL.0 | Self::UV0.0 | Self::COLOR.0 | Self::BILLBOARD.0); /// Returns the raw bit representation. #[inline] diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/hints.rs b/crates/renderide/src/assets/mesh/gpu_mesh/hints.rs index 5dae0bfc1..7999fa1f5 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/hints.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/hints.rs @@ -86,7 +86,6 @@ pub(super) fn derived_streams_compatible_for_in_place( && gpu.uv0_buffer.is_none() && gpu.color_buffer.is_none() && gpu.tangent_buffer.is_none() - && gpu.raw_tangent_buffer.is_none() && gpu.uv1_buffer.is_none() && gpu.uv2_buffer.is_none() && gpu.uv3_buffer.is_none() @@ -121,9 +120,6 @@ pub(super) fn derived_streams_compatible_for_in_place( if !optional_stream_size_matches(gpu.tangent_buffer.as_deref(), Some(vec4_bytes)) { return false; } - if !optional_stream_size_matches(gpu.raw_tangent_buffer.as_deref(), Some(vec4_bytes)) { - return false; - } for buffer in [&gpu.uv1_buffer, &gpu.uv2_buffer, &gpu.uv3_buffer] { if !optional_stream_size_matches(buffer.as_deref(), Some(uv_bytes)) { return false; diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/tangent_generation.rs b/crates/renderide/src/assets/mesh/gpu_mesh/tangent_generation.rs index bc6f337bb..696a3cf30 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/tangent_generation.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/tangent_generation.rs @@ -10,7 +10,6 @@ use crate::shared::{ }; use super::super::layout::VertexDecodeKind; -use super::super::layout::raw_float4_stream_bytes; use super::attribute_reader::AttributeReader; const _: () = assert!( @@ -20,7 +19,6 @@ const _: () = assert!( const DEFAULT_TANGENT: [f32; 4] = [1.0, 0.0, 0.0, 1.0]; const DEFAULT_TANGENT_VEC: Vec4 = Vec4::new(1.0, 0.0, 0.0, 1.0); -const DEFAULT_RAW_TANGENT_PAYLOAD: [f32; 4] = [1.0, 1.0, 1.0, 1.0]; const TANGENT_EPSILON_SQUARED: f32 = 1.0e-20; /// Vertices assigned to one tangent extraction or encoding worker chunk. const VERTEX_STREAM_PARALLEL_CHUNK_VERTICES: usize = 256; @@ -109,18 +107,6 @@ pub(super) fn tangent_stream_bytes( ) } -/// Returns a dense `vec4` tangent payload stream without geometric sanitization. -pub(super) fn raw_tangent_payload_stream_bytes(source: TangentStreamSource<'_>) -> Option> { - raw_float4_stream_bytes( - source.vertex_data, - source.vertex_count, - source.stride, - source.attrs, - VertexAttributeType::Tangent, - DEFAULT_RAW_TANGENT_PAYLOAD, - ) -} - fn host_tangent_stream_bytes( vertex_data: &[u8], vertex_count: usize, @@ -655,34 +641,6 @@ mod tests { assert_eq!(read_tangent(&tangents, 0), [0.0, 1.0, 0.0, -1.0]); } - #[test] - fn raw_tangent_payload_stream_preserves_color_data() { - let attrs = [ - attr(VertexAttributeType::Position, 3), - attr(VertexAttributeType::Normal, 3), - attr(VertexAttributeType::UV0, 2), - attr(VertexAttributeType::Tangent, 4), - ]; - let mut vertices = Vec::new(); - push_vertex_with_tangent( - &mut vertices, - [0.0, 0.0, 0.0], - [0.0, 0.0, 1.0], - [0.0, 0.0], - [0.0, 0.0, 0.0, 0.75], - ); - - let geometric = - tangent_stream_bytes(tangent_source(&vertices, &[], 1, 48, &attrs, &[]), false) - .expect("geometric tangent stream"); - let raw = - raw_tangent_payload_stream_bytes(tangent_source(&vertices, &[], 1, 48, &attrs, &[])) - .expect("raw tangent stream"); - - assert_eq!(read_tangent(&geometric, 0), [1.0, 0.0, 0.0, 1.0]); - assert_eq!(read_tangent(&raw, 0), [0.0, 0.0, 0.0, 0.75]); - } - #[test] fn missing_tangents_are_generated_for_indexed_textured_triangle_mesh() { let attrs = [ diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/update/extended_streams.rs b/crates/renderide/src/assets/mesh/gpu_mesh/update/extended_streams.rs index baf837d5a..763131cb8 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/update/extended_streams.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/update/extended_streams.rs @@ -5,11 +5,10 @@ use crate::shared::VertexAttributeType; use super::super::upload::{ ExtendedVertexUploadSource, UvVertexUploadSource, upload_color_vertex_stream, - upload_default_extended_vertex_streams, upload_default_raw_tangent_vertex_stream, - upload_default_tangent_vertex_stream, upload_default_uv_vertex_stream, - upload_default_wide_high_uv_vertex_stream, upload_default_wide_low_uv_vertex_stream, - upload_extended_vertex_streams, upload_position_normal_vertex_streams, - upload_raw_tangent_vertex_stream, upload_tangent_vertex_stream, upload_uv_vertex_stream, + upload_default_extended_vertex_streams, upload_default_tangent_vertex_stream, + upload_default_uv_vertex_stream, upload_default_wide_high_uv_vertex_stream, + upload_default_wide_low_uv_vertex_stream, upload_extended_vertex_streams, + upload_position_normal_vertex_streams, upload_tangent_vertex_stream, upload_uv_vertex_stream, upload_uv0_vertex_stream, upload_wide_high_uv_vertex_stream, upload_wide_low_uv_vertex_stream, }; use super::super::{ @@ -276,54 +275,6 @@ impl GpuMesh { true } - /// Creates a raw tangent payload stream for UI shaders that use `TANGENT` as data. - pub(crate) fn ensure_raw_tangent_vertex_stream(&mut self, device: &wgpu::Device) -> bool { - profiling::scope!("asset::mesh_ensure_raw_tangent_vertex_stream"); - if self.raw_tangent_vertex_stream_ready() { - return true; - } - - let vc_usize = self.vertex_count as usize; - let raw_tangent_buffer = if let Some(source) = self.extended_vertex_stream_source.as_ref() { - upload_raw_tangent_vertex_stream( - device, - self.asset_id, - ExtendedVertexUploadSource { - vertex_slice: source.vertex_bytes.as_ref(), - index_slice: source.index_bytes.as_ref(), - vertex_count: vc_usize, - vertex_stride: self.vertex_stride as usize, - vertex_attributes: source.vertex_attributes.as_ref(), - index_format: source.index_format, - submeshes: source.submeshes.as_ref(), - }, - ) - } else { - upload_default_raw_tangent_vertex_stream(device, self.asset_id, vc_usize) - }; - - let Some(raw_tangent_buffer) = raw_tangent_buffer else { - return false; - }; - let old_bytes = self - .raw_tangent_buffer - .as_ref() - .map_or(0, |buffer| buffer.size()); - self.raw_tangent_buffer = Some(raw_tangent_buffer); - let new_bytes = self - .raw_tangent_buffer - .as_ref() - .map_or(0, |buffer| buffer.size()); - self.resident_bytes = self - .resident_bytes - .saturating_sub(old_bytes) - .saturating_add(new_bytes); - self.derived_stream_state - .mark_clean(MeshDerivedStreamMask::RAW_TANGENT); - self.drop_extended_vertex_stream_source_if_complete(); - true - } - /// Creates a UV1 stream the first time an embedded shader needs it without other extended streams. pub(crate) fn ensure_uv1_vertex_stream(&mut self, device: &wgpu::Device) -> bool { profiling::scope!("asset::mesh_ensure_uv1_vertex_stream"); diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place.rs b/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place.rs index 67bc422e7..7f2019bb9 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place.rs @@ -343,7 +343,6 @@ fn rebuild_mesh_after_in_place_write( uv0_buffer: mesh.uv0_buffer.clone(), color_buffer: mesh.color_buffer.clone(), tangent_buffer: mesh.tangent_buffer.clone(), - raw_tangent_buffer: mesh.raw_tangent_buffer.clone(), tangent_fallback_mode: mesh.tangent_fallback_mode, uv1_buffer: mesh.uv1_buffer.clone(), uv2_buffer: mesh.uv2_buffer.clone(), diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place_buffers.rs b/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place_buffers.rs index d288d6b76..3bce70f80 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place_buffers.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place_buffers.rs @@ -15,9 +15,7 @@ use super::super::super::layout::{ wide_low_uv_stream_bytes, }; use super::super::hints::{blendshape_descriptor_count, derived_streams_compatible_for_in_place}; -use super::super::tangent_generation::{ - TangentStreamSource, raw_tangent_payload_stream_bytes, tangent_stream_bytes, -}; +use super::super::tangent_generation::{TangentStreamSource, tangent_stream_bytes}; use super::super::upload::{ padded_sparse_bytes, queue_init_buffer_size_matches, write_mesh_upload_buffer, }; @@ -177,7 +175,6 @@ enum InPlaceDerivedStreamJob { WideLowUv, WideHighUv, Tangent, - RawTangent, Uv1, Uv2, Uv3, @@ -190,7 +187,6 @@ enum InPlaceDerivedStreamResult { WideLowUv(Option>), WideHighUv(Option>), Tangent(Option>), - RawTangent(Option>), Uv1(Option>), Uv2(Option>), Uv3(Option>), @@ -246,9 +242,6 @@ impl InPlaceDerivedStreamJob { in_place_tangent_source(source), source.generate_missing_tangents, )), - Self::RawTangent => InPlaceDerivedStreamResult::RawTangent( - raw_tangent_payload_stream_bytes(in_place_tangent_source(source)), - ), Self::Uv1 => InPlaceDerivedStreamResult::Uv1(vertex_float2_stream_bytes( source.vertex_slice, source.vertex_count, @@ -339,7 +332,7 @@ pub(super) fn write_in_place_vertex_and_derived_streams( if ctx .demand_mask - .intersects(MeshDerivedStreamMask::TANGENT | MeshDerivedStreamMask::RAW_TANGENT) + .intersects(MeshDerivedStreamMask::TANGENT | MeshDerivedStreamMask::BILLBOARD) { profiling::scope!("asset::mesh_write_in_place::write_tangent_stream"); let source = TangentStreamSource { @@ -352,8 +345,7 @@ pub(super) fn write_in_place_vertex_and_derived_streams( index_format: ctx.data.index_buffer_format, submeshes: &ctx.data.submeshes, }; - if ctx.demand_mask.contains(MeshDerivedStreamMask::TANGENT) - && let Some(tb) = ctx.mesh.tangent_buffer.as_ref() + if let Some(tb) = ctx.mesh.tangent_buffer.as_ref() && let Some(t) = ctx .prepared_derived_streams .and_then(|prepared| prepared.tangent.as_deref()) @@ -365,16 +357,6 @@ pub(super) fn write_in_place_vertex_and_derived_streams( { write_mesh_upload_buffer(ctx.upload_sink, tb.as_ref(), 0, t.as_ref()); } - if ctx.demand_mask.contains(MeshDerivedStreamMask::RAW_TANGENT) - && let Some(tb) = ctx.mesh.raw_tangent_buffer.as_ref() - && let Some(t) = ctx - .prepared_derived_streams - .and_then(|prepared| prepared.raw_tangent.as_deref()) - .map(std::borrow::Cow::Borrowed) - .or_else(|| raw_tangent_payload_stream_bytes(source).map(std::borrow::Cow::Owned)) - { - write_mesh_upload_buffer(ctx.upload_sink, tb.as_ref(), 0, t.as_ref()); - } } if !write_vertex { @@ -382,7 +364,10 @@ pub(super) fn write_in_place_vertex_and_derived_streams( } if ctx.demand_mask.intersects( - MeshDerivedStreamMask::UV1 | MeshDerivedStreamMask::UV2 | MeshDerivedStreamMask::UV3, + MeshDerivedStreamMask::UV1 + | MeshDerivedStreamMask::UV2 + | MeshDerivedStreamMask::UV3 + | MeshDerivedStreamMask::BILLBOARD, ) { write_in_place_uv1_to_uv3_streams(ctx, vertex_slice); } @@ -427,11 +412,6 @@ fn try_write_in_place_derived_streams_parallel( { jobs.push(InPlaceDerivedStreamJob::Tangent); } - if ctx.demand_mask.contains(MeshDerivedStreamMask::RAW_TANGENT) - && ctx.mesh.raw_tangent_buffer.is_some() - { - jobs.push(InPlaceDerivedStreamJob::RawTangent); - } if write_vertex { if ctx.demand_mask.contains(MeshDerivedStreamMask::UV1) && ctx.mesh.uv1_buffer.is_some() { jobs.push(InPlaceDerivedStreamJob::Uv1); @@ -519,12 +499,6 @@ fn write_in_place_derived_stream_result( } } InPlaceDerivedStreamResult::Tangent(None) => {} - InPlaceDerivedStreamResult::RawTangent(Some(bytes)) => { - if let Some(buffer) = ctx.mesh.raw_tangent_buffer.as_ref() { - write_mesh_upload_buffer(ctx.upload_sink, buffer.as_ref(), 0, &bytes); - } - } - InPlaceDerivedStreamResult::RawTangent(None) => {} InPlaceDerivedStreamResult::Uv1(Some(bytes)) => { if let Some(buffer) = ctx.mesh.uv1_buffer.as_ref() { write_mesh_upload_buffer(ctx.upload_sink, buffer.as_ref(), 0, &bytes); diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/update/queries.rs b/crates/renderide/src/assets/mesh/gpu_mesh/update/queries.rs index cf443a928..4a1fb75fd 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/update/queries.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/update/queries.rs @@ -40,14 +40,6 @@ impl GpuMesh { ) } - /// `true` when this mesh has a current raw tangent payload stream for UI payload shaders. - pub fn raw_tangent_vertex_stream_ready(&self) -> bool { - self.derived_stream_state.streams_ready( - self.raw_tangent_buffer.is_some(), - MeshDerivedStreamMask::RAW_TANGENT, - ) - } - /// `true` when this mesh has a current standalone UV2 stream for compact shaders. pub fn uv2_vertex_stream_ready(&self) -> bool { self.derived_stream_state @@ -76,6 +68,14 @@ impl GpuMesh { ) } + /// `true` when this mesh has current billboard payload streams for particles. + pub fn billboard_vertex_streams_ready(&self) -> bool { + self.derived_stream_state.streams_ready( + self.tangent_buffer.is_some() && self.uv1_buffer.is_some(), + MeshDerivedStreamMask::BILLBOARD, + ) + } + /// Returns whether this mesh has every GPU stream needed to produce world-space skinned output. pub fn supports_world_space_skin_deform(&self, bone_transform_indices: Option<&[i32]>) -> bool { bone_transform_indices.is_some() diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/upload.rs b/crates/renderide/src/assets/mesh/gpu_mesh/upload.rs index d66f7ede9..2a9b953f6 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/upload.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/upload.rs @@ -13,11 +13,10 @@ pub(super) use bone_skin::upload_bone_and_skin_buffers; pub(crate) use derived_streams::{PreparedDerivedStreams, prepare_derived_stream_bytes}; pub(super) use extended_streams::{ ExtendedVertexUploadSource, UvVertexUploadSource, upload_color_vertex_stream, - upload_default_extended_vertex_streams, upload_default_raw_tangent_vertex_stream, - upload_default_tangent_vertex_stream, upload_default_uv_vertex_stream, - upload_default_wide_high_uv_vertex_stream, upload_default_wide_low_uv_vertex_stream, - upload_extended_vertex_streams, upload_position_normal_vertex_streams, - upload_raw_tangent_vertex_stream, upload_tangent_vertex_stream, upload_uv_vertex_stream, + upload_default_extended_vertex_streams, upload_default_tangent_vertex_stream, + upload_default_uv_vertex_stream, upload_default_wide_high_uv_vertex_stream, + upload_default_wide_low_uv_vertex_stream, upload_extended_vertex_streams, + upload_position_normal_vertex_streams, upload_tangent_vertex_stream, upload_uv_vertex_stream, upload_uv0_vertex_stream, upload_wide_high_uv_vertex_stream, upload_wide_low_uv_vertex_stream, }; #[cfg(test)] @@ -92,7 +91,6 @@ pub(super) struct DerivedStreams { pub uv0_buffer: Option>, pub color_buffer: Option>, pub tangent_buffer: Option>, - pub raw_tangent_buffer: Option>, pub uv1_buffer: Option>, pub uv2_buffer: Option>, pub uv3_buffer: Option>, @@ -118,9 +116,6 @@ impl DerivedStreams { if self.tangent_buffer.is_some() { mask |= MeshDerivedStreamMask::TANGENT; } - if self.raw_tangent_buffer.is_some() { - mask |= MeshDerivedStreamMask::RAW_TANGENT; - } if self.uv1_buffer.is_some() { mask |= MeshDerivedStreamMask::UV1; } @@ -413,7 +408,6 @@ enum DerivedBufferProfile { Uv0, Color, Tangent, - RawTangent, Uv1, Uv2, Uv3, @@ -429,7 +423,6 @@ impl DerivedBufferProfile { Self::Uv0 => "uv0", Self::Color => "color", Self::Tangent => "tangent", - Self::RawTangent => "raw_tangent", Self::Uv1 => "uv1", Self::Uv2 => "uv2", Self::Uv3 => "uv3", @@ -455,9 +448,6 @@ impl DerivedBufferProfile { Self::Tangent => { crate::profiling::note_resource_churn!(Buffer, "assets::mesh_tangent_stream"); } - Self::RawTangent => { - crate::profiling::note_resource_churn!(Buffer, "assets::mesh_raw_tangent_stream"); - } Self::Uv1 => { crate::profiling::note_resource_churn!(Buffer, "assets::mesh_uv1_stream"); } @@ -583,14 +573,6 @@ fn upload_prepared_derived_streams( usages.tangent, )? .into_buffer(), - raw_tangent_buffer: upload_derived_buffer( - ctx, - asset_id, - DerivedBufferProfile::RawTangent, - prepared.raw_tangent.as_deref(), - usages.tangent, - )? - .into_buffer(), uv1_buffer: upload_derived_buffer( ctx, asset_id, @@ -832,7 +814,6 @@ mod tests { assert_eq!(prepared.uv0.as_deref(), Some(uv0.as_slice())); assert_eq!(prepared.color.as_deref(), Some(color.as_slice())); assert!(prepared.tangent.is_none()); - assert!(prepared.raw_tangent.is_none()); assert!(prepared.uv1.is_none()); assert!(prepared.uv2.is_none()); assert!(prepared.uv3.is_none()); diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/upload/accounting.rs b/crates/renderide/src/assets/mesh/gpu_mesh/upload/accounting.rs index 60d18796d..053dc94de 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/upload/accounting.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/upload/accounting.rs @@ -36,7 +36,6 @@ pub(in crate::assets::mesh::gpu_mesh) fn resident_bytes_for_mesh_upload( derived.uv0_buffer.as_ref(), derived.color_buffer.as_ref(), derived.tangent_buffer.as_ref(), - derived.raw_tangent_buffer.as_ref(), derived.uv1_buffer.as_ref(), derived.uv2_buffer.as_ref(), derived.uv3_buffer.as_ref(), diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/upload/derived_streams.rs b/crates/renderide/src/assets/mesh/gpu_mesh/upload/derived_streams.rs index 44099075a..9a2f911e2 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/upload/derived_streams.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/upload/derived_streams.rs @@ -11,9 +11,7 @@ use super::super::super::layout::{ vertex_float2_stream_bytes, wide_high_uv_stream_bytes, wide_low_uv_stream_bytes, }; use super::super::demand::{MeshDerivedStreamDemand, MeshDerivedStreamMask}; -use super::super::tangent_generation::{ - TangentStreamSource, raw_tangent_payload_stream_bytes, tangent_stream_bytes, -}; +use super::super::tangent_generation::{TangentStreamSource, tangent_stream_bytes}; /// CPU-prepared derived vertex stream bytes for a full mesh upload. #[derive(Clone, Debug, Default)] @@ -28,8 +26,6 @@ pub(crate) struct PreparedDerivedStreams { pub(crate) color: Option>, /// Geometric tangent stream bytes. pub(crate) tangent: Option>, - /// Raw tangent payload bytes. - pub(crate) raw_tangent: Option>, /// UV1 stream bytes. pub(crate) uv1: Option>, /// UV2 stream bytes. @@ -48,7 +44,6 @@ enum DerivedStreamJob { Uv0, Color, Tangent, - RawTangent, Uv1, Uv2, Uv3, @@ -61,7 +56,6 @@ enum DerivedStreamJobResult { Uv0(Option>), Color(Option>), Tangent(Option>), - RawTangent(Option>), Uv1(Option>), Uv2(Option>), Uv3(Option>), @@ -104,11 +98,6 @@ impl DerivedStreamJob { tangent_source(vertex_slice, index_slice, data, vc_usize, vertex_stride_us), demand.tangent_fallback_mode.generate_missing(), )), - Self::RawTangent => { - DerivedStreamJobResult::RawTangent(raw_tangent_payload_stream_bytes( - tangent_source(vertex_slice, index_slice, data, vc_usize, vertex_stride_us), - )) - } Self::Uv1 => DerivedStreamJobResult::Uv1(vertex_float2_stream_bytes( vertex_slice, vc_usize, @@ -157,7 +146,6 @@ impl PreparedDerivedStreams { DerivedStreamJobResult::Uv0(bytes) => self.uv0 = bytes, DerivedStreamJobResult::Color(bytes) => self.color = bytes, DerivedStreamJobResult::Tangent(bytes) => self.tangent = bytes, - DerivedStreamJobResult::RawTangent(bytes) => self.raw_tangent = bytes, DerivedStreamJobResult::Uv1(bytes) => self.uv1 = bytes, DerivedStreamJobResult::Uv2(bytes) => self.uv2 = bytes, DerivedStreamJobResult::Uv3(bytes) => self.uv3 = bytes, @@ -198,9 +186,6 @@ pub(crate) fn prepare_derived_stream_bytes( if demand.mask.contains(MeshDerivedStreamMask::TANGENT) { jobs.push(DerivedStreamJob::Tangent); } - if demand.mask.contains(MeshDerivedStreamMask::RAW_TANGENT) { - jobs.push(DerivedStreamJob::RawTangent); - } if demand.mask.contains(MeshDerivedStreamMask::UV1) { jobs.push(DerivedStreamJob::Uv1); } @@ -301,9 +286,6 @@ impl PreparedDerivedStreams { if self.tangent.is_some() { mask |= MeshDerivedStreamMask::TANGENT; } - if self.raw_tangent.is_some() { - mask |= MeshDerivedStreamMask::RAW_TANGENT; - } if self.uv1.is_some() { mask |= MeshDerivedStreamMask::UV1; } diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/upload/extended_streams.rs b/crates/renderide/src/assets/mesh/gpu_mesh/upload/extended_streams.rs index c7de235da..2453ee7b7 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/upload/extended_streams.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/upload/extended_streams.rs @@ -15,9 +15,7 @@ use super::super::super::layout::{ extract_float3_position_normal_as_vec4_streams, uv0_float2_stream_bytes, vertex_float2_stream_bytes, wide_high_uv_stream_bytes, wide_low_uv_stream_bytes, }; -use super::super::tangent_generation::{ - TangentStreamSource, raw_tangent_payload_stream_bytes, tangent_stream_bytes, -}; +use super::super::tangent_generation::{TangentStreamSource, tangent_stream_bytes}; /// Tangent plus UV1-UV3 optional vertex buffers from extended stream upload. pub(in crate::assets::mesh::gpu_mesh) type ExtendedVertexStreams = ( @@ -411,41 +409,6 @@ pub(in crate::assets::mesh::gpu_mesh) fn upload_tangent_vertex_stream( )) } -/// Uploads the raw tangent payload expected by raw-tangent shaders. -pub(in crate::assets::mesh::gpu_mesh) fn upload_raw_tangent_vertex_stream( - device: &wgpu::Device, - asset_id: i32, - source: ExtendedVertexUploadSource<'_>, -) -> Option> { - if source.vertex_count == 0 { - return None; - } - let tangent_bytes = raw_tangent_payload_stream_bytes(source.tangent_source()) - .unwrap_or_else(|| float4_default_stream_bytes(source.vertex_count, [1.0; 4])); - Some(create_tangent_stream_buffer( - device, - asset_id, - &tangent_bytes, - )) -} - -/// Uploads a raw tangent payload stream filled with default values. -pub(in crate::assets::mesh::gpu_mesh) fn upload_default_raw_tangent_vertex_stream( - device: &wgpu::Device, - asset_id: i32, - vc_usize: usize, -) -> Option> { - if vc_usize == 0 { - return None; - } - let tangent_bytes = float4_default_stream_bytes(vc_usize, [1.0; 4]); - Some(create_tangent_stream_buffer( - device, - asset_id, - &tangent_bytes, - )) -} - /// Uploads a tangent stream filled with default tangent values. pub(in crate::assets::mesh::gpu_mesh) fn upload_default_tangent_vertex_stream( device: &wgpu::Device, diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/upload/generated.rs b/crates/renderide/src/assets/mesh/gpu_mesh/upload/generated.rs index c030507f9..670b87fb3 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/upload/generated.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/upload/generated.rs @@ -212,10 +212,6 @@ fn generated_particle_mesh_input_is_valid( ("positions", prepared.positions.as_deref().unwrap_or(&[])), ("normals", prepared.normals.as_deref().unwrap_or(&[])), ("tangent", prepared.tangent.as_deref().unwrap_or(&[])), - ( - "raw_tangent", - prepared.raw_tangent.as_deref().unwrap_or(&[]), - ), ] { let size = queue_init_buffer_size(bytes.len()); if size > max_buf || size > max_storage { @@ -288,7 +284,6 @@ struct GeneratedPrimaryDerivedBuffers { struct GeneratedExtendedDerivedBuffers { tangent_buffer: Option>, - raw_tangent_buffer: Option>, uv1_buffer: Option>, uv2_buffer: Option>, uv3_buffer: Option>, @@ -365,16 +360,6 @@ fn upload_generated_extended_derived_streams( limits.storage_size_limit, )? .into_buffer(), - raw_tangent_buffer: upload_generated_derived_buffer( - ctx, - existing.and_then(|mesh| mesh.raw_tangent_buffer.as_ref()), - asset_id, - DerivedBufferProfile::RawTangent, - prepared.raw_tangent.as_deref(), - limits.usages.tangent, - limits.storage_size_limit, - )? - .into_buffer(), uv1_buffer: upload_generated_derived_buffer( ctx, existing.and_then(|mesh| mesh.uv1_buffer.as_ref()), @@ -445,7 +430,6 @@ fn upload_generated_derived_streams( uv0_buffer: primary.uv0_buffer, color_buffer: primary.color_buffer, tangent_buffer: extended.tangent_buffer, - raw_tangent_buffer: extended.raw_tangent_buffer, uv1_buffer: extended.uv1_buffer, uv2_buffer: extended.uv2_buffer, uv3_buffer: extended.uv3_buffer, @@ -467,7 +451,6 @@ fn generated_mesh_resident_bytes( derived.uv0_buffer.as_ref(), derived.color_buffer.as_ref(), derived.tangent_buffer.as_ref(), - derived.raw_tangent_buffer.as_ref(), derived.uv1_buffer.as_ref(), derived.uv2_buffer.as_ref(), derived.uv3_buffer.as_ref(), @@ -541,7 +524,6 @@ pub(crate) fn try_upload_generated_mesh_from_parts( uv0_buffer: derived.uv0_buffer, color_buffer: derived.color_buffer, tangent_buffer: derived.tangent_buffer, - raw_tangent_buffer: derived.raw_tangent_buffer, tangent_fallback_mode: EmbeddedTangentFallbackMode::default(), uv1_buffer: derived.uv1_buffer, uv2_buffer: derived.uv2_buffer, diff --git a/crates/renderide/src/assets/mesh/layout.rs b/crates/renderide/src/assets/mesh/layout.rs index 7936dec5b..fff90b6d8 100644 --- a/crates/renderide/src/assets/mesh/layout.rs +++ b/crates/renderide/src/assets/mesh/layout.rs @@ -22,15 +22,14 @@ pub use buffer_layout::{ extract_bind_poses, index_bytes_per_element, }; pub(in crate::assets::mesh) use skinning::split_bone_weights_tail_for_gpu; -#[cfg(test)] -pub use streams::vertex_float4_stream_bytes; pub use streams::{ UV_VERTEX_ATTRIBUTE_TYPES, WIDE_UV_HIGH_VERTEX_STRIDE_BYTES, WIDE_UV_LOW_VERTEX_STRIDE_BYTES, attribute_offset_and_size, color_float4_stream_bytes, - extract_float3_position_normal_as_vec4_streams, raw_float4_stream_bytes, - uv0_float2_stream_bytes, vertex_float2_stream_bytes, wide_high_uv_stream_bytes, - wide_low_uv_stream_bytes, + extract_float3_position_normal_as_vec4_streams, uv0_float2_stream_bytes, + vertex_float2_stream_bytes, wide_high_uv_stream_bytes, wide_low_uv_stream_bytes, }; pub(in crate::assets::mesh) use streams::{ VertexDecodeKind, decode_vertex_vec2, decode_vertex_vec3, decode_vertex_vec4, }; +#[cfg(test)] +pub use streams::{raw_float4_stream_bytes, vertex_float4_stream_bytes}; diff --git a/crates/renderide/src/assets/mesh/layout/streams.rs b/crates/renderide/src/assets/mesh/layout/streams.rs index a4cdc6b6a..d952cdf5c 100644 --- a/crates/renderide/src/assets/mesh/layout/streams.rs +++ b/crates/renderide/src/assets/mesh/layout/streams.rs @@ -36,8 +36,6 @@ pub const WIDE_UV_HIGH_VERTEX_STRIDE_BYTES: usize = WIDE_UV_PAGE_VERTEX_STRIDE_B /// Attribute semantic used when expanding host vertex scalars into float streams. #[derive(Clone, Copy)] pub(in crate::assets::mesh) enum VertexDecodeKind { - /// Data payloads that should preserve the host-authored scalar values. - Raw, /// Object-space position data. Position, /// Direction vectors such as normals and tangents. @@ -379,6 +377,7 @@ fn write_wide_uv_page_vertex( /// Dense `vec4` vertex stream for an arbitrary float attribute. /// /// Missing or unsupported attributes return `default` per vertex. +#[cfg(test)] fn vertex_float4_stream_bytes_with_kind( vertex_data: &[u8], vertex_count: usize, @@ -431,6 +430,7 @@ fn write_vertex_float4( /// Dense raw `vec4` payload stream for attributes used as shader data instead of geometry. /// /// Missing or unsupported attributes return `default` per vertex. +#[cfg(test)] pub fn raw_float4_stream_bytes( vertex_data: &[u8], vertex_count: usize, @@ -446,7 +446,7 @@ pub fn raw_float4_stream_bytes( attrs, target, default, - VertexDecodeKind::Raw, + VertexDecodeKind::Position, ) } @@ -668,7 +668,7 @@ fn apply_unsigned_integer(value: f32, max_value: f32, kind: VertexDecodeKind) -> match kind { VertexDecodeKind::Color => value / max_value, VertexDecodeKind::Direction => (value / max_value).mul_add(2.0, -1.0), - VertexDecodeKind::Raw | VertexDecodeKind::Position | VertexDecodeKind::TexCoord => value, + VertexDecodeKind::Position | VertexDecodeKind::TexCoord => value, } } diff --git a/crates/renderide/src/backend/asset_transfers/mesh_task.rs b/crates/renderide/src/backend/asset_transfers/mesh_task.rs index 4239f97ea..a13d21143 100644 --- a/crates/renderide/src/backend/asset_transfers/mesh_task.rs +++ b/crates/renderide/src/backend/asset_transfers/mesh_task.rs @@ -452,9 +452,7 @@ fn should_prepare_derived_streams_on_worker( } raw_len >= MESH_PREPARE_BACKGROUND_MIN_BYTES || data.vertex_count >= MESH_PREPARE_BACKGROUND_MIN_VERTICES - || demand - .mask - .intersects(MeshDerivedStreamMask::TANGENT | MeshDerivedStreamMask::RAW_TANGENT) + || demand.mask.contains(MeshDerivedStreamMask::TANGENT) } fn spawn_prepare_derived_streams( diff --git a/crates/renderide/src/backend/facade/graph_access/warmup.rs b/crates/renderide/src/backend/facade/graph_access/warmup.rs index fd1e05e86..27cd6391e 100644 --- a/crates/renderide/src/backend/facade/graph_access/warmup.rs +++ b/crates/renderide/src/backend/facade/graph_access/warmup.rs @@ -26,12 +26,12 @@ use super::BackendGraphAccess; struct ViewAssetPrewarmRequests { uv1_stream_meshes: HashSet, tangent_stream_meshes: HashSet, - raw_tangent_stream_meshes: HashSet, tangent_fallback_modes: HashMap, uv2_stream_meshes: HashSet, uv3_stream_meshes: HashSet, wide_low_uv_stream_meshes: HashSet, wide_high_uv_stream_meshes: HashSet, + billboard_stream_meshes: HashSet, derived_stream_demands: HashMap, } @@ -54,10 +54,7 @@ impl ViewAssetPrewarmRequests { if item.batch_key.embedded_needs_color { demand.mask |= MeshDerivedStreamMask::COLOR; } - if item.batch_key.embedded_needs_tangent && item.batch_key.embedded_raw_tangent_payload { - self.raw_tangent_stream_meshes.insert(item.mesh_asset_id); - demand.mask |= MeshDerivedStreamMask::RAW_TANGENT; - } else if item.batch_key.embedded_needs_tangent { + if item.batch_key.embedded_needs_tangent { self.tangent_stream_meshes.insert(item.mesh_asset_id); demand.mask |= MeshDerivedStreamMask::TANGENT; let mode = self @@ -82,6 +79,10 @@ impl ViewAssetPrewarmRequests { self.wide_high_uv_stream_meshes.insert(item.mesh_asset_id); demand.mask |= MeshDerivedStreamMask::WIDE_UV_HIGH; } + if item.batch_key.embedded_uses_billboard_geometry { + self.billboard_stream_meshes.insert(item.mesh_asset_id); + demand.mask |= MeshDerivedStreamMask::BILLBOARD; + } self.derived_stream_demands .entry(item.mesh_asset_id) .or_default() @@ -241,16 +242,16 @@ impl<'a> BackendGraphAccess<'a> { profiling::scope!("graph::pre_warm_view_assets"); let requests = collect_view_asset_prewarm_requests(views); logger::trace!( - "graph pre-warm view assets: views={} uv1_stream_meshes={} tangent_stream_meshes={} raw_tangent_stream_meshes={} generated_tangent_meshes={} uv2_stream_meshes={} uv3_stream_meshes={} wide_low_uv_stream_meshes={} wide_high_uv_stream_meshes={}", + "graph pre-warm view assets: views={} uv1_stream_meshes={} tangent_stream_meshes={} generated_tangent_meshes={} uv2_stream_meshes={} uv3_stream_meshes={} wide_low_uv_stream_meshes={} wide_high_uv_stream_meshes={} billboard_stream_meshes={}", views.len(), requests.uv1_stream_meshes.len(), requests.tangent_stream_meshes.len(), - requests.raw_tangent_stream_meshes.len(), requests.generated_tangent_mesh_count(), requests.uv2_stream_meshes.len(), requests.uv3_stream_meshes.len(), requests.wide_low_uv_stream_meshes.len(), requests.wide_high_uv_stream_meshes.len(), + requests.billboard_stream_meshes.len(), ); let mesh_ids_needing_all_extended_streams = requests.all_extended_stream_meshes(); self.ensure_view_asset_prewarm_requests( @@ -421,27 +422,7 @@ impl<'a> BackendGraphAccess<'a> { } } for (&mesh_asset_id, demand) in &requests.derived_stream_demands { - if demand - .mask - .intersects(MeshDerivedStreamMask::POSITION | MeshDerivedStreamMask::NORMAL) - { - let _ = self - .asset_transfers - .mesh_pool_mut() - .ensure_position_normal_vertex_streams(device, mesh_asset_id); - } - if demand.mask.contains(MeshDerivedStreamMask::UV0) { - let _ = self - .asset_transfers - .mesh_pool_mut() - .ensure_uv0_vertex_stream(device, mesh_asset_id); - } - if demand.mask.contains(MeshDerivedStreamMask::COLOR) { - let _ = self - .asset_transfers - .mesh_pool_mut() - .ensure_color_vertex_stream(device, mesh_asset_id); - } + self.ensure_demands_streams_prewarm_requests(device, mesh_asset_id, demand); } for &mesh_asset_id in mesh_ids_needing_all_extended_streams { let _ = self @@ -475,11 +456,15 @@ impl<'a> BackendGraphAccess<'a> { requests.tangent_fallback_mode(mesh_asset_id), ); } - for &mesh_asset_id in &requests.raw_tangent_stream_meshes { + for &mesh_asset_id in &requests.billboard_stream_meshes { let _ = self .asset_transfers .mesh_pool_mut() - .ensure_raw_tangent_vertex_stream(device, mesh_asset_id); + .ensure_billboard_vertex_streams( + device, + mesh_asset_id, + requests.tangent_fallback_mode(mesh_asset_id), + ); } for &mesh_asset_id in &requests.uv2_stream_meshes { if mesh_ids_needing_all_extended_streams.contains(&mesh_asset_id) { @@ -512,6 +497,35 @@ impl<'a> BackendGraphAccess<'a> { .ensure_wide_high_uv_vertex_stream(device, mesh_asset_id); } } + + fn ensure_demands_streams_prewarm_requests( + &mut self, + device: &wgpu::Device, + mesh_asset_id: i32, + demand: &MeshDerivedStreamDemand, + ) { + if demand + .mask + .intersects(MeshDerivedStreamMask::POSITION | MeshDerivedStreamMask::NORMAL) + { + let _ = self + .asset_transfers + .mesh_pool_mut() + .ensure_position_normal_vertex_streams(device, mesh_asset_id); + } + if demand.mask.contains(MeshDerivedStreamMask::UV0) { + let _ = self + .asset_transfers + .mesh_pool_mut() + .ensure_uv0_vertex_stream(device, mesh_asset_id); + } + if demand.mask.contains(MeshDerivedStreamMask::COLOR) { + let _ = self + .asset_transfers + .mesh_pool_mut() + .ensure_color_vertex_stream(device, mesh_asset_id); + } + } } #[cfg(test)] diff --git a/crates/renderide/src/gpu_pools/pools/mesh.rs b/crates/renderide/src/gpu_pools/pools/mesh.rs index 06e0bdbe5..eaba02019 100644 --- a/crates/renderide/src/gpu_pools/pools/mesh.rs +++ b/crates/renderide/src/gpu_pools/pools/mesh.rs @@ -261,14 +261,16 @@ impl MeshPool { }) } - /// Lazily creates the raw tangent payload buffer for UI shaders declaring `@location(4)`. - pub fn ensure_raw_tangent_vertex_stream( + /// Lazily creates the billboard payload buffers for particle renderers. + pub fn ensure_billboard_vertex_streams( &mut self, device: &wgpu::Device, asset_id: i32, + tangent_fallback_mode: EmbeddedTangentFallbackMode, ) -> bool { self.ensure_stream(asset_id, |mesh| { - mesh.ensure_raw_tangent_vertex_stream(device) + mesh.ensure_tangent_vertex_stream(device, tangent_fallback_mode) + && mesh.ensure_uv1_vertex_stream(device) }) } diff --git a/crates/renderide/src/materials.rs b/crates/renderide/src/materials.rs index bdda97696..069196726 100644 --- a/crates/renderide/src/materials.rs +++ b/crates/renderide/src/materials.rs @@ -83,7 +83,6 @@ mod pipeline_kind; mod pipeline_property_resolver; pub(crate) mod raster_pipeline; mod registry; -mod render_buffer_shader; mod render_queue; mod render_state; mod router; @@ -158,9 +157,6 @@ pub(crate) use pipeline_property_resolver::PipelinePropertyResolver; /// Shader route table, optional material asset registry, and WGSL composition patches. pub(crate) use registry::{MaterialPipelineResolution, MaterialRegistry}; -pub(crate) use render_buffer_shader::{ - ensure_render_buffer_billboard_variant_bits, remap_variant_bits_for_billboard, -}; pub(crate) use router::{MaterialRouter, resolve_raster_pipeline}; /// Static shader feature flags (multiview, etc.) keyed into the pipeline cache. diff --git a/crates/renderide/src/materials/embedded/stem_metadata.rs b/crates/renderide/src/materials/embedded/stem_metadata.rs index 49e44b582..c134a64fe 100644 --- a/crates/renderide/src/materials/embedded/stem_metadata.rs +++ b/crates/renderide/src/materials/embedded/stem_metadata.rs @@ -35,8 +35,7 @@ use crate::materials::{ use self::tangent_fallback::tangent_fallback_mode_for_stem; use self::vertex_streams::{ - derive_vertex_stream_mask, stem_uses_raw_normal_payload, stem_uses_raw_tangent_payload, - stem_uses_ui_transparent_fallback, + derive_vertex_stream_mask, stem_uses_raw_normal_payload, stem_uses_ui_transparent_fallback, }; /// Host material identity and blend/render state for embedded raster pipeline creation (separate from WGSL build inputs). @@ -75,8 +74,6 @@ struct EmbeddedStemMetadata { tangent_fallback_mode: EmbeddedTangentFallbackMode, /// Number of declared material passes submitted for this target. pass_count: usize, - /// Whether `@location(4)` carries raw shader payload rather than a geometric tangent. - uses_raw_tangent_payload: bool, /// Whether `@location(1)` carries raw shader payload rather than a lighting normal. uses_raw_normal_payload: bool, /// Whether this UI stem should fall back to transparent state until host state arrives. @@ -191,11 +188,6 @@ impl EmbeddedStemQuery { self.metadata.tangent_fallback_mode() } - /// `true` when `@location(4)` carries raw shader payload rather than a geometric tangent. - pub fn uses_raw_tangent_payload(&self) -> bool { - self.metadata.uses_raw_tangent_payload - } - /// `true` when `@location(1)` carries raw shader payload rather than a lighting normal. pub fn uses_raw_normal_payload(&self) -> bool { self.metadata.uses_raw_normal_payload @@ -297,7 +289,6 @@ fn embedded_stem_metadata(base_stem: &str, permutation: ShaderPermutation) -> Em snapshot_requirements, tangent_fallback_mode: tangent_fallback_mode_for_stem(base_stem), pass_count: passes.len().max(1), - uses_raw_tangent_payload: stem_uses_raw_tangent_payload(base_stem), uses_raw_normal_payload: stem_uses_raw_normal_payload(base_stem), uses_ui_transparent_fallback: stem_uses_ui_transparent_fallback(base_stem), uses_alpha_blending: passes.iter().any(|p| p.blend.is_some()), @@ -492,7 +483,6 @@ mod tests { snapshot_requirements: SnapshotRequirements::default(), tangent_fallback_mode: EmbeddedTangentFallbackMode::default(), pass_count: 1, - uses_raw_tangent_payload: false, uses_raw_normal_payload: false, uses_ui_transparent_fallback: false, uses_alpha_blending: false, diff --git a/crates/renderide/src/materials/embedded/stem_metadata/vertex_streams.rs b/crates/renderide/src/materials/embedded/stem_metadata/vertex_streams.rs index 14e424d69..e69623f69 100644 --- a/crates/renderide/src/materials/embedded/stem_metadata/vertex_streams.rs +++ b/crates/renderide/src/materials/embedded/stem_metadata/vertex_streams.rs @@ -161,20 +161,6 @@ pub fn embedded_stem_needs_extended_vertex_streams( EmbeddedStemQuery::for_stem(base_stem, permutation).needs_extended_vertex_streams() } -/// `true` when `@location(4)` carries raw shader payload rather than a geometric tangent. -pub(super) fn stem_uses_raw_tangent_payload(base_stem: &str) -> bool { - matches!( - canonical_stem_name(base_stem), - "billboardunlit" | "ui_circlesegment" | "ui_unlit" - ) -} - -/// `true` when `@location(4)` carries raw shader payload rather than a geometric tangent. -#[cfg(test)] -pub fn embedded_stem_uses_raw_tangent_payload(base_stem: &str) -> bool { - stem_uses_raw_tangent_payload(base_stem) -} - /// `true` when `@location(1)` carries raw shader payload rather than a lighting normal. pub(super) fn stem_uses_raw_normal_payload(base_stem: &str) -> bool { matches!( @@ -225,7 +211,7 @@ mod tests { embedded_stem_needs_uv0_stream, embedded_stem_needs_uv1_stream, embedded_stem_needs_uv2_stream, embedded_stem_needs_uv3_stream, embedded_stem_needs_wide_uv_stream, embedded_stem_uses_raw_normal_payload, - embedded_stem_uses_raw_tangent_payload, embedded_stem_uses_ui_transparent_fallback, + embedded_stem_uses_ui_transparent_fallback, }; fn reflected_with_inputs(inputs: Vec) -> ReflectedRasterLayout { @@ -388,17 +374,6 @@ mod tests { #[test] fn ui_payload_stems_mark_raw_semantics() { - for stem in [ - "billboardunlit_default", - "ui_circlesegment_default", - "ui_unlit_default", - ] { - assert!(embedded_stem_uses_raw_tangent_payload(stem), "{stem}"); - } - assert!(!embedded_stem_uses_raw_tangent_payload( - "pbsmetallic_default" - )); - for stem in [ "billboardunlit_default", "textunlit_default", diff --git a/crates/renderide/src/materials/render_buffer_shader.rs b/crates/renderide/src/materials/render_buffer_shader.rs deleted file mode 100644 index 74dec25cc..000000000 --- a/crates/renderide/src/materials/render_buffer_shader.rs +++ /dev/null @@ -1,251 +0,0 @@ -//! Shader routing helpers for PhotonDust render-buffer draws. - -/// Billboard/Unlit variant bit for CPU-expanded PhotonDust render-buffer geometry. -/// -/// When set, `billboardunlit.wgsl` treats per-vertex point sizes as final particle sizes instead -/// of multiplying them by the material `_PointSize`. -pub(crate) const BILLBOARD_RENDER_BUFFER_ABSOLUTE_SIZE_BIT: u32 = 1u32 << 16; -/// Billboard/Unlit variant bit that enables per-particle color and alpha. -pub(crate) const BILLBOARD_RENDER_BUFFER_VERTEX_COLORS_BIT: u32 = 1u32 << 15; -/// Billboard/Unlit variant bit that enables texture sampling. -pub(crate) const BILLBOARD_RENDER_BUFFER_TEXTURE_BIT: u32 = 1u32 << 10; -/// Billboard/Unlit variant bit that enables base color. -pub(crate) const BILLBOARD_RENDER_BUFFER_COLOR_BIT: u32 = 1u32 << 1; -/// Billboard variant bit that enables simple lighting for non-unlit source materials. -pub(crate) const BILLBOARD_RENDER_BUFFER_SIMPLE_LIT_BIT: u32 = 1u32 << 17; - -const BILLBOARD_ALPHA_TEST_BIT: u32 = 1u32; - -pub(crate) fn remap_variant_bits_for_billboard(stem: &str, source_bits: u32) -> u32 { - if is_unlit_family_embedded_stem(stem) { - BILLBOARD_RENDER_BUFFER_VERTEX_COLORS_BIT - | remap_unlit_variant_bits_for_billboard(source_bits) - } else { - BILLBOARD_RENDER_BUFFER_TEXTURE_BIT - | BILLBOARD_RENDER_BUFFER_COLOR_BIT - | BILLBOARD_RENDER_BUFFER_SIMPLE_LIT_BIT - | map_billboard_vertex_color_variant_bits(stem, source_bits) - | map_billboard_alpha_clip_variant_bits(stem, source_bits) - } -} - -/// Enables render-buffer sizing and particle color semantics for synthetic billboard draws. -pub(crate) fn ensure_render_buffer_billboard_variant_bits(bits: u32) -> u32 { - bits | BILLBOARD_RENDER_BUFFER_ABSOLUTE_SIZE_BIT -} - -/// Returns whether `stem` names an embedded Unlit-family shader other than Billboard/Unlit. -fn is_unlit_family_embedded_stem(stem: &str) -> bool { - let lower = stem.to_ascii_lowercase(); - (lower.starts_with("unlit") || lower.contains("_unlit") || lower.contains("unlit_")) - && !lower.contains("billboard") -} - -/// Remaps Froox Unlit keyword bits to Billboard/Unlit keyword bits for material binding. -fn remap_unlit_variant_bits_for_billboard(unlit_bits: u32) -> u32 { - const PAIRS: &[(u32, u32)] = &[ - (0, 0), - (1, 1), - (2, 18), - (3, 19), - (4, 2), - (5, 3), - (6, 4), - (7, 8), - (8, 9), - (9, 10), - (11, 13), - (12, 14), - (13, 15), - ]; - let mut out = 0u32; - for &(from, to) in PAIRS { - if unlit_bits & (1u32 << from) != 0 { - out |= 1u32 << to; - } - } - out -} - -/// Remaps Froox AlphaClip or Cutoff keyword bits to Billboard/Unlit keyword bits -/// for material binding with non-Unlit materials. -fn map_billboard_alpha_clip_variant_bits(stem: &str, source_bits: u32) -> u32 { - let lower = stem.to_ascii_lowercase(); - if lower.starts_with("xstoon2.0-cutout") { - return BILLBOARD_ALPHA_TEST_BIT; - } - const ALPHA_CLIP_TWO: &[&str] = &["pbsmetallic", "pbsspecular"]; - if ALPHA_CLIP_TWO - .iter() - .any(|prefix| lower.starts_with(prefix)) - { - return ((source_bits >> 2) & 1) * BILLBOARD_ALPHA_TEST_BIT; - } - const ALPHA_CLIP_ONE: &[&str] = &[ - "pbsdisplace", - "pbsdualsided_", - "pbsdualsidedspecular_", - "pbslerp", - "pbsslice_", - "pbsslicespecular_", - "pbsvertexcolor", - "xstoon", - ]; - if ALPHA_CLIP_ONE - .iter() - .any(|prefix| lower.starts_with(prefix)) - { - return ((source_bits >> 1) & 1) * BILLBOARD_ALPHA_TEST_BIT; - } - const ALPHA_CLIP_ZERO: &[&str] = &["fresnel_", "pbsmultiuv", "reflection"]; - if ALPHA_CLIP_ZERO - .iter() - .any(|prefix| lower.starts_with(prefix)) - { - return (source_bits & 1) * BILLBOARD_ALPHA_TEST_BIT; - } - 0u32 -} - -/// Remaps Froox Vertex Colors keyword bits to Billboard/Unlit keyword bits -/// for material binding with non-Unlit materials. -fn map_billboard_vertex_color_variant_bits(stem: &str, source_bits: u32) -> u32 { - let lower = stem.to_ascii_lowercase(); - let source_bit: Option = if lower.starts_with("fresnel_") { - Some(10) - } else if lower.starts_with("pbsdualsidedtransparent") { - Some(5) - } else if lower.starts_with("pbsvertexcolor") || lower.starts_with("pbsdualsided") { - Some(6) - } else if lower.starts_with("xstoon") { - Some(8) - } else { - None - }; - - source_bit.map_or(0, |bit| { - ((source_bits >> bit) & 1) * BILLBOARD_RENDER_BUFFER_VERTEX_COLORS_BIT - }) -} - -#[cfg(test)] -mod tests { - use super::*; - - const BILLBOARD_UNLIT_MASK_TEXTURE_CLIP_BIT: u32 = 1u32 << 18; - const BILLBOARD_UNLIT_MASK_TEXTURE_MUL_BIT: u32 = 1u32 << 19; - - #[test] - fn detects_unlit_family_stems() { - assert!(is_unlit_family_embedded_stem("unlit_default")); - assert!(is_unlit_family_embedded_stem("ui_unlit_default")); - assert!(!is_unlit_family_embedded_stem("billboardunlit_default")); - } - - #[test] - fn remaps_unlit_texture_and_color_bits() { - let unlit = (1u32 << 1) | (1u32 << 9); - let billboard = remap_variant_bits_for_billboard("unlit_default", unlit); - - assert_eq!(billboard & (1u32 << 1), 1u32 << 1); - assert_eq!(billboard & (1u32 << 10), 1u32 << 10); - assert_eq!(billboard & (1u32 << 9), 0); - } - - #[test] - fn remaps_unlit_mask_bits_to_billboard_compatibility_bits() { - let unlit = (1u32 << 2) | (1u32 << 3); - let billboard = remap_unlit_variant_bits_for_billboard(unlit); - - assert_eq!( - billboard & BILLBOARD_UNLIT_MASK_TEXTURE_CLIP_BIT, - BILLBOARD_UNLIT_MASK_TEXTURE_CLIP_BIT - ); - assert_eq!( - billboard & BILLBOARD_UNLIT_MASK_TEXTURE_MUL_BIT, - BILLBOARD_UNLIT_MASK_TEXTURE_MUL_BIT - ); - assert_eq!(billboard & (1u32 << 2), 0); - assert_eq!(billboard & (1u32 << 3), 0); - } - - #[test] - fn remaps_pbs_alphaclip_bits() { - let pbs = (1u32 << 2) | (1u32 << 7); - let billboard = remap_variant_bits_for_billboard("pbsmetallic_default", pbs); - - assert_eq!( - billboard, - BILLBOARD_RENDER_BUFFER_COLOR_BIT - | BILLBOARD_RENDER_BUFFER_TEXTURE_BIT - | BILLBOARD_RENDER_BUFFER_SIMPLE_LIT_BIT - | 1u32 - ); - } - - #[test] - fn remaps_pbs_no_alphaclip_bits() { - let pbs = 1u32 << 7; - let billboard = remap_variant_bits_for_billboard("pbsmetallic_default", pbs); - - assert_eq!( - billboard, - BILLBOARD_RENDER_BUFFER_COLOR_BIT - | BILLBOARD_RENDER_BUFFER_TEXTURE_BIT - | BILLBOARD_RENDER_BUFFER_SIMPLE_LIT_BIT - ); - } - - #[test] - fn remaps_supported_non_unlit_vertex_color_bits_to_billboard_vertex_colors() { - for (stem, bit) in [ - ("fresnel_default", 10), - ("pbsdualsidedtransparent_default", 5), - ("pbsdualsidedspecular_default", 6), - ("pbsvertexcolortransparent_default", 6), - ("xstoon2.0_default", 8), - ] { - let billboard = remap_variant_bits_for_billboard(stem, 1u32 << bit); - - assert_eq!( - billboard & BILLBOARD_RENDER_BUFFER_VERTEX_COLORS_BIT, - BILLBOARD_RENDER_BUFFER_VERTEX_COLORS_BIT, - "{stem}" - ); - assert_eq!( - billboard & BILLBOARD_RENDER_BUFFER_SIMPLE_LIT_BIT, - BILLBOARD_RENDER_BUFFER_SIMPLE_LIT_BIT, - "{stem}" - ); - } - } - - #[test] - fn leaves_unsupported_non_unlit_vertex_color_bits_disabled() { - let billboard = remap_variant_bits_for_billboard("pbsmetallic_default", 1u32 << 7); - - assert_eq!(billboard & BILLBOARD_RENDER_BUFFER_VERTEX_COLORS_BIT, 0); - assert_eq!( - billboard & BILLBOARD_RENDER_BUFFER_SIMPLE_LIT_BIT, - BILLBOARD_RENDER_BUFFER_SIMPLE_LIT_BIT - ); - } - - #[test] - fn forces_cutout_for_xiexe_cutout_stems() { - let billboard = remap_variant_bits_for_billboard("xstoon2.0-cutout_default", 0); - - assert_eq!( - billboard & BILLBOARD_ALPHA_TEST_BIT, - BILLBOARD_ALPHA_TEST_BIT - ); - } - - #[test] - fn render_buffer_variant_bit_is_reserved() { - assert_eq!( - ensure_render_buffer_billboard_variant_bits(0), - BILLBOARD_RENDER_BUFFER_ABSOLUTE_SIZE_BIT - ); - } -} diff --git a/crates/renderide/src/particles/point.rs b/crates/renderide/src/particles/point.rs index 0a8411a28..8fed8a03f 100644 --- a/crates/renderide/src/particles/point.rs +++ b/crates/renderide/src/particles/point.rs @@ -190,8 +190,8 @@ fn build_billboard_mesh_input( /// Builds raw orientation streams consumed by Billboard/Unlit render-buffer alignment. pub(super) fn billboard_extra_streams(points: &[PointParticle]) -> GeneratedExtraStreams { let vertex_count = points.len() * BILLBOARD_VERTICES_PER_POINT; - let mut raw_tangent = vec![0u8; vertex_count * 16]; - let mut uv1 = vec![0u8; vertex_count * 8]; + let mut point_forward_upz = vec![0u8; vertex_count * 16]; + let mut point_up_xy = vec![0u8; vertex_count * 8]; for (point_index, point) in points.iter().enumerate() { let forward = point.rotation * Vec3::Z; let up = point.rotation * Vec3::Y; @@ -200,15 +200,15 @@ pub(super) fn billboard_extra_streams(points: &[PointParticle]) -> GeneratedExtr for corner_index in 0..BILLBOARD_VERTICES_PER_POINT { let vertex_index = point_index * BILLBOARD_VERTICES_PER_POINT + corner_index; let tangent_start = vertex_index * 16; - raw_tangent[tangent_start..tangent_start + 16] + point_forward_upz[tangent_start..tangent_start + 16] .copy_from_slice(bytemuck::cast_slice(&tangent)); let uv1_start = vertex_index * 8; - uv1[uv1_start..uv1_start + 8].copy_from_slice(bytemuck::cast_slice(&up_xy)); + point_up_xy[uv1_start..uv1_start + 8].copy_from_slice(bytemuck::cast_slice(&up_xy)); } } GeneratedExtraStreams { - raw_tangent: Some(raw_tangent), - uv1: Some(uv1), + point_forward_upz: Some(point_forward_upz), + point_up_xy: Some(point_up_xy), } } diff --git a/crates/renderide/src/particles/tests.rs b/crates/renderide/src/particles/tests.rs index eab02c5ec..36e11b41c 100644 --- a/crates/renderide/src/particles/tests.rs +++ b/crates/renderide/src/particles/tests.rs @@ -217,8 +217,8 @@ fn billboard_extra_streams_pack_particle_orientation() { }]; let streams = billboard_extra_streams(&points); - let raw_tangent = streams.raw_tangent.as_deref().expect("raw tangent"); - let uv1 = streams.uv1.as_deref().expect("uv1"); + let raw_tangent = streams.point_forward_upz.as_deref().expect("raw tangent"); + let uv1 = streams.point_up_xy.as_deref().expect("uv1"); let tangent: &[f32] = bytemuck::cast_slice(&raw_tangent[..16]); let up_xy: &[f32] = bytemuck::cast_slice(&uv1[..8]); diff --git a/crates/renderide/src/particles/upload.rs b/crates/renderide/src/particles/upload.rs index b19b2f2d6..e3d583e2e 100644 --- a/crates/renderide/src/particles/upload.rs +++ b/crates/renderide/src/particles/upload.rs @@ -16,9 +16,13 @@ use super::types::ParticleRenderBufferError; #[derive(Debug, Default)] pub(super) struct GeneratedExtraStreams { /// Raw tangent payload stream at shader location 4. - pub(super) raw_tangent: Option>, + /// Overloaded by particle system to hold the forward direction of the particle + /// and the Z component of its up direction. + pub(super) point_forward_upz: Option>, /// UV1 stream at shader location 5. - pub(super) uv1: Option>, + /// Overloaded by particle system to hold the XY components + /// of the up direction of the particle. + pub(super) point_up_xy: Option>, } pub(super) fn generated_vertex_stride() -> usize { @@ -96,8 +100,8 @@ pub(super) fn prepared_generated_derived_streams( normals: Some(normals), uv0: Some(uv0), color: Some(color), - raw_tangent: extra.raw_tangent, - uv1: extra.uv1, + tangent: extra.point_forward_upz, + uv1: extra.point_up_xy, ..PreparedDerivedStreams::default() } } diff --git a/crates/renderide/src/passes/world_mesh_forward/encode/vertex_binding.rs b/crates/renderide/src/passes/world_mesh_forward/encode/vertex_binding.rs index 4bf4edbdd..8d8c06523 100644 --- a/crates/renderide/src/passes/world_mesh_forward/encode/vertex_binding.rs +++ b/crates/renderide/src/passes/world_mesh_forward/encode/vertex_binding.rs @@ -19,8 +19,6 @@ pub(super) struct EmbeddedVertexStreamFlags { embedded_color: bool, /// Tangent at `@location(4)`. embedded_tangent: bool, - /// Whether `@location(4)` carries raw shader payload instead of a geometric tangent. - embedded_raw_tangent_payload: bool, /// Whether `@location(1)` carries raw shader payload instead of a lighting normal. embedded_raw_normal_payload: bool, /// UV1 at `@location(5)`. @@ -29,6 +27,8 @@ pub(super) struct EmbeddedVertexStreamFlags { embedded_uv2: bool, /// UV3 at `@location(7)`. embedded_uv3: bool, + /// Billboard forward and up vecrots at @location(8) and @location(9) + embedded_billboard_geometry: bool, /// Packed UV0-UV3 stream. embedded_wide_low_uvs: bool, /// Packed UV4-UV7 stream. @@ -332,20 +332,7 @@ fn resident_draw_mesh<'a>( return None; } let mesh = gpu.mesh_pool.get(item.mesh_asset_id)?; - if streams.embedded_tangent - && streams.embedded_raw_tangent_payload - && !mesh.raw_tangent_vertex_stream_ready() - { - logger::trace!( - "WorldMeshForward: raw tangent payload stream missing for mesh_asset_id {}; draw skipped until pre-warm catches up", - item.mesh_asset_id - ); - return None; - } - if streams.embedded_tangent - && !streams.embedded_raw_tangent_payload - && !mesh.tangent_vertex_stream_ready() - { + if streams.embedded_tangent && !mesh.tangent_vertex_stream_ready() { logger::trace!( "WorldMeshForward: tangent vertex stream missing for mesh_asset_id {}; draw skipped until pre-warm catches up", item.mesh_asset_id @@ -387,6 +374,13 @@ fn resident_draw_mesh<'a>( ); return None; } + if streams.embedded_billboard_geometry && !mesh.billboard_vertex_streams_ready() { + logger::trace!( + "WorldMeshForward: billboard vertex streams missing for mesh_asset_id {}; draw skipped until pre-warm catches up", + item.mesh_asset_id + ); + return None; + } mesh.debug_streams_ready().then_some(mesh) } @@ -654,7 +648,7 @@ fn bind_optional_vertex_streams( ); } if let Some(slot) = streams.tangent_slot() - && !bind_tangent_stream(rpass, item, gpu, mesh, streams, slot, last_mesh) + && !bind_tangent_stream(rpass, item, gpu, mesh, slot, last_mesh) { return false; } @@ -702,24 +696,9 @@ fn bind_tangent_stream( item: &WorldMeshDrawItem, gpu: WorldMeshDrawGpuRefs<'_>, mesh: &GpuMesh, - streams: EmbeddedVertexStreamFlags, slot: usize, last_mesh: &mut LastMeshBindState, ) -> bool { - if streams.embedded_raw_tangent_payload { - let Some(tangent) = mesh.raw_tangent_buffer.as_deref() else { - return false; - }; - bind_vertex_if_changed!( - rpass, - slot, - tangent.slice(..), - BufferBindId::full(tangent), - last_mesh.vertex - ); - return true; - } - if draw_uses_deformed_tangent_stream(item, mesh) { let Some(cache) = gpu.skin_cache else { return false; @@ -797,11 +776,11 @@ pub(super) fn streams_for_item(item: &WorldMeshDrawItem) -> EmbeddedVertexStream embedded_uv: item.batch_key.embedded_needs_uv0, embedded_color: item.batch_key.embedded_needs_color, embedded_tangent: item.batch_key.embedded_needs_tangent, - embedded_raw_tangent_payload: item.batch_key.embedded_raw_tangent_payload, embedded_raw_normal_payload: item.batch_key.embedded_raw_normal_payload, embedded_uv1: item.batch_key.embedded_needs_uv1, embedded_uv2: item.batch_key.embedded_needs_uv2, embedded_uv3: item.batch_key.embedded_needs_uv3, + embedded_billboard_geometry: item.batch_key.embedded_uses_billboard_geometry, embedded_wide_low_uvs: item.batch_key.embedded_needs_wide_low_uvs, embedded_wide_high_uvs: item.batch_key.embedded_needs_wide_high_uvs, } diff --git a/crates/renderide/src/passes/world_mesh_forward/material_batch.rs b/crates/renderide/src/passes/world_mesh_forward/material_batch.rs index 7fe2326d9..5322568e9 100644 --- a/crates/renderide/src/passes/world_mesh_forward/material_batch.rs +++ b/crates/renderide/src/passes/world_mesh_forward/material_batch.rs @@ -23,7 +23,6 @@ use crate::materials::{ MaterialBlendMode, MaterialPipelineDesc, MaterialPipelineResolution, MaterialPipelineSet, MaterialPipelineVariantSpec, MaterialRegistry, MaterialRenderState, MaterialShaderSpecializationKey, RasterFrontFace, RasterPipelineKind, RasterPrimitiveTopology, - ensure_render_buffer_billboard_variant_bits, remap_variant_bits_for_billboard, }; use crate::passes::WorldMeshForwardEncodeRefs; use crate::render_graph::frame_upload_batch::GraphUploadSink; @@ -37,6 +36,9 @@ const MATERIAL_BATCH_PARALLEL_MIN_RUNS: usize = MATERIAL_BATCH_PARALLEL_CHUNK_RU /// Throttles repeated embedded-bind failures so a single bad material cannot flood logs. static EMBEDDED_MATERIAL_BIND_FAILURE_LOG: LogThrottle = LogThrottle::new(); +/// Generic variant bit used by all shaders compatible with particle system rendering. +const BILLBOARD_RENDER_BUFFER_BIT: u32 = 1u32 << 24; + /// Inclusive `(first_draw_idx, last_draw_idx)` span over the sorted world-mesh draw list /// identifying one contiguous material batch run. pub(crate) type MaterialBatchBoundary = (usize, usize); @@ -453,7 +455,7 @@ impl<'a> MaterialDrawResolver<'a> { )); }; - let shader_variant_bits = self.resolve_embedded_shader_variant_bits(item, stem); + let shader_variant_bits = self.resolve_embedded_shader_variant_bits(item); let (bind_key, bind_group) = bind.embedded_material_bind_group_with_cache_key( EmbeddedMaterialBindShader { stem, @@ -473,29 +475,15 @@ impl<'a> MaterialDrawResolver<'a> { } /// Resolves source shader variant bits for a possibly rerouted embedded draw. - fn resolve_embedded_shader_variant_bits( - &self, - item: &WorldMeshDrawItem, - stem: &str, - ) -> Option { + fn resolve_embedded_shader_variant_bits(&self, item: &WorldMeshDrawItem) -> Option { let batch_key = &item.batch_key; let source_bits = self .registry .and_then(|registry| registry.variant_bits_for_shader_asset(batch_key.shader_asset_id)); - if !stem.starts_with("billboardunlit") { - return source_bits; - } - let mut bits = source_bits.unwrap_or(0); - if let Some(source_stem) = self - .registry - .and_then(|registry| registry.stem_for_shader_asset(batch_key.shader_asset_id)) - { - bits = remap_variant_bits_for_billboard(source_stem, bits); - } if crate::particles::is_generated_billboard_mesh_asset_id(item.mesh_asset_id) { - Some(ensure_render_buffer_billboard_variant_bits(bits)) + Some(source_bits.unwrap_or(0) | BILLBOARD_RENDER_BUFFER_BIT) } else { - source_bits.map(|_| bits) + source_bits } } diff --git a/crates/renderide/src/world_mesh/draw_prep/collect/candidate.rs b/crates/renderide/src/world_mesh/draw_prep/collect/candidate.rs index 72d544a5f..75dbd1529 100644 --- a/crates/renderide/src/world_mesh/draw_prep/collect/candidate.rs +++ b/crates/renderide/src/world_mesh/draw_prep/collect/candidate.rs @@ -88,11 +88,7 @@ pub(super) fn evaluate_draw_candidate( shader_perm: ctx.materials.shader_perm, }, ); - apply_render_buffer_mesh_pipeline_override( - &mut batch_key, - candidate.mesh_asset_id, - ctx.materials.shader_perm, - ); + apply_render_buffer_mesh_pipeline_override(&mut batch_key, candidate.mesh_asset_id); // Per-slot UI rect-mask CPU cull: the per-renderer cull above runs once per renderer (and // bypasses overlay anyway), so the actual rect-vs-viewport check has to live here, where // `_Rect` / `_RectClip` are finally known per material slot. Without this, every off-screen diff --git a/crates/renderide/src/world_mesh/draw_prep/tests.rs b/crates/renderide/src/world_mesh/draw_prep/tests.rs index d4362be02..aaf16cdfa 100644 --- a/crates/renderide/src/world_mesh/draw_prep/tests.rs +++ b/crates/renderide/src/world_mesh/draw_prep/tests.rs @@ -144,7 +144,6 @@ fn property_block_splits_batch_keys() { embedded_needs_uv1: false, embedded_needs_tangent: false, embedded_tangent_fallback_mode: Default::default(), - embedded_raw_tangent_payload: false, embedded_raw_normal_payload: false, embedded_needs_uv2: false, embedded_needs_uv3: false, @@ -154,6 +153,7 @@ fn property_block_splits_batch_keys() { embedded_requires_intersection_pass: false, embedded_uses_scene_depth_snapshot: false, embedded_uses_scene_color_snapshot: false, + embedded_uses_billboard_geometry: false, scene_color_snapshot_mode: Default::default(), render_queue: UNITY_RENDER_QUEUE_GEOMETRY, render_state: Default::default(), @@ -175,7 +175,6 @@ fn property_block_splits_batch_keys() { embedded_needs_uv1: false, embedded_needs_tangent: false, embedded_tangent_fallback_mode: Default::default(), - embedded_raw_tangent_payload: false, embedded_raw_normal_payload: false, embedded_needs_uv2: false, embedded_needs_uv3: false, @@ -185,6 +184,7 @@ fn property_block_splits_batch_keys() { embedded_requires_intersection_pass: false, embedded_uses_scene_depth_snapshot: false, embedded_uses_scene_color_snapshot: false, + embedded_uses_billboard_geometry: false, scene_color_snapshot_mode: Default::default(), render_queue: UNITY_RENDER_QUEUE_GEOMETRY, render_state: Default::default(), diff --git a/crates/renderide/src/world_mesh/materials/key.rs b/crates/renderide/src/world_mesh/materials/key.rs index 90d77fa01..834e04bf4 100644 --- a/crates/renderide/src/world_mesh/materials/key.rs +++ b/crates/renderide/src/world_mesh/materials/key.rs @@ -42,8 +42,6 @@ pub struct MaterialDrawBatchKey { pub embedded_needs_tangent: bool, /// Tangent fallback policy for lazy tangent upload. pub embedded_tangent_fallback_mode: EmbeddedTangentFallbackMode, - /// Whether the tangent stream carries raw shader payload instead of a geometric tangent. - pub embedded_raw_tangent_payload: bool, /// Whether the normal stream carries raw shader payload instead of a lighting normal. pub embedded_raw_normal_payload: bool, /// Whether the embedded stem needs a UV2 vertex stream at `@location(6)`. @@ -62,6 +60,8 @@ pub struct MaterialDrawBatchKey { pub embedded_uses_scene_depth_snapshot: bool, /// Whether the shader samples the scene-color snapshot through frame globals. pub embedded_uses_scene_color_snapshot: bool, + /// Whether the shader needs to generate billboard geometry from vertex indices for particles. + pub embedded_uses_billboard_geometry: bool, /// How the shader expects scene-color snapshots to be refreshed. pub scene_color_snapshot_mode: SceneColorSnapshotMode, /// Effective Unity render queue after material override / fallback resolution. diff --git a/crates/renderide/src/world_mesh/materials/resolve.rs b/crates/renderide/src/world_mesh/materials/resolve.rs index 32a5ba815..9f2a6c81a 100644 --- a/crates/renderide/src/world_mesh/materials/resolve.rs +++ b/crates/renderide/src/world_mesh/materials/resolve.rs @@ -1,7 +1,5 @@ //! Material batch-key resolution for world-mesh draw prep. -use std::sync::Arc; - use crate::materials::ShaderPermutation; use crate::materials::host_data::{MaterialDictionary, MaterialPropertyLookupIds}; use crate::materials::{ @@ -52,8 +50,6 @@ pub(crate) struct ResolvedMaterialBatch { pub embedded_needs_tangent: bool, /// Tangent fallback policy for lazy tangent upload. pub embedded_tangent_fallback_mode: EmbeddedTangentFallbackMode, - /// Whether the tangent stream carries raw shader payload instead of a geometric tangent. - pub embedded_raw_tangent_payload: bool, /// Whether the normal stream carries raw shader payload instead of a lighting normal. pub embedded_raw_normal_payload: bool, /// Whether the active shader permutation requires a UV2 vertex stream. @@ -72,6 +68,8 @@ pub(crate) struct ResolvedMaterialBatch { pub embedded_uses_scene_depth_snapshot: bool, /// Whether the active shader permutation declares a scene-color snapshot binding. pub embedded_uses_scene_color_snapshot: bool, + /// Whether the shader needs to generate billboard geometry from vertex indices for particles. + pub embedded_uses_billboard_geometry: bool, /// How the active shader permutation expects scene-color snapshots to be refreshed. pub scene_color_snapshot_mode: SceneColorSnapshotMode, /// Renderer-local transparent behavior class inferred from resolved material state. @@ -126,7 +124,6 @@ struct EmbeddedMaterialFeatures { needs_uv1: bool, needs_tangent: bool, tangent_fallback_mode: EmbeddedTangentFallbackMode, - raw_tangent_payload: bool, raw_normal_payload: bool, needs_uv2: bool, needs_uv3: bool, @@ -162,7 +159,6 @@ fn embedded_material_features( needs_uv1: vertex_streams.uv1, needs_tangent: vertex_streams.tangent, tangent_fallback_mode: query.tangent_fallback_mode(), - raw_tangent_payload: query.uses_raw_tangent_payload(), raw_normal_payload: query.uses_raw_normal_payload(), needs_uv2: vertex_streams.uv2, needs_uv3: vertex_streams.uv3, @@ -314,7 +310,6 @@ pub(crate) fn resolve_material_batch( embedded_needs_uv1: embedded.needs_uv1, embedded_needs_tangent: embedded.needs_tangent, embedded_tangent_fallback_mode: embedded.tangent_fallback_mode, - embedded_raw_tangent_payload: embedded.raw_tangent_payload, embedded_raw_normal_payload: embedded.raw_normal_payload, embedded_needs_uv2: embedded.needs_uv2, embedded_needs_uv3: embedded.needs_uv3, @@ -325,6 +320,7 @@ pub(crate) fn resolve_material_batch( embedded_uses_scene_depth_snapshot: embedded.uses_scene_depth_snapshot, embedded_uses_scene_color_snapshot: embedded.uses_scene_color_snapshot, scene_color_snapshot_mode: embedded.scene_color_snapshot_mode, + embedded_uses_billboard_geometry: false, transparent_class, blend_mode, render_queue, @@ -334,12 +330,6 @@ pub(crate) fn resolve_material_batch( } } -/// WGSL stem used for generated PhotonDust billboard mesh draws. -const RENDER_BUFFER_BILLBOARD_STEM: &str = "billboardunlit_default"; - -const RENDER_BUFFER_ORDERED_ALPHA_FALLBACK_BLEND: MaterialBlendMode = - MaterialBlendMode::UnityBlend { src: 5, dst: 10 }; - /// Routes generated PhotonDust billboard meshes through Billboard/Unlit. /// /// Point render-buffer uploads expand each particle into four co-located quad vertices. Ordinary @@ -348,66 +338,12 @@ const RENDER_BUFFER_ORDERED_ALPHA_FALLBACK_BLEND: MaterialBlendMode = pub(crate) fn apply_render_buffer_mesh_pipeline_override( batch_key: &mut MaterialDrawBatchKey, mesh_asset_id: i32, - shader_perm: ShaderPermutation, ) { if !crate::particles::is_generated_billboard_mesh_asset_id(mesh_asset_id) { return; } - if let RasterPipelineKind::EmbeddedStem(stem) = &batch_key.pipeline - && stem.as_ref().starts_with("billboardunlit") - { - batch_key.shader_specialization = MaterialShaderSpecializationKey::disabled(); - return; - } - let pipeline = RasterPipelineKind::EmbeddedStem(Arc::from(RENDER_BUFFER_BILLBOARD_STEM)); - let features = embedded_material_features(&pipeline, shader_perm); - batch_key.pipeline = pipeline; batch_key.shader_specialization = MaterialShaderSpecializationKey::disabled(); - batch_key.embedded_needs_uv0 = features.needs_uv0; - batch_key.embedded_needs_color = features.needs_color; - batch_key.embedded_needs_uv1 = features.needs_uv1; - batch_key.embedded_needs_tangent = features.needs_tangent; - batch_key.embedded_tangent_fallback_mode = features.tangent_fallback_mode; - batch_key.embedded_raw_tangent_payload = features.raw_tangent_payload; - batch_key.embedded_raw_normal_payload = features.raw_normal_payload; - batch_key.embedded_needs_uv2 = features.needs_uv2; - batch_key.embedded_needs_uv3 = features.needs_uv3; - batch_key.embedded_needs_wide_low_uvs = features.needs_wide_low_uvs; - batch_key.embedded_needs_wide_high_uvs = features.needs_wide_high_uvs; - batch_key.embedded_needs_extended_vertex_streams = features.needs_extended_vertex_streams; - batch_key.embedded_requires_intersection_pass = features.requires_intersection_pass; - batch_key.embedded_uses_scene_depth_snapshot = features.uses_scene_depth_snapshot; - batch_key.embedded_uses_scene_color_snapshot = features.uses_scene_color_snapshot; - batch_key.scene_color_snapshot_mode = features.scene_color_snapshot_mode; - batch_key.alpha_blended = batch_key.alpha_blended - || features.uses_alpha_blending - || features.uses_scene_color_snapshot; - batch_key.transparent_class = transparent_class_for_material(TransparentMaterialClassInput { - render_queue: batch_key.render_queue, - render_state: batch_key.render_state, - blend_mode: batch_key.blend_mode, - alpha_blended: batch_key.alpha_blended, - uses_scene_color_snapshot: features.uses_scene_color_snapshot, - uses_blended_depth_write: features.uses_blended_depth_write, - uses_two_sided_transparency: features.uses_two_sided_transparency, - }); - batch_key.blend_mode = render_buffer_billboard_blend_mode_for_source( - batch_key.blend_mode, - batch_key.transparent_class, - ); -} - -fn render_buffer_billboard_blend_mode_for_source( - blend_mode: MaterialBlendMode, - transparent_class: TransparentMaterialClass, -) -> MaterialBlendMode { - if blend_mode == MaterialBlendMode::StemDefault - && transparent_class == TransparentMaterialClass::OrderedAlpha - { - RENDER_BUFFER_ORDERED_ALPHA_FALLBACK_BLEND - } else { - blend_mode - } + batch_key.embedded_uses_billboard_geometry = true; } /// Assembles a [`MaterialDrawBatchKey`] from a pre-resolved [`ResolvedMaterialBatch`] entry. @@ -434,7 +370,6 @@ fn batch_key_from_resolved( embedded_needs_uv1: r.embedded_needs_uv1, embedded_needs_tangent: r.embedded_needs_tangent, embedded_tangent_fallback_mode: r.embedded_tangent_fallback_mode, - embedded_raw_tangent_payload: r.embedded_raw_tangent_payload, embedded_raw_normal_payload: r.embedded_raw_normal_payload, embedded_needs_uv2: r.embedded_needs_uv2, embedded_needs_uv3: r.embedded_needs_uv3, @@ -444,6 +379,7 @@ fn batch_key_from_resolved( embedded_requires_intersection_pass: r.embedded_requires_intersection_pass, embedded_uses_scene_depth_snapshot: r.embedded_uses_scene_depth_snapshot, embedded_uses_scene_color_snapshot: r.embedded_uses_scene_color_snapshot, + embedded_uses_billboard_geometry: r.embedded_uses_billboard_geometry, scene_color_snapshot_mode: r.scene_color_snapshot_mode, render_queue: r.render_queue, render_state: r.render_state, @@ -467,6 +403,7 @@ mod ui_rect_clip_tests { UNITY_RENDER_QUEUE_GEOMETRY, UNITY_RENDER_QUEUE_OVERLAY, UNITY_RENDER_QUEUE_TRANSPARENT, }; use crate::shared::TrailTextureMode; + use std::sync::Arc; struct Fixture { registry: PropertyIdRegistry, @@ -602,7 +539,6 @@ mod ui_rect_clip_tests { assert!(resolved.alpha_blended); assert_eq!(resolved.render_queue, UNITY_RENDER_QUEUE_TRANSPARENT); - assert!(resolved.embedded_raw_tangent_payload); } #[test] @@ -777,11 +713,7 @@ mod ui_rect_clip_tests { ); let mesh_asset_id = crate::particles::billboard_render_buffer_mesh_asset_id(3).unwrap(); - apply_render_buffer_mesh_pipeline_override( - &mut key, - mesh_asset_id, - ShaderPermutation::default(), - ); + apply_render_buffer_mesh_pipeline_override(&mut key, mesh_asset_id); let RasterPipelineKind::EmbeddedStem(stem) = &key.pipeline else { panic!("expected embedded billboard pipeline"); @@ -790,127 +722,8 @@ mod ui_rect_clip_tests { assert!(key.embedded_needs_uv0); assert!(key.embedded_needs_color); assert!(key.embedded_needs_tangent); - assert!(key.embedded_raw_tangent_payload); assert!(key.embedded_raw_normal_payload); - } - - #[test] - fn generated_billboard_mesh_preserves_transparent_material_class() { - let registry = PropertyIdRegistry::new(); - let src = registry.intern("_SrcBlend"); - let dst = registry.intern("_DstBlend"); - let render_queue = registry.intern("_RenderQueue"); - let mut store = MaterialPropertyStore::new(); - store.set_shader_asset_for_material(7, 99); - store.set_material(7, src, MaterialPropertyValue::Float(5.0)); - store.set_material(7, dst, MaterialPropertyValue::Float(10.0)); - store.set_material( - 7, - render_queue, - MaterialPropertyValue::Float(UNITY_RENDER_QUEUE_TRANSPARENT as f32), - ); - let dict = MaterialDictionary::new(&store); - let mut router = MaterialRouter::new(RasterPipelineKind::Null); - router.set_shader_pipeline( - 99, - RasterPipelineKind::EmbeddedStem(Arc::from("unlit_default")), - ); - let ids = MaterialPipelinePropertyIds::new(®istry); - let resolved = - resolve_material_batch(7, None, &dict, &router, &ids, ShaderPermutation::default()); - let mut key = batch_key_from_resolved( - 7, - None, - false, - RasterFrontFace::Clockwise, - RasterPrimitiveTopology::TriangleList, - &resolved, - ); - let mesh_asset_id = crate::particles::billboard_render_buffer_mesh_asset_id(3).unwrap(); - - apply_render_buffer_mesh_pipeline_override( - &mut key, - mesh_asset_id, - ShaderPermutation::default(), - ); - - assert!(key.alpha_blended); - assert_eq!(key.render_queue, UNITY_RENDER_QUEUE_TRANSPARENT); - assert!(key.transparent_class.is_transparent()); - } - - #[test] - fn generated_billboard_mesh_uses_alpha_blend_for_stem_default_ordered_transparency() { - let registry = PropertyIdRegistry::new(); - let render_queue = registry.intern("_RenderQueue"); - let mut store = MaterialPropertyStore::new(); - store.set_shader_asset_for_material(7, 99); - store.set_material( - 7, - render_queue, - MaterialPropertyValue::Float(UNITY_RENDER_QUEUE_TRANSPARENT as f32), - ); - let dict = MaterialDictionary::new(&store); - let mut router = MaterialRouter::new(RasterPipelineKind::Null); - router.set_shader_pipeline( - 99, - RasterPipelineKind::EmbeddedStem(Arc::from("pbsvertexcolortransparent_default")), - ); - let ids = MaterialPipelinePropertyIds::new(®istry); - let resolved = - resolve_material_batch(7, None, &dict, &router, &ids, ShaderPermutation::default()); - let mut key = batch_key_from_resolved( - 7, - None, - false, - RasterFrontFace::Clockwise, - RasterPrimitiveTopology::TriangleList, - &resolved, - ); - let mesh_asset_id = crate::particles::billboard_render_buffer_mesh_asset_id(3).unwrap(); - - assert_eq!(key.blend_mode, MaterialBlendMode::StemDefault); - assert_eq!( - key.transparent_class, - TransparentMaterialClass::OrderedAlpha - ); - - apply_render_buffer_mesh_pipeline_override( - &mut key, - mesh_asset_id, - ShaderPermutation::default(), - ); - - assert_eq!(key.blend_mode, RENDER_BUFFER_ORDERED_ALPHA_FALLBACK_BLEND); - assert_eq!( - key.transparent_class, - TransparentMaterialClass::OrderedAlpha - ); - } - - #[test] - fn render_buffer_billboard_blend_fallback_keeps_explicit_and_non_ordered_modes() { - assert_eq!( - render_buffer_billboard_blend_mode_for_source( - MaterialBlendMode::UnityBlend { src: 1, dst: 1 }, - TransparentMaterialClass::OrderedAlpha, - ), - MaterialBlendMode::UnityBlend { src: 1, dst: 1 } - ); - assert_eq!( - render_buffer_billboard_blend_mode_for_source( - MaterialBlendMode::Opaque, - TransparentMaterialClass::OrderedAlpha, - ), - MaterialBlendMode::Opaque - ); - assert_eq!( - render_buffer_billboard_blend_mode_for_source( - MaterialBlendMode::StemDefault, - TransparentMaterialClass::DepthWritingTransparent, - ), - MaterialBlendMode::StemDefault - ); + assert!(key.embedded_uses_billboard_geometry); } #[test] @@ -939,11 +752,7 @@ mod ui_rect_clip_tests { crate::particles::trail_render_buffer_mesh_asset_id(3, TrailTextureMode::Stretch) .unwrap(); - apply_render_buffer_mesh_pipeline_override( - &mut key, - mesh_asset_id, - ShaderPermutation::default(), - ); + apply_render_buffer_mesh_pipeline_override(&mut key, mesh_asset_id); assert_eq!(key.pipeline, original); } diff --git a/crates/renderide/src/world_mesh/test_fixtures.rs b/crates/renderide/src/world_mesh/test_fixtures.rs index fc33a906c..a8f39aea4 100644 --- a/crates/renderide/src/world_mesh/test_fixtures.rs +++ b/crates/renderide/src/world_mesh/test_fixtures.rs @@ -75,7 +75,6 @@ pub fn dummy_world_mesh_draw_item(spec: DummyDrawItemSpec) -> WorldMeshDrawItem embedded_needs_uv1: false, embedded_needs_tangent: false, embedded_tangent_fallback_mode: Default::default(), - embedded_raw_tangent_payload: false, embedded_raw_normal_payload: false, embedded_needs_uv2: false, embedded_needs_uv3: false, @@ -85,6 +84,7 @@ pub fn dummy_world_mesh_draw_item(spec: DummyDrawItemSpec) -> WorldMeshDrawItem embedded_requires_intersection_pass: false, embedded_uses_scene_depth_snapshot: false, embedded_uses_scene_color_snapshot: false, + embedded_uses_billboard_geometry: false, scene_color_snapshot_mode: Default::default(), render_queue, render_state: Default::default(), From 36b6cf179d13f6bfb749e50fee43b499d6cb594c Mon Sep 17 00:00:00 2001 From: Baplar Date: Fri, 5 Jun 2026 23:13:42 +0200 Subject: [PATCH 2/5] Add billboard support to more materials Mostly filters --- .../shaders/materials/billboardunlit.wgsl | 7 +- crates/renderide/shaders/materials/blur.wgsl | 12 +++- .../shaders/materials/channelmatrix.wgsl | 12 +++- crates/renderide/shaders/materials/gamma.wgsl | 12 +++- .../renderide/shaders/materials/getdepth.wgsl | 12 +++- .../shaders/materials/grayscale.wgsl | 12 +++- crates/renderide/shaders/materials/hsv.wgsl | 12 +++- .../renderide/shaders/materials/invert.wgsl | 12 +++- crates/renderide/shaders/materials/lut.wgsl | 12 +++- .../renderide/shaders/materials/matcap.wgsl | 50 +++++++++++-- .../shaders/materials/overlayfresnel.wgsl | 12 +++- .../shaders/materials/overlayunlit.wgsl | 15 +++- .../shaders/materials/pbstriplanar.wgsl | 14 +++- .../materials/pbstriplanarspecular.wgsl | 14 +++- .../materials/pbstriplanartransparent.wgsl | 14 +++- .../pbstriplanartransparentspecular.wgsl | 14 +++- .../shaders/materials/pbsvoronoicrystal.wgsl | 57 ++++++++++++--- .../renderide/shaders/materials/pixelate.wgsl | 12 +++- .../shaders/materials/posterize.wgsl | 12 +++- .../shaders/materials/reflection.wgsl | 24 +++++-- .../renderide/shaders/materials/refract.wgsl | 13 +++- .../shaders/materials/threshold.wgsl | 15 +++- .../shaders/materials/wireframe.wgsl | 34 ++++----- .../materials/wireframedoublesided.wgsl | 38 ++++------ .../materials/wireframeunlittransition.wgsl | 18 ++++- .../shaders/modules/billboard/vertex.wgsl | 26 +++++++ .../shaders/modules/mesh/wireframe.wgsl | 68 ++++++++++++++++++ .../modules/pbs/families/triplanar.wgsl | 36 ++++++++++ .../modules/post/filter_refraction.wgsl | 24 +++++++ .../shaders/modules/post/filter_vertex.wgsl | 72 +++++++++++++++++++ 30 files changed, 575 insertions(+), 110 deletions(-) diff --git a/crates/renderide/shaders/materials/billboardunlit.wgsl b/crates/renderide/shaders/materials/billboardunlit.wgsl index 29e8d1601..6e3b5247f 100644 --- a/crates/renderide/shaders/materials/billboardunlit.wgsl +++ b/crates/renderide/shaders/materials/billboardunlit.wgsl @@ -178,12 +178,7 @@ fn vs_main( let layer = 0u; #endif -#ifdef MULTIVIEW - let vp = mv::select_view_proj(d, view_idx); -#else - let vp = mv::select_view_proj(d, 0u); -#endif - + let vp = mv::select_view_proj(d, layer); var out: VertexOutput; var world_p: vec3; if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { diff --git a/crates/renderide/shaders/materials/blur.wgsl b/crates/renderide/shaders/materials/blur.wgsl index d28f5fa89..d32662d59 100644 --- a/crates/renderide/shaders/materials/blur.wgsl +++ b/crates/renderide/shaders/materials/blur.wgsl @@ -15,6 +15,7 @@ //#mat_default _NormalMap_LodBias float 0.0 //#mat_default _SpreadTex_LodBias float 0.0 +#import renderide::billboard::vertex as bv #import renderide::core::texture_sampling as ts #import renderide::core::uv as uvu #import renderide::post::filter_math as fm @@ -78,6 +79,7 @@ fn kw_SPREAD_TEX() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -85,12 +87,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> fr::VertexOutput { #ifdef MULTIVIEW - return fr::vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return fr::vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return fr::billboard_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return fr::vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } fn refraction_enabled() -> bool { diff --git a/crates/renderide/shaders/materials/channelmatrix.wgsl b/crates/renderide/shaders/materials/channelmatrix.wgsl index 9f5114a88..ace379ac0 100644 --- a/crates/renderide/shaders/materials/channelmatrix.wgsl +++ b/crates/renderide/shaders/materials/channelmatrix.wgsl @@ -10,6 +10,7 @@ //#mat_default _LevelsG vec4 0.0 0.0 1.0 0.0 //#mat_default _LevelsR vec4 0.0 1.0 0.0 0.0 +#import renderide::billboard::vertex as bv #import renderide::post::filter_vertex as fv #import renderide::post::filter_common as fc #import renderide::material::variant_bits as vb @@ -40,6 +41,7 @@ fn kw_RECTCLIP() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -47,12 +49,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> fv::RectVertexOutput { #ifdef MULTIVIEW - return fv::rect_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return fv::rect_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return fv::billboard_rect_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return fv::rect_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_filter blend=material_filter diff --git a/crates/renderide/shaders/materials/gamma.wgsl b/crates/renderide/shaders/materials/gamma.wgsl index 86072f4db..620ab35b2 100644 --- a/crates/renderide/shaders/materials/gamma.wgsl +++ b/crates/renderide/shaders/materials/gamma.wgsl @@ -6,6 +6,7 @@ //#render_queue Transparent+500 //#mat_default _Gamma float 2.2 +#import renderide::billboard::vertex as bv #import renderide::post::filter_vertex as fv #import renderide::post::filter_common as fc #import renderide::material::variant_bits as vb @@ -32,6 +33,7 @@ fn kw_RECTCLIP() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -39,12 +41,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> fv::RectVertexOutput { #ifdef MULTIVIEW - return fv::rect_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return fv::rect_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return fv::billboard_rect_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return fv::rect_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_filter blend=material_filter zwrite=material(on) ztest=material(main) cull=material(back) color_mask=material(rgba) stencil=material offset=material(0,0) diff --git a/crates/renderide/shaders/materials/getdepth.wgsl b/crates/renderide/shaders/materials/getdepth.wgsl index e50fc0b65..7e01efcda 100644 --- a/crates/renderide/shaders/materials/getdepth.wgsl +++ b/crates/renderide/shaders/materials/getdepth.wgsl @@ -12,6 +12,7 @@ //#mat_default _ClipMax float 1.0 //#mat_default _Multiply float 1.0 +#import renderide::billboard::vertex as bv #import renderide::post::filter_vertex as fv #import renderide::post::filter_common as fc #import renderide::frame::scene_depth_sample as sds @@ -48,6 +49,7 @@ fn kw_RECTCLIP() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -55,12 +57,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> fv::RectVertexOutput { #ifdef MULTIVIEW - return fv::rect_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return fv::rect_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return fv::billboard_rect_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return fv::rect_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_filter blend=material_filter zwrite=material(off) ztest=material(main) cull=material(back) color_mask=material(rgba) stencil=material offset=material(0,0) diff --git a/crates/renderide/shaders/materials/grayscale.wgsl b/crates/renderide/shaders/materials/grayscale.wgsl index f70e7e42f..19a150027 100644 --- a/crates/renderide/shaders/materials/grayscale.wgsl +++ b/crates/renderide/shaders/materials/grayscale.wgsl @@ -10,6 +10,7 @@ //#mat_default _RatioG float 0.59 //#mat_default _RatioR float 0.3 +#import renderide::billboard::vertex as bv #import renderide::post::filter_vertex as fv #import renderide::post::filter_common as fc #import renderide::material::variant_bits as vb @@ -47,6 +48,7 @@ fn kw_RECTCLIP() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -54,12 +56,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> fv::RectVertexOutput { #ifdef MULTIVIEW - return fv::rect_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return fv::rect_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return fv::billboard_rect_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return fv::rect_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_filter blend=material_filter diff --git a/crates/renderide/shaders/materials/hsv.wgsl b/crates/renderide/shaders/materials/hsv.wgsl index c6e5d0ef2..aedfd0670 100644 --- a/crates/renderide/shaders/materials/hsv.wgsl +++ b/crates/renderide/shaders/materials/hsv.wgsl @@ -5,6 +5,7 @@ //#mat_default _HSVMul vec4 1.0 1.0 1.0 1.0 //#mat_default _HSVOffset vec4 0.2 0.2 0.2 0.0 +#import renderide::billboard::vertex as bv #import renderide::post::filter_math as fm #import renderide::post::filter_vertex as fv #import renderide::post::filter_common as fc @@ -34,6 +35,7 @@ fn kw_RECTCLIP() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -41,12 +43,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> fv::RectVertexOutput { #ifdef MULTIVIEW - return fv::rect_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return fv::rect_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return fv::billboard_rect_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return fv::rect_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_filter blend=material_filter diff --git a/crates/renderide/shaders/materials/invert.wgsl b/crates/renderide/shaders/materials/invert.wgsl index 193446cbd..9e6c8e342 100644 --- a/crates/renderide/shaders/materials/invert.wgsl +++ b/crates/renderide/shaders/materials/invert.wgsl @@ -4,6 +4,7 @@ //#render_queue Transparent+500 //#mat_default _Lerp float 1.0 +#import renderide::billboard::vertex as bv #import renderide::post::filter_vertex as fv #import renderide::post::filter_common as fc #import renderide::material::variant_bits as vb @@ -30,6 +31,7 @@ fn kw_RECTCLIP() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -37,12 +39,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> fv::RectVertexOutput { #ifdef MULTIVIEW - return fv::rect_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return fv::rect_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return fv::billboard_rect_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return fv::rect_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_filter blend=material_filter diff --git a/crates/renderide/shaders/materials/lut.wgsl b/crates/renderide/shaders/materials/lut.wgsl index e4d5b6632..ffb383861 100644 --- a/crates/renderide/shaders/materials/lut.wgsl +++ b/crates/renderide/shaders/materials/lut.wgsl @@ -5,6 +5,7 @@ //#texture_default _LUT empty //#texture_default _SecondaryLUT empty +#import renderide::billboard::vertex as bv #import renderide::post::filter_vertex as fv #import renderide::post::filter_common as fc #import renderide::core::texture_sampling as ts @@ -45,6 +46,7 @@ fn kw_SRGB() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -52,12 +54,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> fv::RectVertexOutput { #ifdef MULTIVIEW - return fv::rect_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return fv::rect_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return fv::billboard_rect_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return fv::rect_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_filter blend=material_filter diff --git a/crates/renderide/shaders/materials/matcap.wgsl b/crates/renderide/shaders/materials/matcap.wgsl index 9998e13be..6098ea4ba 100644 --- a/crates/renderide/shaders/materials/matcap.wgsl +++ b/crates/renderide/shaders/materials/matcap.wgsl @@ -4,6 +4,7 @@ //#texture_default _MainTex white //#texture_default _NormalMap bump +#import renderide::billboard::vertex as bv #import renderide::frame::globals as rg #import renderide::draw::per_draw as pd #import renderide::core::math as rmath @@ -51,6 +52,7 @@ struct VertexOutput { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -58,13 +60,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) tangent: vec4, + @location(5) uv1: vec2, ) -> VertexOutput { + #ifdef MULTIVIEW + let view_layer = view_idx; + #else + let view_layer = 0u; + #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return billboard_vertex_main(instance_index, view_layer, pos, n, uv0, tangent, uv1, vertex_index); + } + let d = pd::get_draw(instance_index); -#ifdef MULTIVIEW - let view_layer = view_idx; -#else - let view_layer = 0u; -#endif let world_p = mv::world_position(d, pos); let world_n = rmath::safe_normalize(d.normal_matrix * n.xyz, vec3(0.0, 1.0, 0.0)); let tbn = pnorm::orthonormal_tbn(world_n, mv::world_tangent(d, tangent)); @@ -82,6 +89,39 @@ fn vs_main( return out; } +fn billboard_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + uv0: vec2, + tangent: vec4, + uv1: vec2, + vertex_index: u32, +) -> VertexOutput { + let d = pd::get_draw(instance_index); + + let render_billboard_vertex = bv::render_buffer_billboard_vertex( + d, view_idx, pos, vertex_index, n, tangent, uv1, + ); + let world_p = render_billboard_vertex.world_pos; + let axes = render_billboard_vertex.axes; + let billboard_t = axes.right; + let billboard_n = rmath::safe_normalize(cross(axes.right, axes.up), vec3(0.0, 0.0, 1.0)); + let vp = mv::select_view_proj(d, view_idx); + let basis = vb::from_view_projection(vp); + + var out: VertexOutput; + out.clip_pos = vp * world_p; + out.uv_normal = uvu::apply_st(uv0, mat._NormalMap_ST); + out.world_n = mv::world_normal_for_view(d, vec4(billboard_n, 0.0), view_idx).xyz; + out.world_t = mv::world_tangent_for_view(d, vec4(billboard_t, 0.0), view_idx).xyz; + out.world_b = rmath::safe_normalize(cross(out.world_n, out.world_t), vec3(0.0, 0.0, 1.0)); + out.view_x = basis.x; + out.view_y = basis.y; + return out; +} + //#pass type=forward @fragment fn fs_main( diff --git a/crates/renderide/shaders/materials/overlayfresnel.wgsl b/crates/renderide/shaders/materials/overlayfresnel.wgsl index 11056bd3b..072d93e30 100644 --- a/crates/renderide/shaders/materials/overlayfresnel.wgsl +++ b/crates/renderide/shaders/materials/overlayfresnel.wgsl @@ -22,6 +22,7 @@ //#mat_default _GammaCurve float 2.2 //#mat_default _PolarPow float 1.0 +#import renderide::billboard::vertex as bv #import renderide::frame::globals as rg #import renderide::material::fresnel as mf #import renderide::material::variant_bits as vb @@ -92,6 +93,7 @@ fn kw_TEXTURE() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -99,12 +101,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::WorldVertexOutput { #ifdef MULTIVIEW - return mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv); + let view_layer = view_idx; #else - return mv::world_vertex_main(instance_index, 0u, pos, n, t, uv); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::world_vertex_main(instance_index, view_layer, pos, n, t, uv, vertex_index, uv1); + } else { + return mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv); + } } fn sample_overlay_tex( diff --git a/crates/renderide/shaders/materials/overlayunlit.wgsl b/crates/renderide/shaders/materials/overlayunlit.wgsl index 9ba664957..5cdd4d6a5 100644 --- a/crates/renderide/shaders/materials/overlayunlit.wgsl +++ b/crates/renderide/shaders/materials/overlayunlit.wgsl @@ -14,6 +14,7 @@ //#mat_default _PolarPow float 1.0 //#mat_default _Cutoff float 0.5 +#import renderide::billboard::vertex as bv #import renderide::frame::globals as rg #import renderide::material::variant_bits as vb #import renderide::material::vertex_color as vc @@ -88,19 +89,27 @@ fn kw_VERTEXCOLORS() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, - @location(1) _n: vec4, + @location(1) n: vec4, @location(2) uv: vec2, @location(3) color: vec4, + @location(4) t: vec4, + @location(5) uv1: vec2, ) -> mv::UvColorVertexOutput { #ifdef MULTIVIEW - return mv::uv_color_vertex_main(instance_index, view_idx, pos, uv, color); + let view_layer = view_idx; #else - return mv::uv_color_vertex_main(instance_index, 0u, pos, uv, color); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return bv::uv_color_vertex_main(instance_index, view_layer, pos, uv, color, n, t, vertex_index, uv1); + } else { + return mv::uv_color_vertex_main(instance_index, view_layer, pos, uv, color); + } } fn sample_layer( diff --git a/crates/renderide/shaders/materials/pbstriplanar.wgsl b/crates/renderide/shaders/materials/pbstriplanar.wgsl index e6c9c3844..0a7f5bca1 100644 --- a/crates/renderide/shaders/materials/pbstriplanar.wgsl +++ b/crates/renderide/shaders/materials/pbstriplanar.wgsl @@ -24,6 +24,7 @@ //#mat_default _TriBlendPower float 4.0 //#mat_default _Glossiness float 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::pbs::families::triplanar as ptri #import renderide::pbs::lighting as plight @@ -190,17 +191,26 @@ fn sample_surface( @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, + @location(2) uv0: vec2, + @location(4) t: vec4, + @location(5) uv1: vec2, ) -> ptri::VertexOutput { #ifdef MULTIVIEW - return ptri::vertex_main(instance_index, view_idx, pos, n, kw_OBJECTSPACE()); + let view_layer = view_idx; #else - return ptri::vertex_main(instance_index, 0u, pos, n, kw_OBJECTSPACE()); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return ptri::billboard_vertex_main(instance_index, view_layer, pos, n, vertex_index, uv0, t, uv1, kw_OBJECTSPACE()); + } else { + return ptri::vertex_main(instance_index, view_layer, pos, n, kw_OBJECTSPACE()); + } } /// Forward-base pass: ambient + directional lighting + emission. diff --git a/crates/renderide/shaders/materials/pbstriplanarspecular.wgsl b/crates/renderide/shaders/materials/pbstriplanarspecular.wgsl index 0028e2ff7..72b4eb973 100644 --- a/crates/renderide/shaders/materials/pbstriplanarspecular.wgsl +++ b/crates/renderide/shaders/materials/pbstriplanarspecular.wgsl @@ -20,6 +20,7 @@ //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 //#mat_default _TriBlendPower float 4.0 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::pbs::families::triplanar as ptri #import renderide::pbs::lighting as plight @@ -180,17 +181,26 @@ fn sample_surface( @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, + @location(2) uv0: vec2, + @location(4) t: vec4, + @location(5) uv1: vec2, ) -> ptri::VertexOutput { #ifdef MULTIVIEW - return ptri::vertex_main(instance_index, view_idx, pos, n, kw_OBJECTSPACE()); + let view_layer = view_idx; #else - return ptri::vertex_main(instance_index, 0u, pos, n, kw_OBJECTSPACE()); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return ptri::billboard_vertex_main(instance_index, view_layer, pos, n, vertex_index, uv0, t, uv1, kw_OBJECTSPACE()); + } else { + return ptri::vertex_main(instance_index, view_layer, pos, n, kw_OBJECTSPACE()); + } } /// Forward-base pass: ambient + directional lighting + emission. diff --git a/crates/renderide/shaders/materials/pbstriplanartransparent.wgsl b/crates/renderide/shaders/materials/pbstriplanartransparent.wgsl index aaeff94d7..6351dcbc2 100644 --- a/crates/renderide/shaders/materials/pbstriplanartransparent.wgsl +++ b/crates/renderide/shaders/materials/pbstriplanartransparent.wgsl @@ -15,6 +15,7 @@ //#mat_default _TriBlendPower float 4.0 //#mat_default _Glossiness float 0.5 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::pbs::families::triplanar as ptri #import renderide::pbs::lighting as plight @@ -149,17 +150,26 @@ fn sample_surface( @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, + @location(2) uv0: vec2, + @location(4) t: vec4, + @location(5) uv1: vec2, ) -> ptri::VertexOutput { #ifdef MULTIVIEW - return ptri::vertex_main(instance_index, view_idx, pos, n, kw_OBJECTSPACE()); + let view_layer = view_idx; #else - return ptri::vertex_main(instance_index, 0u, pos, n, kw_OBJECTSPACE()); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return ptri::billboard_vertex_main(instance_index, view_layer, pos, n, vertex_index, uv0, t, uv1, kw_OBJECTSPACE()); + } else { + return ptri::vertex_main(instance_index, view_layer, pos, n, kw_OBJECTSPACE()); + } } //#pass type=forward name=forward_transparent blend=transparent_material zwrite=material(off) cull=material(off) color_mask=material(rgba) diff --git a/crates/renderide/shaders/materials/pbstriplanartransparentspecular.wgsl b/crates/renderide/shaders/materials/pbstriplanartransparentspecular.wgsl index 25c05c58a..247c72eef 100644 --- a/crates/renderide/shaders/materials/pbstriplanartransparentspecular.wgsl +++ b/crates/renderide/shaders/materials/pbstriplanartransparentspecular.wgsl @@ -15,6 +15,7 @@ //#mat_default _SpecularColor vec4 1.0 1.0 1.0 0.5 //#mat_default _TriBlendPower float 4.0 +#import renderide::billboard::vertex as bv #import renderide::material::variant_bits as vb #import renderide::pbs::families::triplanar as ptri #import renderide::pbs::lighting as plight @@ -146,17 +147,26 @@ fn sample_surface( @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, + @location(2) uv0: vec2, + @location(4) t: vec4, + @location(5) uv1: vec2, ) -> ptri::VertexOutput { #ifdef MULTIVIEW - return ptri::vertex_main(instance_index, view_idx, pos, n, kw_OBJECTSPACE()); + let view_layer = view_idx; #else - return ptri::vertex_main(instance_index, 0u, pos, n, kw_OBJECTSPACE()); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return ptri::billboard_vertex_main(instance_index, view_layer, pos, n, vertex_index, uv0, t, uv1, kw_OBJECTSPACE()); + } else { + return ptri::vertex_main(instance_index, view_layer, pos, n, kw_OBJECTSPACE()); + } } //#pass type=forward name=forward_transparent blend=transparent_material zwrite=material(off) cull=material(off) color_mask=material(rgba) diff --git a/crates/renderide/shaders/materials/pbsvoronoicrystal.wgsl b/crates/renderide/shaders/materials/pbsvoronoicrystal.wgsl index 089fb94f2..e74bf5341 100644 --- a/crates/renderide/shaders/materials/pbsvoronoicrystal.wgsl +++ b/crates/renderide/shaders/materials/pbsvoronoicrystal.wgsl @@ -22,12 +22,14 @@ //#mat_default _EdgeMetallic float 0.1 //#mat_default _EdgeThickness float 0.1 +#import renderide::billboard::vertex as bv #import renderide::draw::per_draw as pd #import renderide::mesh::vertex as mv #import renderide::pbs::normal as pnorm #import renderide::pbs::lighting as plight #import renderide::pbs::sampling as psamp #import renderide::pbs::surface as psurf +#import renderide::core::math as rmath #import renderide::core::uv as uvu #import renderide::core::normal_decode as nd #import renderide::material::voronoi as vor @@ -48,6 +50,7 @@ struct PbsVoronoiCrystalMaterial { _AnimationOffset: f32, _Glossiness: f32, _Metallic: f32, + _RenderideVariantBits: u32, } @group(1) @binding(0) var mat: PbsVoronoiCrystalMaterial; @@ -73,6 +76,7 @@ struct VertexOutput { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -80,16 +84,23 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> VertexOutput { +#ifdef MULTIVIEW + let view_layer = view_idx; +#else + let view_layer = 0u; +#endif + + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return billboard_vertex_main(instance_index, view_layer, pos, n, vertex_index, uv0, t, uv1); + } + let d = pd::get_draw(instance_index); let world_p = mv::world_position(d, pos); let wn = mv::world_normal(d, n); let wt = mv::world_tangent(d, t); -#ifdef MULTIVIEW - let vp = mv::select_view_proj(d, view_idx); -#else - let vp = mv::select_view_proj(d, 0u); -#endif + let vp = mv::select_view_proj(d, view_layer); var out: VertexOutput; out.clip_pos = vp * world_p; out.world_pos = world_p.xyz; @@ -97,11 +108,39 @@ fn vs_main( out.world_t = wt; out.uv = uv0; out.uv_normal = uvu::apply_st(uv0, mat._NormalMap_ST); -#ifdef MULTIVIEW + out.view_layer = mv::packed_view_layer(instance_index, view_layer); + return out; +} + +fn billboard_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + vertex_index: u32, + uv0: vec2, + tangent: vec4, + uv1: vec2, +) -> VertexOutput { + let d = pd::get_draw(instance_index); + + let render_billboard_vertex = bv::render_buffer_billboard_vertex( + d, view_idx, pos, vertex_index, n, tangent, uv1, + ); + let world_p = render_billboard_vertex.world_pos; + let axes = render_billboard_vertex.axes; + let billboard_t = axes.right; + let billboard_n = rmath::safe_normalize(cross(axes.right, axes.up), vec3(0.0, 0.0, 1.0)); + let vp = mv::select_view_proj(d, view_idx); + + var out: VertexOutput; + out.clip_pos = vp * world_p; + out.world_pos = world_p.xyz; + out.world_n = mv::world_normal_for_view(d, vec4(billboard_n, 0.0), view_idx).xyz; + out.world_t = mv::world_tangent_for_view(d, vec4(billboard_t, 0.0), view_idx); + out.uv = uv0; + out.uv_normal = uvu::apply_st(uv0, mat._NormalMap_ST); out.view_layer = mv::packed_view_layer(instance_index, view_idx); -#else - out.view_layer = mv::packed_view_layer(instance_index, 0u); -#endif return out; } diff --git a/crates/renderide/shaders/materials/pixelate.wgsl b/crates/renderide/shaders/materials/pixelate.wgsl index 85bc4fdbf..7f3662974 100644 --- a/crates/renderide/shaders/materials/pixelate.wgsl +++ b/crates/renderide/shaders/materials/pixelate.wgsl @@ -10,6 +10,7 @@ //#texture_default _ResolutionTex white //#mat_default _Resolution vec4 100.0 100.0 0.0 0.0 +#import renderide::billboard::vertex as bv #import renderide::post::filter_math as fm #import renderide::post::filter_vertex as fv #import renderide::post::filter_common as fc @@ -48,6 +49,7 @@ fn kw_RESOLUTION_TEX() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -55,12 +57,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> fv::RectVertexOutput { #ifdef MULTIVIEW - return fv::rect_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return fv::rect_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return fv::billboard_rect_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return fv::rect_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_filter blend=material_filter diff --git a/crates/renderide/shaders/materials/posterize.wgsl b/crates/renderide/shaders/materials/posterize.wgsl index 7f41fa808..f5e71e30a 100644 --- a/crates/renderide/shaders/materials/posterize.wgsl +++ b/crates/renderide/shaders/materials/posterize.wgsl @@ -6,6 +6,7 @@ //#render_queue Transparent+500 //#mat_default _Levels float 10.0 +#import renderide::billboard::vertex as bv #import renderide::post::filter_vertex as fv #import renderide::post::filter_common as fc #import renderide::material::variant_bits as vb @@ -32,6 +33,7 @@ fn kw_RECTCLIP() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -39,12 +41,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> fv::RectVertexOutput { #ifdef MULTIVIEW - return fv::rect_vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return fv::rect_vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return fv::billboard_rect_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return fv::rect_vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_filter blend=material_filter diff --git a/crates/renderide/shaders/materials/reflection.wgsl b/crates/renderide/shaders/materials/reflection.wgsl index 2fd6456f5..7a8789b38 100644 --- a/crates/renderide/shaders/materials/reflection.wgsl +++ b/crates/renderide/shaders/materials/reflection.wgsl @@ -14,6 +14,7 @@ //#mat_default _Color vec4 1.0 1.0 1.0 1.0 //#mat_default _Cutoff float 0.5 +#import renderide::billboard::vertex as bv #import renderide::frame::globals as rg #import renderide::draw::per_draw as pd #import renderide::material::alpha as ma @@ -65,20 +66,33 @@ struct VertexOutput { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, - @location(1) _n: vec4, + @location(1) n: vec4, @location(2) uv: vec2, + @location(4) t: vec4, + @location(5) uv1: vec2, ) -> VertexOutput { - let d = pd::get_draw(instance_index); - let world_p = mv::world_position(d, pos); #ifdef MULTIVIEW - let vp = mv::select_view_proj(d, view_idx); + let view_layer = view_idx; #else - let vp = mv::select_view_proj(d, 0u); + let view_layer = 0u; #endif + let d = pd::get_draw(instance_index); + let vp = mv::select_view_proj(d, view_layer); + + var world_p: vec4; + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + let render_billboard_vertex = bv::render_buffer_billboard_vertex( + d, view_layer, pos, vertex_index, n, t, uv1, + ); + world_p = render_billboard_vertex.world_pos; + } else { + world_p = mv::world_position(d, pos); + } let clip = vp * world_p; var out: VertexOutput; out.clip_pos = clip; diff --git a/crates/renderide/shaders/materials/refract.wgsl b/crates/renderide/shaders/materials/refract.wgsl index df3a625af..b3ea38dfb 100644 --- a/crates/renderide/shaders/materials/refract.wgsl +++ b/crates/renderide/shaders/materials/refract.wgsl @@ -9,6 +9,8 @@ //#mat_default _NormalMap_LodBias float 0.0 //#mat_default _RefractionStrength float 0.01 +#import renderide::billboard::vertex as bv +#import renderide::post::filter_vertex as fv #import renderide::post::filter_common as fc #import renderide::post::filter_refraction as fr #import renderide::frame::grab_pass as gp @@ -47,6 +49,7 @@ fn kw_NORMALMAP() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @@ -54,12 +57,18 @@ fn vs_main( @location(1) n: vec4, @location(2) uv0: vec2, @location(4) t: vec4, + @location(5) uv1: vec2, ) -> fr::VertexOutput { #ifdef MULTIVIEW - return fr::vertex_main(instance_index, view_idx, pos, n, t, uv0); + let view_layer = view_idx; #else - return fr::vertex_main(instance_index, 0u, pos, n, t, uv0); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return fr::billboard_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return fr::vertex_main(instance_index, view_layer, pos, n, t, uv0); + } } //#pass type=forward name=forward_filter blend=material_filter diff --git a/crates/renderide/shaders/materials/threshold.wgsl b/crates/renderide/shaders/materials/threshold.wgsl index 8f31e2cea..fa2abccba 100644 --- a/crates/renderide/shaders/materials/threshold.wgsl +++ b/crates/renderide/shaders/materials/threshold.wgsl @@ -10,6 +10,7 @@ //#mat_default _Threshold float 0.5 //#mat_default _Transition float 0.01 +#import renderide::billboard::vertex as bv #import renderide::post::filter_common as fc #import renderide::post::filter_vertex as fv #import renderide::material::variant_bits as vb @@ -32,16 +33,26 @@ fn threshold_kw(mask: u32) -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, + @location(1) n: vec4, + @location(2) uv0: vec2, + @location(4) t: vec4, + @location(5) uv1: vec2, ) -> fv::PositionRectVertexOutput { #ifdef MULTIVIEW - return fv::position_rect_vertex_main(instance_index, view_idx, pos); + let view_layer = view_idx; #else - return fv::position_rect_vertex_main(instance_index, 0u, pos); + let view_layer = 0u; #endif + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return fv::billboard_position_rect_vertex_main(instance_index, view_layer, pos, n, t, uv0, vertex_index, uv1); + } else { + return fv::position_rect_vertex_main(instance_index, view_layer, pos); + } } //#pass type=forward name=forward_filter blend=material_filter diff --git a/crates/renderide/shaders/materials/wireframe.wgsl b/crates/renderide/shaders/materials/wireframe.wgsl index 16910779d..44caded23 100644 --- a/crates/renderide/shaders/materials/wireframe.wgsl +++ b/crates/renderide/shaders/materials/wireframe.wgsl @@ -10,6 +10,7 @@ //#mat_default _Exp float 1.0 //#mat_default _Thickness float 1.0 +#import renderide::billboard::vertex as bv #import renderide::core::texture_sampling as ts #import renderide::core::uv as uvu #import renderide::draw::per_draw as pd @@ -37,14 +38,6 @@ const WIREFRAME_KW_SCREENSPACE: u32 = 1u << 1u; @group(1) @binding(1) var _MainTex: texture_2d; @group(1) @binding(2) var _MainTex_sampler: sampler; -struct VertexOutput { - @builtin(position) clip_pos: vec4, - @location(0) world_pos: vec3, - @location(1) world_n: vec3, - @location(2) uv: vec2, - @location(3) @interpolate(flat) view_layer: u32, -} - fn wireframe_kw(mask: u32) -> bool { return vb::enabled(mat._RenderideVariantBits, mask); } @@ -60,32 +53,29 @@ fn kw_SCREENSPACE() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, -) -> VertexOutput { - let draw = pd::get_draw(instance_index); - let world_p = mv::world_position(draw, pos); + @location(4) t: vec4, + @location(5) uv1: vec2, +) -> wf::VertexOutput { #ifdef MULTIVIEW let layer = view_idx; #else let layer = 0u; #endif - let vp = mv::select_view_proj(draw, layer); - - var out: VertexOutput; - out.clip_pos = vp * world_p; - out.world_pos = world_p.xyz; - out.world_n = mv::world_normal(draw, n); - out.uv = uvu::apply_st(uv0, mat._MainTex_ST); - out.view_layer = (instance_index << 1u) | (layer & 1u); - return out; + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return wf::billboard_vs_main(instance_index, layer, vertex_index, pos, n, uv0, t, uv1, mat._MainTex_ST); + } else { + return wf::vs_main(instance_index, layer, pos, n, uv0, mat._MainTex_ST); + } } -fn wireframe_color(in: VertexOutput, edge: f32) -> vec4 { +fn wireframe_color(in: wf::VertexOutput, edge: f32) -> vec4 { var fill_color = mat._FillColor; var line_color = mat._LineColor; if (kw_FRESNEL()) { @@ -100,7 +90,7 @@ fn wireframe_color(in: VertexOutput, edge: f32) -> vec4 { //#pass type=forward blend=alpha zwrite=material(off) ztest=main cull=back color_mask=rgba offset=material(0,0) @fragment fn fs_main( - in: VertexOutput, + in: wf::VertexOutput, @builtin(barycentric) barycentric: vec3, ) -> @location(0) vec4 { let edge = wf::unity_edge_lerp(barycentric, in.world_pos, mat._Thickness, kw_SCREENSPACE()); diff --git a/crates/renderide/shaders/materials/wireframedoublesided.wgsl b/crates/renderide/shaders/materials/wireframedoublesided.wgsl index bf5b4cc2f..9e986889d 100644 --- a/crates/renderide/shaders/materials/wireframedoublesided.wgsl +++ b/crates/renderide/shaders/materials/wireframedoublesided.wgsl @@ -14,6 +14,7 @@ //#mat_default _Exp float 1.0 //#mat_default _Thickness float 1.0 +#import renderide::billboard::vertex as bv #import renderide::core::texture_sampling as ts #import renderide::core::uv as uvu #import renderide::draw::per_draw as pd @@ -45,14 +46,6 @@ const WIREFRAME_KW_SCREENSPACE: u32 = 1u << 1u; @group(1) @binding(1) var _MainTex: texture_2d; @group(1) @binding(2) var _MainTex_sampler: sampler; -struct VertexOutput { - @builtin(position) clip_pos: vec4, - @location(0) world_pos: vec3, - @location(1) world_n: vec3, - @location(2) uv: vec2, - @location(3) @interpolate(flat) view_layer: u32, -} - fn wireframe_kw(mask: u32) -> bool { return vb::enabled(mat._RenderideVariantBits, mask); } @@ -68,32 +61,29 @@ fn kw_SCREENSPACE() -> bool { @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, @location(1) n: vec4, @location(2) uv0: vec2, -) -> VertexOutput { - let draw = pd::get_draw(instance_index); - let world_p = mv::world_position(draw, pos); + @location(4) t: vec4, + @location(5) uv1: vec2, +) -> wf::VertexOutput { #ifdef MULTIVIEW let layer = view_idx; #else let layer = 0u; #endif - let vp = mv::select_view_proj(draw, layer); - - var out: VertexOutput; - out.clip_pos = vp * world_p; - out.world_pos = world_p.xyz; - out.world_n = mv::world_normal(draw, n); - out.uv = uvu::apply_st(uv0, mat._MainTex_ST); - out.view_layer = (instance_index << 1u) | (layer & 1u); - return out; + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + return wf::billboard_vs_main(instance_index, layer, vertex_index, pos, n, uv0, t, uv1, mat._MainTex_ST); + } else { + return wf::vs_main(instance_index, layer, pos, n, uv0, mat._MainTex_ST); + } } -fn pass_color(in: VertexOutput, edge: f32, inner: bool) -> vec4 { +fn pass_color(in: wf::VertexOutput, edge: f32, inner: bool) -> vec4 { var fill_color = mat._FillColor; var line_color = mat._LineColor; if (inner) { @@ -115,7 +105,7 @@ fn pass_color(in: VertexOutput, edge: f32, inner: bool) -> vec4 { return mix(fill_color, line_color, edge); } -fn fragment_wire(in: VertexOutput, barycentric: vec3, inner: bool) -> vec4 { +fn fragment_wire(in: wf::VertexOutput, barycentric: vec3, inner: bool) -> vec4 { let edge = wf::unity_edge_lerp(barycentric, in.world_pos, mat._Thickness, kw_SCREENSPACE()); let tex = ts::sample_tex_2d(_MainTex, _MainTex_sampler, in.uv, mat._MainTex_LodBias); return rg::retain_globals_additive(pass_color(in, edge, inner) * tex); @@ -124,7 +114,7 @@ fn fragment_wire(in: VertexOutput, barycentric: vec3, inner: bool) -> vec4< //#pass type=forward name=inner blend=alpha zwrite=material(off) ztest=main cull=front color_mask=rgba offset=material(0,0) @fragment fn fs_inner( - in: VertexOutput, + in: wf::VertexOutput, @builtin(barycentric) barycentric: vec3, ) -> @location(0) vec4 { return fragment_wire(in, barycentric, true); @@ -133,7 +123,7 @@ fn fs_inner( //#pass type=forward name=outer blend=alpha zwrite=material(off) ztest=main cull=back color_mask=rgba offset=material(0,0) @fragment fn fs_outer( - in: VertexOutput, + in: wf::VertexOutput, @builtin(barycentric) barycentric: vec3, ) -> @location(0) vec4 { return fragment_wire(in, barycentric, false); diff --git a/crates/renderide/shaders/materials/wireframeunlittransition.wgsl b/crates/renderide/shaders/materials/wireframeunlittransition.wgsl index deaf39592..c50f9fca5 100644 --- a/crates/renderide/shaders/materials/wireframeunlittransition.wgsl +++ b/crates/renderide/shaders/materials/wireframeunlittransition.wgsl @@ -14,6 +14,7 @@ //#mat_default _WireTransitionExp float 1.0 //#mat_default _WirePlaneOffset float 0.0 +#import renderide::billboard::vertex as bv #import renderide::core::math as rmath #import renderide::core::texture_sampling as ts #import renderide::core::uv as uvu @@ -34,6 +35,7 @@ struct WireframeUnlitTransitionMaterial { _WireTransitionRange: f32, _WireTransitionExp: f32, _WirePlaneOffset: f32, + _RenderideVariantBits: u32, _MainTex_LodBias: f32, } @@ -66,20 +68,32 @@ fn transition_lerp(distance: f32, offset: f32, range: f32, exponent: f32, invert @vertex fn vs_main( @builtin(instance_index) instance_index: u32, + @builtin(vertex_index) vertex_index: u32, #ifdef MULTIVIEW @builtin(view_index) view_idx: u32, #endif @location(0) pos: vec4, + @location(1) n: vec4, @location(2) uv0: vec2, + @location(4) t: vec4, + @location(5) uv1: vec2, ) -> VertexOutput { - let draw = pd::get_draw(instance_index); - let world_p = mv::world_position(draw, pos); #ifdef MULTIVIEW let layer = view_idx; #else let layer = 0u; #endif + let draw = pd::get_draw(instance_index); let vp = mv::select_view_proj(draw, layer); + var world_p: vec4; + if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits)) { + let render_billboard_vertex = bv::render_buffer_billboard_vertex( + draw, layer, pos, vertex_index, n, t, uv1, + ); + world_p = render_billboard_vertex.world_pos; + } else { + world_p = mv::world_position(draw, pos); + } var out: VertexOutput; out.clip_pos = vp * world_p; diff --git a/crates/renderide/shaders/modules/billboard/vertex.wgsl b/crates/renderide/shaders/modules/billboard/vertex.wgsl index 2bf5055be..83991fde4 100644 --- a/crates/renderide/shaders/modules/billboard/vertex.wgsl +++ b/crates/renderide/shaders/modules/billboard/vertex.wgsl @@ -367,3 +367,29 @@ fn world_object_vertex_main( out.view_layer = mv::packed_view_layer(instance_index, view_idx); return out; } + +fn uv_color_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + uv: vec2, + color: vec4, + n: vec4, + t: vec4, + vertex_index: u32, + uv1: vec2, +) -> mv::UvColorVertexOutput { + let draw = pd::get_draw(instance_index); + let vp = mv::select_view_proj(draw, view_idx); + + let render_billboard_vertex = render_buffer_billboard_vertex( + draw, view_idx, pos, vertex_index, n, t, uv1, + ); + let world_p = render_billboard_vertex.world_pos; + + var out: mv::UvColorVertexOutput; + out.clip_pos = vp * world_p; + out.uv = uv; + out.color = color * dt::particle_color(draw); + return out; +} diff --git a/crates/renderide/shaders/modules/mesh/wireframe.wgsl b/crates/renderide/shaders/modules/mesh/wireframe.wgsl index eb29f95dc..fb9f9703d 100644 --- a/crates/renderide/shaders/modules/mesh/wireframe.wgsl +++ b/crates/renderide/shaders/modules/mesh/wireframe.wgsl @@ -3,6 +3,14 @@ #define_import_path renderide::mesh::wireframe #import renderide::core::math as rmath +#import renderide::billboard::vertex as bv +#import renderide::core::texture_sampling as ts +#import renderide::core::uv as uvu +#import renderide::draw::per_draw as pd +#import renderide::frame::globals as rg +#import renderide::material::variant_bits as vb +#import renderide::mesh::vertex as mv +#import renderide::mesh::wireframe as wf const WIREFRAME_FALLBACK_DISTANCE: f32 = 1000000.0; const WIREFRAME_GRAM_DETERMINANT_RELATIVE_EPSILON: f32 = 1e-7; @@ -142,3 +150,63 @@ fn fresnel_factor(normal: vec3, view_dir: vec3, exponent: f32) -> f32 let v = rmath::safe_normalize(view_dir, vec3(0.0, 0.0, 1.0)); return pow(max(1.0 - abs(dot(n, v)), 0.0), max(exponent, 1e-4)); } + +struct VertexOutput { + @builtin(position) clip_pos: vec4, + @location(0) world_pos: vec3, + @location(1) world_n: vec3, + @location(2) uv: vec2, + @location(3) @interpolate(flat) view_layer: u32, +} + +fn vs_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + uv0: vec2, + maintex_st: vec4, +) -> VertexOutput { + let draw = pd::get_draw(instance_index); + let world_p = mv::world_position(draw, pos); + let vp = mv::select_view_proj(draw, view_idx); + + var out: VertexOutput; + out.clip_pos = vp * world_p; + out.world_pos = world_p.xyz; + out.world_n = mv::world_normal(draw, n); + out.uv = uvu::apply_st(uv0, maintex_st); + out.view_layer = (instance_index << 1u) | (view_idx & 1u); + return out; +} + +fn billboard_vs_main( + instance_index: u32, + view_idx: u32, + vertex_index: u32, + pos: vec4, + n: vec4, + uv0: vec2, + t: vec4, + uv1: vec2, + maintex_st: vec4, +) -> VertexOutput { + let draw = pd::get_draw(instance_index); + let vp = mv::select_view_proj(draw, view_idx); + + let render_billboard_vertex = bv::render_buffer_billboard_vertex( + draw, view_idx, pos, vertex_index, n, t, uv1, + ); + let world_p = render_billboard_vertex.world_pos; + let axes = render_billboard_vertex.axes; + let billboard_t = axes.right; + let billboard_n = rmath::safe_normalize(cross(axes.right, axes.up), vec3(0.0, 0.0, 1.0)); + + var out: VertexOutput; + out.clip_pos = vp * world_p; + out.world_pos = world_p.xyz; + out.world_n = mv::world_normal_for_view(draw, vec4(billboard_n, 0.0), view_idx); + out.uv = uvu::apply_st(uv0, maintex_st); + out.view_layer = (instance_index << 1u) | (view_idx & 1u); + return out; +} diff --git a/crates/renderide/shaders/modules/pbs/families/triplanar.wgsl b/crates/renderide/shaders/modules/pbs/families/triplanar.wgsl index ef7b96cc5..dfc4d7ace 100644 --- a/crates/renderide/shaders/modules/pbs/families/triplanar.wgsl +++ b/crates/renderide/shaders/modules/pbs/families/triplanar.wgsl @@ -2,6 +2,8 @@ #define_import_path renderide::pbs::families::triplanar +#import renderide::billboard::vertex as bv +#import renderide::core::math as rmath #import renderide::core::normal_decode as nd #import renderide::core::texture_sampling as ts #import renderide::draw::per_draw as pd @@ -46,6 +48,40 @@ fn vertex_main( return out; } +fn billboard_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + vertex_index: u32, + uv0: vec2, + t: vec4, + uv1: vec2, + object_space_enabled: bool, +) -> VertexOutput { + let d = pd::get_draw(instance_index); + let vp = mv::select_view_proj(d, view_idx); + + let render_billboard_vertex = bv::render_buffer_billboard_vertex( + d, view_idx, pos, vertex_index, n, t, uv1, + ); + let world_p = render_billboard_vertex.world_pos; + let axes = render_billboard_vertex.axes; + let billboard_t = axes.right; + let billboard_n = rmath::safe_normalize(cross(axes.right, axes.up), vec3(0.0, 0.0, 1.0)); + let wn = mv::world_normal_for_view(d, vec4(billboard_n, 0.0), view_idx); + let object_n = normalize(billboard_n.xyz); + + var out: VertexOutput; + out.clip_pos = vp * world_p; + out.world_pos = world_p.xyz; + out.world_n = wn; + out.proj_pos = select(world_p.xyz, pos.xyz, object_space_enabled); + out.projection_n = select(wn, object_n, object_space_enabled); + out.view_layer = mv::packed_view_layer(instance_index, view_idx); + return out; +} + fn blend_rnm(n1_in: vec3, n2_in: vec3) -> vec3 { let n1 = vec3(n1_in.x, n1_in.y, n1_in.z + 1.0); let n2 = vec3(-n2_in.x, -n2_in.y, n2_in.z); diff --git a/crates/renderide/shaders/modules/post/filter_refraction.wgsl b/crates/renderide/shaders/modules/post/filter_refraction.wgsl index 73ff7db3d..29bc28795 100644 --- a/crates/renderide/shaders/modules/post/filter_refraction.wgsl +++ b/crates/renderide/shaders/modules/post/filter_refraction.wgsl @@ -53,6 +53,30 @@ fn vertex_main( return out; } +fn billboard_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + t: vec4, + uv0: vec2, + vertex_index: u32, + uv1: vec2 +) -> VertexOutput { + let inner = fv::billboard_vertex_main(instance_index, view_idx, pos, n, t, uv0, vertex_index, uv1); + var out: VertexOutput; + out.clip_pos = inner.clip_pos; + out.primary_uv = inner.primary_uv; + out.world_pos = inner.world_pos; + out.world_n = inner.world_n; + out.view_layer = inner.view_layer; + out.view_n = inner.view_n; + out.obj_xy = pos.xy; + out.view_t = view_tangent_for_draw(instance_index, view_idx, inner.world_t); + out.clip_w = inner.clip_pos.w; + return out; +} + fn normal_offset( refraction_enabled: bool, normal_map_enabled: bool, diff --git a/crates/renderide/shaders/modules/post/filter_vertex.wgsl b/crates/renderide/shaders/modules/post/filter_vertex.wgsl index 355597766..8a5285745 100644 --- a/crates/renderide/shaders/modules/post/filter_vertex.wgsl +++ b/crates/renderide/shaders/modules/post/filter_vertex.wgsl @@ -2,6 +2,7 @@ #define_import_path renderide::post::filter_vertex +#import renderide::billboard::vertex as bv #import renderide::core::math as rmath #import renderide::mesh::vertex as mv #import renderide::draw::per_draw as pd @@ -57,6 +58,37 @@ fn vertex_main( return out; } +fn billboard_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + t: vec4, + primary_uv: vec2, + vertex_index: u32, + uv1: vec2 +) -> VertexOutput { + let d = pd::get_draw(instance_index); + let vp = mv::select_view_proj(d, view_idx); + + let render_billboard_vertex = bv::render_buffer_billboard_vertex( + d, view_idx, pos, vertex_index, n, t, uv1, + ); + let world_p = render_billboard_vertex.world_pos; + let axes = render_billboard_vertex.axes; + let billboard_t = axes.right; + let billboard_n = rmath::safe_normalize(cross(axes.right, axes.up), vec3(0.0, 0.0, 1.0)); + var out: VertexOutput; + out.clip_pos = vp * world_p; + out.primary_uv = primary_uv; + out.world_pos = world_p.xyz; + out.world_n = mv::world_normal_for_view(d, vec4(billboard_n, 0.0), view_idx); + out.world_t = mv::world_tangent_for_view(d, vec4(billboard_t, 0.0), view_idx); + out.view_layer = view_idx; + out.view_n = vb::world_to_view_normal(out.world_n, vp); + return out; +} + fn rect_vertex_main( instance_index: u32, view_idx: u32, @@ -77,6 +109,28 @@ fn rect_vertex_main( return out; } +fn billboard_rect_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + t: vec4, + primary_uv: vec2, + vertex_index: u32, + uv1: vec2 +) -> RectVertexOutput { + let inner = billboard_vertex_main(instance_index, view_idx, pos, n, t, primary_uv, vertex_index, uv1); + var out: RectVertexOutput; + out.clip_pos = inner.clip_pos; + out.primary_uv = inner.primary_uv; + out.world_pos = inner.world_pos; + out.world_n = inner.world_n; + out.view_layer = inner.view_layer; + out.view_n = inner.view_n; + out.obj_xy = pos.xy; + return out; +} + fn position_rect_vertex_main( instance_index: u32, view_idx: u32, @@ -92,3 +146,21 @@ fn position_rect_vertex_main( out.view_layer = view_idx; return out; } + +fn billboard_position_rect_vertex_main( + instance_index: u32, + view_idx: u32, + pos: vec4, + n: vec4, + t: vec4, + primary_uv: vec2, + vertex_index: u32, + uv1: vec2 +) -> PositionRectVertexOutput { + let inner = billboard_vertex_main(instance_index, view_idx, pos, n, t, primary_uv, vertex_index, uv1); + var out: PositionRectVertexOutput; + out.clip_pos = inner.clip_pos; + out.obj_xy = pos.xy; + out.view_layer = view_idx; + return out; +} From 3e80f18189ad7a89bd4cab7d75be6012f2aa5245 Mon Sep 17 00:00:00 2001 From: Baplar Date: Fri, 5 Jun 2026 23:53:19 +0200 Subject: [PATCH 3/5] Revert removal of raw tangent buffer --- crates/renderide/src/assets/mesh/gpu_mesh.rs | 9 +++ .../src/assets/mesh/gpu_mesh/demand.rs | 20 ++--- .../src/assets/mesh/gpu_mesh/hints.rs | 4 + .../mesh/gpu_mesh/tangent_generation.rs | 42 +++++++++++ .../mesh/gpu_mesh/update/extended_streams.rs | 57 +++++++++++++- .../assets/mesh/gpu_mesh/update/in_place.rs | 1 + .../mesh/gpu_mesh/update/in_place_buffers.rs | 40 ++++++++-- .../assets/mesh/gpu_mesh/update/queries.rs | 16 ++-- .../src/assets/mesh/gpu_mesh/upload.rs | 27 ++++++- .../assets/mesh/gpu_mesh/upload/accounting.rs | 1 + .../mesh/gpu_mesh/upload/derived_streams.rs | 20 ++++- .../mesh/gpu_mesh/upload/extended_streams.rs | 39 +++++++++- .../assets/mesh/gpu_mesh/upload/generated.rs | 18 +++++ crates/renderide/src/assets/mesh/layout.rs | 9 ++- .../src/assets/mesh/layout/streams.rs | 8 +- .../src/backend/asset_transfers/mesh_task.rs | 4 +- .../src/backend/facade/graph_access/warmup.rs | 74 ++++++++----------- crates/renderide/src/gpu_pools/pools/mesh.rs | 8 +- .../src/materials/embedded/stem_metadata.rs | 12 ++- .../embedded/stem_metadata/vertex_streams.rs | 27 ++++++- .../src/materials/shader_specialization.rs | 9 +++ crates/renderide/src/particles/tests.rs | 12 +-- crates/renderide/src/particles/upload.rs | 2 +- crates/renderide/src/passes.rs | 5 +- .../src/passes/world_mesh_forward.rs | 4 +- .../encode/vertex_binding.rs | 45 ++++++++--- .../world_mesh_forward/material_batch.rs | 2 +- .../src/world_mesh/draw_prep/tests.rs | 2 + .../renderide/src/world_mesh/materials/key.rs | 2 + .../src/world_mesh/materials/resolve.rs | 56 +++++++++++++- .../renderide/src/world_mesh/test_fixtures.rs | 1 + 31 files changed, 456 insertions(+), 120 deletions(-) diff --git a/crates/renderide/src/assets/mesh/gpu_mesh.rs b/crates/renderide/src/assets/mesh/gpu_mesh.rs index d6f830c04..be4367b27 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh.rs @@ -155,6 +155,8 @@ pub struct GpuMesh { pub color_buffer: Option>, /// `vec4` tangent stream for shaders using extended vertex inputs. pub tangent_buffer: Option>, + /// Raw `vec4` tangent payload for UI shaders that use the tangent semantic as data. + pub raw_tangent_buffer: Option>, /// Tangent fallback policy used for the current tangent stream. pub tangent_fallback_mode: EmbeddedTangentFallbackMode, /// `vec2` UV1 stream for shaders using extended vertex inputs. @@ -295,6 +297,7 @@ pub(super) fn extended_vertex_stream_source_from_raw( pub(super) fn extended_vertex_stream_bytes(mesh: &GpuMesh) -> u64 { [ mesh.tangent_buffer.as_ref(), + mesh.raw_tangent_buffer.as_ref(), mesh.uv1_buffer.as_ref(), mesh.uv2_buffer.as_ref(), mesh.uv3_buffer.as_ref(), @@ -324,6 +327,7 @@ fn rebuildable_derived_stream_mask( } if source.has_compact_extended_payload { mask |= MeshDerivedStreamMask::TANGENT + | MeshDerivedStreamMask::RAW_TANGENT | MeshDerivedStreamMask::UV1 | MeshDerivedStreamMask::UV2 | MeshDerivedStreamMask::UV3; @@ -360,6 +364,9 @@ impl GpuMesh { if self.tangent_buffer.is_some() { mask |= MeshDerivedStreamMask::TANGENT; } + if self.raw_tangent_buffer.is_some() { + mask |= MeshDerivedStreamMask::RAW_TANGENT; + } if self.uv1_buffer.is_some() { mask |= MeshDerivedStreamMask::UV1; } @@ -429,6 +436,7 @@ impl GpuMesh { uv0_buffer: None, color_buffer: None, tangent_buffer: None, + raw_tangent_buffer: None, tangent_fallback_mode: EmbeddedTangentFallbackMode::default(), uv1_buffer: None, uv2_buffer: None, @@ -536,6 +544,7 @@ impl GpuMesh { uv0_buffer: derived.uv0_buffer, color_buffer: derived.color_buffer, tangent_buffer: derived.tangent_buffer, + raw_tangent_buffer: derived.raw_tangent_buffer, tangent_fallback_mode: EmbeddedTangentFallbackMode::default(), uv1_buffer: derived.uv1_buffer, uv2_buffer: derived.uv2_buffer, diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/demand.rs b/crates/renderide/src/assets/mesh/gpu_mesh/demand.rs index 2a2741a01..d3007190f 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/demand.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/demand.rs @@ -21,18 +21,18 @@ impl MeshDerivedStreamMask { pub(crate) const COLOR: Self = Self(1 << 3); /// Sanitized geometric tangent stream. pub(crate) const TANGENT: Self = Self(1 << 4); + /// Raw tangent payload stream. + pub(crate) const RAW_TANGENT: Self = Self(1 << 5); /// Compact UV1 stream. - pub(crate) const UV1: Self = Self(1 << 5); + pub(crate) const UV1: Self = Self(1 << 6); /// Compact UV2 stream. - pub(crate) const UV2: Self = Self(1 << 6); + pub(crate) const UV2: Self = Self(1 << 7); /// Compact UV3 stream. - pub(crate) const UV3: Self = Self(1 << 7); + pub(crate) const UV3: Self = Self(1 << 8); /// Packed UV0-UV3 stream for wide low UV inputs. - pub(crate) const WIDE_UV_LOW: Self = Self(1 << 8); + pub(crate) const WIDE_UV_LOW: Self = Self(1 << 9); /// Packed UV4-UV7 stream for high UV inputs. - pub(crate) const WIDE_UV_HIGH: Self = Self(1 << 9); - /// Billboard direction stream replacing tangent and uv1. - pub(crate) const BILLBOARD: Self = Self(1 << 10); + pub(crate) const WIDE_UV_HIGH: Self = Self(1 << 10); /// Streams affected when interleaved vertex data changes. pub(crate) const VERTEX_DERIVED: Self = Self( Self::POSITION.0 @@ -40,12 +40,12 @@ impl MeshDerivedStreamMask { | Self::UV0.0 | Self::COLOR.0 | Self::TANGENT.0 + | Self::RAW_TANGENT.0 | Self::UV1.0 | Self::UV2.0 | Self::UV3.0 | Self::WIDE_UV_LOW.0 - | Self::WIDE_UV_HIGH.0 - | Self::BILLBOARD.0, + | Self::WIDE_UV_HIGH.0, ); /// Streams affected when index order changes. pub(crate) const INDEX_DERIVED: Self = Self(Self::TANGENT.0); @@ -53,7 +53,7 @@ impl MeshDerivedStreamMask { pub(crate) const DRAWABLE_PRIMARY: Self = Self(Self::POSITION.0 | Self::NORMAL.0); /// Streams produced by generated particle meshes in steady state. pub(crate) const GENERATED_PARTICLE: Self = - Self(Self::POSITION.0 | Self::NORMAL.0 | Self::UV0.0 | Self::COLOR.0 | Self::BILLBOARD.0); + Self(Self::POSITION.0 | Self::NORMAL.0 | Self::UV0.0 | Self::COLOR.0); /// Returns the raw bit representation. #[inline] diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/hints.rs b/crates/renderide/src/assets/mesh/gpu_mesh/hints.rs index 7999fa1f5..5dae0bfc1 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/hints.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/hints.rs @@ -86,6 +86,7 @@ pub(super) fn derived_streams_compatible_for_in_place( && gpu.uv0_buffer.is_none() && gpu.color_buffer.is_none() && gpu.tangent_buffer.is_none() + && gpu.raw_tangent_buffer.is_none() && gpu.uv1_buffer.is_none() && gpu.uv2_buffer.is_none() && gpu.uv3_buffer.is_none() @@ -120,6 +121,9 @@ pub(super) fn derived_streams_compatible_for_in_place( if !optional_stream_size_matches(gpu.tangent_buffer.as_deref(), Some(vec4_bytes)) { return false; } + if !optional_stream_size_matches(gpu.raw_tangent_buffer.as_deref(), Some(vec4_bytes)) { + return false; + } for buffer in [&gpu.uv1_buffer, &gpu.uv2_buffer, &gpu.uv3_buffer] { if !optional_stream_size_matches(buffer.as_deref(), Some(uv_bytes)) { return false; diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/tangent_generation.rs b/crates/renderide/src/assets/mesh/gpu_mesh/tangent_generation.rs index 696a3cf30..bc6f337bb 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/tangent_generation.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/tangent_generation.rs @@ -10,6 +10,7 @@ use crate::shared::{ }; use super::super::layout::VertexDecodeKind; +use super::super::layout::raw_float4_stream_bytes; use super::attribute_reader::AttributeReader; const _: () = assert!( @@ -19,6 +20,7 @@ const _: () = assert!( const DEFAULT_TANGENT: [f32; 4] = [1.0, 0.0, 0.0, 1.0]; const DEFAULT_TANGENT_VEC: Vec4 = Vec4::new(1.0, 0.0, 0.0, 1.0); +const DEFAULT_RAW_TANGENT_PAYLOAD: [f32; 4] = [1.0, 1.0, 1.0, 1.0]; const TANGENT_EPSILON_SQUARED: f32 = 1.0e-20; /// Vertices assigned to one tangent extraction or encoding worker chunk. const VERTEX_STREAM_PARALLEL_CHUNK_VERTICES: usize = 256; @@ -107,6 +109,18 @@ pub(super) fn tangent_stream_bytes( ) } +/// Returns a dense `vec4` tangent payload stream without geometric sanitization. +pub(super) fn raw_tangent_payload_stream_bytes(source: TangentStreamSource<'_>) -> Option> { + raw_float4_stream_bytes( + source.vertex_data, + source.vertex_count, + source.stride, + source.attrs, + VertexAttributeType::Tangent, + DEFAULT_RAW_TANGENT_PAYLOAD, + ) +} + fn host_tangent_stream_bytes( vertex_data: &[u8], vertex_count: usize, @@ -641,6 +655,34 @@ mod tests { assert_eq!(read_tangent(&tangents, 0), [0.0, 1.0, 0.0, -1.0]); } + #[test] + fn raw_tangent_payload_stream_preserves_color_data() { + let attrs = [ + attr(VertexAttributeType::Position, 3), + attr(VertexAttributeType::Normal, 3), + attr(VertexAttributeType::UV0, 2), + attr(VertexAttributeType::Tangent, 4), + ]; + let mut vertices = Vec::new(); + push_vertex_with_tangent( + &mut vertices, + [0.0, 0.0, 0.0], + [0.0, 0.0, 1.0], + [0.0, 0.0], + [0.0, 0.0, 0.0, 0.75], + ); + + let geometric = + tangent_stream_bytes(tangent_source(&vertices, &[], 1, 48, &attrs, &[]), false) + .expect("geometric tangent stream"); + let raw = + raw_tangent_payload_stream_bytes(tangent_source(&vertices, &[], 1, 48, &attrs, &[])) + .expect("raw tangent stream"); + + assert_eq!(read_tangent(&geometric, 0), [1.0, 0.0, 0.0, 1.0]); + assert_eq!(read_tangent(&raw, 0), [0.0, 0.0, 0.0, 0.75]); + } + #[test] fn missing_tangents_are_generated_for_indexed_textured_triangle_mesh() { let attrs = [ diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/update/extended_streams.rs b/crates/renderide/src/assets/mesh/gpu_mesh/update/extended_streams.rs index 763131cb8..baf837d5a 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/update/extended_streams.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/update/extended_streams.rs @@ -5,10 +5,11 @@ use crate::shared::VertexAttributeType; use super::super::upload::{ ExtendedVertexUploadSource, UvVertexUploadSource, upload_color_vertex_stream, - upload_default_extended_vertex_streams, upload_default_tangent_vertex_stream, - upload_default_uv_vertex_stream, upload_default_wide_high_uv_vertex_stream, - upload_default_wide_low_uv_vertex_stream, upload_extended_vertex_streams, - upload_position_normal_vertex_streams, upload_tangent_vertex_stream, upload_uv_vertex_stream, + upload_default_extended_vertex_streams, upload_default_raw_tangent_vertex_stream, + upload_default_tangent_vertex_stream, upload_default_uv_vertex_stream, + upload_default_wide_high_uv_vertex_stream, upload_default_wide_low_uv_vertex_stream, + upload_extended_vertex_streams, upload_position_normal_vertex_streams, + upload_raw_tangent_vertex_stream, upload_tangent_vertex_stream, upload_uv_vertex_stream, upload_uv0_vertex_stream, upload_wide_high_uv_vertex_stream, upload_wide_low_uv_vertex_stream, }; use super::super::{ @@ -275,6 +276,54 @@ impl GpuMesh { true } + /// Creates a raw tangent payload stream for UI shaders that use `TANGENT` as data. + pub(crate) fn ensure_raw_tangent_vertex_stream(&mut self, device: &wgpu::Device) -> bool { + profiling::scope!("asset::mesh_ensure_raw_tangent_vertex_stream"); + if self.raw_tangent_vertex_stream_ready() { + return true; + } + + let vc_usize = self.vertex_count as usize; + let raw_tangent_buffer = if let Some(source) = self.extended_vertex_stream_source.as_ref() { + upload_raw_tangent_vertex_stream( + device, + self.asset_id, + ExtendedVertexUploadSource { + vertex_slice: source.vertex_bytes.as_ref(), + index_slice: source.index_bytes.as_ref(), + vertex_count: vc_usize, + vertex_stride: self.vertex_stride as usize, + vertex_attributes: source.vertex_attributes.as_ref(), + index_format: source.index_format, + submeshes: source.submeshes.as_ref(), + }, + ) + } else { + upload_default_raw_tangent_vertex_stream(device, self.asset_id, vc_usize) + }; + + let Some(raw_tangent_buffer) = raw_tangent_buffer else { + return false; + }; + let old_bytes = self + .raw_tangent_buffer + .as_ref() + .map_or(0, |buffer| buffer.size()); + self.raw_tangent_buffer = Some(raw_tangent_buffer); + let new_bytes = self + .raw_tangent_buffer + .as_ref() + .map_or(0, |buffer| buffer.size()); + self.resident_bytes = self + .resident_bytes + .saturating_sub(old_bytes) + .saturating_add(new_bytes); + self.derived_stream_state + .mark_clean(MeshDerivedStreamMask::RAW_TANGENT); + self.drop_extended_vertex_stream_source_if_complete(); + true + } + /// Creates a UV1 stream the first time an embedded shader needs it without other extended streams. pub(crate) fn ensure_uv1_vertex_stream(&mut self, device: &wgpu::Device) -> bool { profiling::scope!("asset::mesh_ensure_uv1_vertex_stream"); diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place.rs b/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place.rs index 7f2019bb9..67bc422e7 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place.rs @@ -343,6 +343,7 @@ fn rebuild_mesh_after_in_place_write( uv0_buffer: mesh.uv0_buffer.clone(), color_buffer: mesh.color_buffer.clone(), tangent_buffer: mesh.tangent_buffer.clone(), + raw_tangent_buffer: mesh.raw_tangent_buffer.clone(), tangent_fallback_mode: mesh.tangent_fallback_mode, uv1_buffer: mesh.uv1_buffer.clone(), uv2_buffer: mesh.uv2_buffer.clone(), diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place_buffers.rs b/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place_buffers.rs index 3bce70f80..d288d6b76 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place_buffers.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/update/in_place_buffers.rs @@ -15,7 +15,9 @@ use super::super::super::layout::{ wide_low_uv_stream_bytes, }; use super::super::hints::{blendshape_descriptor_count, derived_streams_compatible_for_in_place}; -use super::super::tangent_generation::{TangentStreamSource, tangent_stream_bytes}; +use super::super::tangent_generation::{ + TangentStreamSource, raw_tangent_payload_stream_bytes, tangent_stream_bytes, +}; use super::super::upload::{ padded_sparse_bytes, queue_init_buffer_size_matches, write_mesh_upload_buffer, }; @@ -175,6 +177,7 @@ enum InPlaceDerivedStreamJob { WideLowUv, WideHighUv, Tangent, + RawTangent, Uv1, Uv2, Uv3, @@ -187,6 +190,7 @@ enum InPlaceDerivedStreamResult { WideLowUv(Option>), WideHighUv(Option>), Tangent(Option>), + RawTangent(Option>), Uv1(Option>), Uv2(Option>), Uv3(Option>), @@ -242,6 +246,9 @@ impl InPlaceDerivedStreamJob { in_place_tangent_source(source), source.generate_missing_tangents, )), + Self::RawTangent => InPlaceDerivedStreamResult::RawTangent( + raw_tangent_payload_stream_bytes(in_place_tangent_source(source)), + ), Self::Uv1 => InPlaceDerivedStreamResult::Uv1(vertex_float2_stream_bytes( source.vertex_slice, source.vertex_count, @@ -332,7 +339,7 @@ pub(super) fn write_in_place_vertex_and_derived_streams( if ctx .demand_mask - .intersects(MeshDerivedStreamMask::TANGENT | MeshDerivedStreamMask::BILLBOARD) + .intersects(MeshDerivedStreamMask::TANGENT | MeshDerivedStreamMask::RAW_TANGENT) { profiling::scope!("asset::mesh_write_in_place::write_tangent_stream"); let source = TangentStreamSource { @@ -345,7 +352,8 @@ pub(super) fn write_in_place_vertex_and_derived_streams( index_format: ctx.data.index_buffer_format, submeshes: &ctx.data.submeshes, }; - if let Some(tb) = ctx.mesh.tangent_buffer.as_ref() + if ctx.demand_mask.contains(MeshDerivedStreamMask::TANGENT) + && let Some(tb) = ctx.mesh.tangent_buffer.as_ref() && let Some(t) = ctx .prepared_derived_streams .and_then(|prepared| prepared.tangent.as_deref()) @@ -357,6 +365,16 @@ pub(super) fn write_in_place_vertex_and_derived_streams( { write_mesh_upload_buffer(ctx.upload_sink, tb.as_ref(), 0, t.as_ref()); } + if ctx.demand_mask.contains(MeshDerivedStreamMask::RAW_TANGENT) + && let Some(tb) = ctx.mesh.raw_tangent_buffer.as_ref() + && let Some(t) = ctx + .prepared_derived_streams + .and_then(|prepared| prepared.raw_tangent.as_deref()) + .map(std::borrow::Cow::Borrowed) + .or_else(|| raw_tangent_payload_stream_bytes(source).map(std::borrow::Cow::Owned)) + { + write_mesh_upload_buffer(ctx.upload_sink, tb.as_ref(), 0, t.as_ref()); + } } if !write_vertex { @@ -364,10 +382,7 @@ pub(super) fn write_in_place_vertex_and_derived_streams( } if ctx.demand_mask.intersects( - MeshDerivedStreamMask::UV1 - | MeshDerivedStreamMask::UV2 - | MeshDerivedStreamMask::UV3 - | MeshDerivedStreamMask::BILLBOARD, + MeshDerivedStreamMask::UV1 | MeshDerivedStreamMask::UV2 | MeshDerivedStreamMask::UV3, ) { write_in_place_uv1_to_uv3_streams(ctx, vertex_slice); } @@ -412,6 +427,11 @@ fn try_write_in_place_derived_streams_parallel( { jobs.push(InPlaceDerivedStreamJob::Tangent); } + if ctx.demand_mask.contains(MeshDerivedStreamMask::RAW_TANGENT) + && ctx.mesh.raw_tangent_buffer.is_some() + { + jobs.push(InPlaceDerivedStreamJob::RawTangent); + } if write_vertex { if ctx.demand_mask.contains(MeshDerivedStreamMask::UV1) && ctx.mesh.uv1_buffer.is_some() { jobs.push(InPlaceDerivedStreamJob::Uv1); @@ -499,6 +519,12 @@ fn write_in_place_derived_stream_result( } } InPlaceDerivedStreamResult::Tangent(None) => {} + InPlaceDerivedStreamResult::RawTangent(Some(bytes)) => { + if let Some(buffer) = ctx.mesh.raw_tangent_buffer.as_ref() { + write_mesh_upload_buffer(ctx.upload_sink, buffer.as_ref(), 0, &bytes); + } + } + InPlaceDerivedStreamResult::RawTangent(None) => {} InPlaceDerivedStreamResult::Uv1(Some(bytes)) => { if let Some(buffer) = ctx.mesh.uv1_buffer.as_ref() { write_mesh_upload_buffer(ctx.upload_sink, buffer.as_ref(), 0, &bytes); diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/update/queries.rs b/crates/renderide/src/assets/mesh/gpu_mesh/update/queries.rs index 4a1fb75fd..cf443a928 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/update/queries.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/update/queries.rs @@ -40,6 +40,14 @@ impl GpuMesh { ) } + /// `true` when this mesh has a current raw tangent payload stream for UI payload shaders. + pub fn raw_tangent_vertex_stream_ready(&self) -> bool { + self.derived_stream_state.streams_ready( + self.raw_tangent_buffer.is_some(), + MeshDerivedStreamMask::RAW_TANGENT, + ) + } + /// `true` when this mesh has a current standalone UV2 stream for compact shaders. pub fn uv2_vertex_stream_ready(&self) -> bool { self.derived_stream_state @@ -68,14 +76,6 @@ impl GpuMesh { ) } - /// `true` when this mesh has current billboard payload streams for particles. - pub fn billboard_vertex_streams_ready(&self) -> bool { - self.derived_stream_state.streams_ready( - self.tangent_buffer.is_some() && self.uv1_buffer.is_some(), - MeshDerivedStreamMask::BILLBOARD, - ) - } - /// Returns whether this mesh has every GPU stream needed to produce world-space skinned output. pub fn supports_world_space_skin_deform(&self, bone_transform_indices: Option<&[i32]>) -> bool { bone_transform_indices.is_some() diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/upload.rs b/crates/renderide/src/assets/mesh/gpu_mesh/upload.rs index 2a9b953f6..d66f7ede9 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/upload.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/upload.rs @@ -13,10 +13,11 @@ pub(super) use bone_skin::upload_bone_and_skin_buffers; pub(crate) use derived_streams::{PreparedDerivedStreams, prepare_derived_stream_bytes}; pub(super) use extended_streams::{ ExtendedVertexUploadSource, UvVertexUploadSource, upload_color_vertex_stream, - upload_default_extended_vertex_streams, upload_default_tangent_vertex_stream, - upload_default_uv_vertex_stream, upload_default_wide_high_uv_vertex_stream, - upload_default_wide_low_uv_vertex_stream, upload_extended_vertex_streams, - upload_position_normal_vertex_streams, upload_tangent_vertex_stream, upload_uv_vertex_stream, + upload_default_extended_vertex_streams, upload_default_raw_tangent_vertex_stream, + upload_default_tangent_vertex_stream, upload_default_uv_vertex_stream, + upload_default_wide_high_uv_vertex_stream, upload_default_wide_low_uv_vertex_stream, + upload_extended_vertex_streams, upload_position_normal_vertex_streams, + upload_raw_tangent_vertex_stream, upload_tangent_vertex_stream, upload_uv_vertex_stream, upload_uv0_vertex_stream, upload_wide_high_uv_vertex_stream, upload_wide_low_uv_vertex_stream, }; #[cfg(test)] @@ -91,6 +92,7 @@ pub(super) struct DerivedStreams { pub uv0_buffer: Option>, pub color_buffer: Option>, pub tangent_buffer: Option>, + pub raw_tangent_buffer: Option>, pub uv1_buffer: Option>, pub uv2_buffer: Option>, pub uv3_buffer: Option>, @@ -116,6 +118,9 @@ impl DerivedStreams { if self.tangent_buffer.is_some() { mask |= MeshDerivedStreamMask::TANGENT; } + if self.raw_tangent_buffer.is_some() { + mask |= MeshDerivedStreamMask::RAW_TANGENT; + } if self.uv1_buffer.is_some() { mask |= MeshDerivedStreamMask::UV1; } @@ -408,6 +413,7 @@ enum DerivedBufferProfile { Uv0, Color, Tangent, + RawTangent, Uv1, Uv2, Uv3, @@ -423,6 +429,7 @@ impl DerivedBufferProfile { Self::Uv0 => "uv0", Self::Color => "color", Self::Tangent => "tangent", + Self::RawTangent => "raw_tangent", Self::Uv1 => "uv1", Self::Uv2 => "uv2", Self::Uv3 => "uv3", @@ -448,6 +455,9 @@ impl DerivedBufferProfile { Self::Tangent => { crate::profiling::note_resource_churn!(Buffer, "assets::mesh_tangent_stream"); } + Self::RawTangent => { + crate::profiling::note_resource_churn!(Buffer, "assets::mesh_raw_tangent_stream"); + } Self::Uv1 => { crate::profiling::note_resource_churn!(Buffer, "assets::mesh_uv1_stream"); } @@ -573,6 +583,14 @@ fn upload_prepared_derived_streams( usages.tangent, )? .into_buffer(), + raw_tangent_buffer: upload_derived_buffer( + ctx, + asset_id, + DerivedBufferProfile::RawTangent, + prepared.raw_tangent.as_deref(), + usages.tangent, + )? + .into_buffer(), uv1_buffer: upload_derived_buffer( ctx, asset_id, @@ -814,6 +832,7 @@ mod tests { assert_eq!(prepared.uv0.as_deref(), Some(uv0.as_slice())); assert_eq!(prepared.color.as_deref(), Some(color.as_slice())); assert!(prepared.tangent.is_none()); + assert!(prepared.raw_tangent.is_none()); assert!(prepared.uv1.is_none()); assert!(prepared.uv2.is_none()); assert!(prepared.uv3.is_none()); diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/upload/accounting.rs b/crates/renderide/src/assets/mesh/gpu_mesh/upload/accounting.rs index 053dc94de..60d18796d 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/upload/accounting.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/upload/accounting.rs @@ -36,6 +36,7 @@ pub(in crate::assets::mesh::gpu_mesh) fn resident_bytes_for_mesh_upload( derived.uv0_buffer.as_ref(), derived.color_buffer.as_ref(), derived.tangent_buffer.as_ref(), + derived.raw_tangent_buffer.as_ref(), derived.uv1_buffer.as_ref(), derived.uv2_buffer.as_ref(), derived.uv3_buffer.as_ref(), diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/upload/derived_streams.rs b/crates/renderide/src/assets/mesh/gpu_mesh/upload/derived_streams.rs index 9a2f911e2..44099075a 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/upload/derived_streams.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/upload/derived_streams.rs @@ -11,7 +11,9 @@ use super::super::super::layout::{ vertex_float2_stream_bytes, wide_high_uv_stream_bytes, wide_low_uv_stream_bytes, }; use super::super::demand::{MeshDerivedStreamDemand, MeshDerivedStreamMask}; -use super::super::tangent_generation::{TangentStreamSource, tangent_stream_bytes}; +use super::super::tangent_generation::{ + TangentStreamSource, raw_tangent_payload_stream_bytes, tangent_stream_bytes, +}; /// CPU-prepared derived vertex stream bytes for a full mesh upload. #[derive(Clone, Debug, Default)] @@ -26,6 +28,8 @@ pub(crate) struct PreparedDerivedStreams { pub(crate) color: Option>, /// Geometric tangent stream bytes. pub(crate) tangent: Option>, + /// Raw tangent payload bytes. + pub(crate) raw_tangent: Option>, /// UV1 stream bytes. pub(crate) uv1: Option>, /// UV2 stream bytes. @@ -44,6 +48,7 @@ enum DerivedStreamJob { Uv0, Color, Tangent, + RawTangent, Uv1, Uv2, Uv3, @@ -56,6 +61,7 @@ enum DerivedStreamJobResult { Uv0(Option>), Color(Option>), Tangent(Option>), + RawTangent(Option>), Uv1(Option>), Uv2(Option>), Uv3(Option>), @@ -98,6 +104,11 @@ impl DerivedStreamJob { tangent_source(vertex_slice, index_slice, data, vc_usize, vertex_stride_us), demand.tangent_fallback_mode.generate_missing(), )), + Self::RawTangent => { + DerivedStreamJobResult::RawTangent(raw_tangent_payload_stream_bytes( + tangent_source(vertex_slice, index_slice, data, vc_usize, vertex_stride_us), + )) + } Self::Uv1 => DerivedStreamJobResult::Uv1(vertex_float2_stream_bytes( vertex_slice, vc_usize, @@ -146,6 +157,7 @@ impl PreparedDerivedStreams { DerivedStreamJobResult::Uv0(bytes) => self.uv0 = bytes, DerivedStreamJobResult::Color(bytes) => self.color = bytes, DerivedStreamJobResult::Tangent(bytes) => self.tangent = bytes, + DerivedStreamJobResult::RawTangent(bytes) => self.raw_tangent = bytes, DerivedStreamJobResult::Uv1(bytes) => self.uv1 = bytes, DerivedStreamJobResult::Uv2(bytes) => self.uv2 = bytes, DerivedStreamJobResult::Uv3(bytes) => self.uv3 = bytes, @@ -186,6 +198,9 @@ pub(crate) fn prepare_derived_stream_bytes( if demand.mask.contains(MeshDerivedStreamMask::TANGENT) { jobs.push(DerivedStreamJob::Tangent); } + if demand.mask.contains(MeshDerivedStreamMask::RAW_TANGENT) { + jobs.push(DerivedStreamJob::RawTangent); + } if demand.mask.contains(MeshDerivedStreamMask::UV1) { jobs.push(DerivedStreamJob::Uv1); } @@ -286,6 +301,9 @@ impl PreparedDerivedStreams { if self.tangent.is_some() { mask |= MeshDerivedStreamMask::TANGENT; } + if self.raw_tangent.is_some() { + mask |= MeshDerivedStreamMask::RAW_TANGENT; + } if self.uv1.is_some() { mask |= MeshDerivedStreamMask::UV1; } diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/upload/extended_streams.rs b/crates/renderide/src/assets/mesh/gpu_mesh/upload/extended_streams.rs index 2453ee7b7..c7de235da 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/upload/extended_streams.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/upload/extended_streams.rs @@ -15,7 +15,9 @@ use super::super::super::layout::{ extract_float3_position_normal_as_vec4_streams, uv0_float2_stream_bytes, vertex_float2_stream_bytes, wide_high_uv_stream_bytes, wide_low_uv_stream_bytes, }; -use super::super::tangent_generation::{TangentStreamSource, tangent_stream_bytes}; +use super::super::tangent_generation::{ + TangentStreamSource, raw_tangent_payload_stream_bytes, tangent_stream_bytes, +}; /// Tangent plus UV1-UV3 optional vertex buffers from extended stream upload. pub(in crate::assets::mesh::gpu_mesh) type ExtendedVertexStreams = ( @@ -409,6 +411,41 @@ pub(in crate::assets::mesh::gpu_mesh) fn upload_tangent_vertex_stream( )) } +/// Uploads the raw tangent payload expected by raw-tangent shaders. +pub(in crate::assets::mesh::gpu_mesh) fn upload_raw_tangent_vertex_stream( + device: &wgpu::Device, + asset_id: i32, + source: ExtendedVertexUploadSource<'_>, +) -> Option> { + if source.vertex_count == 0 { + return None; + } + let tangent_bytes = raw_tangent_payload_stream_bytes(source.tangent_source()) + .unwrap_or_else(|| float4_default_stream_bytes(source.vertex_count, [1.0; 4])); + Some(create_tangent_stream_buffer( + device, + asset_id, + &tangent_bytes, + )) +} + +/// Uploads a raw tangent payload stream filled with default values. +pub(in crate::assets::mesh::gpu_mesh) fn upload_default_raw_tangent_vertex_stream( + device: &wgpu::Device, + asset_id: i32, + vc_usize: usize, +) -> Option> { + if vc_usize == 0 { + return None; + } + let tangent_bytes = float4_default_stream_bytes(vc_usize, [1.0; 4]); + Some(create_tangent_stream_buffer( + device, + asset_id, + &tangent_bytes, + )) +} + /// Uploads a tangent stream filled with default tangent values. pub(in crate::assets::mesh::gpu_mesh) fn upload_default_tangent_vertex_stream( device: &wgpu::Device, diff --git a/crates/renderide/src/assets/mesh/gpu_mesh/upload/generated.rs b/crates/renderide/src/assets/mesh/gpu_mesh/upload/generated.rs index 670b87fb3..c030507f9 100644 --- a/crates/renderide/src/assets/mesh/gpu_mesh/upload/generated.rs +++ b/crates/renderide/src/assets/mesh/gpu_mesh/upload/generated.rs @@ -212,6 +212,10 @@ fn generated_particle_mesh_input_is_valid( ("positions", prepared.positions.as_deref().unwrap_or(&[])), ("normals", prepared.normals.as_deref().unwrap_or(&[])), ("tangent", prepared.tangent.as_deref().unwrap_or(&[])), + ( + "raw_tangent", + prepared.raw_tangent.as_deref().unwrap_or(&[]), + ), ] { let size = queue_init_buffer_size(bytes.len()); if size > max_buf || size > max_storage { @@ -284,6 +288,7 @@ struct GeneratedPrimaryDerivedBuffers { struct GeneratedExtendedDerivedBuffers { tangent_buffer: Option>, + raw_tangent_buffer: Option>, uv1_buffer: Option>, uv2_buffer: Option>, uv3_buffer: Option>, @@ -360,6 +365,16 @@ fn upload_generated_extended_derived_streams( limits.storage_size_limit, )? .into_buffer(), + raw_tangent_buffer: upload_generated_derived_buffer( + ctx, + existing.and_then(|mesh| mesh.raw_tangent_buffer.as_ref()), + asset_id, + DerivedBufferProfile::RawTangent, + prepared.raw_tangent.as_deref(), + limits.usages.tangent, + limits.storage_size_limit, + )? + .into_buffer(), uv1_buffer: upload_generated_derived_buffer( ctx, existing.and_then(|mesh| mesh.uv1_buffer.as_ref()), @@ -430,6 +445,7 @@ fn upload_generated_derived_streams( uv0_buffer: primary.uv0_buffer, color_buffer: primary.color_buffer, tangent_buffer: extended.tangent_buffer, + raw_tangent_buffer: extended.raw_tangent_buffer, uv1_buffer: extended.uv1_buffer, uv2_buffer: extended.uv2_buffer, uv3_buffer: extended.uv3_buffer, @@ -451,6 +467,7 @@ fn generated_mesh_resident_bytes( derived.uv0_buffer.as_ref(), derived.color_buffer.as_ref(), derived.tangent_buffer.as_ref(), + derived.raw_tangent_buffer.as_ref(), derived.uv1_buffer.as_ref(), derived.uv2_buffer.as_ref(), derived.uv3_buffer.as_ref(), @@ -524,6 +541,7 @@ pub(crate) fn try_upload_generated_mesh_from_parts( uv0_buffer: derived.uv0_buffer, color_buffer: derived.color_buffer, tangent_buffer: derived.tangent_buffer, + raw_tangent_buffer: derived.raw_tangent_buffer, tangent_fallback_mode: EmbeddedTangentFallbackMode::default(), uv1_buffer: derived.uv1_buffer, uv2_buffer: derived.uv2_buffer, diff --git a/crates/renderide/src/assets/mesh/layout.rs b/crates/renderide/src/assets/mesh/layout.rs index fff90b6d8..7936dec5b 100644 --- a/crates/renderide/src/assets/mesh/layout.rs +++ b/crates/renderide/src/assets/mesh/layout.rs @@ -22,14 +22,15 @@ pub use buffer_layout::{ extract_bind_poses, index_bytes_per_element, }; pub(in crate::assets::mesh) use skinning::split_bone_weights_tail_for_gpu; +#[cfg(test)] +pub use streams::vertex_float4_stream_bytes; pub use streams::{ UV_VERTEX_ATTRIBUTE_TYPES, WIDE_UV_HIGH_VERTEX_STRIDE_BYTES, WIDE_UV_LOW_VERTEX_STRIDE_BYTES, attribute_offset_and_size, color_float4_stream_bytes, - extract_float3_position_normal_as_vec4_streams, uv0_float2_stream_bytes, - vertex_float2_stream_bytes, wide_high_uv_stream_bytes, wide_low_uv_stream_bytes, + extract_float3_position_normal_as_vec4_streams, raw_float4_stream_bytes, + uv0_float2_stream_bytes, vertex_float2_stream_bytes, wide_high_uv_stream_bytes, + wide_low_uv_stream_bytes, }; pub(in crate::assets::mesh) use streams::{ VertexDecodeKind, decode_vertex_vec2, decode_vertex_vec3, decode_vertex_vec4, }; -#[cfg(test)] -pub use streams::{raw_float4_stream_bytes, vertex_float4_stream_bytes}; diff --git a/crates/renderide/src/assets/mesh/layout/streams.rs b/crates/renderide/src/assets/mesh/layout/streams.rs index d952cdf5c..a4cdc6b6a 100644 --- a/crates/renderide/src/assets/mesh/layout/streams.rs +++ b/crates/renderide/src/assets/mesh/layout/streams.rs @@ -36,6 +36,8 @@ pub const WIDE_UV_HIGH_VERTEX_STRIDE_BYTES: usize = WIDE_UV_PAGE_VERTEX_STRIDE_B /// Attribute semantic used when expanding host vertex scalars into float streams. #[derive(Clone, Copy)] pub(in crate::assets::mesh) enum VertexDecodeKind { + /// Data payloads that should preserve the host-authored scalar values. + Raw, /// Object-space position data. Position, /// Direction vectors such as normals and tangents. @@ -377,7 +379,6 @@ fn write_wide_uv_page_vertex( /// Dense `vec4` vertex stream for an arbitrary float attribute. /// /// Missing or unsupported attributes return `default` per vertex. -#[cfg(test)] fn vertex_float4_stream_bytes_with_kind( vertex_data: &[u8], vertex_count: usize, @@ -430,7 +431,6 @@ fn write_vertex_float4( /// Dense raw `vec4` payload stream for attributes used as shader data instead of geometry. /// /// Missing or unsupported attributes return `default` per vertex. -#[cfg(test)] pub fn raw_float4_stream_bytes( vertex_data: &[u8], vertex_count: usize, @@ -446,7 +446,7 @@ pub fn raw_float4_stream_bytes( attrs, target, default, - VertexDecodeKind::Position, + VertexDecodeKind::Raw, ) } @@ -668,7 +668,7 @@ fn apply_unsigned_integer(value: f32, max_value: f32, kind: VertexDecodeKind) -> match kind { VertexDecodeKind::Color => value / max_value, VertexDecodeKind::Direction => (value / max_value).mul_add(2.0, -1.0), - VertexDecodeKind::Position | VertexDecodeKind::TexCoord => value, + VertexDecodeKind::Raw | VertexDecodeKind::Position | VertexDecodeKind::TexCoord => value, } } diff --git a/crates/renderide/src/backend/asset_transfers/mesh_task.rs b/crates/renderide/src/backend/asset_transfers/mesh_task.rs index a13d21143..4239f97ea 100644 --- a/crates/renderide/src/backend/asset_transfers/mesh_task.rs +++ b/crates/renderide/src/backend/asset_transfers/mesh_task.rs @@ -452,7 +452,9 @@ fn should_prepare_derived_streams_on_worker( } raw_len >= MESH_PREPARE_BACKGROUND_MIN_BYTES || data.vertex_count >= MESH_PREPARE_BACKGROUND_MIN_VERTICES - || demand.mask.contains(MeshDerivedStreamMask::TANGENT) + || demand + .mask + .intersects(MeshDerivedStreamMask::TANGENT | MeshDerivedStreamMask::RAW_TANGENT) } fn spawn_prepare_derived_streams( diff --git a/crates/renderide/src/backend/facade/graph_access/warmup.rs b/crates/renderide/src/backend/facade/graph_access/warmup.rs index 27cd6391e..fd1e05e86 100644 --- a/crates/renderide/src/backend/facade/graph_access/warmup.rs +++ b/crates/renderide/src/backend/facade/graph_access/warmup.rs @@ -26,12 +26,12 @@ use super::BackendGraphAccess; struct ViewAssetPrewarmRequests { uv1_stream_meshes: HashSet, tangent_stream_meshes: HashSet, + raw_tangent_stream_meshes: HashSet, tangent_fallback_modes: HashMap, uv2_stream_meshes: HashSet, uv3_stream_meshes: HashSet, wide_low_uv_stream_meshes: HashSet, wide_high_uv_stream_meshes: HashSet, - billboard_stream_meshes: HashSet, derived_stream_demands: HashMap, } @@ -54,7 +54,10 @@ impl ViewAssetPrewarmRequests { if item.batch_key.embedded_needs_color { demand.mask |= MeshDerivedStreamMask::COLOR; } - if item.batch_key.embedded_needs_tangent { + if item.batch_key.embedded_needs_tangent && item.batch_key.embedded_raw_tangent_payload { + self.raw_tangent_stream_meshes.insert(item.mesh_asset_id); + demand.mask |= MeshDerivedStreamMask::RAW_TANGENT; + } else if item.batch_key.embedded_needs_tangent { self.tangent_stream_meshes.insert(item.mesh_asset_id); demand.mask |= MeshDerivedStreamMask::TANGENT; let mode = self @@ -79,10 +82,6 @@ impl ViewAssetPrewarmRequests { self.wide_high_uv_stream_meshes.insert(item.mesh_asset_id); demand.mask |= MeshDerivedStreamMask::WIDE_UV_HIGH; } - if item.batch_key.embedded_uses_billboard_geometry { - self.billboard_stream_meshes.insert(item.mesh_asset_id); - demand.mask |= MeshDerivedStreamMask::BILLBOARD; - } self.derived_stream_demands .entry(item.mesh_asset_id) .or_default() @@ -242,16 +241,16 @@ impl<'a> BackendGraphAccess<'a> { profiling::scope!("graph::pre_warm_view_assets"); let requests = collect_view_asset_prewarm_requests(views); logger::trace!( - "graph pre-warm view assets: views={} uv1_stream_meshes={} tangent_stream_meshes={} generated_tangent_meshes={} uv2_stream_meshes={} uv3_stream_meshes={} wide_low_uv_stream_meshes={} wide_high_uv_stream_meshes={} billboard_stream_meshes={}", + "graph pre-warm view assets: views={} uv1_stream_meshes={} tangent_stream_meshes={} raw_tangent_stream_meshes={} generated_tangent_meshes={} uv2_stream_meshes={} uv3_stream_meshes={} wide_low_uv_stream_meshes={} wide_high_uv_stream_meshes={}", views.len(), requests.uv1_stream_meshes.len(), requests.tangent_stream_meshes.len(), + requests.raw_tangent_stream_meshes.len(), requests.generated_tangent_mesh_count(), requests.uv2_stream_meshes.len(), requests.uv3_stream_meshes.len(), requests.wide_low_uv_stream_meshes.len(), requests.wide_high_uv_stream_meshes.len(), - requests.billboard_stream_meshes.len(), ); let mesh_ids_needing_all_extended_streams = requests.all_extended_stream_meshes(); self.ensure_view_asset_prewarm_requests( @@ -422,7 +421,27 @@ impl<'a> BackendGraphAccess<'a> { } } for (&mesh_asset_id, demand) in &requests.derived_stream_demands { - self.ensure_demands_streams_prewarm_requests(device, mesh_asset_id, demand); + if demand + .mask + .intersects(MeshDerivedStreamMask::POSITION | MeshDerivedStreamMask::NORMAL) + { + let _ = self + .asset_transfers + .mesh_pool_mut() + .ensure_position_normal_vertex_streams(device, mesh_asset_id); + } + if demand.mask.contains(MeshDerivedStreamMask::UV0) { + let _ = self + .asset_transfers + .mesh_pool_mut() + .ensure_uv0_vertex_stream(device, mesh_asset_id); + } + if demand.mask.contains(MeshDerivedStreamMask::COLOR) { + let _ = self + .asset_transfers + .mesh_pool_mut() + .ensure_color_vertex_stream(device, mesh_asset_id); + } } for &mesh_asset_id in mesh_ids_needing_all_extended_streams { let _ = self @@ -456,15 +475,11 @@ impl<'a> BackendGraphAccess<'a> { requests.tangent_fallback_mode(mesh_asset_id), ); } - for &mesh_asset_id in &requests.billboard_stream_meshes { + for &mesh_asset_id in &requests.raw_tangent_stream_meshes { let _ = self .asset_transfers .mesh_pool_mut() - .ensure_billboard_vertex_streams( - device, - mesh_asset_id, - requests.tangent_fallback_mode(mesh_asset_id), - ); + .ensure_raw_tangent_vertex_stream(device, mesh_asset_id); } for &mesh_asset_id in &requests.uv2_stream_meshes { if mesh_ids_needing_all_extended_streams.contains(&mesh_asset_id) { @@ -497,35 +512,6 @@ impl<'a> BackendGraphAccess<'a> { .ensure_wide_high_uv_vertex_stream(device, mesh_asset_id); } } - - fn ensure_demands_streams_prewarm_requests( - &mut self, - device: &wgpu::Device, - mesh_asset_id: i32, - demand: &MeshDerivedStreamDemand, - ) { - if demand - .mask - .intersects(MeshDerivedStreamMask::POSITION | MeshDerivedStreamMask::NORMAL) - { - let _ = self - .asset_transfers - .mesh_pool_mut() - .ensure_position_normal_vertex_streams(device, mesh_asset_id); - } - if demand.mask.contains(MeshDerivedStreamMask::UV0) { - let _ = self - .asset_transfers - .mesh_pool_mut() - .ensure_uv0_vertex_stream(device, mesh_asset_id); - } - if demand.mask.contains(MeshDerivedStreamMask::COLOR) { - let _ = self - .asset_transfers - .mesh_pool_mut() - .ensure_color_vertex_stream(device, mesh_asset_id); - } - } } #[cfg(test)] diff --git a/crates/renderide/src/gpu_pools/pools/mesh.rs b/crates/renderide/src/gpu_pools/pools/mesh.rs index eaba02019..06e0bdbe5 100644 --- a/crates/renderide/src/gpu_pools/pools/mesh.rs +++ b/crates/renderide/src/gpu_pools/pools/mesh.rs @@ -261,16 +261,14 @@ impl MeshPool { }) } - /// Lazily creates the billboard payload buffers for particle renderers. - pub fn ensure_billboard_vertex_streams( + /// Lazily creates the raw tangent payload buffer for UI shaders declaring `@location(4)`. + pub fn ensure_raw_tangent_vertex_stream( &mut self, device: &wgpu::Device, asset_id: i32, - tangent_fallback_mode: EmbeddedTangentFallbackMode, ) -> bool { self.ensure_stream(asset_id, |mesh| { - mesh.ensure_tangent_vertex_stream(device, tangent_fallback_mode) - && mesh.ensure_uv1_vertex_stream(device) + mesh.ensure_raw_tangent_vertex_stream(device) }) } diff --git a/crates/renderide/src/materials/embedded/stem_metadata.rs b/crates/renderide/src/materials/embedded/stem_metadata.rs index c134a64fe..49e44b582 100644 --- a/crates/renderide/src/materials/embedded/stem_metadata.rs +++ b/crates/renderide/src/materials/embedded/stem_metadata.rs @@ -35,7 +35,8 @@ use crate::materials::{ use self::tangent_fallback::tangent_fallback_mode_for_stem; use self::vertex_streams::{ - derive_vertex_stream_mask, stem_uses_raw_normal_payload, stem_uses_ui_transparent_fallback, + derive_vertex_stream_mask, stem_uses_raw_normal_payload, stem_uses_raw_tangent_payload, + stem_uses_ui_transparent_fallback, }; /// Host material identity and blend/render state for embedded raster pipeline creation (separate from WGSL build inputs). @@ -74,6 +75,8 @@ struct EmbeddedStemMetadata { tangent_fallback_mode: EmbeddedTangentFallbackMode, /// Number of declared material passes submitted for this target. pass_count: usize, + /// Whether `@location(4)` carries raw shader payload rather than a geometric tangent. + uses_raw_tangent_payload: bool, /// Whether `@location(1)` carries raw shader payload rather than a lighting normal. uses_raw_normal_payload: bool, /// Whether this UI stem should fall back to transparent state until host state arrives. @@ -188,6 +191,11 @@ impl EmbeddedStemQuery { self.metadata.tangent_fallback_mode() } + /// `true` when `@location(4)` carries raw shader payload rather than a geometric tangent. + pub fn uses_raw_tangent_payload(&self) -> bool { + self.metadata.uses_raw_tangent_payload + } + /// `true` when `@location(1)` carries raw shader payload rather than a lighting normal. pub fn uses_raw_normal_payload(&self) -> bool { self.metadata.uses_raw_normal_payload @@ -289,6 +297,7 @@ fn embedded_stem_metadata(base_stem: &str, permutation: ShaderPermutation) -> Em snapshot_requirements, tangent_fallback_mode: tangent_fallback_mode_for_stem(base_stem), pass_count: passes.len().max(1), + uses_raw_tangent_payload: stem_uses_raw_tangent_payload(base_stem), uses_raw_normal_payload: stem_uses_raw_normal_payload(base_stem), uses_ui_transparent_fallback: stem_uses_ui_transparent_fallback(base_stem), uses_alpha_blending: passes.iter().any(|p| p.blend.is_some()), @@ -483,6 +492,7 @@ mod tests { snapshot_requirements: SnapshotRequirements::default(), tangent_fallback_mode: EmbeddedTangentFallbackMode::default(), pass_count: 1, + uses_raw_tangent_payload: false, uses_raw_normal_payload: false, uses_ui_transparent_fallback: false, uses_alpha_blending: false, diff --git a/crates/renderide/src/materials/embedded/stem_metadata/vertex_streams.rs b/crates/renderide/src/materials/embedded/stem_metadata/vertex_streams.rs index e69623f69..14e424d69 100644 --- a/crates/renderide/src/materials/embedded/stem_metadata/vertex_streams.rs +++ b/crates/renderide/src/materials/embedded/stem_metadata/vertex_streams.rs @@ -161,6 +161,20 @@ pub fn embedded_stem_needs_extended_vertex_streams( EmbeddedStemQuery::for_stem(base_stem, permutation).needs_extended_vertex_streams() } +/// `true` when `@location(4)` carries raw shader payload rather than a geometric tangent. +pub(super) fn stem_uses_raw_tangent_payload(base_stem: &str) -> bool { + matches!( + canonical_stem_name(base_stem), + "billboardunlit" | "ui_circlesegment" | "ui_unlit" + ) +} + +/// `true` when `@location(4)` carries raw shader payload rather than a geometric tangent. +#[cfg(test)] +pub fn embedded_stem_uses_raw_tangent_payload(base_stem: &str) -> bool { + stem_uses_raw_tangent_payload(base_stem) +} + /// `true` when `@location(1)` carries raw shader payload rather than a lighting normal. pub(super) fn stem_uses_raw_normal_payload(base_stem: &str) -> bool { matches!( @@ -211,7 +225,7 @@ mod tests { embedded_stem_needs_uv0_stream, embedded_stem_needs_uv1_stream, embedded_stem_needs_uv2_stream, embedded_stem_needs_uv3_stream, embedded_stem_needs_wide_uv_stream, embedded_stem_uses_raw_normal_payload, - embedded_stem_uses_ui_transparent_fallback, + embedded_stem_uses_raw_tangent_payload, embedded_stem_uses_ui_transparent_fallback, }; fn reflected_with_inputs(inputs: Vec) -> ReflectedRasterLayout { @@ -374,6 +388,17 @@ mod tests { #[test] fn ui_payload_stems_mark_raw_semantics() { + for stem in [ + "billboardunlit_default", + "ui_circlesegment_default", + "ui_unlit_default", + ] { + assert!(embedded_stem_uses_raw_tangent_payload(stem), "{stem}"); + } + assert!(!embedded_stem_uses_raw_tangent_payload( + "pbsmetallic_default" + )); + for stem in [ "billboardunlit_default", "textunlit_default", diff --git a/crates/renderide/src/materials/shader_specialization.rs b/crates/renderide/src/materials/shader_specialization.rs index 6de307439..ef054abdc 100644 --- a/crates/renderide/src/materials/shader_specialization.rs +++ b/crates/renderide/src/materials/shader_specialization.rs @@ -7,6 +7,7 @@ pub(crate) const STATIC_VARIANT_BITS_OVERRIDE: &str = "renderide_static_variant_ const STATIC_VARIANT_BITS_DISABLED: u32 = 0; const STATIC_VARIANT_BITS_ENABLED: u32 = 1; +const DEFAULT_VARIANT_BITS_ENABLED: u32 = 2; /// Pipeline-cache selector for material shader specialization constants. /// @@ -35,6 +36,14 @@ impl MaterialShaderSpecializationKey { } } + /// Returns a key that exposes the given variant bitmask as a default pipeline mask. + pub(crate) const fn from_default_variant_bits(bits: u32) -> Self { + Self { + static_variant_bits_mode: DEFAULT_VARIANT_BITS_ENABLED, + static_variant_bits: bits, + } + } + /// Returns a static key when variant bits are known, or the disabled key otherwise. pub(crate) const fn from_optional_variant_bits(bits: Option) -> Self { match bits { diff --git a/crates/renderide/src/particles/tests.rs b/crates/renderide/src/particles/tests.rs index 36e11b41c..7d72601d8 100644 --- a/crates/renderide/src/particles/tests.rs +++ b/crates/renderide/src/particles/tests.rs @@ -217,15 +217,15 @@ fn billboard_extra_streams_pack_particle_orientation() { }]; let streams = billboard_extra_streams(&points); - let raw_tangent = streams.point_forward_upz.as_deref().expect("raw tangent"); - let uv1 = streams.point_up_xy.as_deref().expect("uv1"); - let tangent: &[f32] = bytemuck::cast_slice(&raw_tangent[..16]); - let up_xy: &[f32] = bytemuck::cast_slice(&uv1[..8]); + let point_forward_upz = streams.point_forward_upz.as_deref().expect("raw tangent"); + let point_up_xy = streams.point_up_xy.as_deref().expect("uv1"); + let tangent: &[f32] = bytemuck::cast_slice(&point_forward_upz[..16]); + let up_xy: &[f32] = bytemuck::cast_slice(&point_up_xy[..8]); assert_eq!(tangent, &[0.0, 0.0, 1.0, 0.0]); assert_eq!(up_xy, &[0.0, 1.0]); - assert_eq!(raw_tangent.len(), BILLBOARD_VERTICES_PER_POINT * 16); - assert_eq!(uv1.len(), BILLBOARD_VERTICES_PER_POINT * 8); + assert_eq!(point_forward_upz.len(), BILLBOARD_VERTICES_PER_POINT * 16); + assert_eq!(point_up_xy.len(), BILLBOARD_VERTICES_PER_POINT * 8); } #[test] diff --git a/crates/renderide/src/particles/upload.rs b/crates/renderide/src/particles/upload.rs index e3d583e2e..64b0169d4 100644 --- a/crates/renderide/src/particles/upload.rs +++ b/crates/renderide/src/particles/upload.rs @@ -100,7 +100,7 @@ pub(super) fn prepared_generated_derived_streams( normals: Some(normals), uv0: Some(uv0), color: Some(color), - tangent: extra.point_forward_upz, + raw_tangent: extra.point_forward_upz, uv1: extra.point_up_xy, ..PreparedDerivedStreams::default() } diff --git a/crates/renderide/src/passes.rs b/crates/renderide/src/passes.rs index 42979d91e..531b91257 100644 --- a/crates/renderide/src/passes.rs +++ b/crates/renderide/src/passes.rs @@ -23,8 +23,9 @@ pub(crate) use post_processing::{ pub(crate) use scene_color_compose::{SceneColorComposeGraphResources, SceneColorComposePass}; pub(crate) use world_mesh_forward::ForwardMsaaResources; pub(crate) use world_mesh_forward::{ - GTAO_VIEW_NORMAL_FORMAT, MaterialBatchBoundary, PreparedWorldMeshForwardFrame, - WorldMeshDepthSnapshotPass, WorldMeshDesktopOverlayGraphResources, WorldMeshDesktopOverlayPass, + BILLBOARD_RENDER_BUFFER_BIT, GTAO_VIEW_NORMAL_FORMAT, MaterialBatchBoundary, + PreparedWorldMeshForwardFrame, WorldMeshDepthSnapshotPass, + WorldMeshDesktopOverlayGraphResources, WorldMeshDesktopOverlayPass, WorldMeshForwardDepthPrepass, WorldMeshForwardDepthPrepassGraphResources, WorldMeshForwardDepthPrepassPipelineKey, WorldMeshForwardDepthResolvePass, WorldMeshForwardEncodeRefs, WorldMeshForwardGraphResources, diff --git a/crates/renderide/src/passes/world_mesh_forward.rs b/crates/renderide/src/passes/world_mesh_forward.rs index 0b0e65e68..72e5fc633 100644 --- a/crates/renderide/src/passes/world_mesh_forward.rs +++ b/crates/renderide/src/passes/world_mesh_forward.rs @@ -60,7 +60,9 @@ pub(crate) use depth_prepass::{ WorldMeshForwardDepthPrepassPipelineKey, depth_prepass_pipeline_key_for_draw, pre_warm_depth_prepass_pipeline, }; -pub(crate) use material_batch::{MaterialBatchBoundary, MaterialBatchPacket, MaterialDrawResolver}; +pub(crate) use material_batch::{ + BILLBOARD_RENDER_BUFFER_BIT, MaterialBatchBoundary, MaterialBatchPacket, MaterialDrawResolver, +}; pub(crate) use normal_pass::{ GTAO_VIEW_NORMAL_FORMAT, WorldMeshForwardNormalPipelineKey, normal_pipeline_key_for_draw, pre_warm_normal_pipeline, diff --git a/crates/renderide/src/passes/world_mesh_forward/encode/vertex_binding.rs b/crates/renderide/src/passes/world_mesh_forward/encode/vertex_binding.rs index 8d8c06523..4bf4edbdd 100644 --- a/crates/renderide/src/passes/world_mesh_forward/encode/vertex_binding.rs +++ b/crates/renderide/src/passes/world_mesh_forward/encode/vertex_binding.rs @@ -19,6 +19,8 @@ pub(super) struct EmbeddedVertexStreamFlags { embedded_color: bool, /// Tangent at `@location(4)`. embedded_tangent: bool, + /// Whether `@location(4)` carries raw shader payload instead of a geometric tangent. + embedded_raw_tangent_payload: bool, /// Whether `@location(1)` carries raw shader payload instead of a lighting normal. embedded_raw_normal_payload: bool, /// UV1 at `@location(5)`. @@ -27,8 +29,6 @@ pub(super) struct EmbeddedVertexStreamFlags { embedded_uv2: bool, /// UV3 at `@location(7)`. embedded_uv3: bool, - /// Billboard forward and up vecrots at @location(8) and @location(9) - embedded_billboard_geometry: bool, /// Packed UV0-UV3 stream. embedded_wide_low_uvs: bool, /// Packed UV4-UV7 stream. @@ -332,7 +332,20 @@ fn resident_draw_mesh<'a>( return None; } let mesh = gpu.mesh_pool.get(item.mesh_asset_id)?; - if streams.embedded_tangent && !mesh.tangent_vertex_stream_ready() { + if streams.embedded_tangent + && streams.embedded_raw_tangent_payload + && !mesh.raw_tangent_vertex_stream_ready() + { + logger::trace!( + "WorldMeshForward: raw tangent payload stream missing for mesh_asset_id {}; draw skipped until pre-warm catches up", + item.mesh_asset_id + ); + return None; + } + if streams.embedded_tangent + && !streams.embedded_raw_tangent_payload + && !mesh.tangent_vertex_stream_ready() + { logger::trace!( "WorldMeshForward: tangent vertex stream missing for mesh_asset_id {}; draw skipped until pre-warm catches up", item.mesh_asset_id @@ -374,13 +387,6 @@ fn resident_draw_mesh<'a>( ); return None; } - if streams.embedded_billboard_geometry && !mesh.billboard_vertex_streams_ready() { - logger::trace!( - "WorldMeshForward: billboard vertex streams missing for mesh_asset_id {}; draw skipped until pre-warm catches up", - item.mesh_asset_id - ); - return None; - } mesh.debug_streams_ready().then_some(mesh) } @@ -648,7 +654,7 @@ fn bind_optional_vertex_streams( ); } if let Some(slot) = streams.tangent_slot() - && !bind_tangent_stream(rpass, item, gpu, mesh, slot, last_mesh) + && !bind_tangent_stream(rpass, item, gpu, mesh, streams, slot, last_mesh) { return false; } @@ -696,9 +702,24 @@ fn bind_tangent_stream( item: &WorldMeshDrawItem, gpu: WorldMeshDrawGpuRefs<'_>, mesh: &GpuMesh, + streams: EmbeddedVertexStreamFlags, slot: usize, last_mesh: &mut LastMeshBindState, ) -> bool { + if streams.embedded_raw_tangent_payload { + let Some(tangent) = mesh.raw_tangent_buffer.as_deref() else { + return false; + }; + bind_vertex_if_changed!( + rpass, + slot, + tangent.slice(..), + BufferBindId::full(tangent), + last_mesh.vertex + ); + return true; + } + if draw_uses_deformed_tangent_stream(item, mesh) { let Some(cache) = gpu.skin_cache else { return false; @@ -776,11 +797,11 @@ pub(super) fn streams_for_item(item: &WorldMeshDrawItem) -> EmbeddedVertexStream embedded_uv: item.batch_key.embedded_needs_uv0, embedded_color: item.batch_key.embedded_needs_color, embedded_tangent: item.batch_key.embedded_needs_tangent, + embedded_raw_tangent_payload: item.batch_key.embedded_raw_tangent_payload, embedded_raw_normal_payload: item.batch_key.embedded_raw_normal_payload, embedded_uv1: item.batch_key.embedded_needs_uv1, embedded_uv2: item.batch_key.embedded_needs_uv2, embedded_uv3: item.batch_key.embedded_needs_uv3, - embedded_billboard_geometry: item.batch_key.embedded_uses_billboard_geometry, embedded_wide_low_uvs: item.batch_key.embedded_needs_wide_low_uvs, embedded_wide_high_uvs: item.batch_key.embedded_needs_wide_high_uvs, } diff --git a/crates/renderide/src/passes/world_mesh_forward/material_batch.rs b/crates/renderide/src/passes/world_mesh_forward/material_batch.rs index 5322568e9..32b8d9779 100644 --- a/crates/renderide/src/passes/world_mesh_forward/material_batch.rs +++ b/crates/renderide/src/passes/world_mesh_forward/material_batch.rs @@ -37,7 +37,7 @@ const MATERIAL_BATCH_PARALLEL_MIN_RUNS: usize = MATERIAL_BATCH_PARALLEL_CHUNK_RU static EMBEDDED_MATERIAL_BIND_FAILURE_LOG: LogThrottle = LogThrottle::new(); /// Generic variant bit used by all shaders compatible with particle system rendering. -const BILLBOARD_RENDER_BUFFER_BIT: u32 = 1u32 << 24; +pub(crate) const BILLBOARD_RENDER_BUFFER_BIT: u32 = 1u32 << 24; /// Inclusive `(first_draw_idx, last_draw_idx)` span over the sorted world-mesh draw list /// identifying one contiguous material batch run. diff --git a/crates/renderide/src/world_mesh/draw_prep/tests.rs b/crates/renderide/src/world_mesh/draw_prep/tests.rs index aaf16cdfa..d445377f4 100644 --- a/crates/renderide/src/world_mesh/draw_prep/tests.rs +++ b/crates/renderide/src/world_mesh/draw_prep/tests.rs @@ -144,6 +144,7 @@ fn property_block_splits_batch_keys() { embedded_needs_uv1: false, embedded_needs_tangent: false, embedded_tangent_fallback_mode: Default::default(), + embedded_raw_tangent_payload: false, embedded_raw_normal_payload: false, embedded_needs_uv2: false, embedded_needs_uv3: false, @@ -175,6 +176,7 @@ fn property_block_splits_batch_keys() { embedded_needs_uv1: false, embedded_needs_tangent: false, embedded_tangent_fallback_mode: Default::default(), + embedded_raw_tangent_payload: false, embedded_raw_normal_payload: false, embedded_needs_uv2: false, embedded_needs_uv3: false, diff --git a/crates/renderide/src/world_mesh/materials/key.rs b/crates/renderide/src/world_mesh/materials/key.rs index 834e04bf4..bd2ff59e1 100644 --- a/crates/renderide/src/world_mesh/materials/key.rs +++ b/crates/renderide/src/world_mesh/materials/key.rs @@ -42,6 +42,8 @@ pub struct MaterialDrawBatchKey { pub embedded_needs_tangent: bool, /// Tangent fallback policy for lazy tangent upload. pub embedded_tangent_fallback_mode: EmbeddedTangentFallbackMode, + /// Whether the tangent stream carries raw shader payload instead of a geometric tangent. + pub embedded_raw_tangent_payload: bool, /// Whether the normal stream carries raw shader payload instead of a lighting normal. pub embedded_raw_normal_payload: bool, /// Whether the embedded stem needs a UV2 vertex stream at `@location(6)`. diff --git a/crates/renderide/src/world_mesh/materials/resolve.rs b/crates/renderide/src/world_mesh/materials/resolve.rs index 9f2a6c81a..f23ba6505 100644 --- a/crates/renderide/src/world_mesh/materials/resolve.rs +++ b/crates/renderide/src/world_mesh/materials/resolve.rs @@ -10,6 +10,7 @@ use crate::materials::{ material_blend_mode_from_maps, material_render_queue_from_maps, material_render_state_from_maps, resolve_raster_pipeline, }; +use crate::passes::BILLBOARD_RENDER_BUFFER_BIT; use super::FrameMaterialBatchCache; use super::key::MaterialDrawBatchKey; @@ -50,6 +51,8 @@ pub(crate) struct ResolvedMaterialBatch { pub embedded_needs_tangent: bool, /// Tangent fallback policy for lazy tangent upload. pub embedded_tangent_fallback_mode: EmbeddedTangentFallbackMode, + /// Whether the tangent stream carries raw shader payload instead of a geometric tangent. + pub embedded_raw_tangent_payload: bool, /// Whether the normal stream carries raw shader payload instead of a lighting normal. pub embedded_raw_normal_payload: bool, /// Whether the active shader permutation requires a UV2 vertex stream. @@ -124,6 +127,7 @@ struct EmbeddedMaterialFeatures { needs_uv1: bool, needs_tangent: bool, tangent_fallback_mode: EmbeddedTangentFallbackMode, + raw_tangent_payload: bool, raw_normal_payload: bool, needs_uv2: bool, needs_uv3: bool, @@ -159,6 +163,7 @@ fn embedded_material_features( needs_uv1: vertex_streams.uv1, needs_tangent: vertex_streams.tangent, tangent_fallback_mode: query.tangent_fallback_mode(), + raw_tangent_payload: query.uses_raw_tangent_payload(), raw_normal_payload: query.uses_raw_normal_payload(), needs_uv2: vertex_streams.uv2, needs_uv3: vertex_streams.uv3, @@ -310,6 +315,7 @@ pub(crate) fn resolve_material_batch( embedded_needs_uv1: embedded.needs_uv1, embedded_needs_tangent: embedded.needs_tangent, embedded_tangent_fallback_mode: embedded.tangent_fallback_mode, + embedded_raw_tangent_payload: embedded.raw_tangent_payload, embedded_raw_normal_payload: embedded.raw_normal_payload, embedded_needs_uv2: embedded.needs_uv2, embedded_needs_uv3: embedded.needs_uv3, @@ -342,8 +348,11 @@ pub(crate) fn apply_render_buffer_mesh_pipeline_override( if !crate::particles::is_generated_billboard_mesh_asset_id(mesh_asset_id) { return; } - batch_key.shader_specialization = MaterialShaderSpecializationKey::disabled(); + batch_key.shader_specialization = + MaterialShaderSpecializationKey::from_default_variant_bits(BILLBOARD_RENDER_BUFFER_BIT); batch_key.embedded_uses_billboard_geometry = true; + batch_key.embedded_raw_tangent_payload = true; + batch_key.embedded_needs_uv1 = true; } /// Assembles a [`MaterialDrawBatchKey`] from a pre-resolved [`ResolvedMaterialBatch`] entry. @@ -370,6 +379,7 @@ fn batch_key_from_resolved( embedded_needs_uv1: r.embedded_needs_uv1, embedded_needs_tangent: r.embedded_needs_tangent, embedded_tangent_fallback_mode: r.embedded_tangent_fallback_mode, + embedded_raw_tangent_payload: r.embedded_raw_tangent_payload, embedded_raw_normal_payload: r.embedded_raw_normal_payload, embedded_needs_uv2: r.embedded_needs_uv2, embedded_needs_uv3: r.embedded_needs_uv3, @@ -539,6 +549,7 @@ mod ui_rect_clip_tests { assert!(resolved.alpha_blended); assert_eq!(resolved.render_queue, UNITY_RENDER_QUEUE_TRANSPARENT); + assert!(resolved.embedded_raw_tangent_payload); } #[test] @@ -722,8 +733,49 @@ mod ui_rect_clip_tests { assert!(key.embedded_needs_uv0); assert!(key.embedded_needs_color); assert!(key.embedded_needs_tangent); + assert!(key.embedded_raw_tangent_payload); assert!(key.embedded_raw_normal_payload); - assert!(key.embedded_uses_billboard_geometry); + } + + #[test] + fn generated_billboard_mesh_uses_original_material() { + let registry = PropertyIdRegistry::new(); + let src = registry.intern("_SrcBlend"); + let dst = registry.intern("_DstBlend"); + let render_queue = registry.intern("_RenderQueue"); + let mut store = MaterialPropertyStore::new(); + store.set_shader_asset_for_material(7, 99); + store.set_material(7, src, MaterialPropertyValue::Float(5.0)); + store.set_material(7, dst, MaterialPropertyValue::Float(10.0)); + store.set_material( + 7, + render_queue, + MaterialPropertyValue::Float(UNITY_RENDER_QUEUE_TRANSPARENT as f32), + ); + let dict = MaterialDictionary::new(&store); + let mut router = MaterialRouter::new(RasterPipelineKind::Null); + router.set_shader_pipeline( + 99, + RasterPipelineKind::EmbeddedStem(Arc::from("unlit_default")), + ); + let ids = MaterialPipelinePropertyIds::new(®istry); + let resolved = + resolve_material_batch(7, None, &dict, &router, &ids, ShaderPermutation::default()); + let mut key = batch_key_from_resolved( + 7, + None, + false, + RasterFrontFace::Clockwise, + RasterPrimitiveTopology::TriangleList, + &resolved, + ); + let mesh_asset_id = crate::particles::billboard_render_buffer_mesh_asset_id(3).unwrap(); + + apply_render_buffer_mesh_pipeline_override(&mut key, mesh_asset_id); + assert_eq!(key.material_asset_id, 7); + assert!(key.alpha_blended); + assert_eq!(key.render_queue, UNITY_RENDER_QUEUE_TRANSPARENT); + assert!(key.transparent_class.is_transparent()); } #[test] diff --git a/crates/renderide/src/world_mesh/test_fixtures.rs b/crates/renderide/src/world_mesh/test_fixtures.rs index a8f39aea4..bbf16e8a6 100644 --- a/crates/renderide/src/world_mesh/test_fixtures.rs +++ b/crates/renderide/src/world_mesh/test_fixtures.rs @@ -75,6 +75,7 @@ pub fn dummy_world_mesh_draw_item(spec: DummyDrawItemSpec) -> WorldMeshDrawItem embedded_needs_uv1: false, embedded_needs_tangent: false, embedded_tangent_fallback_mode: Default::default(), + embedded_raw_tangent_payload: false, embedded_raw_normal_payload: false, embedded_needs_uv2: false, embedded_needs_uv3: false, From e3a159b4a61065d0b888e2954b58047f0185ac29 Mon Sep 17 00:00:00 2001 From: Baplar Date: Sat, 6 Jun 2026 00:51:20 +0200 Subject: [PATCH 4/5] Fix tests after billboard refactoring --- .../src/world_mesh/draw_prep/tests.rs | 2 - .../renderide/src/world_mesh/materials/key.rs | 2 - .../src/world_mesh/materials/resolve.rs | 52 ++------------ .../renderide/src/world_mesh/test_fixtures.rs | 1 - crates/renderide/tests/shader_module_audit.rs | 70 ++++++------------- .../tests/shader_module_audit/pbs/fur_toon.rs | 18 ++++- .../shader_module_audit/pbs/materials.rs | 33 ++++++++- .../shader_module_audit/tangent_basis.rs | 3 +- 8 files changed, 76 insertions(+), 105 deletions(-) diff --git a/crates/renderide/src/world_mesh/draw_prep/tests.rs b/crates/renderide/src/world_mesh/draw_prep/tests.rs index d445377f4..d4362be02 100644 --- a/crates/renderide/src/world_mesh/draw_prep/tests.rs +++ b/crates/renderide/src/world_mesh/draw_prep/tests.rs @@ -154,7 +154,6 @@ fn property_block_splits_batch_keys() { embedded_requires_intersection_pass: false, embedded_uses_scene_depth_snapshot: false, embedded_uses_scene_color_snapshot: false, - embedded_uses_billboard_geometry: false, scene_color_snapshot_mode: Default::default(), render_queue: UNITY_RENDER_QUEUE_GEOMETRY, render_state: Default::default(), @@ -186,7 +185,6 @@ fn property_block_splits_batch_keys() { embedded_requires_intersection_pass: false, embedded_uses_scene_depth_snapshot: false, embedded_uses_scene_color_snapshot: false, - embedded_uses_billboard_geometry: false, scene_color_snapshot_mode: Default::default(), render_queue: UNITY_RENDER_QUEUE_GEOMETRY, render_state: Default::default(), diff --git a/crates/renderide/src/world_mesh/materials/key.rs b/crates/renderide/src/world_mesh/materials/key.rs index bd2ff59e1..90d77fa01 100644 --- a/crates/renderide/src/world_mesh/materials/key.rs +++ b/crates/renderide/src/world_mesh/materials/key.rs @@ -62,8 +62,6 @@ pub struct MaterialDrawBatchKey { pub embedded_uses_scene_depth_snapshot: bool, /// Whether the shader samples the scene-color snapshot through frame globals. pub embedded_uses_scene_color_snapshot: bool, - /// Whether the shader needs to generate billboard geometry from vertex indices for particles. - pub embedded_uses_billboard_geometry: bool, /// How the shader expects scene-color snapshots to be refreshed. pub scene_color_snapshot_mode: SceneColorSnapshotMode, /// Effective Unity render queue after material override / fallback resolution. diff --git a/crates/renderide/src/world_mesh/materials/resolve.rs b/crates/renderide/src/world_mesh/materials/resolve.rs index f23ba6505..fa52f4eac 100644 --- a/crates/renderide/src/world_mesh/materials/resolve.rs +++ b/crates/renderide/src/world_mesh/materials/resolve.rs @@ -71,8 +71,6 @@ pub(crate) struct ResolvedMaterialBatch { pub embedded_uses_scene_depth_snapshot: bool, /// Whether the active shader permutation declares a scene-color snapshot binding. pub embedded_uses_scene_color_snapshot: bool, - /// Whether the shader needs to generate billboard geometry from vertex indices for particles. - pub embedded_uses_billboard_geometry: bool, /// How the active shader permutation expects scene-color snapshots to be refreshed. pub scene_color_snapshot_mode: SceneColorSnapshotMode, /// Renderer-local transparent behavior class inferred from resolved material state. @@ -326,7 +324,6 @@ pub(crate) fn resolve_material_batch( embedded_uses_scene_depth_snapshot: embedded.uses_scene_depth_snapshot, embedded_uses_scene_color_snapshot: embedded.uses_scene_color_snapshot, scene_color_snapshot_mode: embedded.scene_color_snapshot_mode, - embedded_uses_billboard_geometry: false, transparent_class, blend_mode, render_queue, @@ -350,8 +347,8 @@ pub(crate) fn apply_render_buffer_mesh_pipeline_override( } batch_key.shader_specialization = MaterialShaderSpecializationKey::from_default_variant_bits(BILLBOARD_RENDER_BUFFER_BIT); - batch_key.embedded_uses_billboard_geometry = true; batch_key.embedded_raw_tangent_payload = true; + batch_key.embedded_raw_normal_payload = true; batch_key.embedded_needs_uv1 = true; } @@ -389,7 +386,6 @@ fn batch_key_from_resolved( embedded_requires_intersection_pass: r.embedded_requires_intersection_pass, embedded_uses_scene_depth_snapshot: r.embedded_uses_scene_depth_snapshot, embedded_uses_scene_color_snapshot: r.embedded_uses_scene_color_snapshot, - embedded_uses_billboard_geometry: r.embedded_uses_billboard_geometry, scene_color_snapshot_mode: r.scene_color_snapshot_mode, render_queue: r.render_queue, render_state: r.render_state, @@ -702,7 +698,7 @@ mod ui_rect_clip_tests { } #[test] - fn generated_billboard_mesh_overrides_to_billboard_pipeline() { + fn generated_billboard_mesh_keeps_using_main_pipeline() { let mut store = MaterialPropertyStore::new(); store.set_shader_asset_for_material(7, 99); let dict = MaterialDictionary::new(&store); @@ -729,55 +725,15 @@ mod ui_rect_clip_tests { let RasterPipelineKind::EmbeddedStem(stem) = &key.pipeline else { panic!("expected embedded billboard pipeline"); }; - assert_eq!(stem.as_ref(), "billboardunlit_default"); + assert_eq!(stem.as_ref(), "unlit_default"); assert!(key.embedded_needs_uv0); + assert!(key.embedded_needs_uv1); assert!(key.embedded_needs_color); assert!(key.embedded_needs_tangent); assert!(key.embedded_raw_tangent_payload); assert!(key.embedded_raw_normal_payload); } - #[test] - fn generated_billboard_mesh_uses_original_material() { - let registry = PropertyIdRegistry::new(); - let src = registry.intern("_SrcBlend"); - let dst = registry.intern("_DstBlend"); - let render_queue = registry.intern("_RenderQueue"); - let mut store = MaterialPropertyStore::new(); - store.set_shader_asset_for_material(7, 99); - store.set_material(7, src, MaterialPropertyValue::Float(5.0)); - store.set_material(7, dst, MaterialPropertyValue::Float(10.0)); - store.set_material( - 7, - render_queue, - MaterialPropertyValue::Float(UNITY_RENDER_QUEUE_TRANSPARENT as f32), - ); - let dict = MaterialDictionary::new(&store); - let mut router = MaterialRouter::new(RasterPipelineKind::Null); - router.set_shader_pipeline( - 99, - RasterPipelineKind::EmbeddedStem(Arc::from("unlit_default")), - ); - let ids = MaterialPipelinePropertyIds::new(®istry); - let resolved = - resolve_material_batch(7, None, &dict, &router, &ids, ShaderPermutation::default()); - let mut key = batch_key_from_resolved( - 7, - None, - false, - RasterFrontFace::Clockwise, - RasterPrimitiveTopology::TriangleList, - &resolved, - ); - let mesh_asset_id = crate::particles::billboard_render_buffer_mesh_asset_id(3).unwrap(); - - apply_render_buffer_mesh_pipeline_override(&mut key, mesh_asset_id); - assert_eq!(key.material_asset_id, 7); - assert!(key.alpha_blended); - assert_eq!(key.render_queue, UNITY_RENDER_QUEUE_TRANSPARENT); - assert!(key.transparent_class.is_transparent()); - } - #[test] fn generated_trail_mesh_does_not_get_billboard_pipeline_override() { let mut store = MaterialPropertyStore::new(); diff --git a/crates/renderide/src/world_mesh/test_fixtures.rs b/crates/renderide/src/world_mesh/test_fixtures.rs index bbf16e8a6..fc33a906c 100644 --- a/crates/renderide/src/world_mesh/test_fixtures.rs +++ b/crates/renderide/src/world_mesh/test_fixtures.rs @@ -85,7 +85,6 @@ pub fn dummy_world_mesh_draw_item(spec: DummyDrawItemSpec) -> WorldMeshDrawItem embedded_requires_intersection_pass: false, embedded_uses_scene_depth_snapshot: false, embedded_uses_scene_color_snapshot: false, - embedded_uses_billboard_geometry: false, scene_color_snapshot_mode: Default::default(), render_queue, render_state: Default::default(), diff --git a/crates/renderide/tests/shader_module_audit.rs b/crates/renderide/tests/shader_module_audit.rs index 102840fa5..55569a762 100644 --- a/crates/renderide/tests/shader_module_audit.rs +++ b/crates/renderide/tests/shader_module_audit.rs @@ -354,32 +354,34 @@ fn billboard_render_buffer_uses_indexed_corner_separate_from_sample_uv() -> io:: "Billboard/Unlit must know the indexed vertex id for generated render-buffer quads" ); assert!( - src.contains("fn render_buffer_billboard_unit_corner(vertex_index: u32) -> vec2") - && src.contains("let corner = vertex_index % 4u;"), + src.contains("let render_billboard_vertex = bv::render_buffer_billboard_vertex(") + && src.contains("world_p = render_billboard_vertex.world_pos.xyz"), "Billboard/Unlit must derive generated render-buffer quad corners from vertex order" ); + + let module = module_source("billboard/vertex.wgsl")?; assert!( - src.contains( - "fn billboard_corner_for_vertex(pos: vec3, uv: vec2, vertex_index: u32) -> vec2" - ) && src.contains( + module.contains( + "fn render_buffer_billboard_corner_for_vertex(vertex_index: u32) -> vec2" + ) && module.contains( "return render_buffer_billboard_unit_corner(vertex_index) * 2.0 - vec2(1.0, 1.0);" - ) && src.contains("return mb::billboard_corner(pos, uv);"), + ) && src.contains("let corner = mb::billboard_corner(pos.xyz, uv);"), "Render-buffer billboards must not reuse framed atlas UVs as geometry corners" ); assert!( - src.contains("let corner = billboard_corner_for_vertex(pos.xyz, uv, vertex_index);") - && src.contains("out.uv = uv;"), + module.contains("let corner = render_buffer_billboard_corner_for_vertex(vertex_index);") + && module.contains("out.uv = uv;"), "Billboard/Unlit must keep atlas sampling UVs separate from generated geometry corners" ); assert!( src.contains("@location(4) point_forward_upz: vec4") && src.contains("@location(5) point_up_xy: vec2") - && src.contains("fn render_buffer_billboard_basis("), + && module.contains("fn render_buffer_billboard_basis("), "Render-buffer billboards must receive particle orientation streams for Unity alignment modes" ); assert!( - src.contains("pd::particle_alignment(d)") - && src.contains("fn screen_clamped_billboard_size("), + module.contains("pd::particle_alignment(draw)") + && module.contains("fn screen_clamped_billboard_size("), "Render-buffer billboards must apply renderer alignment and screen-size clamp metadata" ); @@ -405,22 +407,12 @@ fn billboard_render_buffer_variant_bits_keep_native_and_compatibility_layout() - ("BILLBOARDUNLIT_KW_VERTEX_LINEAR_COLOR", 13), ("BILLBOARDUNLIT_KW_VERTEX_SRGB_COLOR", 14), ("BILLBOARDUNLIT_KW_VERTEXCOLORS", 15), - ("BILLBOARDUNLIT_KW_RENDER_BUFFER", 16), ] { assert!( src.contains(&format!("const {constant_name}: u32 = 1u << {bit_index}u;")), "{constant_name} must keep Billboard/Unlit's native sorted keyword bit order" ); } - assert!( - src.contains("const BILLBOARDUNLIT_KW_SIMPLE_LIT: u32 = 1u << 17u;"), - "Non-Unlit shading support for render-buffer billboards must use compatibility bit after native Billboard/Unlit keywords" - ); - assert!( - src.contains("const BILLBOARDUNLIT_KW_UNLIT_MASK_TEXTURE_CLIP: u32 = 1u << 18u;") - && src.contains("const BILLBOARDUNLIT_KW_UNLIT_MASK_TEXTURE_MUL: u32 = 1u << 19u;"), - "Unlit mask support for render-buffer billboards must use compatibility bits after native Billboard/Unlit keywords" - ); Ok(()) } @@ -449,22 +441,22 @@ fn billboard_render_buffer_preserves_fragment_alpha_and_fog_behavior() -> io::Re #[test] fn billboard_render_buffer_alignment_matches_unity_modes() -> io::Result<()> { - let src = material_source("billboardunlit.wgsl")?; + let module = module_source("billboard/vertex.wgsl")?; assert!( - src.contains("return facing_basis(center_world, view_layer, pointdata.z, false);"), - "Render-buffer Facing alignment must keep Unity-style roll disabled" + module.contains("return facing_basis(center_world, view_layer, pointdata.z);"), + "Render-buffer Facing alignment must keep Unity-style roll" ); assert!( - src.contains("fn direction_stretch_particle_basis(") - && src.contains("let velocity_world = mv::model_vector(d, point_forward_upz.xyz);") - && src.contains( + module.contains("fn direction_stretch_particle_basis(") + && module.contains("let velocity_world = mv::model_vector(draw, point_forward_upz.xyz);") + && module.contains( "let velocity_in_plane = velocity_world - to_camera * dot(velocity_world, to_camera);" ) - && src.contains("let view_up_in_plane = view_up - to_camera * dot(view_up, to_camera);") - && src.contains("up = rmath::safe_normalize(cross(to_camera, right), up);") - && src.contains( - "return direction_stretch_particle_basis(d, center_world, point_forward_upz, view_layer);" + && module.contains("let view_up_in_plane = view_up - to_camera * dot(view_up, to_camera);") + && module.contains("up = rmath::safe_normalize(cross(to_camera, right), up);") + && module.contains( + "return direction_stretch_particle_basis(draw, center_world, point_forward_upz, view_layer);" ), "Render-buffer Direction alignment must project velocity into the camera-facing stretch plane" ); @@ -472,22 +464,6 @@ fn billboard_render_buffer_alignment_matches_unity_modes() -> io::Result<()> { Ok(()) } -#[test] -fn billboard_render_buffer_supports_simple_lit_non_unlit_sources() -> io::Result<()> { - let src = material_source("billboardunlit.wgsl")?; - - assert!( - src.contains("if (kw_SIMPLE_LIT())") - && src.contains("out.world_p = world_p;") - && src.contains("out.n = rmath::safe_normalize(cross(axes.right, axes.up)") - && src.contains("let base = clamp(col.rgb, vec3(0.0), vec3(1.0));") - && src.contains("dl::shade_clustered_diffuse"), - "Billboard/Unlit must offer simple shading capabilities for non-Unlit source materials" - ); - - Ok(()) -} - #[test] fn mesh_particle_vertex_module_applies_alignment_and_color_metadata() -> io::Result<()> { let src = module_source("mesh/vertex.wgsl")?; diff --git a/crates/renderide/tests/shader_module_audit/pbs/fur_toon.rs b/crates/renderide/tests/shader_module_audit/pbs/fur_toon.rs index a85013c01..7f0b615c2 100644 --- a/crates/renderide/tests/shader_module_audit/pbs/fur_toon.rs +++ b/crates/renderide/tests/shader_module_audit/pbs/fur_toon.rs @@ -286,7 +286,7 @@ fn classic_furfx_modules_keep_source_parity_details() -> io::Result<()> { let common = module_source("fur/common.wgsl")?; for required in [ "@location(9) base_world_pos: vec3,", - "let base_world_pos = mv::world_position(draw, pos).xyz;", + "base_world_pos = mv::world_position(draw, pos).xyz;", "out.shell_noise_uv = uv0 + shell_noise_offset;", "out.base_world_pos = base_world_pos;", "var color = tex_rgb;\n color = color - shadow_rgb * hair_coloring;\n color = color - vec3(pow(1.0 - fur_multiplier, 4.0) * hair_shading);\n color = color * tint_rgb;", @@ -329,6 +329,22 @@ fn classic_furfx_modules_keep_source_parity_details() -> io::Result<()> { Ok(()) } +#[test] +fn furfx_supports_billboard_rendering() -> io::Result<()> { + let common = module_source("fur/common.wgsl")?; + for required in [ + "if (bv::kw_RENDER_BUFFER(variant_bits))", + "billboard_vertex = bv::render_buffer_billboard_vertex(", + "base_world_pos = billboard_vertex.world_pos.xyz;", + ] { + assert!( + common.contains(required), + "fur/common.wgsl must be compatible with billboard rendering `{required}`" + ); + } + Ok(()) +} + #[test] fn furfx_shell_force_uses_projection_local_offset() -> io::Result<()> { let common = module_source("fur/common.wgsl")?; diff --git a/crates/renderide/tests/shader_module_audit/pbs/materials.rs b/crates/renderide/tests/shader_module_audit/pbs/materials.rs index 8714fd59b..17e802a92 100644 --- a/crates/renderide/tests/shader_module_audit/pbs/materials.rs +++ b/crates/renderide/tests/shader_module_audit/pbs/materials.rs @@ -361,8 +361,7 @@ fn pbs_metallic_uses_uvsec_for_detail_uvs() -> io::Result<()> { "_UVSec: f32", "@location(5) uv1: vec2", "pdet::detail_uv(uv0, uv1, mat._UVSec, mat._DetailAlbedoMap_ST)", - "mv::world_uv2_vertex_main(instance_index, view_idx, pos, n, t, uv0, uv1)", - "mv::world_uv2_vertex_main(instance_index, 0u, pos, n, t, uv0, uv1)", + "mv::world_uv2_vertex_main(instance_index, view_layer, pos, n, t, uv0, uv1)", ] { assert!( src.contains(required), @@ -499,3 +498,33 @@ fn pbs_standard_parallax_uses_tangent_space_view_dir() -> io::Result<()> { Ok(()) } + +#[test] +fn most_pbs_shaders_support_billboard_rendering() -> io::Result<()> { + for file_name in [ + "pbsmetallic.wgsl", + "pbsspecular.wgsl", + "pbscolormask.wgsl", + "pbscolorsplat.wgsl", + "pbsdualsided.wgsl", + "pbsintersect.wgsl", + "pbslerp.wgsl", + "pbsmultiuv.wgsl", + "pbsrim.wgsl", + "pbsslice.wgsl", + "pbsstencil.wgsl", + "pbstriplanar.wgsl", + "pbsvertexcolortransparent.wgsl", + ] { + let src = material_source(file_name)?; + assert!( + src.contains("#import renderide::billboard::vertex as bv"), + "{file_name} should import the billboard vertex module" + ); + assert!( + src.contains("if (bv::kw_RENDER_BUFFER(mat._RenderideVariantBits))"), + "{file_name} should use billboard vertex conversions if the variant bit is specified" + ); + } + Ok(()) +} diff --git a/crates/renderide/tests/shader_module_audit/tangent_basis.rs b/crates/renderide/tests/shader_module_audit/tangent_basis.rs index fb6f19f93..53ea3e65a 100644 --- a/crates/renderide/tests/shader_module_audit/tangent_basis.rs +++ b/crates/renderide/tests/shader_module_audit/tangent_basis.rs @@ -92,8 +92,7 @@ fn fresnel_normal_mapped_shaders_use_normal_matrix_vertex_path() -> io::Result<( for file_name in ["fresnellerp.wgsl", "overlayfresnel.wgsl"] { let src = material_source(file_name)?; assert!( - src.contains("mv::world_vertex_main(instance_index, view_idx, pos, n, t, uv)") - && src.contains("mv::world_vertex_main(instance_index, 0u, pos, n, t, uv)"), + src.contains("mv::world_vertex_main(instance_index, view_layer, pos, n, t, uv)"), "{file_name} must use the standard world vertex helper so normals use the normal matrix" ); assert!( From 54036773623e66788a3baba448c5e0eab8a13189 Mon Sep 17 00:00:00 2001 From: Baplar Date: Sat, 6 Jun 2026 01:21:54 +0200 Subject: [PATCH 5/5] Remove added stuff from billboardunlit, we now use proper Unlit when applicable --- .../shaders/materials/billboardunlit.wgsl | 33 +------------------ crates/renderide/tests/shader_module_audit.rs | 6 +--- 2 files changed, 2 insertions(+), 37 deletions(-) diff --git a/crates/renderide/shaders/materials/billboardunlit.wgsl b/crates/renderide/shaders/materials/billboardunlit.wgsl index 6e3b5247f..f5d8e6f0d 100644 --- a/crates/renderide/shaders/materials/billboardunlit.wgsl +++ b/crates/renderide/shaders/materials/billboardunlit.wgsl @@ -12,7 +12,6 @@ //#render_queue AlphaTest+200 //#texture_default _Tex white //#texture_default _OffsetTex black -//#texture_default _MaskTex white //#mat_default _Color vec4 1.0 1.0 1.0 1.0 //#mat_default _OffsetMagnitude vec4 0.1 0.1 0.0 0.0 //#mat_default _PointSize vec4 0.1 0.1 0.0 0.0 @@ -20,7 +19,6 @@ //#mat_default _Cutoff float 0.5 //#mat_default _Tex_LodBias float 0.0 //#mat_default _OffsetTex_LodBias float 0.0 -//#mat_default _MaskTex_LodBias float 0.0 #import renderide::billboard::vertex as bv #import renderide::core::texture_sampling as ts @@ -41,7 +39,6 @@ struct BillboardUnlitMaterial { _Color: vec4, _Tex_ST: vec4, _RightEye_ST: vec4, - _MaskTex_ST: vec4, _OffsetTex_ST: vec4, _OffsetMagnitude: vec4, _PointSize: vec4, @@ -50,7 +47,6 @@ struct BillboardUnlitMaterial { _RenderideVariantBits: u32, _Tex_LodBias: f32, _OffsetTex_LodBias: f32, - _MaskTex_LodBias: f32, _pad0: f32, } @@ -70,16 +66,12 @@ const BILLBOARDUNLIT_KW_VERTEX_HDRSRGBALPHA_COLOR: u32 = 1u << 12u; const BILLBOARDUNLIT_KW_VERTEX_LINEAR_COLOR: u32 = 1u << 13u; const BILLBOARDUNLIT_KW_VERTEX_SRGB_COLOR: u32 = 1u << 14u; const BILLBOARDUNLIT_KW_VERTEXCOLORS: u32 = 1u << 15u; -const BILLBOARDUNLIT_KW_UNLIT_MASK_TEXTURE_CLIP: u32 = 1u << 16u; -const BILLBOARDUNLIT_KW_UNLIT_MASK_TEXTURE_MUL: u32 = 1u << 17u; @group(1) @binding(0) var mat: BillboardUnlitMaterial; @group(1) @binding(1) var _Tex: texture_2d; @group(1) @binding(2) var _Tex_sampler: sampler; @group(1) @binding(3) var _OffsetTex: texture_2d; @group(1) @binding(4) var _OffsetTex_sampler: sampler; -@group(1) @binding(5) var _MaskTex: texture_2d; -@group(1) @binding(6) var _MaskTex_sampler: sampler; fn bb_kw(mask: u32) -> bool { return vb::enabled(mat._RenderideVariantBits, mask); @@ -93,14 +85,6 @@ fn kw_COLOR() -> bool { return bb_kw(BILLBOARDUNLIT_KW_COLOR); } -fn kw_UNLIT_MASK_TEXTURE_CLIP() -> bool { - return bb_kw(BILLBOARDUNLIT_KW_UNLIT_MASK_TEXTURE_CLIP); -} - -fn kw_UNLIT_MASK_TEXTURE_MUL() -> bool { - return bb_kw(BILLBOARDUNLIT_KW_UNLIT_MASK_TEXTURE_MUL); -} - fn kw_MUL_ALPHA_INTENSITY() -> bool { return bb_kw(BILLBOARDUNLIT_KW_MUL_ALPHA_INTENSITY); } @@ -286,22 +270,7 @@ fn fs_main( col = vec4(1.0); } - let mask_clip = kw_UNLIT_MASK_TEXTURE_CLIP(); - let mask_mul = kw_UNLIT_MASK_TEXTURE_MUL(); - if (mask_mul || mask_clip) { - let uv_mask = uvu::apply_st(in.uv, mat._MaskTex_ST); - let mask_sample = ts::sample_tex_2d(_MaskTex, _MaskTex_sampler, uv_mask, mat._MaskTex_LodBias); - let mask_lum = ma::mask_luminance(mask_sample); - - if (mask_mul) { - col.a = col.a * mask_lum; - } - if (mask_clip && mask_lum <= mat._Cutoff) { - discard; - } - } - - if (kw_ALPHATEST() && !mask_clip && col.a < mat._Cutoff) { + if (kw_ALPHATEST() && col.a < mat._Cutoff) { discard; } diff --git a/crates/renderide/tests/shader_module_audit.rs b/crates/renderide/tests/shader_module_audit.rs index 55569a762..f4bb5e4c0 100644 --- a/crates/renderide/tests/shader_module_audit.rs +++ b/crates/renderide/tests/shader_module_audit.rs @@ -422,13 +422,9 @@ fn billboard_render_buffer_preserves_fragment_alpha_and_fog_behavior() -> io::Re let src = material_source("billboardunlit.wgsl")?; assert!( - src.contains("if (kw_ALPHATEST() && !mask_clip && col.a < mat._Cutoff)"), + src.contains("if (kw_ALPHATEST() && col.a < mat._Cutoff)"), "Billboard/Unlit alpha test must match Unity clip(col.a - _Cutoff) equality semantics" ); - assert!( - src.contains("if (mask_clip && mask_lum <= mat._Cutoff)"), - "Unlit mask compatibility for render-buffer billboards must preserve Unlit's mask discard threshold" - ); assert!( src.contains("#import renderide::frame::fog as rfog") && src.contains("out.fog_coord = rfog::coord_from_world_pos(world_p, layer);")