Skip to content

Commit 964340c

Browse files
committed
Take reflectance into account when calculating specular transmission
1 parent 0a89ee2 commit 964340c

2 files changed

Lines changed: 11 additions & 4 deletions

File tree

crates/bevy_pbr/src/render/pbr_functions.wgsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ fn apply_pbr_lighting(
343343
let emissive_light = emissive.rgb * output_color.a;
344344

345345
if specular_transmission > 0.0 {
346-
transmitted_light += transmission::specular_transmissive_light(in.world_position, in.frag_coord.xyz, view_z, in.N, in.V, ior, thickness, perceptual_roughness, specular_transmissive_color, specular_transmitted_environment_light).rgb;
346+
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;
347347
}
348348

349349
if (in.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ATTENUATION_ENABLED_BIT) != 0u {

crates/bevy_pbr/src/render/pbr_transmission.wgsl

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#define_import_path bevy_pbr::transmission
22

3+
#import bevy_pbr::lighting as lighting
34
#import bevy_pbr::prepass_utils as prepass_utils
45
#import bevy_pbr::utils PI, interleaved_gradient_noise, SPIRAL_OFFSET_0_, SPIRAL_OFFSET_1_, SPIRAL_OFFSET_2_, SPIRAL_OFFSET_3_, SPIRAL_OFFSET_4_, SPIRAL_OFFSET_5_, SPIRAL_OFFSET_6_, SPIRAL_OFFSET_7_
56
#import bevy_pbr::mesh_view_bindings as view_bindings
67

7-
fn specular_transmissive_light(world_position: vec4<f32>, frag_coord: vec3<f32>, view_z: f32, N: vec3<f32>, V: vec3<f32>, ior: f32, thickness: f32, perceptual_roughness: f32, specular_transmissive_color: vec3<f32>, transmitted_environment_light_specular: vec3<f32>) -> vec3<f32> {
8+
fn specular_transmissive_light(world_position: vec4<f32>, frag_coord: vec3<f32>, view_z: f32, N: vec3<f32>, V: vec3<f32>, F0: vec3<f32>, ior: f32, thickness: f32, perceptual_roughness: f32, specular_transmissive_color: vec3<f32>, transmitted_environment_light_specular: vec3<f32>) -> vec3<f32> {
89
// Calculate the ratio between refaction indexes. Assume air/vacuum for the space outside the mesh
910
let eta = 1.0 / ior;
1011

@@ -34,8 +35,14 @@ fn specular_transmissive_light(world_position: vec4<f32>, frag_coord: vec3<f32>,
3435
background_color = fetch_transmissive_background(offset_position, frag_coord, view_z, perceptual_roughness);
3536
}
3637

37-
// Calculate final color by applying specular transmissive color to a mix of background color and transmitted specular environment light
38-
return specular_transmissive_color * mix(transmitted_environment_light_specular, background_color.rgb, background_color.a);
38+
// Incidence vector of the refracted ray, relative to the exit normal (Note: We assume the exit normal is the entry normal but inverted)
39+
let MinusNdotT = dot(-N, T);
40+
41+
// Calculate 1.0 - fresnel factor (how much light is _NOT_ reflected, i.e. how much is transmitted)
42+
let F = vec3(1.0) - lighting::fresnel(F0, MinusNdotT);
43+
44+
// Calculate final color by applying fresnel multiplied specular transmissive color to a mix of background color and transmitted specular environment light
45+
return F * specular_transmissive_color * mix(transmitted_environment_light_specular, background_color.rgb, background_color.a);
3946
}
4047

4148
fn fetch_transmissive_background_non_rough(offset_position: vec2<f32>) -> vec4<f32> {

0 commit comments

Comments
 (0)