1#define_import_path bevy_pbr::pbr_deferred_functions 4 pbr_types::{PbrInput, pbr_input_new, STANDARD_MATERIAL_FLAGS_UNLIT_BIT}, 5 pbr_deferred_types as deferred_types, 8 mesh_view_bindings::view, 9 utils::{octahedral_encode, octahedral_decode}, 10 prepass_io::FragmentOutput, 11 view_transformations::{position_ndc_to_world, frag_coord_to_ndc}, 14#ifdef MESHLET_MESH_MATERIAL_PASS 15#import bevy_pbr::meshlet_visibility_buffer_resolve::VertexOutput 17#import bevy_pbr::prepass_io::VertexOutput 20#ifdef MOTION_VECTOR_PREPASS 21 #import bevy_pbr::pbr_prepass_functions::calculate_motion_vector 25fn deferred_gbuffer_from_pbr_input(in: PbrInput) -> vec4<u32> { 31 let rec_709_coeffs = vec3<f32>(0.2126, 0.7152, 0.0722); 32 let diffuse_occlusion = dot(in.diffuse_occlusion, rec_709_coeffs); 34 let reflectance = dot(in.material.reflectance, rec_709_coeffs); 35#ifdef WEBGL2 // More crunched for webgl so we can also fit depth. 36 var props = deferred_types::pack_unorm3x4_plus_unorm_20_(vec4( 42 let clearcoat = u32(round(saturate(in.material.clearcoat) * 15.0)); 43 let clearcoat_perceptual_roughness = 44 u32(round(clamp(in.material.clearcoat_perceptual_roughness, 0.0, 0.5) * 30.0)); 45 let clearcoat_props = f32(clearcoat | (clearcoat_perceptual_roughness << 4u)) / 255.0; 46 var props = deferred_types::pack_unorm4x8_(vec4( 52 let flags = deferred_types::deferred_flags_from_mesh_material_flags(in.flags, in.material.flags); 53 let octahedral_normal = octahedral_encode(normalize(in.N)); 54 var base_color_srgb = vec3(0.0); 55 var emissive = in.material.emissive.rgb; 56 if ((in.material.flags & STANDARD_MATERIAL_FLAGS_UNLIT_BIT) != 0u) { 59 emissive = in.material.base_color.rgb; 61 base_color_srgb = pow(in.material.base_color.rgb, vec3(1.0 / 2.2)); 67 let base_color = in.material.base_color.rgb; 68 let metallic = in.material.metallic; 69 let specular_transmission = in.material.specular_transmission; 70 let diffuse_transmission = in.material.diffuse_transmission; 71 let diffuse_color = pbr_functions::calculate_diffuse_color( 74 specular_transmission, 77 emissive += in.lightmap_light * diffuse_color * view.exposure; 80 deferred_types::pack_unorm4x8_(vec4(base_color_srgb, in.material.perceptual_roughness)), 81 rgb9e5::vec3_to_rgb9e5_(emissive), 83 deferred_types::pack_24bit_normal_and_flags(octahedral_normal, flags), 89fn pbr_input_from_deferred_gbuffer(frag_coord: vec4<f32>, gbuffer: vec4<u32>) -> PbrInput { 90 var pbr = pbr_input_new(); 92 let flags = deferred_types::unpack_flags(gbuffer.a); 93 let deferred_flags = deferred_types::mesh_material_flags_from_deferred_flags(flags); 94 pbr.flags = deferred_flags.x; 95 pbr.material.flags = deferred_flags.y; 97 let base_rough = deferred_types::unpack_unorm4x8_(gbuffer.r); 98 pbr.material.perceptual_roughness = base_rough.a; 99 let emissive = rgb9e5::rgb9e5_to_vec3_(gbuffer.g); 100 if ((pbr.material.flags & STANDARD_MATERIAL_FLAGS_UNLIT_BIT) != 0u) { 101 pbr.material.base_color = vec4(emissive, 1.0); 102 pbr.material.emissive = vec4(vec3(0.0), 0.0); 104 pbr.material.base_color = vec4(pow(base_rough.rgb, vec3(2.2)), 1.0); 105 pbr.material.emissive = vec4(emissive, 0.0); 107#ifdef WEBGL2 // More crunched for webgl so we can also fit depth. 108 let props = deferred_types::unpack_unorm3x4_plus_unorm_20_(gbuffer.b); 110 pbr.material.reflectance = vec3(saturate(props.r - 0.03333333333)); 112 let props = deferred_types::unpack_unorm4x8_(gbuffer.b); 113 let clearcoat_props = u32(round(props.a * 255.0)); 114 pbr.material.reflectance = vec3(props.r); 115 pbr.material.clearcoat = f32(clearcoat_props & 0x0fu) / 15.0; 116 pbr.material.clearcoat_perceptual_roughness = f32(clearcoat_props >> 4u) / 30.0; 118 pbr.material.metallic = props.g; 119 pbr.diffuse_occlusion = vec3(props.b); 120 let octahedral_normal = deferred_types::unpack_24bit_normal(gbuffer.a); 121 let N = octahedral_decode(octahedral_normal); 123 let world_position = vec4(position_ndc_to_world(frag_coord_to_ndc(frag_coord)), 1.0); 124 let is_orthographic = view.clip_from_view[3].w == 1.0; 125 let V = pbr_functions::calculate_view(world_position, is_orthographic); 127 pbr.frag_coord = frag_coord; 128 pbr.world_normal = N; 129 pbr.world_position = world_position; 133 pbr.is_orthographic = is_orthographic; 138#ifdef PREPASS_PIPELINE 139fn deferred_output(in: VertexOutput, pbr_input: PbrInput) -> FragmentOutput { 140 var out: FragmentOutput; 143 out.deferred = deferred_gbuffer_from_pbr_input(pbr_input); 145 out.deferred_lighting_pass_id = pbr_input.material.deferred_lighting_pass_id; 148 out.normal = vec4(in.world_normal * 0.5 + vec3(0.5), 1.0); 151#ifdef MOTION_VECTOR_PREPASS 152#ifdef MESHLET_MESH_MATERIAL_PASS 153 out.motion_vector = in.motion_vector; 155 out.motion_vector = calculate_motion_vector(in.world_position, in.previous_world_position);