mirror of
https://github.com/bevyengine/bevy
synced 2025-02-16 14:08:32 +00:00
Gate diffuse and specular transmission behind shader defs (#11627)
# Objective - Address #10338 ## Solution - When implementing specular and diffuse transmission, I inadvertently introduced a performance regression. On high-end hardware it is barely noticeable, but **for lower-end hardware it can be pretty brutal**. If I understand it correctly, this is likely due to use of masking by the GPU to implement control flow, which means that you still pay the price for the branches you don't take; - To avoid that, this PR introduces new shader defs (controlled via `StandardMaterialKey`) that conditionally include the transmission logic, that way the shader code for both types of transmission isn't even sent to the GPU if you're not using them; - This PR also renames ~~`STANDARDMATERIAL_NORMAL_MAP`~~ to `STANDARD_MATERIAL_NORMAL_MAP` for consistency with the naming convention used elsewhere in the codebase. (Drive-by fix) --- ## Changelog - Added new shader defs, set when using transmission in the `StandardMaterial`: - `STANDARD_MATERIAL_SPECULAR_TRANSMISSION`; - `STANDARD_MATERIAL_DIFFUSE_TRANSMISSION`; - `STANDARD_MATERIAL_SPECULAR_OR_DIFFUSE_TRANSMISSION`. - Fixed performance regression caused by the introduction of transmission, by gating transmission shader logic behind the newly introduced shader defs; - Renamed ~~`STANDARDMATERIAL_NORMAL_MAP`~~ to `STANDARD_MATERIAL_NORMAL_MAP` for consistency; ## Migration Guide - If you were using `#ifdef STANDARDMATERIAL_NORMAL_MAP` on your shader code, make sure to update the name to `STANDARD_MATERIAL_NORMAL_MAP`; (with an underscore between `STANDARD` and `MATERIAL`)
This commit is contained in:
parent
0ffc8d8a6f
commit
91c467ebfc
5 changed files with 125 additions and 104 deletions
|
@ -43,7 +43,7 @@ fn fragment(
|
||||||
double_sided,
|
double_sided,
|
||||||
is_front,
|
is_front,
|
||||||
#ifdef VERTEX_TANGENTS
|
#ifdef VERTEX_TANGENTS
|
||||||
#ifdef STANDARDMATERIAL_NORMAL_MAP
|
#ifdef STANDARD_MATERIAL_NORMAL_MAP
|
||||||
mesh.world_tangent,
|
mesh.world_tangent,
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -740,6 +740,8 @@ pub struct StandardMaterialKey {
|
||||||
cull_mode: Option<Face>,
|
cull_mode: Option<Face>,
|
||||||
depth_bias: i32,
|
depth_bias: i32,
|
||||||
relief_mapping: bool,
|
relief_mapping: bool,
|
||||||
|
diffuse_transmission: bool,
|
||||||
|
specular_transmission: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&StandardMaterial> for StandardMaterialKey {
|
impl From<&StandardMaterial> for StandardMaterialKey {
|
||||||
|
@ -752,6 +754,8 @@ impl From<&StandardMaterial> for StandardMaterialKey {
|
||||||
material.parallax_mapping_method,
|
material.parallax_mapping_method,
|
||||||
ParallaxMappingMethod::Relief { .. }
|
ParallaxMappingMethod::Relief { .. }
|
||||||
),
|
),
|
||||||
|
diffuse_transmission: material.diffuse_transmission > 0.0,
|
||||||
|
specular_transmission: material.specular_transmission > 0.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -811,11 +815,24 @@ impl Material for StandardMaterial {
|
||||||
let shader_defs = &mut fragment.shader_defs;
|
let shader_defs = &mut fragment.shader_defs;
|
||||||
|
|
||||||
if key.bind_group_data.normal_map {
|
if key.bind_group_data.normal_map {
|
||||||
shader_defs.push("STANDARDMATERIAL_NORMAL_MAP".into());
|
shader_defs.push("STANDARD_MATERIAL_NORMAL_MAP".into());
|
||||||
}
|
}
|
||||||
if key.bind_group_data.relief_mapping {
|
if key.bind_group_data.relief_mapping {
|
||||||
shader_defs.push("RELIEF_MAPPING".into());
|
shader_defs.push("RELIEF_MAPPING".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if key.bind_group_data.diffuse_transmission {
|
||||||
|
shader_defs.push("STANDARD_MATERIAL_DIFFUSE_TRANSMISSION".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if key.bind_group_data.specular_transmission {
|
||||||
|
shader_defs.push("STANDARD_MATERIAL_SPECULAR_TRANSMISSION".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if key.bind_group_data.diffuse_transmission || key.bind_group_data.specular_transmission
|
||||||
|
{
|
||||||
|
shader_defs.push("STANDARD_MATERIAL_SPECULAR_OR_DIFFUSE_TRANSMISSION".into());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
descriptor.primitive.cull_mode = key.bind_group_data.cull_mode;
|
descriptor.primitive.cull_mode = key.bind_group_data.cull_mode;
|
||||||
if let Some(label) = &mut descriptor.label {
|
if let Some(label) = &mut descriptor.label {
|
||||||
|
|
|
@ -190,7 +190,7 @@ fn pbr_input_from_standard_material(
|
||||||
double_sided,
|
double_sided,
|
||||||
is_front,
|
is_front,
|
||||||
#ifdef VERTEX_TANGENTS
|
#ifdef VERTEX_TANGENTS
|
||||||
#ifdef STANDARDMATERIAL_NORMAL_MAP
|
#ifdef STANDARD_MATERIAL_NORMAL_MAP
|
||||||
in.world_tangent,
|
in.world_tangent,
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -50,7 +50,7 @@ fn prepare_world_normal(
|
||||||
) -> vec3<f32> {
|
) -> vec3<f32> {
|
||||||
var output: vec3<f32> = world_normal;
|
var output: vec3<f32> = world_normal;
|
||||||
#ifndef VERTEX_TANGENTS
|
#ifndef VERTEX_TANGENTS
|
||||||
#ifndef STANDARDMATERIAL_NORMAL_MAP
|
#ifndef STANDARD_MATERIAL_NORMAL_MAP
|
||||||
// NOTE: When NOT using normal-mapping, if looking at the back face of a double-sided
|
// NOTE: When NOT using normal-mapping, if looking at the back face of a double-sided
|
||||||
// material, the normal needs to be inverted. This is a branchless version of that.
|
// material, the normal needs to be inverted. This is a branchless version of that.
|
||||||
output = (f32(!double_sided || is_front) * 2.0 - 1.0) * output;
|
output = (f32(!double_sided || is_front) * 2.0 - 1.0) * output;
|
||||||
|
@ -65,7 +65,7 @@ fn apply_normal_mapping(
|
||||||
double_sided: bool,
|
double_sided: bool,
|
||||||
is_front: bool,
|
is_front: bool,
|
||||||
#ifdef VERTEX_TANGENTS
|
#ifdef VERTEX_TANGENTS
|
||||||
#ifdef STANDARDMATERIAL_NORMAL_MAP
|
#ifdef STANDARD_MATERIAL_NORMAL_MAP
|
||||||
world_tangent: vec4<f32>,
|
world_tangent: vec4<f32>,
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -83,7 +83,7 @@ fn apply_normal_mapping(
|
||||||
var N: vec3<f32> = world_normal;
|
var N: vec3<f32> = world_normal;
|
||||||
|
|
||||||
#ifdef VERTEX_TANGENTS
|
#ifdef VERTEX_TANGENTS
|
||||||
#ifdef STANDARDMATERIAL_NORMAL_MAP
|
#ifdef STANDARD_MATERIAL_NORMAL_MAP
|
||||||
// NOTE: The mikktspace method of normal mapping explicitly requires that these NOT be
|
// NOTE: The mikktspace method of normal mapping explicitly requires that these NOT be
|
||||||
// normalized nor any Gram-Schmidt applied to ensure the vertex normal is orthogonal to the
|
// normalized nor any Gram-Schmidt applied to ensure the vertex normal is orthogonal to the
|
||||||
// vertex tangent! Do not change this code unless you really know what you are doing.
|
// vertex tangent! Do not change this code unless you really know what you are doing.
|
||||||
|
@ -95,7 +95,7 @@ fn apply_normal_mapping(
|
||||||
|
|
||||||
#ifdef VERTEX_TANGENTS
|
#ifdef VERTEX_TANGENTS
|
||||||
#ifdef VERTEX_UVS
|
#ifdef VERTEX_UVS
|
||||||
#ifdef STANDARDMATERIAL_NORMAL_MAP
|
#ifdef STANDARD_MATERIAL_NORMAL_MAP
|
||||||
// Nt is the tangent-space normal.
|
// Nt is the tangent-space normal.
|
||||||
var Nt = textureSampleBias(pbr_bindings::normal_map_texture, pbr_bindings::normal_map_sampler, uv, mip_bias).rgb;
|
var Nt = textureSampleBias(pbr_bindings::normal_map_texture, pbr_bindings::normal_map_sampler, uv, mip_bias).rgb;
|
||||||
if (standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_TWO_COMPONENT_NORMAL_MAP) != 0u {
|
if (standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_TWO_COMPONENT_NORMAL_MAP) != 0u {
|
||||||
|
@ -213,24 +213,24 @@ fn apply_pbr_lighting(
|
||||||
let light_contrib = lighting::point_light(in.world_position.xyz, light_id, roughness, NdotV, in.N, in.V, R, F0, f_ab, diffuse_color);
|
let light_contrib = lighting::point_light(in.world_position.xyz, light_id, roughness, NdotV, in.N, in.V, R, F0, f_ab, diffuse_color);
|
||||||
direct_light += light_contrib * shadow;
|
direct_light += light_contrib * shadow;
|
||||||
|
|
||||||
if diffuse_transmission > 0.0 {
|
#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION
|
||||||
// NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated
|
// NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated
|
||||||
// world position, inverted normal and view vectors, and the following simplified
|
// world position, inverted normal and view vectors, and the following simplified
|
||||||
// values for a fully diffuse transmitted light contribution approximation:
|
// values for a fully diffuse transmitted light contribution approximation:
|
||||||
//
|
//
|
||||||
// roughness = 1.0;
|
// roughness = 1.0;
|
||||||
// NdotV = 1.0;
|
// NdotV = 1.0;
|
||||||
// R = vec3<f32>(0.0) // doesn't really matter
|
// R = vec3<f32>(0.0) // doesn't really matter
|
||||||
// f_ab = vec2<f32>(0.1)
|
// f_ab = vec2<f32>(0.1)
|
||||||
// F0 = vec3<f32>(0.0)
|
// F0 = vec3<f32>(0.0)
|
||||||
var transmitted_shadow: f32 = 1.0;
|
var transmitted_shadow: f32 = 1.0;
|
||||||
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)
|
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)
|
||||||
&& (view_bindings::point_lights.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) {
|
&& (view_bindings::point_lights.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) {
|
||||||
transmitted_shadow = shadows::fetch_point_shadow(light_id, diffuse_transmissive_lobe_world_position, -in.world_normal);
|
transmitted_shadow = shadows::fetch_point_shadow(light_id, diffuse_transmissive_lobe_world_position, -in.world_normal);
|
||||||
}
|
|
||||||
let light_contrib = lighting::point_light(diffuse_transmissive_lobe_world_position.xyz, light_id, 1.0, 1.0, -in.N, -in.V, vec3<f32>(0.0), vec3<f32>(0.0), vec2<f32>(0.1), diffuse_transmissive_color);
|
|
||||||
transmitted_light += light_contrib * transmitted_shadow;
|
|
||||||
}
|
}
|
||||||
|
let transmitted_light_contrib = lighting::point_light(diffuse_transmissive_lobe_world_position.xyz, light_id, 1.0, 1.0, -in.N, -in.V, vec3<f32>(0.0), vec3<f32>(0.0), vec2<f32>(0.1), diffuse_transmissive_color);
|
||||||
|
transmitted_light += transmitted_light_contrib * transmitted_shadow;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spot lights (direct)
|
// Spot lights (direct)
|
||||||
|
@ -245,24 +245,24 @@ fn apply_pbr_lighting(
|
||||||
let light_contrib = lighting::spot_light(in.world_position.xyz, light_id, roughness, NdotV, in.N, in.V, R, F0, f_ab, diffuse_color);
|
let light_contrib = lighting::spot_light(in.world_position.xyz, light_id, roughness, NdotV, in.N, in.V, R, F0, f_ab, diffuse_color);
|
||||||
direct_light += light_contrib * shadow;
|
direct_light += light_contrib * shadow;
|
||||||
|
|
||||||
if diffuse_transmission > 0.0 {
|
#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION
|
||||||
// NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated
|
// NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated
|
||||||
// world position, inverted normal and view vectors, and the following simplified
|
// world position, inverted normal and view vectors, and the following simplified
|
||||||
// values for a fully diffuse transmitted light contribution approximation:
|
// values for a fully diffuse transmitted light contribution approximation:
|
||||||
//
|
//
|
||||||
// roughness = 1.0;
|
// roughness = 1.0;
|
||||||
// NdotV = 1.0;
|
// NdotV = 1.0;
|
||||||
// R = vec3<f32>(0.0) // doesn't really matter
|
// R = vec3<f32>(0.0) // doesn't really matter
|
||||||
// f_ab = vec2<f32>(0.1)
|
// f_ab = vec2<f32>(0.1)
|
||||||
// F0 = vec3<f32>(0.0)
|
// F0 = vec3<f32>(0.0)
|
||||||
var transmitted_shadow: f32 = 1.0;
|
var transmitted_shadow: f32 = 1.0;
|
||||||
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)
|
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)
|
||||||
&& (view_bindings::point_lights.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) {
|
&& (view_bindings::point_lights.data[light_id].flags & mesh_view_types::POINT_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) {
|
||||||
transmitted_shadow = shadows::fetch_spot_shadow(light_id, diffuse_transmissive_lobe_world_position, -in.world_normal);
|
transmitted_shadow = shadows::fetch_spot_shadow(light_id, diffuse_transmissive_lobe_world_position, -in.world_normal);
|
||||||
}
|
|
||||||
let light_contrib = lighting::spot_light(diffuse_transmissive_lobe_world_position.xyz, light_id, 1.0, 1.0, -in.N, -in.V, vec3<f32>(0.0), vec3<f32>(0.0), vec2<f32>(0.1), diffuse_transmissive_color);
|
|
||||||
transmitted_light += light_contrib * transmitted_shadow;
|
|
||||||
}
|
}
|
||||||
|
let transmitted_light_contrib = lighting::spot_light(diffuse_transmissive_lobe_world_position.xyz, light_id, 1.0, 1.0, -in.N, -in.V, vec3<f32>(0.0), vec3<f32>(0.0), vec2<f32>(0.1), diffuse_transmissive_color);
|
||||||
|
transmitted_light += transmitted_light_contrib * transmitted_shadow;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// directional lights (direct)
|
// directional lights (direct)
|
||||||
|
@ -286,40 +286,40 @@ fn apply_pbr_lighting(
|
||||||
#endif
|
#endif
|
||||||
direct_light += light_contrib * shadow;
|
direct_light += light_contrib * shadow;
|
||||||
|
|
||||||
if diffuse_transmission > 0.0 {
|
#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION
|
||||||
// NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated
|
// NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated
|
||||||
// world position, inverted normal and view vectors, and the following simplified
|
// world position, inverted normal and view vectors, and the following simplified
|
||||||
// values for a fully diffuse transmitted light contribution approximation:
|
// values for a fully diffuse transmitted light contribution approximation:
|
||||||
//
|
//
|
||||||
// roughness = 1.0;
|
// roughness = 1.0;
|
||||||
// NdotV = 1.0;
|
// NdotV = 1.0;
|
||||||
// R = vec3<f32>(0.0) // doesn't really matter
|
// R = vec3<f32>(0.0) // doesn't really matter
|
||||||
// f_ab = vec2<f32>(0.1)
|
// f_ab = vec2<f32>(0.1)
|
||||||
// F0 = vec3<f32>(0.0)
|
// F0 = vec3<f32>(0.0)
|
||||||
var transmitted_shadow: f32 = 1.0;
|
var transmitted_shadow: f32 = 1.0;
|
||||||
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)
|
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)
|
||||||
&& (view_bindings::lights.directional_lights[i].flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) {
|
&& (view_bindings::lights.directional_lights[i].flags & mesh_view_types::DIRECTIONAL_LIGHT_FLAGS_SHADOWS_ENABLED_BIT) != 0u) {
|
||||||
transmitted_shadow = shadows::fetch_directional_shadow(i, diffuse_transmissive_lobe_world_position, -in.world_normal, view_z);
|
transmitted_shadow = shadows::fetch_directional_shadow(i, diffuse_transmissive_lobe_world_position, -in.world_normal, view_z);
|
||||||
}
|
|
||||||
let light_contrib = lighting::directional_light(i, 1.0, 1.0, -in.N, -in.V, vec3<f32>(0.0), vec3<f32>(0.0), vec2<f32>(0.1), diffuse_transmissive_color);
|
|
||||||
transmitted_light += light_contrib * transmitted_shadow;
|
|
||||||
}
|
}
|
||||||
|
let transmitted_light_contrib = lighting::directional_light(i, 1.0, 1.0, -in.N, -in.V, vec3<f32>(0.0), vec3<f32>(0.0), vec2<f32>(0.1), diffuse_transmissive_color);
|
||||||
|
transmitted_light += transmitted_light_contrib * transmitted_shadow;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ambient light (indirect)
|
// Ambient light (indirect)
|
||||||
var indirect_light = ambient::ambient_light(in.world_position, in.N, in.V, NdotV, diffuse_color, F0, perceptual_roughness, diffuse_occlusion);
|
var indirect_light = ambient::ambient_light(in.world_position, in.N, in.V, NdotV, diffuse_color, F0, perceptual_roughness, diffuse_occlusion);
|
||||||
|
|
||||||
if diffuse_transmission > 0.0 {
|
#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION
|
||||||
// NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated
|
// NOTE: We use the diffuse transmissive color, the second Lambertian lobe's calculated
|
||||||
// world position, inverted normal and view vectors, and the following simplified
|
// world position, inverted normal and view vectors, and the following simplified
|
||||||
// values for a fully diffuse transmitted light contribution approximation:
|
// values for a fully diffuse transmitted light contribution approximation:
|
||||||
//
|
//
|
||||||
// perceptual_roughness = 1.0;
|
// perceptual_roughness = 1.0;
|
||||||
// NdotV = 1.0;
|
// NdotV = 1.0;
|
||||||
// F0 = vec3<f32>(0.0)
|
// F0 = vec3<f32>(0.0)
|
||||||
// diffuse_occlusion = vec3<f32>(1.0)
|
// diffuse_occlusion = vec3<f32>(1.0)
|
||||||
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));
|
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));
|
||||||
}
|
#endif
|
||||||
|
|
||||||
// Environment map light (indirect)
|
// Environment map light (indirect)
|
||||||
#ifdef ENVIRONMENT_MAP
|
#ifdef ENVIRONMENT_MAP
|
||||||
|
@ -339,38 +339,42 @@ fn apply_pbr_lighting(
|
||||||
// light in the call to `specular_transmissive_light()` below
|
// light in the call to `specular_transmissive_light()` below
|
||||||
var specular_transmitted_environment_light = vec3<f32>(0.0);
|
var specular_transmitted_environment_light = vec3<f32>(0.0);
|
||||||
|
|
||||||
if diffuse_transmission > 0.0 || specular_transmission > 0.0 {
|
#ifdef STANDARD_MATERIAL_SPECULAR_OR_DIFFUSE_TRANSMISSION
|
||||||
// NOTE: We use the diffuse transmissive color, inverted normal and view vectors,
|
// NOTE: We use the diffuse transmissive color, inverted normal and view vectors,
|
||||||
// and the following simplified values for the transmitted environment light contribution
|
// and the following simplified values for the transmitted environment light contribution
|
||||||
// approximation:
|
// approximation:
|
||||||
//
|
//
|
||||||
// diffuse_color = vec3<f32>(1.0) // later we use `diffuse_transmissive_color` and `specular_transmissive_color`
|
// diffuse_color = vec3<f32>(1.0) // later we use `diffuse_transmissive_color` and `specular_transmissive_color`
|
||||||
// NdotV = 1.0;
|
// NdotV = 1.0;
|
||||||
// R = T // see definition below
|
// R = T // see definition below
|
||||||
// F0 = vec3<f32>(1.0)
|
// F0 = vec3<f32>(1.0)
|
||||||
// diffuse_occlusion = 1.0
|
// diffuse_occlusion = 1.0
|
||||||
//
|
//
|
||||||
// (This one is slightly different from the other light types above, because the environment
|
// (This one is slightly different from the other light types above, because the environment
|
||||||
// map light returns both diffuse and specular components separately, and we want to use both)
|
// map light returns both diffuse and specular components separately, and we want to use both)
|
||||||
|
|
||||||
let T = -normalize(
|
let T = -normalize(
|
||||||
in.V + // start with view vector at entry point
|
in.V + // start with view vector at entry point
|
||||||
refract(in.V, -in.N, 1.0 / ior) * thickness // add refracted vector scaled by thickness, towards exit point
|
refract(in.V, -in.N, 1.0 / ior) * thickness // add refracted vector scaled by thickness, towards exit point
|
||||||
); // normalize to find exit point view vector
|
); // normalize to find exit point view vector
|
||||||
|
|
||||||
let transmitted_environment_light = bevy_pbr::environment_map::environment_map_light(
|
let transmitted_environment_light = bevy_pbr::environment_map::environment_map_light(
|
||||||
perceptual_roughness,
|
perceptual_roughness,
|
||||||
roughness,
|
roughness,
|
||||||
vec3<f32>(1.0),
|
vec3<f32>(1.0),
|
||||||
1.0,
|
1.0,
|
||||||
f_ab,
|
f_ab,
|
||||||
-in.N,
|
-in.N,
|
||||||
T,
|
T,
|
||||||
vec3<f32>(1.0),
|
vec3<f32>(1.0),
|
||||||
in.world_position.xyz);
|
in.world_position.xyz);
|
||||||
transmitted_light += transmitted_environment_light.diffuse * diffuse_transmissive_color;
|
#ifdef STANDARD_MATERIAL_DIFFUSE_TRANSMISSION
|
||||||
specular_transmitted_environment_light = transmitted_environment_light.specular * specular_transmissive_color;
|
transmitted_light += transmitted_environment_light.diffuse * diffuse_transmissive_color;
|
||||||
}
|
#endif
|
||||||
|
#ifdef STANDARD_MATERIAL_SPECULAR_TRANSMISSION
|
||||||
|
specular_transmitted_environment_light = transmitted_environment_light.specular * specular_transmissive_color;
|
||||||
|
#endif
|
||||||
|
#endif // STANDARD_MATERIAL_SPECULAR_OR_DIFFUSE_TRANSMISSION
|
||||||
#else
|
#else
|
||||||
// If there's no environment map light, there's no transmitted environment
|
// If there's no environment map light, there's no transmitted environment
|
||||||
// light specular component, so we can just hardcode it to zero.
|
// light specular component, so we can just hardcode it to zero.
|
||||||
|
@ -383,9 +387,8 @@ fn apply_pbr_lighting(
|
||||||
|
|
||||||
let emissive_light = emissive.rgb * output_color.a;
|
let emissive_light = emissive.rgb * output_color.a;
|
||||||
|
|
||||||
if specular_transmission > 0.0 {
|
#ifdef STANDARD_MATERIAL_SPECULAR_TRANSMISSION
|
||||||
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;
|
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;
|
||||||
}
|
|
||||||
|
|
||||||
if (in.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ATTENUATION_ENABLED_BIT) != 0u {
|
if (in.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ATTENUATION_ENABLED_BIT) != 0u {
|
||||||
// We reuse the `atmospheric_fog()` function here, as it's fundamentally
|
// We reuse the `atmospheric_fog()` function here, as it's fundamentally
|
||||||
|
@ -401,6 +404,7 @@ fn apply_pbr_lighting(
|
||||||
vec3<f32>(0.0) // TODO: Pass in (pre-attenuated) scattered light contribution here
|
vec3<f32>(0.0) // TODO: Pass in (pre-attenuated) scattered light contribution here
|
||||||
).rgb;
|
).rgb;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Total light
|
// Total light
|
||||||
output_color = vec4<f32>(
|
output_color = vec4<f32>(
|
||||||
|
|
|
@ -38,9 +38,9 @@ fn fragment(
|
||||||
double_sided,
|
double_sided,
|
||||||
is_front,
|
is_front,
|
||||||
#ifdef VERTEX_TANGENTS
|
#ifdef VERTEX_TANGENTS
|
||||||
#ifdef STANDARDMATERIAL_NORMAL_MAP
|
#ifdef STANDARD_MATERIAL_NORMAL_MAP
|
||||||
in.world_tangent,
|
in.world_tangent,
|
||||||
#endif // STANDARDMATERIAL_NORMAL_MAP
|
#endif // STANDARD_MATERIAL_NORMAL_MAP
|
||||||
#endif // VERTEX_TANGENTS
|
#endif // VERTEX_TANGENTS
|
||||||
#ifdef VERTEX_UVS
|
#ifdef VERTEX_UVS
|
||||||
in.uv,
|
in.uv,
|
||||||
|
|
Loading…
Add table
Reference in a new issue