Path: blob/main/crates/bevy_pbr/src/render/pbr_prepass.wgsl
6600 views
#import bevy_pbr::{ pbr_prepass_functions, pbr_bindings, pbr_bindings::material, pbr_types, pbr_functions, pbr_functions::SampleBias, prepass_io, mesh_bindings::mesh, mesh_view_bindings::view, } #import bevy_render::bindless::{bindless_samplers_filtering, bindless_textures_2d} #ifdef MESHLET_MESH_MATERIAL_PASS #import bevy_pbr::meshlet_visibility_buffer_resolve::resolve_vertex_output #endif #ifdef BINDLESS #import bevy_pbr::pbr_bindings::material_indices #endif // BINDLESS #ifdef PREPASS_FRAGMENT @fragment fn fragment( #ifdef MESHLET_MESH_MATERIAL_PASS @builtin(position) frag_coord: vec4<f32>, #else in: prepass_io::VertexOutput, @builtin(front_facing) is_front: bool, #endif ) -> prepass_io::FragmentOutput { #ifdef MESHLET_MESH_MATERIAL_PASS let in = resolve_vertex_output(frag_coord); let is_front = true; #else // MESHLET_MESH_MATERIAL_PASS #ifdef BINDLESS let slot = mesh[in.instance_index].material_and_lightmap_bind_group_slot & 0xffffu; let flags = pbr_bindings::material_array[material_indices[slot].material].flags; let uv_transform = pbr_bindings::material_array[material_indices[slot].material].uv_transform; #else // BINDLESS let flags = pbr_bindings::material.flags; let uv_transform = pbr_bindings::material.uv_transform; #endif // BINDLESS // If we're in the crossfade section of a visibility range, conditionally // discard the fragment according to the visibility pattern. #ifdef VISIBILITY_RANGE_DITHER pbr_functions::visibility_range_dither(in.position, in.visibility_range_dither); #endif // VISIBILITY_RANGE_DITHER pbr_prepass_functions::prepass_alpha_discard(in); #endif // MESHLET_MESH_MATERIAL_PASS var out: prepass_io::FragmentOutput; #ifdef UNCLIPPED_DEPTH_ORTHO_EMULATION out.frag_depth = in.unclipped_depth; #endif // UNCLIPPED_DEPTH_ORTHO_EMULATION #ifdef NORMAL_PREPASS // NOTE: Unlit bit not set means == 0 is true, so the true case is if lit if (flags & pbr_types::STANDARD_MATERIAL_FLAGS_UNLIT_BIT) == 0u { let double_sided = (flags & pbr_types::STANDARD_MATERIAL_FLAGS_DOUBLE_SIDED_BIT) != 0u; let world_normal = pbr_functions::prepare_world_normal( in.world_normal, double_sided, is_front, ); var normal = world_normal; #ifdef VERTEX_UVS #ifdef VERTEX_TANGENTS #ifdef STANDARD_MATERIAL_NORMAL_MAP // TODO: Transforming UVs mean we need to apply derivative chain rule for meshlet mesh material pass #ifdef STANDARD_MATERIAL_NORMAL_MAP_UV_B let uv = (uv_transform * vec3(in.uv_b, 1.0)).xy; #else let uv = (uv_transform * vec3(in.uv, 1.0)).xy; #endif // Fill in the sample bias so we can sample from textures. var bias: SampleBias; #ifdef MESHLET_MESH_MATERIAL_PASS bias.ddx_uv = in.ddx_uv; bias.ddy_uv = in.ddy_uv; #else // MESHLET_MESH_MATERIAL_PASS bias.mip_bias = view.mip_bias; #endif // MESHLET_MESH_MATERIAL_PASS let Nt = #ifdef MESHLET_MESH_MATERIAL_PASS textureSampleGrad( #else // MESHLET_MESH_MATERIAL_PASS textureSampleBias( #endif // MESHLET_MESH_MATERIAL_PASS #ifdef BINDLESS bindless_textures_2d[material_indices[slot].normal_map_texture], bindless_samplers_filtering[material_indices[slot].normal_map_sampler], #else // BINDLESS pbr_bindings::normal_map_texture, pbr_bindings::normal_map_sampler, #endif // BINDLESS uv, #ifdef MESHLET_MESH_MATERIAL_PASS bias.ddx_uv, bias.ddy_uv, #else // MESHLET_MESH_MATERIAL_PASS bias.mip_bias, #endif // MESHLET_MESH_MATERIAL_PASS ).rgb; let TBN = pbr_functions::calculate_tbn_mikktspace(normal, in.world_tangent); normal = pbr_functions::apply_normal_mapping( flags, TBN, double_sided, is_front, Nt, ); #endif // STANDARD_MATERIAL_NORMAL_MAP #endif // VERTEX_TANGENTS #endif // VERTEX_UVS out.normal = vec4(normal * 0.5 + vec3(0.5), 1.0); } else { out.normal = vec4(in.world_normal * 0.5 + vec3(0.5), 1.0); } #endif // NORMAL_PREPASS #ifdef MOTION_VECTOR_PREPASS #ifdef MESHLET_MESH_MATERIAL_PASS out.motion_vector = in.motion_vector; #else out.motion_vector = pbr_prepass_functions::calculate_motion_vector(in.world_position, in.previous_world_position); #endif #endif return out; } #else @fragment fn fragment(in: prepass_io::VertexOutput) { pbr_prepass_functions::prepass_alpha_discard(in); } #endif // PREPASS_FRAGMENT