1#define_import_path bevy_pbr::pbr_functions 3#import bevy_pbr::pbr_types as PbrTypes 4#import bevy_pbr::mesh_types as MeshTypes 5#import bevy_pbr::mesh_bindings as MeshBindings 6#import bevy_pbr::mesh_view_types as ViewTypes 7#import bevy_pbr::mesh_view_bindings as ViewBindings 8#import bevy_pbr::lighting as Lighting 9#import bevy_pbr::clustered_forward as Clustering 10#import bevy_pbr::shadows as Shadows 15 standard_material_flags: u32, 16 world_normal: vec3<f32>, 18#ifdef STANDARDMATERIAL_NORMAL_MAP 19 world_tangent: vec4<f32>, 27 var N: vec3<f32> = normalize(world_normal); 30#ifdef STANDARDMATERIAL_NORMAL_MAP 35 var T: vec3<f32> = world_tangent.xyz; 36 var B: vec3<f32> = world_tangent.w * cross(N, T); 40 if ((standard_material_flags & PbrTypes::STANDARD_MATERIAL_FLAGS_DOUBLE_SIDED_BIT) != 0u) { 44#ifdef STANDARDMATERIAL_NORMAL_MAP 54#ifdef STANDARDMATERIAL_NORMAL_MAP 56 var Nt = textureSample(normal_map_texture, normal_map_sampler, uv).rgb; 57 if ((standard_material_flags & PbrTypes::STANDARD_MATERIAL_FLAGS_TWO_COMPONENT_NORMAL_MAP) != 0u) { 59 Nt = vec3<f32>(Nt.rg * 2.0 - 1.0, 0.0); 60 Nt.z = sqrt(1.0 - Nt.x * Nt.x - Nt.y * Nt.y); 65 if ((standard_material_flags & PbrTypes::STANDARD_MATERIAL_FLAGS_FLIP_NORMAL_MAP_Y) != 0u) { 73 N = normalize(Nt.x * T + Nt.y * B + Nt.z * N); 84 world_position: vec4<f32>, 85 is_orthographic: bool, 88 if (is_orthographic) { 90 V = normalize(vec3<f32>(ViewBindings::view.view_proj[0].z, ViewBindings::view.view_proj[1].z, ViewBindings::view.view_proj[2].z)); 93 V = normalize(ViewBindings::view.world_position.xyz - world_position.xyz); 99 material: PbrTypes::StandardMaterial, 101 frag_coord: vec4<f32>, 102 world_position: vec4<f32>, 105 world_normal: vec3<f32>, 111 is_orthographic: bool, 115fn pbr_input_new() -> PbrInput { 116 var pbr_input: PbrInput; 118 pbr_input.material = PbrTypes::standard_material_new(); 119 pbr_input.occlusion = 1.0; 121 pbr_input.frag_coord = vec4<f32>(0.0, 0.0, 0.0, 1.0); 122 pbr_input.world_position = vec4<f32>(0.0, 0.0, 0.0, 1.0); 123 pbr_input.world_normal = vec3<f32>(0.0, 0.0, 1.0); 125 pbr_input.is_orthographic = false; 127 pbr_input.N = vec3<f32>(0.0, 0.0, 1.0); 128 pbr_input.V = vec3<f32>(1.0, 0.0, 0.0); 136 var output_color: vec4<f32> = in.material.base_color; 139 let emissive = in.material.emissive; 142 let metallic = in.material.metallic; 143 let perceptual_roughness = in.material.perceptual_roughness; 144 let roughness = Lighting::perceptualRoughnessToRoughness(perceptual_roughness); 146 let occlusion = in.occlusion; 148 if ((in.material.flags & PbrTypes::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE) != 0u) { 150 output_color.a = 1.0; 151 } else if ((in.material.flags & PbrTypes::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_MASK) != 0u) { 152 if (output_color.a >= in.material.alpha_cutoff) { 154 output_color.a = 1.0; 163 let NdotV = max(dot(in.N, in.V), 0.0001); 167 let reflectance = in.material.reflectance; 168 let F0 = 0.16 * reflectance * reflectance * (1.0 - metallic) + output_color.rgb * metallic; 171 let diffuse_color = output_color.rgb * (1.0 - metallic); 173 let R = reflect(-in.V, in.N); 176 var light_accum: vec3<f32> = vec3<f32>(0.0); 178 let view_z = dot(vec4<f32>( 179 ViewBindings::view.inverse_view[0].z, 180 ViewBindings::view.inverse_view[1].z, 181 ViewBindings::view.inverse_view[2].z, 182 ViewBindings::view.inverse_view[3].z 183 ), in.world_position); 184 let cluster_index = Clustering::fragment_cluster_index(in.frag_coord.xy, view_z, in.is_orthographic); 185 let offset_and_counts = Clustering::unpack_offset_and_counts(cluster_index); 188 for (var i: u32 = offset_and_counts[0]; i < offset_and_counts[0] + offset_and_counts[1]; i = i + 1u) { 189 let light_id = Clustering::get_light_id(i); 190 let light = ViewBindings::point_lights.data[light_id]; 191 var shadow: f32 = 1.0; 192 if ((MeshBindings::mesh.flags & MeshTypes::MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 193 && (light.flags & ViewTypes::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 194 shadow = Shadows::fetch_point_shadow(light_id, in.world_position, in.world_normal); 196 let light_contrib = Lighting::point_light(in.world_position.xyz, light, roughness, NdotV, in.N, in.V, R, F0, diffuse_color); 197 light_accum = light_accum + light_contrib * shadow; 201 for (var i: u32 = offset_and_counts[0] + offset_and_counts[1]; i < offset_and_counts[0] + offset_and_counts[1] + offset_and_counts[2]; i = i + 1u) { 202 let light_id = Clustering::get_light_id(i); 203 let light = ViewBindings::point_lights.data[light_id]; 204 var shadow: f32 = 1.0; 205 if ((MeshBindings::mesh.flags & MeshTypes::MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 206 && (light.flags & ViewTypes::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 207 shadow = Shadows::fetch_spot_shadow(light_id, in.world_position, in.world_normal); 209 let light_contrib = Lighting::spot_light(in.world_position.xyz, light, roughness, NdotV, in.N, in.V, R, F0, diffuse_color); 210 light_accum = light_accum + light_contrib * shadow; 213 let n_directional_lights = ViewBindings::lights.n_directional_lights; 214 for (var i: u32 = 0u; i < n_directional_lights; i = i + 1u) { 215 let light = ViewBindings::lights.directional_lights[i]; 216 var shadow: f32 = 1.0; 217 if ((MeshBindings::mesh.flags & MeshTypes::MESH_FLAGS_SHADOW_RECEIVER_BIT) != 0u 218 && (light.flags & ViewTypes::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) { 219 shadow = Shadows::fetch_directional_shadow(i, in.world_position, in.world_normal); 221 let light_contrib = Lighting::directional_light(light, roughness, NdotV, in.N, in.V, R, F0, diffuse_color); 222 light_accum = light_accum + light_contrib * shadow; 225 let diffuse_ambient = Lighting::EnvBRDFApprox(diffuse_color, 1.0, NdotV); 226 let specular_ambient = Lighting::EnvBRDFApprox(F0, perceptual_roughness, NdotV); 228 output_color = vec4<f32>( 230 (diffuse_ambient + specular_ambient) * ViewBindings::lights.ambient_color.rgb * occlusion + 231 emissive.rgb * output_color.a, 234 output_color = Clustering::cluster_debug_visualization( 245fn tone_mapping(in: vec4<f32>) -> vec4<f32> { 247 return vec4<f32>(Lighting::reinhard_luminance(in.rgb), in.a);