5 mesh_view_bindings as view_bindings, 7 pbr_lighting as lighting, 8 pbr_lighting::{LAYER_BASE, LAYER_CLEARCOAT}, 9 clustered_forward as clustering, 11 pbr_ambient as ambient, 15 MESH_FLAGS_SHADOW_RECEIVER_BIT, 16 MESH_FLAGS_SIGN_DETERMINANT_MODEL_3X3_BIT, 17 MESH_FLAGS_TRANSMITTED_SHADOW_RECEIVER_BIT, 22import package::render::mesh_view_bindings::globals; 23import package::render::view_transformations::{position_world_to_ndc}; 24import bevy_render::maths::{E, powsafe}; 26@if(STANDARD_MATERIAL_SPECULAR_TRANSMISSION) import package::transmission; 28@if(IRRADIANCE_VOLUME) import package::light_probe::irradiance_volume; 30@if(MESHLET_MESH_MATERIAL_PASS) import package::meshlet::visibility_buffer_resolve::VertexOutput; 31@elif(PREPASS_PIPELINE) import package::prepass::io::VertexOutput; 32@else import package::render::forward_io::VertexOutput; 34@if(ENVIRONMENT_MAP) import package::light_probe::environment_map; 36@if(TONEMAP_IN_SHADER) import bevy_core_pipeline::tonemapping::{tone_mapping, screen_space_dither}; 42 @if(MESHLET_MESH_MATERIAL_PASS) 44 @if(MESHLET_MESH_MATERIAL_PASS) 57const DITHER_THRESHOLD_MAP: vec4<u32> = vec4( 78@if(VISIBILITY_RANGE_DITHER) 79fn visibility_range_dither(frag_coord: vec4<f32>, dither: i32) { 86 if (dither <= -16 || dither >= 16) { 91 let coords = vec2<u32>(floor(frag_coord.xy)) % 4u; 92 let threshold = i32((DITHER_THRESHOLD_MAP[coords.y] >> (coords.x * 8)) & 0xff); 93 if ((dither >= 0 && dither + threshold >= 16) || (dither < 0 && 1 + dither + threshold <= 0)) { 98fn alpha_discard(material_flags: u32, alpha_cutoff: f32, output_color: vec4<f32>) -> vec4<f32> { 99 var color = output_color; 100 let alpha_mode = material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS; 101 if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE { 111 if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_MASK || 112 alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_ALPHA_TO_COVERAGE { 113 if color.a >= alpha_cutoff { 126fn prepare_world_normal( 127 world_normal: vec3<f32>, 131 var output: vec3<f32> = world_normal; 132 @if(!VERTEX_TANGENTS && !STANDARD_MATERIAL_NORMAL_MAP) 135 output = (f32(!double_sided || is_front) * 2.0 - 1.0) * output; 139fn winding_corrected_front_facing(mesh_flags: u32, is_front: bool) -> bool { 140 let positive_determinant = (mesh_flags & MESH_FLAGS_SIGN_DETERMINANT_MODEL_3X3_BIT) != 0u; 141 return is_front == positive_determinant; 148fn calculate_tbn_mikktspace(world_normal: vec3<f32>, world_tangent: vec4<f32>) -> mat3x3<f32> { 155 var N: vec3<f32> = world_normal; 161 var T: vec3<f32> = world_tangent.xyz; 162 var B: vec3<f32> = world_tangent.w * cross(N, T); 164@if(MESHLET_MESH_MATERIAL_PASS) { 166 let inverse_length_n = 1.0 / length(N); 167 T *= inverse_length_n; 168 B *= inverse_length_n; 169 N *= inverse_length_n; 172 return mat3x3(T, B, N); 175fn apply_normal_mapping( 176 standard_material_flags: u32, 189 if (standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_TWO_COMPONENT_NORMAL_MAP) != 0u { 191 Nt = vec3<f32>(Nt.rg * 2.0 - 1.0, 0.0); 192 Nt.z = sqrt(1.0 - Nt.x * Nt.x - Nt.y * Nt.y); 197 if (standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_FLIP_NORMAL_MAP_Y) != 0u { 201 if double_sided && !is_front { 210 N = Nt.x * T + Nt.y * B + Nt.z * N; 220@if(STANDARD_MATERIAL_ANISOTROPY) 221fn bend_normal_for_anisotropy(lighting_input: ptr<function, lighting::LightingInput>) { 223 let N = (*lighting_input).layers[LAYER_BASE].N; 224 let roughness = (*lighting_input).layers[LAYER_BASE].roughness; 225 let V = (*lighting_input).V; 226 let anisotropy = (*lighting_input).anisotropy; 227 let Ba = (*lighting_input).Ba; 229 var bent_normal = normalize(cross(cross(Ba, V), Ba)); 234 let bendFactor = 1.0 - anisotropy * (1.0 - roughness); 235 let bendFactorPow4 = bendFactor * bendFactor * bendFactor * bendFactor; 236 bent_normal = normalize(mix(bent_normal, N, bendFactorPow4)); 243 let R = normalize(mix(reflect(-V, bent_normal), bent_normal, roughness * roughness)); 245 (*lighting_input).layers[LAYER_BASE].N = bent_normal; 246 (*lighting_input).layers[LAYER_BASE].R = R; 252 world_position: vec4<f32>, 253 is_orthographic: bool, 258 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)); 261 V = normalize(view_bindings::view.world_position.xyz - world_position.xyz); 267fn calculate_diffuse_color( 268 base_color: vec3<f32>, 270 specular_transmission: f32, 271 diffuse_transmission: f32 273 return base_color * (1.0 - metallic) * (1.0 - specular_transmission) * 274 (1.0 - diffuse_transmission); 278fn calculate_F0_dielectric(reflectance: vec3<f32>) -> vec3<f32> { 279 return 0.16 * reflectance * reflectance; 284fn calculate_F0(base_color: vec3<f32>, metallic: f32, reflectance: vec3<f32>) -> vec3<f32> { 285 return mix(calculate_F0_dielectric(reflectance), base_color, metallic); 288@if(CONTACT_SHADOWS && DEPTH_PREPASS) 289fn calculate_contact_shadow( 290 world_position: vec3<f32>, 291 frag_coord: vec2<f32>, 292 light_dir: vec3<f32>, 293 contact_shadow_steps: u32, 295 @if(BLUE_NOISE_TEXTURE) 296 let noise_size = textureDimensions(view_bindings::blue_noise_texture, 0); 297 @if(BLUE_NOISE_TEXTURE) 298 let noise_layers = textureNumLayers(view_bindings::blue_noise_texture); 299 @if(BLUE_NOISE_TEXTURE) 300 let noise = textureLoad( 301 view_bindings::blue_noise_texture, 302 vec2<i32>(frag_coord) % vec2<i32>(noise_size), 303 i32(view_bindings::globals.frame_count % noise_layers), 307 let noise = utils::interleaved_gradient_noise(frag_coord, view_bindings::globals.frame_count); 309 let depth_size = vec2<f32>(textureDimensions(view_bindings::depth_prepass_texture)); 310 var rm = raymarch::depth_ray_march_new_from_depth(depth_size); 311 raymarch::depth_ray_march_from_cs(&rm, position_world_to_ndc(world_position)); 312 raymarch::depth_ray_march_to_ws(&rm, world_position + light_dir * view_bindings::contact_shadows_settings.length); 313 rm.linear_steps = contact_shadow_steps; 314 rm.depth_thickness_linear_z = view_bindings::contact_shadows_settings.thickness; 315 rm.march_behind_surfaces = true; 318 let rm_result = raymarch::depth_ray_march_march(&rm); 320 return clamp((rm_result.hit_penetration_frac - 0.5) / (1.0 - 0.5), 0.0, 1.0); 325@if(!PREPASS_FRAGMENT) 326fn apply_pbr_lighting( 327 in: pbr_types::PbrInput, 329 var output_color: vec4<f32> = in.material.base_color; 331 let emissive = in.material.emissive; 334 let metallic = in.material.metallic; 335 let perceptual_roughness = in.material.perceptual_roughness; 336 let roughness = lighting::perceptualRoughnessToRoughness(perceptual_roughness); 337 let ior = in.material.ior; 338 let thickness = in.material.thickness; 339 let reflectance = in.material.reflectance; 340 let diffuse_transmission = in.material.diffuse_transmission; 341 let specular_transmission = in.material.specular_transmission; 343 let specular_transmissive_color = specular_transmission * in.material.base_color.rgb; 345 let diffuse_occlusion = in.diffuse_occlusion; 346 let specular_occlusion = in.specular_occlusion; 349 let NdotV = max(dot(in.N, in.V), 0.0001); 350 let R = reflect(-in.V, in.N); 354 @if(STANDARD_MATERIAL_CLEARCOAT) 355 let clearcoat = in.material.clearcoat; 356 @if(STANDARD_MATERIAL_CLEARCOAT) 357 let clearcoat_perceptual_roughness = in.material.clearcoat_perceptual_roughness; 358 @if(STANDARD_MATERIAL_CLEARCOAT) 359 let clearcoat_roughness = lighting::perceptualRoughnessToRoughness(clearcoat_perceptual_roughness); 360 @if(STANDARD_MATERIAL_CLEARCOAT) 361 let clearcoat_N = in.clearcoat_N; 362 @if(STANDARD_MATERIAL_CLEARCOAT) 363 let clearcoat_NdotV = max(dot(clearcoat_N, in.V), 0.0001); 364 @if(STANDARD_MATERIAL_CLEARCOAT) 365 let clearcoat_R = reflect(-in.V, clearcoat_N); 367 let diffuse_color = calculate_diffuse_color( 370 specular_transmission, 375 let diffuse_transmissive_color = output_color.rgb * (1.0 - metallic) * (1.0 - specular_transmission) * diffuse_transmission; 378 let diffuse_transmissive_lobe_world_position = in.world_position - vec4<f32>(in.world_normal, 0.0) * thickness; 380 let F0 = calculate_F0(output_color.rgb, metallic, reflectance); 381 let F_ab = lighting::F_AB(perceptual_roughness, NdotV); 383 var direct_light: vec3<f32> = vec3<f32>(0.0); 386 var transmitted_light: vec3<f32> = vec3<f32>(0.0); 389 var lighting_input: lighting::LightingInput; 390 lighting_input.layers[LAYER_BASE].NdotV = NdotV; 391 lighting_input.layers[LAYER_BASE].N = in.N; 392 lighting_input.layers[LAYER_BASE].R = R; 393 lighting_input.layers[LAYER_BASE].perceptual_roughness = perceptual_roughness; 394 lighting_input.layers[LAYER_BASE].roughness = roughness; 395 lighting_input.P = in.world_position.xyz; 396 lighting_input.V = in.V; 397 lighting_input.diffuse_color = diffuse_color; 398 lighting_input.metallic = metallic; 399 lighting_input.F0_dielectric = calculate_F0_dielectric(reflectance); 400 lighting_input.F0_metallic = output_color.rgb; 401 lighting_input.F_ab = F_ab; 402@if(STANDARD_MATERIAL_CLEARCOAT) { 403 lighting_input.layers[LAYER_CLEARCOAT].NdotV = clearcoat_NdotV; 404 lighting_input.layers[LAYER_CLEARCOAT].N = clearcoat_N; 405 lighting_input.layers[LAYER_CLEARCOAT].R = clearcoat_R; 406 lighting_input.layers[LAYER_CLEARCOAT].perceptual_roughness = clearcoat_perceptual_roughness; 407 lighting_input.layers[LAYER_CLEARCOAT].roughness = clearcoat_roughness; 408 lighting_input.clearcoat_strength = clearcoat; 410@if(STANDARD_MATERIAL_ANISOTROPY) { 411 lighting_input.anisotropy = in.anisotropy_strength; 412 lighting_input.Ta = in.anisotropy_T; 413 lighting_input.Ba = in.anisotropy_B; 417 @if(STANDARD_MATERIAL_DIFFUSE_TRANSMISSION) 418 var transmissive_lighting_input: lighting::LightingInput; 419@if(STANDARD_MATERIAL_DIFFUSE_TRANSMISSION) { 420 transmissive_lighting_input.layers[LAYER_BASE].NdotV = 1.0; 421 transmissive_lighting_input.layers[LAYER_BASE].N = -in.N; 422 transmissive_lighting_input.layers[LAYER_BASE].R = vec3(0.0); 423 transmissive_lighting_input.layers[LAYER_BASE].perceptual_roughness = 1.0; 424 transmissive_lighting_input.layers[LAYER_BASE].roughness = 1.0; 425 transmissive_lighting_input.P = diffuse_transmissive_lobe_world_position.xyz; 426 transmissive_lighting_input.V = -in.V; 427 transmissive_lighting_input.diffuse_color = diffuse_transmissive_color; 428 transmissive_lighting_input.metallic = 0.0; 429 transmissive_lighting_input.F0_dielectric = vec3(0.0); 430 transmissive_lighting_input.F0_metallic = vec3(0.0); 431 transmissive_lighting_input.F_ab = vec2(0.1); 432@if(STANDARD_MATERIAL_CLEARCOAT) { 433 transmissive_lighting_input.layers[LAYER_CLEARCOAT].NdotV = 0.0; 434 transmissive_lighting_input.layers[LAYER_CLEARCOAT].N = vec3(0.0); 435 transmissive_lighting_input.layers[LAYER_CLEARCOAT].R = vec3(0.0); 436 transmissive_lighting_input.layers[LAYER_CLEARCOAT].perceptual_roughness = 0.0; 437 transmissive_lighting_input.layers[LAYER_CLEARCOAT].roughness = 0.0; 438 transmissive_lighting_input.clearcoat_strength = 0.0; 440@if(STANDARD_MATERIAL_ANISOTROPY) { 441 transmissive_lighting_input.anisotropy = in.anisotropy_strength; 442 transmissive_lighting_input.Ta = in.anisotropy_T; 443 transmissive_lighting_input.Ba = in.anisotropy_B; 447 let view_z = dot(vec4<f32>( 448 view_bindings::view.view_from_world[0].z, 449 view_bindings::view.view_from_world[1].z, 450 view_bindings::view.view_from_world[2].z, 451 view_bindings::view.view_from_world[3].z 452 ), in.world_position); 453 let cluster_index = clustering::view_fragment_cluster_index(in.frag_coord.xy, view_z, in.is_orthographic); 454 var clusterable_object_index_ranges = 455 clustering::unpack_clusterable_object_index_ranges(cluster_index); 458 let contact_shadow_steps = view_bindings::contact_shadows_settings.linear_steps; 460 let contact_shadow_enabled = contact_shadow_steps > 0u; 463 for (var i: u32 = clusterable_object_index_ranges.first_point_light_index_offset; 464 i < clusterable_object_index_ranges.first_spot_light_index_offset; 466 let light_id = clustering::get_clusterable_object_id(i); 472 (view_bindings::clustered_lights.data[light_id].flags & 473 mesh_view_types::POINT_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESH_DIFFUSE_BIT) != 0u; 475 let enable_diffuse = true; 477 var shadow: f32 = 1.0; 478 if ((in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 479 && (view_bindings::clustered_lights.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 480 shadow = shadows::fetch_point_shadow(light_id, in.world_position, in.world_normal, in.frag_coord.xy); 483 @if(CONTACT_SHADOWS && DEPTH_PREPASS) 484 if contact_shadow_enabled && (in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u && shadow > 0.0 && 485 (view_bindings::clustered_lights.data[light_id].flags & 486 mesh_view_types::POINT_LIGHT_FLAGS_CONTACT_SHADOWS_ENABLED_BIT) != 0u { 487 let L = normalize(view_bindings::clustered_lights.data[light_id].position_radius.xyz - in.world_position.xyz); 488 shadow *= calculate_contact_shadow(in.world_position.xyz, in.frag_coord.xy, L, contact_shadow_steps); 491 let light_contrib = lighting::point_light(light_id, &lighting_input, enable_diffuse, true); 492 direct_light += light_contrib * shadow; 494@if(STANDARD_MATERIAL_DIFFUSE_TRANSMISSION) { 504 var transmitted_shadow: f32 = 1.0; 505 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) 506 && (view_bindings::clustered_lights.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 507 transmitted_shadow = shadows::fetch_point_shadow(light_id, diffuse_transmissive_lobe_world_position, -in.world_normal, in.frag_coord.xy); 510 let transmitted_light_contrib = 511 lighting::point_light(light_id, &transmissive_lighting_input, enable_diffuse, true); 512 transmitted_light += transmitted_light_contrib * transmitted_shadow; 517 for (var i: u32 = clusterable_object_index_ranges.first_spot_light_index_offset; 518 i < clusterable_object_index_ranges.first_rect_light_index_offset; 520 let light_id = clustering::get_clusterable_object_id(i); 526 (view_bindings::clustered_lights.data[light_id].flags & 527 mesh_view_types::POINT_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESH_DIFFUSE_BIT) != 0u; 529 let enable_diffuse = true; 531 var shadow: f32 = 1.0; 532 if ((in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 533 && (view_bindings::clustered_lights.data[light_id].flags & 534 mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 535 shadow = shadows::fetch_spot_shadow( 539 view_bindings::clustered_lights.data[light_id].shadow_map_near_z, 544 @if(CONTACT_SHADOWS && DEPTH_PREPASS) 545 if contact_shadow_enabled && (in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u && shadow > 0.0 && 546 (view_bindings::clustered_lights.data[light_id].flags & 547 mesh_view_types::POINT_LIGHT_FLAGS_CONTACT_SHADOWS_ENABLED_BIT) != 0u { 548 let L = normalize(view_bindings::clustered_lights.data[light_id].position_radius.xyz - in.world_position.xyz); 549 shadow *= calculate_contact_shadow(in.world_position.xyz, in.frag_coord.xy, L, contact_shadow_steps); 552 let light_contrib = lighting::spot_light(light_id, &lighting_input, enable_diffuse); 553 direct_light += light_contrib * shadow; 555@if(STANDARD_MATERIAL_DIFFUSE_TRANSMISSION) { 565 var transmitted_shadow: f32 = 1.0; 566 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) 567 && (view_bindings::clustered_lights.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 568 transmitted_shadow = shadows::fetch_spot_shadow( 570 diffuse_transmissive_lobe_world_position, 572 view_bindings::clustered_lights.data[light_id].shadow_map_near_z, 577 let transmitted_light_contrib = 578 lighting::spot_light(light_id, &transmissive_lighting_input, enable_diffuse); 579 transmitted_light += transmitted_light_contrib * transmitted_shadow; 584 let n_directional_lights = view_bindings::lights.n_directional_lights; 585 for (var i: u32 = 0u; i < n_directional_lights; i = i + 1u) { 588 let light = &view_bindings::lights.directional_lights[i]; 595 mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESH_DIFFUSE_BIT) != 598 let enable_diffuse = true; 600 var shadow: f32 = 1.0; 601 if ((in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 602 && (view_bindings::lights.directional_lights[i].flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 603 shadow = shadows::fetch_directional_shadow(i, in.world_position, in.world_normal, view_z, in.frag_coord.xy); 604 shadow *= in.directional_shadow_factor; 607 @if(CONTACT_SHADOWS && DEPTH_PREPASS) 608 if contact_shadow_enabled && (in.flags & MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u && shadow > 0.0 && 609 (view_bindings::lights.directional_lights[i].flags & 610 mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_CONTACT_SHADOWS_ENABLED_BIT) != 0u { 611 let L = view_bindings::lights.directional_lights[i].direction_to_light; 612 shadow *= calculate_contact_shadow(in.world_position.xyz, in.frag_coord.xy, L, contact_shadow_steps); 615 var light_contrib = lighting::directional_light(i, &lighting_input, enable_diffuse); 617 @if(DIRECTIONAL_LIGHT_SHADOW_MAP_DEBUG_CASCADES) 618 light_contrib = shadows::cascade_debug_visualization(light_contrib, i, view_z); 619 direct_light += light_contrib * shadow; 621@if(STANDARD_MATERIAL_DIFFUSE_TRANSMISSION) { 631 var transmitted_shadow: f32 = 1.0; 632 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) 633 && (view_bindings::lights.directional_lights[i].flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 634 transmitted_shadow = shadows::fetch_directional_shadow(i, diffuse_transmissive_lobe_world_position, -in.world_normal, view_z, in.frag_coord.xy); 637 let transmitted_light_contrib = 638 lighting::directional_light(i, &transmissive_lighting_input, enable_diffuse); 639 transmitted_light += transmitted_light_contrib * transmitted_shadow; 643@if(AREA_LIGHT_LUTS) { 647@if(AVAILABLE_STORAGE_BUFFER_BINDINGS__GE_3) 648 let rect_light_start = clusterable_object_index_ranges.first_rect_light_index_offset; 649@if(AVAILABLE_STORAGE_BUFFER_BINDINGS__GE_3) 650 let rect_light_end = clusterable_object_index_ranges.first_reflection_probe_index_offset; 651@if(!AVAILABLE_STORAGE_BUFFER_BINDINGS__GE_3) 652 let rect_light_start = 0u; 653@if(!AVAILABLE_STORAGE_BUFFER_BINDINGS__GE_3) 654 let rect_light_end = view_bindings::lights.n_rect_lights; 655 for (var i: u32 = rect_light_start; i < rect_light_end; i = i + 1u) { 656@if(AVAILABLE_STORAGE_BUFFER_BINDINGS__GE_3) 657 var light = lighting::unpack_clustered_rect_light(clustering::get_clusterable_object_id(i)); 658@if(!AVAILABLE_STORAGE_BUFFER_BINDINGS__GE_3) 659 var light = view_bindings::lights.rect_lights[i]; 660 let enable_diffuse = true; 661 let light_contrib = lighting::rect_light(&light, &lighting_input, enable_diffuse); 662 direct_light += light_contrib; 664 @if(STANDARD_MATERIAL_DIFFUSE_TRANSMISSION) { 665 let transmitted_light_contrib = 666 lighting::rect_light(&light, &transmissive_lighting_input, enable_diffuse); 667 transmitted_light += transmitted_light_contrib; 672 @if(STANDARD_MATERIAL_DIFFUSE_TRANSMISSION) 681 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)); 694 var indirect_light = vec3(0.0f); 695 var found_diffuse_indirect = false; 698 indirect_light += in.lightmap_light * diffuse_color; 699 found_diffuse_indirect = true; 702 @if(IRRADIANCE_VOLUME) 704 if (!found_diffuse_indirect) { 705 let irradiance_volume_light = irradiance_volume::irradiance_volume_light( 706 in.world_position.xyz, 708 &clusterable_object_index_ranges, 710 indirect_light += irradiance_volume_light * diffuse_color * diffuse_occlusion; 711 found_diffuse_indirect = true; 715@if(ENVIRONMENT_MAP) { 720 @if(SCREEN_SPACE_REFLECTIONS) 721 let use_ssr = perceptual_roughness <= view_bindings::ssr_settings.max_perceptual_roughness 722 && perceptual_roughness >= view_bindings::ssr_settings.min_perceptual_roughness; 726 @if(STANDARD_MATERIAL_ANISOTROPY) 727 var bent_normal_lighting_input = lighting_input; 728 @if(STANDARD_MATERIAL_ANISOTROPY) 729 bend_normal_for_anisotropy(&bent_normal_lighting_input); 730 @if(STANDARD_MATERIAL_ANISOTROPY) 731 let environment_map_lighting_input = &bent_normal_lighting_input; 733 let environment_map_lighting_input = &lighting_input; 735 let environment_light = environment_map::environment_map_light( 736 environment_map_lighting_input, 737 &clusterable_object_index_ranges, 738 found_diffuse_indirect, 741 indirect_light += environment_light.diffuse * diffuse_occlusion; 743 indirect_light += environment_light.specular * specular_occlusion; 751 let enable_ambient = (view_bindings::lights.ambient_light_flags & mesh_view_types::AMBIENT_LIGHT_FLAGS_AFFECTS_LIGHTMAPPED_MESHES_BIT) != 0u; 753 let enable_ambient = true; 754 if (enable_ambient) { 755 indirect_light += ambient::ambient_light(in.world_position, in.N, in.V, NdotV, diffuse_color, F0, perceptual_roughness, diffuse_occlusion); 760 var specular_transmitted_environment_light = vec3<f32>(0.0); 762@if(ENVIRONMENT_MAP) { 764@if(STANDARD_MATERIAL_DIFFUSE_OR_SPECULAR_TRANSMISSION) { 780 refract(in.V, -in.N, 1.0 / ior) * thickness 783 var transmissive_environment_light_input: lighting::LightingInput; 784 transmissive_environment_light_input.diffuse_color = vec3(1.0); 785 transmissive_environment_light_input.layers[LAYER_BASE].NdotV = 1.0; 786 transmissive_environment_light_input.P = in.world_position.xyz; 787 transmissive_environment_light_input.layers[LAYER_BASE].N = -in.N; 788 transmissive_environment_light_input.V = in.V; 789 transmissive_environment_light_input.layers[LAYER_BASE].R = T; 790 transmissive_environment_light_input.layers[LAYER_BASE].perceptual_roughness = perceptual_roughness; 791 transmissive_environment_light_input.layers[LAYER_BASE].roughness = roughness; 792 transmissive_environment_light_input.metallic = 0.0; 793 transmissive_environment_light_input.F0_dielectric = vec3<f32>(1.0); 794 transmissive_environment_light_input.F0_metallic = vec3<f32>(0.0); 795 transmissive_environment_light_input.F_ab = vec2(0.1); 796@if(STANDARD_MATERIAL_CLEARCOAT) { 798 transmissive_environment_light_input.clearcoat_strength = 0.0; 799 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].NdotV = 0.0; 800 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].N = in.N; 801 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].R = vec3(0.0); 802 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].perceptual_roughness = 0.0; 803 transmissive_environment_light_input.layers[LAYER_CLEARCOAT].roughness = 0.0; 806 let transmitted_environment_light = environment_map::environment_map_light( 807 &transmissive_environment_light_input, 808 &clusterable_object_index_ranges, 812 @if(STANDARD_MATERIAL_DIFFUSE_TRANSMISSION) 813 transmitted_light += transmitted_environment_light.diffuse * diffuse_transmissive_color; 814 @if(STANDARD_MATERIAL_SPECULAR_TRANSMISSION) 815 specular_transmitted_environment_light = transmitted_environment_light.specular * specular_transmissive_color; 821 var emissive_light = emissive.rgb * output_color.a; 827 @if(STANDARD_MATERIAL_CLEARCOAT) { 828 let clearcoat_fresnel = lighting::F_Schlick(0.04, 1.0, clearcoat_NdotV); 829 emissive_light = emissive_light * (1.0 - clearcoat * clearcoat_fresnel); 832 emissive_light = emissive_light * mix(1.0, view_bindings::view.exposure, emissive.a); 834@if(STANDARD_MATERIAL_SPECULAR_TRANSMISSION) { 835 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; 837 if (in.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ATTENUATION_ENABLED_BIT) != 0u 838 && in.material.attenuation_distance != 0.0 { 840 let transmittance = pow( 841 in.material.attenuation_color.rgb, 842 vec3<f32>(thickness / in.material.attenuation_distance), 844 transmitted_light *= transmittance; 849 output_color = vec4<f32>( 850 (view_bindings::view.exposure * (transmitted_light + direct_light + indirect_light)) + emissive_light, 854 output_color = clustering::cluster_debug_visualization( 858 clusterable_object_index_ranges, 867 fog_params: mesh_view_types::Fog, 868 input_color: vec4<f32>, 869 fragment_world_position: vec3<f32>, 870 view_world_position: vec3<f32>, 871 frag_coord_xy: vec2<f32>, 873 let view_to_world = fragment_world_position.xyz - view_world_position.xyz; 879 let distance = length(view_to_world); 882 let view_pos = view_transformations::position_world_to_view(fragment_world_position); 883 let view_z = view_pos.z; 886 let view_direction_normal = normalize(-view_to_world); 887 let fragment_world_position_vec4 = vec4<f32>(fragment_world_position, 1.0); 889 var scattering = vec3<f32>(0.0); 890 if fog_params.directional_light_color.a > 0.0 { 891 let view_to_world_normalized = view_to_world / distance; 892 let n_directional_lights = view_bindings::lights.n_directional_lights; 893 for (var i: u32 = 0u; i < n_directional_lights; i = i + 1u) { 894 let light = view_bindings::lights.directional_lights[i]; 895 let scattering_contribution = pow( 897 dot(view_to_world_normalized, light.direction_to_light), 900 fog_params.directional_light_exponent 901 ) * light.color.rgb * view_bindings::view.exposure; 904 var shadow: f32 = 1.0; 905 if ((light.flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 906 shadow = shadows::fetch_directional_shadow(i, fragment_world_position_vec4, view_direction_normal, view_z, frag_coord_xy); 908 scattering += scattering_contribution * shadow; 912 if fog_params.mode == mesh_view_types::FOG_MODE_LINEAR { 913 return package::render::fog::linear_fog(fog_params, input_color, distance, scattering); 914 } else if fog_params.mode == mesh_view_types::FOG_MODE_EXPONENTIAL { 915 return package::render::fog::exponential_fog(fog_params, input_color, distance, scattering); 916 } else if fog_params.mode == mesh_view_types::FOG_MODE_EXPONENTIAL_SQUARED { 917 return package::render::fog::exponential_squared_fog(fog_params, input_color, distance, scattering); 918 } else if fog_params.mode == mesh_view_types::FOG_MODE_ATMOSPHERIC { 919 return package::render::fog::atmospheric_fog(fog_params, input_color, distance, scattering); 925@if(PREMULTIPLY_ALPHA) 926fn premultiply_alpha(standard_material_flags: u32, color: vec4<f32>) -> vec4<f32> { 931@if(BLEND_PREMULTIPLIED_ALPHA) { 935 let alpha_mode = standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS; 936 if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_ADD { 948 return vec4<f32>(color.rgb * color.a, 0.0); 972 return vec4<f32>(color.rgb * color.a, color.a); 978fn main_pass_post_lighting_processing( 979 pbr_input: pbr_types::PbrInput, 980 input_color: vec4<f32>, 982 var output_color = input_color; 986 if ((pbr_input.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_FOG_ENABLED_BIT) != 0u) { 987 output_color = apply_fog( 990 pbr_input.world_position.xyz, 991 view_bindings::view.world_position.xyz, 992 pbr_input.frag_coord.xy, 996@if(TONEMAP_IN_SHADER) { 997 output_color = tone_mapping(output_color, view_bindings::view.color_grading); 999 var output_rgb = output_color.rgb; 1000 output_rgb = powsafe(output_rgb, 1.0 / 2.2); 1001 output_rgb += screen_space_dither(pbr_input.frag_coord.xy); 1004 output_rgb = powsafe(output_rgb, 2.2); 1005 output_color = vec4(output_rgb, output_color.a); 1008 @if(PREMULTIPLY_ALPHA) 1009 output_color = premultiply_alpha(pbr_input.material.flags, output_color); 1010 return output_color;