@@ -302,6 +302,28 @@ fn calculate_F0(base_color: vec3<f32>, metallic: f32, reflectance: vec3<f32>) ->
302302 return mix (calculate_F0_dielectric (reflectance ), base_color , metallic );
303303}
304304
305+ #ifdef STANDARD_MATERIAL_SPECULAR_TRANSMISSION
306+ fn volume_attenuation (
307+ radiance : vec3 <f32 >,
308+ transmission_distance : f32 ,
309+ attenuation_color : vec3 <f32 >,
310+ attenuation_distance : f32 ,
311+ ) -> vec3 <f32 > {
312+ if attenuation_distance == 0 .0 {
313+ // Attenuation distance is +∞, indicated by zero, so the transmitted
314+ // color is not attenuated.
315+ return radiance ;
316+ } else {
317+ // Compute light attenuation using Beer's law.
318+ let transmittance = pow (
319+ attenuation_color ,
320+ vec3 <f32 >(transmission_distance / attenuation_distance ),
321+ );
322+ return transmittance * radiance ;
323+ }
324+ }
325+ #endif // STANDARD_MATERIAL_SPECULAR_TRANSMISSION
326+
305327#ifdef CONTACT_SHADOWS
306328#ifdef DEPTH_PREPASS
307329fn calculate_contact_shadow (
@@ -852,19 +874,12 @@ fn apply_pbr_lighting(
852874 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 ;
853875
854876 if (in . material . flags & pbr_types :: STANDARD_MATERIAL_FLAGS_ATTENUATION_ENABLED_BIT ) != 0u {
855- // We reuse the `atmospheric_fog()` function here, as it's fundamentally
856- // equivalent to the attenuation that takes place inside the material volume,
857- // and will allow us to eventually hook up subsurface scattering more easily
858- var attenuation_fog : mesh_view_types :: Fog ;
859- attenuation_fog . base_color . a = 1 .0 ;
860- let attenuation_color = max (in . material . attenuation_color . rgb , vec3 <f32 >(1e-6 ));
861- attenuation_fog . be = - log (attenuation_color ) / in . material . attenuation_distance ;
862- // TODO: Add the subsurface scattering factor below
863- // attenuation_fog.bi = /* ... */
864- transmitted_light = bevy_pbr :: fog :: atmospheric_fog (
865- attenuation_fog , vec4 <f32 >(transmitted_light , 1 .0 ), thickness ,
866- vec3 <f32 >(0 .0 ) // TODO: Pass in (pre-attenuated) scattered light contribution here
867- ). rgb ;
877+ transmitted_light = volume_attenuation (
878+ transmitted_light ,
879+ thickness ,
880+ in . material . attenuation_color . rgb ,
881+ in . material . attenuation_distance ,
882+ );
868883 }
869884#endif
870885
0 commit comments