1#define_import_path bevy_pbr::pbr_functions 6 mesh_view_bindings as view_bindings, 9 lighting::{LAYER_BASE, LAYER_CLEARCOAT}, 10 clustered_forward as clustering, 16 mesh_types::{MESH_FLAGS_SHADOW_RECEIVER_BIT, MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT}, 18#import bevy_pbr::mesh_view_bindings::globals 19#import bevy_pbr::view_transformations::{position_world_to_ndc} 20#import bevy_render::maths::{E, powsafe} 22#ifdef STANDARD_MATERIAL_SPECULAR_TRANSMISSION 23#import bevy_pbr::transmission 26#ifdef IRRADIANCE_VOLUME 27#import bevy_pbr::irradiance_volume 30#ifdef MESHLET_MESH_MATERIAL_PASS 31#import bevy_pbr::meshlet_visibility_buffer_resolve::VertexOutput 32#else ifdef PREPASS_PIPELINE 33#import bevy_pbr::prepass_io::VertexOutput 34#else // PREPASS_PIPELINE 35#import bevy_pbr::forward_io::VertexOutput 36#endif // PREPASS_PIPELINE 39#import bevy_pbr::environment_map 42#ifdef TONEMAP_IN_SHADER 43#import bevy_core_pipeline::tonemapping::{tone_mapping, screen_space_dither} 50#ifdef MESHLET_MESH_MATERIAL_PASS 53#else // MESHLET_MESH_MATERIAL_PASS 55#endif // MESHLET_MESH_MATERIAL_PASS 65const DITHER_THRESHOLD_MAP: vec4<u32> = vec4( 86#ifdef VISIBILITY_RANGE_DITHER 87fn visibility_range_dither(frag_coord: vec4<f32>, dither: i32) { 94 if (dither <= -16 || dither >= 16) { 99 let coords = vec2<u32>(floor(frag_coord.xy)) % 4u; 100 let threshold = i32((DITHER_THRESHOLD_MAP[coords.y] >> (coords.x * 8)) & 0xff); 101 if ((dither >= 0 && dither + threshold >= 16) || (dither < 0 && 1 + dither + threshold <= 0)) { 107fn alpha_discard(material: pbr_types::StandardMaterial, output_color: vec4<f32>) -> vec4<f32> { 108 var color = output_color; 109 let alpha_mode = material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS; 110 if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE { 119 else if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_MASK || 120 alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_ALPHA_TO_COVERAGE { 121 if color.a >= material.alpha_cutoff { 134fn prepare_world_normal( 135 world_normal: vec3<f32>, 139 var output: vec3<f32> = world_normal; 140#ifndef VERTEX_TANGENTS 141#ifndef STANDARD_MATERIAL_NORMAL_MAP 144 output = (f32(!double_sided || is_front) * 2.0 - 1.0) * output; 154fn calculate_tbn_mikktspace(world_normal: vec3<f32>, world_tangent: vec4<f32>) -> mat3x3<f32> { 161 var N: vec3<f32> = world_normal; 167 var T: vec3<f32> = world_tangent.xyz; 168 var B: vec3<f32> = world_tangent.w * cross(N, T); 170#ifdef MESHLET_MESH_MATERIAL_PASS 172 let inverse_length_n = 1.0 / length(N); 173 T *= inverse_length_n; 174 B *= inverse_length_n; 175 N *= inverse_length_n; 178 return mat3x3(T, B, N); 181fn apply_normal_mapping( 182 standard_material_flags: u32, 195 if (standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_TWO_COMPONENT_NORMAL_MAP) != 0u { 197 Nt = vec3<f32>(Nt.rg * 2.0 - 1.0, 0.0); 198 Nt.z = sqrt(1.0 - Nt.x * Nt.x - Nt.y * Nt.y); 203 if (standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_FLIP_NORMAL_MAP_Y) != 0u { 207 if double_sided && !is_front { 216 N = Nt.x * T + Nt.y * B + Nt.z * N; 221#ifdef STANDARD_MATERIAL_ANISOTROPY 228fn bend_normal_for_anisotropy(lighting_input: ptr<function, lighting::LightingInput>) { 230 let N = (*lighting_input).layers[LAYER_BASE].N; 231 let roughness = (*lighting_input).layers[LAYER_BASE].roughness; 232 let V = (*lighting_input).V; 233 let anisotropy = (*lighting_input).anisotropy; 234 let Ba = (*lighting_input).Ba; 236 var bent_normal = normalize(cross(cross(Ba, V), Ba)); 241 let a = pow(2.0, pow(2.0, 1.0 - anisotropy * (1.0 - roughness))); 242 bent_normal = normalize(mix(bent_normal, N, a)); 249 let R = normalize(mix(reflect(-V, bent_normal), bent_normal, roughness * roughness)); 251 (*lighting_input).layers[LAYER_BASE].N = bent_normal; 252 (*lighting_input).layers[LAYER_BASE].R = R; 255#endif // STANDARD_MATERIAL_ANISOTROPY 260 world_position: vec4<f32>, 261 is_orthographic: bool, 266 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)); 269 V = normalize(view_bindings::view.world_position.xyz - world_position.xyz); 275fn calculate_diffuse_color( 276 base_color: vec3<f32>, 278 specular_transmission: f32, 279 diffuse_transmission: f32 281 return base_color * (1.0 - metallic) * (1.0 - specular_transmission) * 282 (1.0 - diffuse_transmission); 286fn calculate_F0_dielectric(reflectance: vec3<f32>) -> vec3<f32> { 287 return 0.16 * reflectance * reflectance; 292fn calculate_F0(base_color: vec3<f32>, metallic: f32, reflectance: vec3<f32>) -> vec3<f32> { 293 return mix(calculate_F0_dielectric(reflectance), base_color, metallic); 296#ifdef CONTACT_SHADOWS 298fn calculate_contact_shadow( 299 world_position: vec3<f32>, 300 frag_coord: vec2<f32>, 301 light_dir: vec3<f32>, 302 contact_shadow_steps: u32, 304#ifdef BLUE_NOISE_TEXTURE 305 let noise_size = textureDimensions(view_bindings::blue_noise_texture, 0); 306 let noise_layers = textureNumLayers(view_bindings::blue_noise_texture); 307 let noise = textureLoad( 308 view_bindings::blue_noise_texture, 309 vec2<i32>(frag_coord) % vec2<i32>(noise_size), 310 i32(view_bindings::globals.frame_count % noise_layers), 314 let noise = utils::interleaved_gradient_noise(frag_coord, view_bindings::globals.frame_count); 317 let depth_size = vec2<f32>(textureDimensions(view_bindings::depth_prepass_texture)); 318 var rm = raymarch::depth_ray_march_new_from_depth(depth_size); 319 raymarch::depth_ray_march_from_cs(&rm, position_world_to_ndc(world_position)); 320 raymarch::depth_ray_march_to_ws(&rm, world_position + light_dir * view_bindings::contact_shadows_settings.length); 321 rm.linear_steps = contact_shadow_steps; 322 rm.depth_thickness_linear_z = view_bindings::contact_shadows_settings.thickness; 323 rm.march_behind_surfaces = true; 326 let rm_result = raymarch::depth_ray_march_march(&rm); 328 return clamp((rm_result.hit_penetration_frac - 0.5) / (1.0 - 0.5), 0.0, 1.0); 335#ifndef PREPASS_FRAGMENT 336fn apply_pbr_lighting( 337 in: pbr_types::PbrInput, 339 var output_color: vec4<f32> = in.material.base_color; 341 let emissive = in.material.emissive; 344 let metallic = in.material.metallic; 345 let perceptual_roughness = in.material.perceptual_roughness; 346 let roughness = lighting::perceptualRoughnessToRoughness(perceptual_roughness); 347 let ior = in.material.ior; 348 let thickness = in.material.thickness; 349 let reflectance = in.material.reflectance; 350 let diffuse_transmission = in.material.diffuse_transmission; 351 let specular_transmission = in.material.specular_transmission; 353 let specular_transmissive_color = specular_transmission * in.material.base_color.rgb; 355 let diffuse_occlusion = in.diffuse_occlusion; 356 let specular_occlusion = in.specular_occlusion; 359 let NdotV = max(dot(in.N, in.V), 0.0001); 360 let R = reflect(-in.V, in.N); 362#ifdef STANDARD_MATERIAL_CLEARCOAT 365 let clearcoat = in.material.clearcoat; 366 let clearcoat_perceptual_roughness = in.material.clearcoat_perceptual_roughness; 367 let clearcoat_roughness = lighting::perceptualRoughnessToRoughness(clearcoat_perceptual_roughness); 368 let clearcoat_N = in.clearcoat_N; 369 let clearcoat_NdotV = max(dot(clearcoat_N, in.V), 0.0001); 370 let clearcoat_R = reflect(-in.V, clearcoat_N); 371#endif // STANDARD_MATERIAL_CLEARCOAT 373 let diffuse_color = calculate_diffuse_color( 376 specular_transmission, 381 let diffuse_transmissive_color = output_color.rgb * (1.0 - metallic) * (1.0 - specular_transmission) * diffuse_transmission; 384 let diffuse_transmissive_lobe_world_position = in.world_position - vec4<f32>(in.world_normal, 0.0) * thickness; 386 let F0 = calculate_F0(output_color.rgb, metallic, reflectance); 387 let F_ab = lighting::F_AB(perceptual_roughness, NdotV); 389 var direct_light: vec3<f32> = vec3<f32>(0.0); 392 var transmitted_light: vec3<f32> = vec3<f32>(0.0); 395 var lighting_input: lighting::LightingInput; 396 lighting_input.layers[LAYER_BASE].NdotV = NdotV; 397 lighting_input.layers[LAYER_BASE].N = in.N; 398 lighting_input.layers[LAYER_BASE].R = R; 399 lighting_input.layers[LAYER_BASE].perceptual_roughness = perceptual_roughness; 400 lighting_input.layers[LAYER_BASE].roughness = roughness; 401 lighting_input.P = in.world_position.xyz; 402 lighting_input.V = in.V; 403 lighting_input.diffuse_color = diffuse_color; 404 lighting_input.metallic = metallic; 405 lighting_input.F0_dielectric = calculate_F0_dielectric(reflectance); 406 lighting_input.F0_metallic = output_color.rgb; 407 lighting_input.F_ab = F_ab; 408#ifdef STANDARD_MATERIAL_CLEARCOAT 409 lighting_input.layers[LAYER_CLEARCOAT].NdotV = clearcoat_NdotV; 410 lighting_input.layers[LAYER_CLEARCOAT].N = clearcoat_N; 411 lighting_input.layers[LAYER_CLEARCOAT].R = clearcoat_R; 412 lighting_input.layers[LAYER_CLEARCOAT].perceptual_roughness = clearcoat_perceptual_roughness; 413 lighting_input.layers[LAYER_CLEARCOAT].roughness = clearcoat_roughness; 414 lighting_input.clearcoat_strength = clearcoat; 415#endif // STANDARD_MATERIAL_CLEARCOAT 416#ifdef STANDARD_MATERIAL_ANISOTROPY 417 lighting_input.anisotropy = in.anisotropy_strength; 418 lighting_input.Ta = in.anisotropy_T; 419 lighting_input.Ba = in.anisotropy_B; 420#endif // STANDARD_MATERIAL_ANISOTROPY 423#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 424 var transmissive_lighting_input: lighting::LightingInput; 425 transmissive_lighting_input.layers[LAYER_BASE].NdotV = 1.0; 426 transmissive_lighting_input.layers[LAYER_BASE].N = -in.N; 427 transmissive_lighting_input.layers[LAYER_BASE].R = vec3(0.0); 428 transmissive_lighting_input.layers[LAYER_BASE].perceptual_roughness = 1.0; 429 transmissive_lighting_input.layers[LAYER_BASE].roughness = 1.0; 430 transmissive_lighting_input.P = diffuse_transmissive_lobe_world_position.xyz; 431 transmissive_lighting_input.V = -in.V; 432 transmissive_lighting_input.diffuse_color = diffuse_transmissive_color; 433 transmissive_lighting_input.metallic = 0.0; 434 transmissive_lighting_input.F0_dielectric = vec3(0.0); 435 transmissive_lighting_input.F0_metallic = vec3(0.0); 436 transmissive_lighting_input.F_ab = vec2(0.1); 437#ifdef STANDARD_MATERIAL_CLEARCOAT 438 transmissive_lighting_input.layers[LAYER_CLEARCOAT].NdotV = 0.0; 439 transmissive_lighting_input.layers[LAYER_CLEARCOAT].N = vec3(0.0); 440 transmissive_lighting_input.layers[LAYER_CLEARCOAT].R = vec3(0.0); 441 transmissive_lighting_input.layers[LAYER_CLEARCOAT].perceptual_roughness = 0.0; 442 transmissive_lighting_input.layers[LAYER_CLEARCOAT].roughness = 0.0; 443 transmissive_lighting_input.clearcoat_strength = 0.0; 444#endif // STANDARD_MATERIAL_CLEARCOAT 445#ifdef STANDARD_MATERIAL_ANISOTROPY 446 transmissive_lighting_input.anisotropy = in.anisotropy_strength; 447 transmissive_lighting_input.Ta = in.anisotropy_T; 448 transmissive_lighting_input.Ba = in.anisotropy_B; 449#endif // STANDARD_MATERIAL_ANISOTROPY 450#endif // STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 452 let view_z = dot(vec4<f32>( 453 view_bindings::view.view_from_world[0].z, 454 view_bindings::view.view_from_world[1].z, 455 view_bindings::view.view_from_world[2].z, 456 view_bindings::view.view_from_world[3].z 457 ), in.world_position); 458 let cluster_index = clustering::view_fragment_cluster_index(in.frag_coord.xy, view_z, in.is_orthographic); 459 var clusterable_object_index_ranges = 460 clustering::unpack_clusterable_object_index_ranges(cluster_index); 462#ifdef CONTACT_SHADOWS 463 let contact_shadow_steps = view_bindings::contact_shadows_settings.linear_steps; 464 let contact_shadow_enabled = contact_shadow_steps > 0u; 468 for (var i: u32 = clusterable_object_index_ranges.first_point_light_index_offset; 469 i < clusterable_object_index_ranges.first_spot_light_index_offset; 471 let light_id = clustering::get_clusterable_object_id(i); 477 (view_bindings::clustered_lights.data[light_id].flags & 478 mesh_view_types::POINT_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESH_DIFFUSE_BIT) != 0u; 480 let enable_diffuse = true; 483 var shadow: f32 = 1.0; 484 if ((in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 485 && (view_bindings::clustered_lights.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 486 shadow = shadows::fetch_point_shadow(light_id, in.world_position, in.world_normal, in.frag_coord.xy); 489#ifdef CONTACT_SHADOWS 491 if contact_shadow_enabled && (in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u && shadow > 0.0 && 492 (view_bindings::clustered_lights.data[light_id].flags & 493 mesh_view_types::POINT_LIGHT_FLAGS_CONTACT_SHADOWS_ENABLED_BIT) != 0u { 494 let L = normalize(view_bindings::clustered_lights.data[light_id].position_radius.xyz - in.world_position.xyz); 495 shadow *= calculate_contact_shadow(in.world_position.xyz, in.frag_coord.xy, L, contact_shadow_steps); 500 let light_contrib = lighting::point_light(light_id, &lighting_input, enable_diffuse, true); 501 direct_light += light_contrib * shadow; 503#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 513 var transmitted_shadow: f32 = 1.0; 514 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) 515 && (view_bindings::clustered_lights.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 516 transmitted_shadow = shadows::fetch_point_shadow(light_id, diffuse_transmissive_lobe_world_position, -in.world_normal, in.frag_coord.xy); 519 let transmitted_light_contrib = 520 lighting::point_light(light_id, &transmissive_lighting_input, enable_diffuse, true); 521 transmitted_light += transmitted_light_contrib * transmitted_shadow; 526 for (var i: u32 = clusterable_object_index_ranges.first_spot_light_index_offset; 527 i < clusterable_object_index_ranges.first_reflection_probe_index_offset; 529 let light_id = clustering::get_clusterable_object_id(i); 535 (view_bindings::clustered_lights.data[light_id].flags & 536 mesh_view_types::POINT_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESH_DIFFUSE_BIT) != 0u; 538 let enable_diffuse = true; 541 var shadow: f32 = 1.0; 542 if ((in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 543 && (view_bindings::clustered_lights.data[light_id].flags & 544 mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 545 shadow = shadows::fetch_spot_shadow( 549 view_bindings::clustered_lights.data[light_id].shadow_map_near_z, 554#ifdef CONTACT_SHADOWS 556 if contact_shadow_enabled && (in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u && shadow > 0.0 && 557 (view_bindings::clustered_lights.data[light_id].flags & 558 mesh_view_types::POINT_LIGHT_FLAGS_CONTACT_SHADOWS_ENABLED_BIT) != 0u { 559 let L = normalize(view_bindings::clustered_lights.data[light_id].position_radius.xyz - in.world_position.xyz); 560 shadow *= calculate_contact_shadow(in.world_position.xyz, in.frag_coord.xy, L, contact_shadow_steps); 565 let light_contrib = lighting::spot_light(light_id, &lighting_input, enable_diffuse); 566 direct_light += light_contrib * shadow; 568#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 578 var transmitted_shadow: f32 = 1.0; 579 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) 580 && (view_bindings::clustered_lights.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 581 transmitted_shadow = shadows::fetch_spot_shadow( 583 diffuse_transmissive_lobe_world_position, 585 view_bindings::clustered_lights.data[light_id].shadow_map_near_z, 590 let transmitted_light_contrib = 591 lighting::spot_light(light_id, &transmissive_lighting_input, enable_diffuse); 592 transmitted_light += transmitted_light_contrib * transmitted_shadow; 597 let n_directional_lights = view_bindings::lights.n_directional_lights; 598 for (var i: u32 = 0u; i < n_directional_lights; i = i + 1u) { 601 let light = &view_bindings::lights.directional_lights[i]; 608 mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESH_DIFFUSE_BIT) != 611 let enable_diffuse = true; 614 var shadow: f32 = 1.0; 615 if ((in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 616 && (view_bindings::lights.directional_lights[i].flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 617 shadow = shadows::fetch_directional_shadow(i, in.world_position, in.world_normal, view_z, in.frag_coord.xy); 620#ifdef CONTACT_SHADOWS 622 if contact_shadow_enabled && (in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u && shadow > 0.0 && 623 (view_bindings::lights.directional_lights[i].flags & 624 mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_CONTACT_SHADOWS_ENABLED_BIT) != 0u { 625 let L = view_bindings::lights.directional_lights[i].direction_to_light; 626 shadow *= calculate_contact_shadow(in.world_position.xyz, in.frag_coord.xy, L, contact_shadow_steps); 631 var light_contrib = lighting::directional_light(i, &lighting_input, enable_diffuse); 633#ifdef DIRECTIONAL_LIGHT_SHADOW_MAP_DEBUG_CASCADES 634 light_contrib = shadows::cascade_debug_visualization(light_contrib, i, view_z); 636 direct_light += light_contrib * shadow; 638#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 648 var transmitted_shadow: f32 = 1.0; 649 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) 650 && (view_bindings::lights.directional_lights[i].flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 651 transmitted_shadow = shadows::fetch_directional_shadow(i, diffuse_transmissive_lobe_world_position, -in.world_normal, view_z, in.frag_coord.xy); 654 let transmitted_light_contrib = 655 lighting::directional_light(i, &transmissive_lighting_input, enable_diffuse); 656 transmitted_light += transmitted_light_contrib * transmitted_shadow; 660#ifdef AREA_LIGHT_LUTS 662 let n_rect_lights = view_bindings::lights.n_rect_lights; 663 for (var i: u32 = 0u; i < n_rect_lights; i = i + 1u) { 664 let enable_diffuse = true; 665 let light_contrib = lighting::rect_light(i, &lighting_input, enable_diffuse); 666 direct_light += light_contrib; 668 #ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 669 let transmitted_light_contrib = 670 lighting::rect_light(i, &transmissive_lighting_input, enable_diffuse); 671 transmitted_light += transmitted_light_contrib; 676#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 685 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)); 699 var indirect_light = vec3(0.0f); 700 var found_diffuse_indirect = false; 703 indirect_light += in.lightmap_light * diffuse_color; 704 found_diffuse_indirect = true; 707#ifdef IRRADIANCE_VOLUME 709 if (!found_diffuse_indirect) { 710 let irradiance_volume_light = irradiance_volume::irradiance_volume_light( 711 in.world_position.xyz, 713 &clusterable_object_index_ranges, 715 indirect_light += irradiance_volume_light * diffuse_color * diffuse_occlusion; 716 found_diffuse_indirect = true; 721#ifdef ENVIRONMENT_MAP 726#ifdef SCREEN_SPACE_REFLECTIONS 727 let use_ssr = perceptual_roughness <= view_bindings::ssr_settings.max_perceptual_roughness 728 && perceptual_roughness >= view_bindings::ssr_settings.min_perceptual_roughness; 729#else // SCREEN_SPACE_REFLECTIONS 731#endif // SCREEN_SPACE_REFLECTIONS 733#ifdef STANDARD_MATERIAL_ANISOTROPY 734 var bent_normal_lighting_input = lighting_input; 735 bend_normal_for_anisotropy(&bent_normal_lighting_input); 736 let environment_map_lighting_input = &bent_normal_lighting_input; 737#else // STANDARD_MATERIAL_ANISOTROPY 738 let environment_map_lighting_input = &lighting_input; 739#endif // STANDARD_MATERIAL_ANISOTROPY 741 let environment_light = environment_map::environment_map_light( 742 environment_map_lighting_input, 743 &clusterable_object_index_ranges, 744 found_diffuse_indirect, 747 indirect_light += environment_light.diffuse * diffuse_occlusion; 749 indirect_light += environment_light.specular * specular_occlusion; 751#endif // ENVIRONMENT_MAP 757 let enable_ambient = view_bindings::lights.ambient_light_affects_lightmapped_meshes != 0u; 759 let enable_ambient = true; 761 if (enable_ambient) { 762 indirect_light += ambient::ambient_light(in.world_position, in.N, in.V, NdotV, diffuse_color, F0, perceptual_roughness, diffuse_occlusion); 767 var specular_transmitted_environment_light = vec3<f32>(0.0); 769#ifdef ENVIRONMENT_MAP 771#ifdef STANDARD_MATERIAL_DIFFUSE_OR_SPECULAR_TRANSMISSION 787 refract(in.V, -in.N, 1.0 / ior) * thickness 790 var transmissive_environment_light_input: lighting::LightingInput; 791 transmissive_environment_light_input.diffuse_color = vec3(1.0); 792 transmissive_environment_light_input.layers[LAYER_BASE].NdotV = 1.0; 793 transmissive_environment_light_input.P = in.world_position.xyz; 794 transmissive_environment_light_input.layers[LAYER_BASE].N = -in.N; 795 transmissive_environment_light_input.V = in.V; 796 transmissive_environment_light_input.layers[LAYER_BASE].R = T; 797 transmissive_environment_light_input.layers[LAYER_BASE].perceptual_roughness = perceptual_roughness; 798 transmissive_environment_light_input.layers[LAYER_BASE].roughness = roughness; 799 transmissive_environment_light_input.metallic = 0.0; 800 transmissive_environment_light_input.F0_dielectric = vec3<f32>(1.0); 801 transmissive_environment_light_input.F0_metallic = vec3<f32>(0.0); 802 transmissive_environment_light_input.F_ab = vec2(0.1); 803#ifdef STANDARD_MATERIAL_CLEARCOAT 805 transmissive_environment_light_input.clearcoat_strength = 0.0; 806 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].NdotV = 0.0; 807 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].N = in.N; 808 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].R = vec3(0.0); 809 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].perceptual_roughness = 0.0; 810 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].roughness = 0.0; 811#endif // STANDARD_MATERIAL_CLEARCOAT 813 let transmitted_environment_light = environment_map::environment_map_light( 814 &transmissive_environment_light_input, 815 &clusterable_object_index_ranges, 819#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 820 transmitted_light += transmitted_environment_light.diffuse * diffuse_transmissive_color; 821#endif // STANDARD_MATERIAL_DIFFUSE_TRANSMISSION 822#ifdef STANDARD_MATERIAL_SPECULAR_TRANSMISSION 823 specular_transmitted_environment_light = transmitted_environment_light.specular * specular_transmissive_color; 824#endif // STANDARD_MATERIAL_SPECULAR_TRANSMISSION 826#endif // STANDARD_MATERIAL_SPECULAR_OR_DIFFUSE_TRANSMISSION 828#endif // ENVIRONMENT_MAP 830 var emissive_light = emissive.rgb * output_color.a; 836#ifdef STANDARD_MATERIAL_CLEARCOAT 837 emissive_light = emissive_light * (0.04 + (1.0 - 0.04) * pow(1.0 - clearcoat_NdotV, 5.0)); 840 emissive_light = emissive_light * mix(1.0, view_bindings::view.exposure, emissive.a); 842#ifdef STANDARD_MATERIAL_SPECULAR_TRANSMISSION 843 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; 845 if (in.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ATTENUATION_ENABLED_BIT) != 0u { 849 var attenuation_fog: mesh_view_types::Fog; 850 attenuation_fog.base_color.a = 1.0; 851 attenuation_fog.be = pow(1.0 - in.material.attenuation_color.rgb, vec3<f32>(E)) / in.material.attenuation_distance; 854 transmitted_light = bevy_pbr::fog::atmospheric_fog( 855 attenuation_fog, vec4<f32>(transmitted_light, 1.0), thickness, 862 output_color = vec4<f32>( 863 (view_bindings::view.exposure * (transmitted_light + direct_light + indirect_light)) + emissive_light, 867 output_color = clustering::cluster_debug_visualization( 871 clusterable_object_index_ranges, 877#endif // PREPASS_FRAGMENT 881 fog_params: mesh_view_types::Fog, 882 input_color: vec4<f32>, 883 fragment_world_position: vec3<f32>, 884 view_world_position: vec3<f32>, 885 frag_coord_xy: vec2<f32>, 887 let view_to_world = fragment_world_position.xyz - view_world_position.xyz; 893 let distance = length(view_to_world); 896 let view_pos = view_transformations::position_world_to_view(fragment_world_position); 897 let view_z = view_pos.z; 900 let view_direction_normal = normalize(-view_to_world); 901 let fragment_world_position_vec4 = vec4<f32>(fragment_world_position, 1.0); 903 var scattering = vec3<f32>(0.0); 904 if fog_params.directional_light_color.a > 0.0 { 905 let view_to_world_normalized = view_to_world / distance; 906 let n_directional_lights = view_bindings::lights.n_directional_lights; 907 for (var i: u32 = 0u; i < n_directional_lights; i = i + 1u) { 908 let light = view_bindings::lights.directional_lights[i]; 909 let scattering_contribution = pow( 911 dot(view_to_world_normalized, light.direction_to_light), 914 fog_params.directional_light_exponent 915 ) * light.color.rgb * view_bindings::view.exposure; 918 var shadow: f32 = 1.0; 919 if ((light.flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 920 shadow = shadows::fetch_directional_shadow(i, fragment_world_position_vec4, view_direction_normal, view_z, frag_coord_xy); 922 scattering += scattering_contribution * shadow; 926 if fog_params.mode == mesh_view_types::FOG_MODE_LINEAR { 927 return bevy_pbr::fog::linear_fog(fog_params, input_color, distance, scattering); 928 } else if fog_params.mode == mesh_view_types::FOG_MODE_EXPONENTIAL { 929 return bevy_pbr::fog::exponential_fog(fog_params, input_color, distance, scattering); 930 } else if fog_params.mode == mesh_view_types::FOG_MODE_EXPONENTIAL_SQUARED { 931 return bevy_pbr::fog::exponential_squared_fog(fog_params, input_color, distance, scattering); 932 } else if fog_params.mode == mesh_view_types::FOG_MODE_ATMOSPHERIC { 933 return bevy_pbr::fog::atmospheric_fog(fog_params, input_color, distance, scattering); 938#endif // DISTANCE_FOG 940#ifdef PREMULTIPLY_ALPHA 941fn premultiply_alpha(standard_material_flags: u32, color: vec4<f32>) -> vec4<f32> { 946#ifdef BLEND_PREMULTIPLIED_ALPHA 950 let alpha_mode = standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS; 951 if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_ADD { 963 return vec4<f32>(color.rgb * color.a, 0.0); 987 return vec4<f32>(color.rgb * color.a, color.a); 994fn main_pass_post_lighting_processing( 995 pbr_input: pbr_types::PbrInput, 996 input_color: vec4<f32>, 998 var output_color = input_color; 1002 if ((pbr_input.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_FOG_ENABLED_BIT) != 0u) { 1003 output_color = apply_fog( 1006 pbr_input.world_position.xyz, 1007 view_bindings::view.world_position.xyz, 1008 pbr_input.frag_coord.xy, 1011#endif // DISTANCE_FOG 1013#ifdef TONEMAP_IN_SHADER 1014 output_color = tone_mapping(output_color, view_bindings::view.color_grading); 1016 var output_rgb = output_color.rgb; 1017 output_rgb = powsafe(output_rgb, 1.0 / 2.2); 1018 output_rgb += screen_space_dither(pbr_input.frag_coord.xy); 1021 output_rgb = powsafe(output_rgb, 2.2); 1022 output_color = vec4(output_rgb, output_color.a); 1025#ifdef PREMULTIPLY_ALPHA 1026 output_color = premultiply_alpha(pbr_input.material.flags, output_color); 1028 return output_color;