UNPKG

gpu-curtains

Version:

gpu-curtains is a 3D WebGPU rendering engine. It can be used as a standalone 3D engine, but also includes extra classes focused on mapping 3d objects to DOM elements; It allows users to synchronize values such as position, sizing, or scale between them.

93 lines (73 loc) 2.25 kB
const getIBLGGXFresnel = ( /* */ ` // multi scattering equations // not used for now since our IBL GGX Fresnel already handles energy conseervation // could be used if we dropped the environment map LUT texture fn DFGApprox( normal: vec3f, viewDirection: vec3f, roughness: f32, ) -> vec2f { let dotNV: f32 = saturate(dot( normal, viewDirection )); let c0: vec4f = vec4( - 1, - 0.0275, - 0.572, 0.022 ); let c1: vec4f = vec4( 1, 0.0425, 1.04, - 0.04 ); let r: vec4f = roughness * c0 + c1; let a004: f32 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; let fab: vec2f = vec2( - 1.04, 1.04 ) * a004 + r.zw; return fab; } struct IBLGGXFresnel { FssEss: vec3f, FmsEms: vec3f } struct TotalScattering { single: vec3f, multi: vec3f, } fn computeMultiscattering( normal: vec3f, viewDirection: vec3f, specularColor: vec3f, f90: f32, roughness: f32, ptr_totalScattering: ptr<function, IBLGGXFresnel> ) { let fab: vec2f = DFGApprox( normal, viewDirection, roughness ); let Fr: vec3f = specularColor; let FssEss: vec3f = Fr * fab.x + f90 * fab.y; let Ess: f32 = fab.x + fab.y; let Ems: f32 = 1.0 - Ess; let Favg: vec3f = Fr + ( 1.0 - Fr ) * 0.047619; // 1/21 let Fms: vec3f = FssEss * Favg / ( 1.0 - Ems * Favg ); (*ptr_totalScattering).FssEss += FssEss; (*ptr_totalScattering).FmsEms += Fms * Ems; } fn getIBLGGXFresnel( normal: vec3f, viewDirection: vec3f, roughness: f32, f0: vec3f, specularWeight: f32, clampSampler: sampler, lutTexture: texture_2d<f32> ) -> IBLGGXFresnel { var iBLGGXFresnel: IBLGGXFresnel; let NdotV: f32 = saturate(dot(normal, viewDirection)); let brdfSamplePoint: vec2f = saturate(vec2(NdotV, roughness)); let brdf: vec3f = textureSample( lutTexture, clampSampler, brdfSamplePoint ).rgb; let Fr: vec3f = max(vec3(1.0 - roughness), f0) - f0; let k_S: vec3f = f0 + Fr * pow(1.0 - NdotV, 5.0); iBLGGXFresnel.FssEss = specularWeight * (k_S * brdf.x + brdf.y); let Ems: f32 = (1.0 - (brdf.x + brdf.y)); let F_avg: vec3f = specularWeight * (f0 + (1.0 - f0) / 21.0); iBLGGXFresnel.FmsEms = Ems * iBLGGXFresnel.FssEss * F_avg / (1.0 - F_avg * Ems); return iBLGGXFresnel; } ` ); export { getIBLGGXFresnel };