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, 16 mesh_types::{MESH_FLAGS_SHADOW_RECEIVER_BIT, MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT}, 18#import bevy_render::maths::{E, powsafe} 20#ifdef MESHLET_MESH_MATERIAL_PASS 21#import bevy_pbr::meshlet_visibility_buffer_resolve::VertexOutput 22#else ifdef PREPASS_PIPELINE 23#import bevy_pbr::prepass_io::VertexOutput 24#else // PREPASS_PIPELINE 25#import bevy_pbr::forward_io::VertexOutput 26#endif // PREPASS_PIPELINE 29#import bevy_pbr::environment_map 32#ifdef TONEMAP_IN_SHADER 33#import bevy_core_pipeline::tonemapping::{tone_mapping, screen_space_dither} 40#ifdef MESHLET_MESH_MATERIAL_PASS 43#else // MESHLET_MESH_MATERIAL_PASS 45#endif // MESHLET_MESH_MATERIAL_PASS 55const DITHER_THRESHOLD_MAP: vec4<u32> = vec4( 76#ifdef VISIBILITY_RANGE_DITHER 77fn visibility_range_dither(frag_coord: vec4<f32>, dither: i32) { 84 if (dither <= -16 || dither >= 16) { 89 let coords = vec2<u32>(floor(frag_coord.xy)) % 4u; 90 let threshold = i32((DITHER_THRESHOLD_MAP[coords.y] >> (coords.x * 8)) & 0xff); 91 if ((dither >= 0 && dither + threshold >= 16) || (dither < 0 && 1 + dither + threshold <= 0)) { 97fn alpha_discard(material: pbr_types::StandardMaterial, output_color: vec4<f32>) -> vec4<f32> { 98 var color = output_color; 99 let alpha_mode = material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS; 100 if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE { 109 else if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_MASK || 110 alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_ALPHA_TO_COVERAGE { 111 if color.a >= material.alpha_cutoff { 124fn prepare_world_normal( 125 world_normal: vec3<f32>, 129 var output: vec3<f32> = world_normal; 130#ifndef VERTEX_TANGENTS 131#ifndef STANDARD_MATERIAL_NORMAL_MAP 134 output = (f32(!double_sided || is_front) * 2.0 - 1.0) * output; 144fn calculate_tbn_mikktspace(world_normal: vec3<f32>, world_tangent: vec4<f32>) -> mat3x3<f32> { 151 var N: vec3<f32> = world_normal; 157 var T: vec3<f32> = world_tangent.xyz; 158 var B: vec3<f32> = world_tangent.w * cross(N, T); 160#ifdef MESHLET_MESH_MATERIAL_PASS 162 let inverse_length_n = 1.0 / length(N); 163 T *= inverse_length_n; 164 B *= inverse_length_n; 165 N *= inverse_length_n; 168 return mat3x3(T, B, N); 171fn apply_normal_mapping( 172 standard_material_flags: u32, 185 if (standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_TWO_COMPONENT_NORMAL_MAP) != 0u { 187 Nt = vec3<f32>(Nt.rg * 2.0 - 1.0, 0.0); 188 Nt.z = sqrt(1.0 - Nt.x * Nt.x - Nt.y * Nt.y); 193 if (standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_FLIP_NORMAL_MAP_Y) != 0u { 197 if double_sided && !is_front { 206 N = Nt.x * T + Nt.y * B + Nt.z * N; 211#ifdef STANDARD_MATERIAL_ANISOTROPY 218fn bend_normal_for_anisotropy(lighting_input: ptr<function, lighting::LightingInput>) { 220 let N = (*lighting_input).layers[LAYER_BASE].N; 221 let roughness = (*lighting_input).layers[LAYER_BASE].roughness; 222 let V = (*lighting_input).V; 223 let anisotropy = (*lighting_input).anisotropy; 224 let Ba = (*lighting_input).Ba; 226 var bent_normal = normalize(cross(cross(Ba, V), Ba)); 231 let a = pow(2.0, pow(2.0, 1.0 - anisotropy * (1.0 - roughness))); 232 bent_normal = normalize(mix(bent_normal, N, a)); 239 let R = normalize(mix(reflect(-V, bent_normal), bent_normal, roughness * roughness)); 241 (*lighting_input).layers[LAYER_BASE].N = bent_normal; 242 (*lighting_input).layers[LAYER_BASE].R = R; 245#endif // STANDARD_MATERIAL_ANISOTROPY 250 world_position: vec4<f32>, 251 is_orthographic: bool, 256 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)); 259 V = normalize(view_bindings::view.world_position.xyz - world_position.xyz); 265fn calculate_diffuse_color( 266 base_color: vec3<f32>, 268 specular_transmission: f32, 269 diffuse_transmission: f32 271 return base_color * (1.0 - metallic) * (1.0 - specular_transmission) * 272 (1.0 - diffuse_transmission); 277fn calculate_F0(base_color: vec3<f32>, metallic: f32, reflectance: vec3<f32>) -> vec3<f32> { 278 return 0.16 * reflectance * reflectance * (1.0 - metallic) + base_color * metallic; 281#ifndef PREPASS_FRAGMENT 282fn apply_pbr_lighting( 283 in: pbr_types::PbrInput, 285 var output_color: vec4<f32> = in.material.base_color; 287 let emissive = in.material.emissive; 290 let metallic = in.material.metallic; 291 let perceptual_roughness = in.material.perceptual_roughness; 292 let roughness = lighting::perceptualRoughnessToRoughness(perceptual_roughness); 293 let ior = in.material.ior; 294 let thickness = in.material.thickness; 295 let reflectance = in.material.reflectance; 296 let diffuse_transmission = in.material.diffuse_transmission; 297 let specular_transmission = in.material.specular_transmission; 299 let specular_transmissive_color = specular_transmission * in.material.base_color.rgb; 301 let diffuse_occlusion = in.diffuse_occlusion; 302 let specular_occlusion = in.specular_occlusion; 305 let NdotV = max(dot(in.N, in.V), 0.0001); 306 let R = reflect(-in.V, in.N); 308#ifdef STANDARD_MATERIAL_CLEARCOAT 311 let clearcoat = in.material.clearcoat; 312 let clearcoat_perceptual_roughness = in.material.clearcoat_perceptual_roughness; 313 let clearcoat_roughness = lighting::perceptualRoughnessToRoughness(clearcoat_perceptual_roughness); 314 let clearcoat_N = in.clearcoat_N; 315 let clearcoat_NdotV = max(dot(clearcoat_N, in.V), 0.0001); 316 let clearcoat_R = reflect(-in.V, clearcoat_N); 317#endif // STANDARD_MATERIAL_CLEARCOAT 319 let diffuse_color = calculate_diffuse_color( 322 specular_transmission, 327 let diffuse_transmissive_color = output_color.rgb * (1.0 - metallic) * (1.0 - specular_transmission) * diffuse_transmission; 330 let diffuse_transmissive_lobe_world_position = in.world_position - vec4<f32>(in.world_normal, 0.0) * thickness; 332 let F0 = calculate_F0(output_color.rgb, metallic, reflectance); 333 let F_ab = lighting::F_AB(perceptual_roughness, NdotV); 335 var direct_light: vec3<f32> = vec3<f32>(0.0); 338 var transmitted_light: vec3<f32> = vec3<f32>(0.0); 341 var lighting_input: lighting::LightingInput; 342 lighting_input.layers[LAYER_BASE].NdotV = NdotV; 343 lighting_input.layers[LAYER_BASE].N = in.N; 344 lighting_input.layers[LAYER_BASE].R = R; 345 lighting_input.layers[LAYER_BASE].perceptual_roughness = perceptual_roughness; 346 lighting_input.layers[LAYER_BASE].roughness = roughness; 347 lighting_input.P = in.world_position.xyz; 348 lighting_input.V = in.V; 349 lighting_input.diffuse_color = diffuse_color; 350 lighting_input.F0_ = F0; 351 lighting_input.F_ab = F_ab; 352#ifdef STANDARD_MATERIAL_CLEARCOAT 353 lighting_input.layers[LAYER_CLEARCOAT].NdotV = clearcoat_NdotV; 354 lighting_input.layers[LAYER_CLEARCOAT].N = clearcoat_N; 355 lighting_input.layers[LAYER_CLEARCOAT].R = clearcoat_R; 356 lighting_input.layers[LAYER_CLEARCOAT].perceptual_roughness = clearcoat_perceptual_roughness; 357 lighting_input.layers[LAYER_CLEARCOAT].roughness = clearcoat_roughness; 358 lighting_input.clearcoat_strength = clearcoat; 359#endif // STANDARD_MATERIAL_CLEARCOAT 360#ifdef STANDARD_MATERIAL_ANISOTROPY 361 lighting_input.anisotropy = in.anisotropy_strength; 362 lighting_input.Ta = in.anisotropy_T; 363 lighting_input.Ba = in.anisotropy_B; 364#endif // STANDARD_MATERIAL_ANISOTROPY 367#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 368 var transmissive_lighting_input: lighting::LightingInput; 369 transmissive_lighting_input.layers[LAYER_BASE].NdotV = 1.0; 370 transmissive_lighting_input.layers[LAYER_BASE].N = -in.N; 371 transmissive_lighting_input.layers[LAYER_BASE].R = vec3(0.0); 372 transmissive_lighting_input.layers[LAYER_BASE].perceptual_roughness = 1.0; 373 transmissive_lighting_input.layers[LAYER_BASE].roughness = 1.0; 374 transmissive_lighting_input.P = diffuse_transmissive_lobe_world_position.xyz; 375 transmissive_lighting_input.V = -in.V; 376 transmissive_lighting_input.diffuse_color = diffuse_transmissive_color; 377 transmissive_lighting_input.F0_ = vec3(0.0); 378 transmissive_lighting_input.F_ab = vec2(0.1); 379#ifdef STANDARD_MATERIAL_CLEARCOAT 380 transmissive_lighting_input.layers[LAYER_CLEARCOAT].NdotV = 0.0; 381 transmissive_lighting_input.layers[LAYER_CLEARCOAT].N = vec3(0.0); 382 transmissive_lighting_input.layers[LAYER_CLEARCOAT].R = vec3(0.0); 383 transmissive_lighting_input.layers[LAYER_CLEARCOAT].perceptual_roughness = 0.0; 384 transmissive_lighting_input.layers[LAYER_CLEARCOAT].roughness = 0.0; 385 transmissive_lighting_input.clearcoat_strength = 0.0; 386#endif // STANDARD_MATERIAL_CLEARCOAT 387#ifdef STANDARD_MATERIAL_ANISOTROPY 388 transmissive_lighting_input.anisotropy = in.anisotropy_strength; 389 transmissive_lighting_input.Ta = in.anisotropy_T; 390 transmissive_lighting_input.Ba = in.anisotropy_B; 391#endif // STANDARD_MATERIAL_ANISOTROPY 392#endif // STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 394 let view_z = dot(vec4<f32>( 395 view_bindings::view.view_from_world[0].z, 396 view_bindings::view.view_from_world[1].z, 397 view_bindings::view.view_from_world[2].z, 398 view_bindings::view.view_from_world[3].z 399 ), in.world_position); 400 let cluster_index = clustering::fragment_cluster_index(in.frag_coord.xy, view_z, in.is_orthographic); 401 var clusterable_object_index_ranges = 402 clustering::unpack_clusterable_object_index_ranges(cluster_index); 405 for (var i: u32 = clusterable_object_index_ranges.first_point_light_index_offset; 406 i < clusterable_object_index_ranges.first_spot_light_index_offset; 408 let light_id = clustering::get_clusterable_object_id(i); 414 (view_bindings::clusterable_objects.data[light_id].flags & 415 mesh_view_types::POINT_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESH_DIFFUSE_BIT) != 0u; 417 let enable_diffuse = true; 420 var shadow: f32 = 1.0; 421 if ((in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 422 && (view_bindings::clusterable_objects.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 423 shadow = shadows::fetch_point_shadow(light_id, in.world_position, in.world_normal); 426 let light_contrib = lighting::point_light(light_id, &lighting_input, enable_diffuse, true); 427 direct_light += light_contrib * shadow; 429#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 439 var transmitted_shadow: f32 = 1.0; 440 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) 441 && (view_bindings::clusterable_objects.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 442 transmitted_shadow = shadows::fetch_point_shadow(light_id, diffuse_transmissive_lobe_world_position, -in.world_normal); 445 let transmitted_light_contrib = 446 lighting::point_light(light_id, &transmissive_lighting_input, enable_diffuse, true); 447 transmitted_light += transmitted_light_contrib * transmitted_shadow; 452 for (var i: u32 = clusterable_object_index_ranges.first_spot_light_index_offset; 453 i < clusterable_object_index_ranges.first_reflection_probe_index_offset; 455 let light_id = clustering::get_clusterable_object_id(i); 461 (view_bindings::clusterable_objects.data[light_id].flags & 462 mesh_view_types::POINT_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESH_DIFFUSE_BIT) != 0u; 464 let enable_diffuse = true; 467 var shadow: f32 = 1.0; 468 if ((in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 469 && (view_bindings::clusterable_objects.data[light_id].flags & 470 mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 471 shadow = shadows::fetch_spot_shadow( 475 view_bindings::clusterable_objects.data[light_id].shadow_map_near_z, 479 let light_contrib = lighting::spot_light(light_id, &lighting_input, enable_diffuse); 480 direct_light += light_contrib * shadow; 482#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 492 var transmitted_shadow: f32 = 1.0; 493 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) 494 && (view_bindings::clusterable_objects.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 495 transmitted_shadow = shadows::fetch_spot_shadow( 497 diffuse_transmissive_lobe_world_position, 499 view_bindings::clusterable_objects.data[light_id].shadow_map_near_z, 503 let transmitted_light_contrib = 504 lighting::spot_light(light_id, &transmissive_lighting_input, enable_diffuse); 505 transmitted_light += transmitted_light_contrib * transmitted_shadow; 510 let n_directional_lights = view_bindings::lights.n_directional_lights; 511 for (var i: u32 = 0u; i < n_directional_lights; i = i + 1u) { 514 let light = &view_bindings::lights.directional_lights[i]; 521 mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESH_DIFFUSE_BIT) != 524 let enable_diffuse = true; 527 var shadow: f32 = 1.0; 528 if ((in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 529 && (view_bindings::lights.directional_lights[i].flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 530 shadow = shadows::fetch_directional_shadow(i, in.world_position, in.world_normal, view_z); 533 var light_contrib = lighting::directional_light(i, &lighting_input, enable_diffuse); 535#ifdef DIRECTIONAL_LIGHT_SHADOW_MAP_DEBUG_CASCADES 536 light_contrib = shadows::cascade_debug_visualization(light_contrib, i, view_z); 538 direct_light += light_contrib * shadow; 540#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 550 var transmitted_shadow: f32 = 1.0; 551 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) 552 && (view_bindings::lights.directional_lights[i].flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 553 transmitted_shadow = shadows::fetch_directional_shadow(i, diffuse_transmissive_lobe_world_position, -in.world_normal, view_z); 556 let transmitted_light_contrib = 557 lighting::directional_light(i, &transmissive_lighting_input, enable_diffuse); 558 transmitted_light += transmitted_light_contrib * transmitted_shadow; 562#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 571 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)); 585 var indirect_light = vec3(0.0f); 586 var found_diffuse_indirect = false; 589 indirect_light += in.lightmap_light * diffuse_color; 590 found_diffuse_indirect = true; 593#ifdef IRRADIANCE_VOLUME 595 if (!found_diffuse_indirect) { 596 let irradiance_volume_light = irradiance_volume::irradiance_volume_light( 597 in.world_position.xyz, 599 &clusterable_object_index_ranges, 601 indirect_light += irradiance_volume_light * diffuse_color * diffuse_occlusion; 602 found_diffuse_indirect = true; 607#ifdef ENVIRONMENT_MAP 610#ifdef SCREEN_SPACE_REFLECTIONS 611 let use_ssr = perceptual_roughness <= 612 view_bindings::ssr_settings.perceptual_roughness_threshold; 613#else // SCREEN_SPACE_REFLECTIONS 615#endif // SCREEN_SPACE_REFLECTIONS 618#ifdef STANDARD_MATERIAL_ANISOTROPY 619 var bent_normal_lighting_input = lighting_input; 620 bend_normal_for_anisotropy(&bent_normal_lighting_input); 621 let environment_map_lighting_input = &bent_normal_lighting_input; 622#else // STANDARD_MATERIAL_ANISOTROPY 623 let environment_map_lighting_input = &lighting_input; 624#endif // STANDARD_MATERIAL_ANISOTROPY 626 let environment_light = environment_map::environment_map_light( 627 environment_map_lighting_input, 628 &clusterable_object_index_ranges, 629 found_diffuse_indirect, 632 indirect_light += environment_light.diffuse * diffuse_occlusion + 633 environment_light.specular * specular_occlusion; 635#endif // ENVIRONMENT_MAP 641 let enable_ambient = view_bindings::lights.ambient_light_affects_lightmapped_meshes != 0u; 643 let enable_ambient = true; 645 if (enable_ambient) { 646 indirect_light += ambient::ambient_light(in.world_position, in.N, in.V, NdotV, diffuse_color, F0, perceptual_roughness, diffuse_occlusion); 651 var specular_transmitted_environment_light = vec3<f32>(0.0); 653#ifdef ENVIRONMENT_MAP 655#ifdef STANDARD_MATERIAL_DIFFUSE_OR_SPECULAR_TRANSMISSION 671 refract(in.V, -in.N, 1.0 / ior) * thickness 674 var transmissive_environment_light_input: lighting::LightingInput; 675 transmissive_environment_light_input.diffuse_color = vec3(1.0); 676 transmissive_environment_light_input.layers[LAYER_BASE].NdotV = 1.0; 677 transmissive_environment_light_input.P = in.world_position.xyz; 678 transmissive_environment_light_input.layers[LAYER_BASE].N = -in.N; 679 transmissive_environment_light_input.V = in.V; 680 transmissive_environment_light_input.layers[LAYER_BASE].R = T; 681 transmissive_environment_light_input.layers[LAYER_BASE].perceptual_roughness = perceptual_roughness; 682 transmissive_environment_light_input.layers[LAYER_BASE].roughness = roughness; 683 transmissive_environment_light_input.F0_ = vec3<f32>(1.0); 684 transmissive_environment_light_input.F_ab = vec2(0.1); 685#ifdef STANDARD_MATERIAL_CLEARCOAT 687 transmissive_environment_light_input.clearcoat_strength = 0.0; 688 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].NdotV = 0.0; 689 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].N = in.N; 690 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].R = vec3(0.0); 691 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].perceptual_roughness = 0.0; 692 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].roughness = 0.0; 693#endif // STANDARD_MATERIAL_CLEARCOAT 695 let transmitted_environment_light = environment_map::environment_map_light( 696 &transmissive_environment_light_input, 697 &clusterable_object_index_ranges, 701#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 702 transmitted_light += transmitted_environment_light.diffuse * diffuse_transmissive_color; 703#endif // STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 704#ifdef STANDARD_MATERIAL_SPECULAR_TRANSMISSION 705 specular_transmitted_environment_light = transmitted_environment_light.specular * specular_transmissive_color; 706#endif // STANDARD_MATERIAL_SPECULAR_TRANSMISSION 708#endif // STANDARD_MATERIAL_SPECULAR_OR_DIFFUSE_TRANSMISSION 710#endif // ENVIRONMENT_MAP 712 var emissive_light = emissive.rgb * output_color.a; 718#ifdef STANDARD_MATERIAL_CLEARCOAT 719 emissive_light = emissive_light * (0.04 + (1.0 - 0.04) * pow(1.0 - clearcoat_NdotV, 5.0)); 722 emissive_light = emissive_light * mix(1.0, view_bindings::view.exposure, emissive.a); 724#ifdef STANDARD_MATERIAL_SPECULAR_TRANSMISSION 725 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; 727 if (in.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ATTENUATION_ENABLED_BIT) != 0u { 731 var attenuation_fog: mesh_view_types::Fog; 732 attenuation_fog.base_color.a = 1.0; 733 attenuation_fog.be = pow(1.0 - in.material.attenuation_color.rgb, vec3<f32>(E)) / in.material.attenuation_distance; 736 transmitted_light = bevy_pbr::fog::atmospheric_fog( 737 attenuation_fog, vec4<f32>(transmitted_light, 1.0), thickness, 744 output_color = vec4<f32>( 745 (view_bindings::view.exposure * (transmitted_light + direct_light + indirect_light)) + emissive_light, 749 output_color = clustering::cluster_debug_visualization( 753 clusterable_object_index_ranges, 759#endif // PREPASS_FRAGMENT 762fn apply_fog(fog_params: mesh_view_types::Fog, input_color: vec4<f32>, fragment_world_position: vec3<f32>, view_world_position: vec3<f32>) -> vec4<f32> { 763 let view_to_world = fragment_world_position.xyz - view_world_position.xyz; 769 let distance = length(view_to_world); 772 let view_pos = view_transformations::position_world_to_view(fragment_world_position); 773 let view_z = view_pos.z; 776 let view_direction_normal = normalize(-view_to_world); 777 let fragment_world_position_vec4 = vec4<f32>(fragment_world_position, 1.0); 779 var scattering = vec3<f32>(0.0); 780 if fog_params.directional_light_color.a > 0.0 { 781 let view_to_world_normalized = view_to_world / distance; 782 let n_directional_lights = view_bindings::lights.n_directional_lights; 783 for (var i: u32 = 0u; i < n_directional_lights; i = i + 1u) { 784 let light = view_bindings::lights.directional_lights[i]; 785 let scattering_contribution = pow( 787 dot(view_to_world_normalized, light.direction_to_light), 790 fog_params.directional_light_exponent 791 ) * light.color.rgb * view_bindings::view.exposure; 794 var shadow: f32 = 1.0; 795 if ((light.flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 796 shadow = shadows::fetch_directional_shadow(i, fragment_world_position_vec4, view_direction_normal, view_z); 798 scattering += scattering_contribution * shadow; 802 if fog_params.mode == mesh_view_types::FOG_MODE_LINEAR { 803 return bevy_pbr::fog::linear_fog(fog_params, input_color, distance, scattering); 804 } else if fog_params.mode == mesh_view_types::FOG_MODE_EXPONENTIAL { 805 return bevy_pbr::fog::exponential_fog(fog_params, input_color, distance, scattering); 806 } else if fog_params.mode == mesh_view_types::FOG_MODE_EXPONENTIAL_SQUARED { 807 return bevy_pbr::fog::exponential_squared_fog(fog_params, input_color, distance, scattering); 808 } else if fog_params.mode == mesh_view_types::FOG_MODE_ATMOSPHERIC { 809 return bevy_pbr::fog::atmospheric_fog(fog_params, input_color, distance, scattering); 814#endif // DISTANCE_FOG 816#ifdef PREMULTIPLY_ALPHA 817fn premultiply_alpha(standard_material_flags: u32, color: vec4<f32>) -> vec4<f32> { 822#ifdef BLEND_PREMULTIPLIED_ALPHA 826 let alpha_mode = standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS; 827 if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_ADD { 839 return vec4<f32>(color.rgb * color.a, 0.0); 863 return vec4<f32>(color.rgb * color.a, color.a); 870fn main_pass_post_lighting_processing( 871 pbr_input: pbr_types::PbrInput, 872 input_color: vec4<f32>, 874 var output_color = input_color; 878 if ((pbr_input.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_FOG_ENABLED_BIT) != 0u) { 879 output_color = apply_fog(view_bindings::fog, output_color, pbr_input.world_position.xyz, view_bindings::view.world_position.xyz); 881#endif // DISTANCE_FOG 883#ifdef TONEMAP_IN_SHADER 884 output_color = tone_mapping(output_color, view_bindings::view.color_grading); 886 var output_rgb = output_color.rgb; 887 output_rgb = powsafe(output_rgb, 1.0 / 2.2); 888 output_rgb += screen_space_dither(pbr_input.frag_coord.xy); 891 output_rgb = powsafe(output_rgb, 2.2); 892 output_color = vec4(output_rgb, output_color.a); 895#ifdef PREMULTIPLY_ALPHA 896 output_color = premultiply_alpha(pbr_input.material.flags, output_color);