1#define_import_path bevy_pbr::pbr_functions 6 mesh_view_bindings as view_bindings, 9 lighting::{LAYER_BASE, LAYER_CLEARCOAT}, 11 clustered_forward as clustering, 15 mesh_types::{MESH_FLAGS_SHADOW_RECEIVER_BIT, MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT}, 17#import bevy_render::maths::{E, powsafe} 19#ifdef MESHLET_MESH_MATERIAL_PASS 20#import bevy_pbr::meshlet_visibility_buffer_resolve::VertexOutput 21#else ifdef PREPASS_PIPELINE 22#import bevy_pbr::prepass_io::VertexOutput 23#else // PREPASS_PIPELINE 24#import bevy_pbr::forward_io::VertexOutput 25#endif // PREPASS_PIPELINE 28#import bevy_pbr::environment_map 31#ifdef TONEMAP_IN_SHADER 32#import bevy_core_pipeline::tonemapping::{tone_mapping, screen_space_dither} 39#ifdef MESHLET_MESH_MATERIAL_PASS 42#else // MESHLET_MESH_MATERIAL_PASS 44#endif // MESHLET_MESH_MATERIAL_PASS 54const DITHER_THRESHOLD_MAP: vec4<u32> = vec4( 75#ifdef VISIBILITY_RANGE_DITHER 76fn visibility_range_dither(frag_coord: vec4<f32>, dither: i32) { 83 if (dither <= -16 || dither >= 16) { 88 let coords = vec2<u32>(floor(frag_coord.xy)) % 4u; 89 let threshold = i32((DITHER_THRESHOLD_MAP[coords.y] >> (coords.x * 8)) & 0xff); 90 if ((dither >= 0 && dither + threshold >= 16) || (dither < 0 && 1 + dither + threshold <= 0)) { 96fn alpha_discard(material: pbr_types::StandardMaterial, output_color: vec4<f32>) -> vec4<f32> { 97 var color = output_color; 98 let alpha_mode = material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS; 99 if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE { 108 else if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_MASK || 109 alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_ALPHA_TO_COVERAGE { 110 if color.a >= material.alpha_cutoff { 123fn prepare_world_normal( 124 world_normal: vec3<f32>, 128 var output: vec3<f32> = world_normal; 129#ifndef VERTEX_TANGENTS 130#ifndef STANDARD_MATERIAL_NORMAL_MAP 133 output = (f32(!double_sided || is_front) * 2.0 - 1.0) * output; 143fn calculate_tbn_mikktspace(world_normal: vec3<f32>, world_tangent: vec4<f32>) -> mat3x3<f32> { 150 var N: vec3<f32> = world_normal; 156 var T: vec3<f32> = world_tangent.xyz; 157 var B: vec3<f32> = world_tangent.w * cross(N, T); 159#ifdef MESHLET_MESH_MATERIAL_PASS 161 let inverse_length_n = 1.0 / length(N); 162 T *= inverse_length_n; 163 B *= inverse_length_n; 164 N *= inverse_length_n; 167 return mat3x3(T, B, N); 170fn apply_normal_mapping( 171 standard_material_flags: u32, 184 if (standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_TWO_COMPONENT_NORMAL_MAP) != 0u { 186 Nt = vec3<f32>(Nt.rg * 2.0 - 1.0, 0.0); 187 Nt.z = sqrt(1.0 - Nt.x * Nt.x - Nt.y * Nt.y); 192 if (standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_FLIP_NORMAL_MAP_Y) != 0u { 196 if double_sided && !is_front { 205 N = Nt.x * T + Nt.y * B + Nt.z * N; 210#ifdef STANDARD_MATERIAL_ANISOTROPY 217fn bend_normal_for_anisotropy(lighting_input: ptr<function, lighting::LightingInput>) { 219 let N = (*lighting_input).layers[LAYER_BASE].N; 220 let roughness = (*lighting_input).layers[LAYER_BASE].roughness; 221 let V = (*lighting_input).V; 222 let anisotropy = (*lighting_input).anisotropy; 223 let Ba = (*lighting_input).Ba; 225 var bent_normal = normalize(cross(cross(Ba, V), Ba)); 230 let a = pow(2.0, pow(2.0, 1.0 - anisotropy * (1.0 - roughness))); 231 bent_normal = normalize(mix(bent_normal, N, a)); 238 let R = normalize(mix(reflect(-V, bent_normal), bent_normal, roughness * roughness)); 240 (*lighting_input).layers[LAYER_BASE].N = bent_normal; 241 (*lighting_input).layers[LAYER_BASE].R = R; 244#endif // STANDARD_MATERIAL_ANISOTROPY 249 world_position: vec4<f32>, 250 is_orthographic: bool, 255 V = normalize(vec3<f32>(view_bindings::view.clip_from_world[0].z, view_bindings::view.clip_from_world[1].z, view_bindings::view.clip_from_world[2].z)); 258 V = normalize(view_bindings::view.world_position.xyz - world_position.xyz); 264fn calculate_diffuse_color( 265 base_color: vec3<f32>, 267 specular_transmission: f32, 268 diffuse_transmission: f32 270 return base_color * (1.0 - metallic) * (1.0 - specular_transmission) * 271 (1.0 - diffuse_transmission); 276fn calculate_F0(base_color: vec3<f32>, metallic: f32, reflectance: vec3<f32>) -> vec3<f32> { 277 return 0.16 * reflectance * reflectance * (1.0 - metallic) + base_color * metallic; 280#ifndef PREPASS_FRAGMENT 281fn apply_pbr_lighting( 282 in: pbr_types::PbrInput, 284 var output_color: vec4<f32> = in.material.base_color; 286 let emissive = in.material.emissive; 289 let metallic = in.material.metallic; 290 let perceptual_roughness = in.material.perceptual_roughness; 291 let roughness = lighting::perceptualRoughnessToRoughness(perceptual_roughness); 292 let ior = in.material.ior; 293 let thickness = in.material.thickness; 294 let reflectance = in.material.reflectance; 295 let diffuse_transmission = in.material.diffuse_transmission; 296 let specular_transmission = in.material.specular_transmission; 298 let specular_transmissive_color = specular_transmission * in.material.base_color.rgb; 300 let diffuse_occlusion = in.diffuse_occlusion; 301 let specular_occlusion = in.specular_occlusion; 304 let NdotV = max(dot(in.N, in.V), 0.0001); 305 let R = reflect(-in.V, in.N); 307#ifdef STANDARD_MATERIAL_CLEARCOAT 310 let clearcoat = in.material.clearcoat; 311 let clearcoat_perceptual_roughness = in.material.clearcoat_perceptual_roughness; 312 let clearcoat_roughness = lighting::perceptualRoughnessToRoughness(clearcoat_perceptual_roughness); 313 let clearcoat_N = in.clearcoat_N; 314 let clearcoat_NdotV = max(dot(clearcoat_N, in.V), 0.0001); 315 let clearcoat_R = reflect(-in.V, clearcoat_N); 316#endif // STANDARD_MATERIAL_CLEARCOAT 318 let diffuse_color = calculate_diffuse_color( 321 specular_transmission, 326 let diffuse_transmissive_color = output_color.rgb * (1.0 - metallic) * (1.0 - specular_transmission) * diffuse_transmission; 329 let diffuse_transmissive_lobe_world_position = in.world_position - vec4<f32>(in.world_normal, 0.0) * thickness; 331 let F0 = calculate_F0(output_color.rgb, metallic, reflectance); 332 let F_ab = lighting::F_AB(perceptual_roughness, NdotV); 334 var direct_light: vec3<f32> = vec3<f32>(0.0); 337 var transmitted_light: vec3<f32> = vec3<f32>(0.0); 340 var lighting_input: lighting::LightingInput; 341 lighting_input.layers[LAYER_BASE].NdotV = NdotV; 342 lighting_input.layers[LAYER_BASE].N = in.N; 343 lighting_input.layers[LAYER_BASE].R = R; 344 lighting_input.layers[LAYER_BASE].perceptual_roughness = perceptual_roughness; 345 lighting_input.layers[LAYER_BASE].roughness = roughness; 346 lighting_input.P = in.world_position.xyz; 347 lighting_input.V = in.V; 348 lighting_input.diffuse_color = diffuse_color; 349 lighting_input.F0_ = F0; 350 lighting_input.F_ab = F_ab; 351#ifdef STANDARD_MATERIAL_CLEARCOAT 352 lighting_input.layers[LAYER_CLEARCOAT].NdotV = clearcoat_NdotV; 353 lighting_input.layers[LAYER_CLEARCOAT].N = clearcoat_N; 354 lighting_input.layers[LAYER_CLEARCOAT].R = clearcoat_R; 355 lighting_input.layers[LAYER_CLEARCOAT].perceptual_roughness = clearcoat_perceptual_roughness; 356 lighting_input.layers[LAYER_CLEARCOAT].roughness = clearcoat_roughness; 357 lighting_input.clearcoat_strength = clearcoat; 358#endif // STANDARD_MATERIAL_CLEARCOAT 359#ifdef STANDARD_MATERIAL_ANISOTROPY 360 lighting_input.anisotropy = in.anisotropy_strength; 361 lighting_input.Ta = in.anisotropy_T; 362 lighting_input.Ba = in.anisotropy_B; 363#endif // STANDARD_MATERIAL_ANISOTROPY 366#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 367 var transmissive_lighting_input: lighting::LightingInput; 368 transmissive_lighting_input.layers[LAYER_BASE].NdotV = 1.0; 369 transmissive_lighting_input.layers[LAYER_BASE].N = -in.N; 370 transmissive_lighting_input.layers[LAYER_BASE].R = vec3(0.0); 371 transmissive_lighting_input.layers[LAYER_BASE].perceptual_roughness = 1.0; 372 transmissive_lighting_input.layers[LAYER_BASE].roughness = 1.0; 373 transmissive_lighting_input.P = diffuse_transmissive_lobe_world_position.xyz; 374 transmissive_lighting_input.V = -in.V; 375 transmissive_lighting_input.diffuse_color = diffuse_transmissive_color; 376 transmissive_lighting_input.F0_ = vec3(0.0); 377 transmissive_lighting_input.F_ab = vec2(0.1); 378#ifdef STANDARD_MATERIAL_CLEARCOAT 379 transmissive_lighting_input.layers[LAYER_CLEARCOAT].NdotV = 0.0; 380 transmissive_lighting_input.layers[LAYER_CLEARCOAT].N = vec3(0.0); 381 transmissive_lighting_input.layers[LAYER_CLEARCOAT].R = vec3(0.0); 382 transmissive_lighting_input.layers[LAYER_CLEARCOAT].perceptual_roughness = 0.0; 383 transmissive_lighting_input.layers[LAYER_CLEARCOAT].roughness = 0.0; 384 transmissive_lighting_input.clearcoat_strength = 0.0; 385#endif // STANDARD_MATERIAL_CLEARCOAT 386#ifdef STANDARD_MATERIAL_ANISOTROPY 387 transmissive_lighting_input.anisotropy = in.anisotropy_strength; 388 transmissive_lighting_input.Ta = in.anisotropy_T; 389 transmissive_lighting_input.Ba = in.anisotropy_B; 390#endif // STANDARD_MATERIAL_ANISOTROPY 391#endif // STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 393 let view_z = dot(vec4<f32>( 394 view_bindings::view.view_from_world[0].z, 395 view_bindings::view.view_from_world[1].z, 396 view_bindings::view.view_from_world[2].z, 397 view_bindings::view.view_from_world[3].z 398 ), in.world_position); 399 let cluster_index = clustering::fragment_cluster_index(in.frag_coord.xy, view_z, in.is_orthographic); 400 var clusterable_object_index_ranges = 401 clustering::unpack_clusterable_object_index_ranges(cluster_index); 404 for (var i: u32 = clusterable_object_index_ranges.first_point_light_index_offset; 405 i < clusterable_object_index_ranges.first_spot_light_index_offset; 407 let light_id = clustering::get_clusterable_object_id(i); 413 (view_bindings::clusterable_objects.data[light_id].flags & 414 mesh_view_types::POINT_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESH_DIFFUSE_BIT) != 0u; 416 let enable_diffuse = true; 419 var shadow: f32 = 1.0; 420 if ((in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 421 && (view_bindings::clusterable_objects.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 422 shadow = shadows::fetch_point_shadow(light_id, in.world_position, in.world_normal); 425 let light_contrib = lighting::point_light(light_id, &lighting_input, enable_diffuse); 426 direct_light += light_contrib * shadow; 428#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 438 var transmitted_shadow: f32 = 1.0; 439 if ((in.flags & (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT)) == (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT) 440 && (view_bindings::clusterable_objects.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 441 transmitted_shadow = shadows::fetch_point_shadow(light_id, diffuse_transmissive_lobe_world_position, -in.world_normal); 444 let transmitted_light_contrib = 445 lighting::point_light(light_id, &transmissive_lighting_input, enable_diffuse); 446 transmitted_light += transmitted_light_contrib * transmitted_shadow; 451 for (var i: u32 = clusterable_object_index_ranges.first_spot_light_index_offset; 452 i < clusterable_object_index_ranges.first_reflection_probe_index_offset; 454 let light_id = clustering::get_clusterable_object_id(i); 460 (view_bindings::clusterable_objects.data[light_id].flags & 461 mesh_view_types::POINT_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESH_DIFFUSE_BIT) != 0u; 463 let enable_diffuse = true; 466 var shadow: f32 = 1.0; 467 if ((in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 468 && (view_bindings::clusterable_objects.data[light_id].flags & 469 mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 470 shadow = shadows::fetch_spot_shadow( 474 view_bindings::clusterable_objects.data[light_id].shadow_map_near_z, 478 let light_contrib = lighting::spot_light(light_id, &lighting_input, enable_diffuse); 479 direct_light += light_contrib * shadow; 481#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 491 var transmitted_shadow: f32 = 1.0; 492 if ((in.flags & (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT)) == (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT) 493 && (view_bindings::clusterable_objects.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 494 transmitted_shadow = shadows::fetch_spot_shadow( 496 diffuse_transmissive_lobe_world_position, 498 view_bindings::clusterable_objects.data[light_id].shadow_map_near_z, 502 let transmitted_light_contrib = 503 lighting::spot_light(light_id, &transmissive_lighting_input, enable_diffuse); 504 transmitted_light += transmitted_light_contrib * transmitted_shadow; 509 let n_directional_lights = view_bindings::lights.n_directional_lights; 510 for (var i: u32 = 0u; i < n_directional_lights; i = i + 1u) { 513 let light = &view_bindings::lights.directional_lights[i]; 514 if (*light).skip != 0u { 523 mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESH_DIFFUSE_BIT) != 526 let enable_diffuse = true; 529 var shadow: f32 = 1.0; 530 if ((in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 531 && (view_bindings::lights.directional_lights[i].flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 532 shadow = shadows::fetch_directional_shadow(i, in.world_position, in.world_normal, view_z); 535 var light_contrib = lighting::directional_light(i, &lighting_input, enable_diffuse); 537#ifdef DIRECTIONAL_LIGHT_SHADOW_MAP_DEBUG_CASCADES 538 light_contrib = shadows::cascade_debug_visualization(light_contrib, i, view_z); 540 direct_light += light_contrib * shadow; 542#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 552 var transmitted_shadow: f32 = 1.0; 553 if ((in.flags & (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT)) == (MESH_FLAGS_SHADOW_RECEIVER_BIT | MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT) 554 && (view_bindings::lights.directional_lights[i].flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 555 transmitted_shadow = shadows::fetch_directional_shadow(i, diffuse_transmissive_lobe_world_position, -in.world_normal, view_z); 558 let transmitted_light_contrib = 559 lighting::directional_light(i, &transmissive_lighting_input, enable_diffuse); 560 transmitted_light += transmitted_light_contrib * transmitted_shadow; 564#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 573 transmitted_light += ambient::ambient_light(diffuse_transmissive_lobe_world_position, -in.N, -in.V, 1.0, diffuse_transmissive_color, vec3<f32>(0.0), 1.0, vec3<f32>(1.0)); 587 var indirect_light = vec3(0.0f); 588 var found_diffuse_indirect = false; 591 indirect_light += in.lightmap_light * diffuse_color; 592 found_diffuse_indirect = true; 595#ifdef IRRADIANCE_VOLUME 597 if (!found_diffuse_indirect) { 598 let irradiance_volume_light = irradiance_volume::irradiance_volume_light( 599 in.world_position.xyz, 601 &clusterable_object_index_ranges, 603 indirect_light += irradiance_volume_light * diffuse_color * diffuse_occlusion; 604 found_diffuse_indirect = true; 609#ifdef ENVIRONMENT_MAP 611#ifdef STANDARD_MATERIAL_ANISOTROPY 612 var bent_normal_lighting_input = lighting_input; 613 bend_normal_for_anisotropy(&bent_normal_lighting_input); 614 let environment_map_lighting_input = &bent_normal_lighting_input; 615#else // STANDARD_MATERIAL_ANISOTROPY 616 let environment_map_lighting_input = &lighting_input; 617#endif // STANDARD_MATERIAL_ANISOTROPY 619 let environment_light = environment_map::environment_map_light( 620 environment_map_lighting_input, 621 &clusterable_object_index_ranges, 622 found_diffuse_indirect, 627#ifdef SCREEN_SPACE_REFLECTIONS 628 let use_ssr = perceptual_roughness <= 629 view_bindings::ssr_settings.perceptual_roughness_threshold; 630#else // SCREEN_SPACE_REFLECTIONS 632#endif // SCREEN_SPACE_REFLECTIONS 635 let environment_light = environment_map::environment_map_light( 637 &clusterable_object_index_ranges, 638 found_diffuse_indirect 641 indirect_light += environment_light.diffuse * diffuse_occlusion + 642 environment_light.specular * specular_occlusion; 645#endif // ENVIRONMENT_MAP 648 indirect_light += ambient::ambient_light(in.world_position, in.N, in.V, NdotV, diffuse_color, F0, perceptual_roughness, diffuse_occlusion); 652 var specular_transmitted_environment_light = vec3<f32>(0.0); 654#ifdef ENVIRONMENT_MAP 656#ifdef STANDARD_MATERIAL_DIFFUSE_OR_SPECULAR_TRANSMISSION 672 refract(in.V, -in.N, 1.0 / ior) * thickness 675 var transmissive_environment_light_input: lighting::LightingInput; 676 transmissive_environment_light_input.diffuse_color = vec3(1.0); 677 transmissive_environment_light_input.layers[LAYER_BASE].NdotV = 1.0; 678 transmissive_environment_light_input.P = in.world_position.xyz; 679 transmissive_environment_light_input.layers[LAYER_BASE].N = -in.N; 680 transmissive_environment_light_input.V = in.V; 681 transmissive_environment_light_input.layers[LAYER_BASE].R = T; 682 transmissive_environment_light_input.layers[LAYER_BASE].perceptual_roughness = perceptual_roughness; 683 transmissive_environment_light_input.layers[LAYER_BASE].roughness = roughness; 684 transmissive_environment_light_input.F0_ = vec3<f32>(1.0); 685 transmissive_environment_light_input.F_ab = vec2(0.1); 686#ifdef STANDARD_MATERIAL_CLEARCOAT 688 transmissive_environment_light_input.clearcoat_strength = 0.0; 689 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].NdotV = 0.0; 690 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].N = in.N; 691 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].R = vec3(0.0); 692 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].perceptual_roughness = 0.0; 693 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].roughness = 0.0; 694#endif // STANDARD_MATERIAL_CLEARCOAT 696 let transmitted_environment_light = environment_map::environment_map_light( 697 &transmissive_environment_light_input, 698 &clusterable_object_index_ranges, 702#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 703 transmitted_light += transmitted_environment_light.diffuse * diffuse_transmissive_color; 704#endif // STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 705#ifdef STANDARD_MATERIAL_SPECULAR_TRANSMISSION 706 specular_transmitted_environment_light = transmitted_environment_light.specular * specular_transmissive_color; 707#endif // STANDARD_MATERIAL_SPECULAR_TRANSMISSION 709#endif // STANDARD_MATERIAL_SPECULAR_OR_DIFFUSE_TRANSMISSION 711#endif // ENVIRONMENT_MAP 713 var emissive_light = emissive.rgb * output_color.a; 719#ifdef STANDARD_MATERIAL_CLEARCOAT 720 emissive_light = emissive_light * (0.04 + (1.0 - 0.04) * pow(1.0 - clearcoat_NdotV, 5.0)); 723 emissive_light = emissive_light * mix(1.0, view_bindings::view.exposure, emissive.a); 725#ifdef STANDARD_MATERIAL_SPECULAR_TRANSMISSION 726 transmitted_light += transmission::specular_transmissive_light(in.world_position, in.frag_coord.xyz, view_z, in.N, in.V, F0, ior, thickness, perceptual_roughness, specular_transmissive_color, specular_transmitted_environment_light).rgb; 728 if (in.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ATTENUATION_ENABLED_BIT) != 0u { 732 var attenuation_fog: mesh_view_types::Fog; 733 attenuation_fog.base_color.a = 1.0; 734 attenuation_fog.be = pow(1.0 - in.material.attenuation_color.rgb, vec3<f32>(E)) / in.material.attenuation_distance; 737 transmitted_light = bevy_pbr::fog::atmospheric_fog( 738 attenuation_fog, vec4<f32>(transmitted_light, 1.0), thickness, 745 output_color = vec4<f32>( 746 (view_bindings::view.exposure * (transmitted_light + direct_light + indirect_light)) + emissive_light, 750 output_color = clustering::cluster_debug_visualization( 754 clusterable_object_index_ranges, 760#endif // PREPASS_FRAGMENT 763fn apply_fog(fog_params: mesh_view_types::Fog, input_color: vec4<f32>, fragment_world_position: vec3<f32>, view_world_position: vec3<f32>) -> vec4<f32> { 764 let view_to_world = fragment_world_position.xyz - view_world_position.xyz; 770 let distance = length(view_to_world); 772 var scattering = vec3<f32>(0.0); 773 if fog_params.directional_light_color.a > 0.0 { 774 let view_to_world_normalized = view_to_world / distance; 775 let n_directional_lights = view_bindings::lights.n_directional_lights; 776 for (var i: u32 = 0u; i < n_directional_lights; i = i + 1u) { 777 let light = view_bindings::lights.directional_lights[i]; 780 dot(view_to_world_normalized, light.direction_to_light), 783 fog_params.directional_light_exponent 784 ) * light.color.rgb * view_bindings::view.exposure; 788 if fog_params.mode == mesh_view_types::FOG_MODE_LINEAR { 789 return bevy_pbr::fog::linear_fog(fog_params, input_color, distance, scattering); 790 } else if fog_params.mode == mesh_view_types::FOG_MODE_EXPONENTIAL { 791 return bevy_pbr::fog::exponential_fog(fog_params, input_color, distance, scattering); 792 } else if fog_params.mode == mesh_view_types::FOG_MODE_EXPONENTIAL_SQUARED { 793 return bevy_pbr::fog::exponential_squared_fog(fog_params, input_color, distance, scattering); 794 } else if fog_params.mode == mesh_view_types::FOG_MODE_ATMOSPHERIC { 795 return bevy_pbr::fog::atmospheric_fog(fog_params, input_color, distance, scattering); 800#endif // DISTANCE_FOG 802#ifdef PREMULTIPLY_ALPHA 803fn premultiply_alpha(standard_material_flags: u32, color: vec4<f32>) -> vec4<f32> { 808#ifdef BLEND_PREMULTIPLIED_ALPHA 812 let alpha_mode = standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS; 813 if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_ADD { 825 return vec4<f32>(color.rgb * color.a, 0.0); 849 return vec4<f32>(color.rgb * color.a, color.a); 856fn main_pass_post_lighting_processing( 857 pbr_input: pbr_types::PbrInput, 858 input_color: vec4<f32>, 860 var output_color = input_color; 864 if ((pbr_input.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_FOG_ENABLED_BIT) != 0u) { 865 output_color = apply_fog(view_bindings::fog, output_color, pbr_input.world_position.xyz, view_bindings::view.world_position.xyz); 867#endif // DISTANCE_FOG 869#ifdef TONEMAP_IN_SHADER 870 output_color = tone_mapping(output_color, view_bindings::view.color_grading); 872 var output_rgb = output_color.rgb; 873 output_rgb = powsafe(output_rgb, 1.0 / 2.2); 874 output_rgb += screen_space_dither(pbr_input.frag_coord.xy); 877 output_rgb = powsafe(output_rgb, 2.2); 878 output_color = vec4(output_rgb, output_color.a); 881#ifdef PREMULTIPLY_ALPHA 882 output_color = premultiply_alpha(pbr_input.material.flags, output_color);