Skip to content

Commit 27e3dd4

Browse files
author
Mike Bond
committed
WebGPU OpenPBR base layer support for direct lighting
1 parent 4c7243a commit 27e3dd4

39 files changed

+1022
-1339
lines changed

packages/dev/core/src/Shaders/ShadersInclude/openpbrBlockAmbientOcclusion.fx

Lines changed: 0 additions & 30 deletions
This file was deleted.

packages/dev/core/src/Shaders/ShadersInclude/openpbrDirectLighting.fx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,12 @@
4848
slab_metal = computeAreaSpecularLighting(preInfo{X}, light{X}.vLightSpecular.rgb, baseConductorReflectance.F0, baseConductorReflectance.F90);
4949
#else
5050
{
51-
vec3 coloredFresnel;
5251
// For OpenPBR, we use the F82 specular model for metallic materials and mix with the
5352
// usual Schlick lobe.
5453
#if (CONDUCTOR_SPECULAR_MODEL == CONDUCTOR_SPECULAR_MODEL_OPENPBR)
55-
coloredFresnel = specular_weight * getF82Specular(preInfo{X}.VdotH, baseConductorReflectance.coloredF0, baseConductorReflectance.coloredF90, specular_roughness);
54+
vec3 coloredFresnel = specular_weight * getF82Specular(preInfo{X}.VdotH, baseConductorReflectance.coloredF0, baseConductorReflectance.coloredF90, specular_roughness);
5655
#else
57-
coloredFresnel = fresnelSchlickGGX(preInfo{X}.VdotH, baseConductorReflectance.coloredF0, baseConductorReflectance.coloredF90);
56+
vec3 coloredFresnel = fresnelSchlickGGX(preInfo{X}.VdotH, baseConductorReflectance.coloredF0, baseConductorReflectance.coloredF90);
5857
#endif
5958

6059
#ifdef ANISOTROPIC
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// _____________________________ Base Diffuse Layer IBL _______________________________________
2+
#ifdef REFLECTION
3+
// Pass in a vector to sample teh irradiance with (to handle reflection or )
4+
vec3 baseDiffuseEnvironmentLight = sampleIrradiance(
5+
normalW
6+
#if defined(NORMAL) && defined(USESPHERICALINVERTEX)
7+
, vEnvironmentIrradiance
8+
#endif
9+
#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))
10+
, reflectionMatrix
11+
#endif
12+
#ifdef USEIRRADIANCEMAP
13+
, irradianceSampler
14+
#ifdef USE_IRRADIANCE_DOMINANT_DIRECTION
15+
, vReflectionDominantDirection
16+
#endif
17+
#endif
18+
#ifdef REALTIME_FILTERING
19+
, vReflectionFilteringInfo
20+
#ifdef IBL_CDF_FILTERING
21+
, icdfSampler
22+
#endif
23+
#endif
24+
, vReflectionInfos
25+
, viewDirectionW
26+
, base_diffuse_roughness
27+
, base_color
28+
);
29+
30+
// _____________________________ Base Specular Layer IBL _______________________________________
31+
32+
#ifdef REFLECTIONMAP_3D
33+
vec3 reflectionCoords = vec3(0., 0., 0.);
34+
#else
35+
vec2 reflectionCoords = vec2(0., 0.);
36+
#endif
37+
reflectionCoords = createReflectionCoords(vPositionW, normalW);
38+
float specularAlphaG = specular_roughness * specular_roughness;
39+
vec3 baseSpecularEnvironmentLight = sampleRadiance(specularAlphaG, vReflectionMicrosurfaceInfos.rgb, vReflectionInfos
40+
#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)
41+
, baseGeoInfo.NdotVUnclamped
42+
#endif
43+
, reflectionSampler
44+
, reflectionCoords
45+
#ifdef REALTIME_FILTERING
46+
, vReflectionFilteringInfo
47+
#endif
48+
);
49+
50+
baseSpecularEnvironmentLight = mix(baseSpecularEnvironmentLight.rgb, baseDiffuseEnvironmentLight, specularAlphaG);
51+
52+
vec3 coatEnvironmentLight = vec3(0., 0., 0.);
53+
if (coat_weight > 0.0) {
54+
#ifdef REFLECTIONMAP_3D
55+
vec3 reflectionCoords = vec3(0., 0., 0.);
56+
#else
57+
vec2 reflectionCoords = vec2(0., 0.);
58+
#endif
59+
reflectionCoords = createReflectionCoords(vPositionW, coatNormalW);
60+
float coatAlphaG = coat_roughness * coat_roughness;
61+
coatEnvironmentLight = sampleRadiance(coatAlphaG, vReflectionMicrosurfaceInfos.rgb, vReflectionInfos
62+
#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)
63+
, coatGeoInfo.NdotVUnclamped
64+
#endif
65+
, reflectionSampler
66+
, reflectionCoords
67+
#ifdef REALTIME_FILTERING
68+
, vReflectionFilteringInfo
69+
#endif
70+
);
71+
}
72+
73+
// ______________________________ IBL Fresnel Reflectance ____________________________
74+
75+
// Dielectric IBL Fresnel
76+
// The colored fresnel represents the % of light reflected by the base specular lobe
77+
// The non-colored fresnel represents the % of light that doesn't penetrate through
78+
// the base specular lobe. i.e. the specular lobe isn't energy conserving for coloured specular.
79+
float dielectricIblFresnel = getReflectanceFromBRDFLookup(vec3(baseDielectricReflectance.F0), vec3(baseDielectricReflectance.F90), baseGeoInfo.environmentBrdf).r;
80+
vec3 dielectricIblColoredFresnel = getReflectanceFromBRDFLookup(baseDielectricReflectance.coloredF0, baseDielectricReflectance.coloredF90, baseGeoInfo.environmentBrdf);
81+
82+
// Conductor IBL Fresnel
83+
vec3 conductorIblFresnel = conductorIblFresnel(baseConductorReflectance, baseGeoInfo.NdotV, specular_roughness, baseGeoInfo.environmentBrdf);
84+
85+
// Coat IBL Fresnel
86+
float coatIblFresnel = 0.0;
87+
if (coat_weight > 0.0) {
88+
coatIblFresnel = getReflectanceFromBRDFLookup(vec3(coatReflectance.F0), vec3(coatReflectance.F90), coatGeoInfo.environmentBrdf).r;
89+
}
90+
91+
92+
vec3 slab_diffuse_ibl = vec3(0., 0., 0.);
93+
vec3 slab_glossy_ibl = vec3(0., 0., 0.);
94+
vec3 slab_metal_ibl = vec3(0., 0., 0.);
95+
vec3 slab_coat_ibl = vec3(0., 0., 0.);
96+
97+
slab_diffuse_ibl = baseDiffuseEnvironmentLight * vLightingIntensity.z;
98+
slab_diffuse_ibl *= aoOut.ambientOcclusionColor;
99+
100+
// Add the specular environment light
101+
slab_glossy_ibl = baseSpecularEnvironmentLight * vLightingIntensity.z;
102+
103+
// _____________________________ Metal Layer IBL ____________________________
104+
slab_metal_ibl = baseSpecularEnvironmentLight * conductorIblFresnel * vLightingIntensity.z;
105+
106+
// _____________________________ Coat Layer IBL _____________________________
107+
if (coat_weight > 0.0) {
108+
slab_coat_ibl = coatEnvironmentLight * vLightingIntensity.z;
109+
}
110+
111+
// TEMP
112+
vec3 slab_subsurface_ibl = vec3(0., 0., 0.);
113+
vec3 slab_translucent_base_ibl = vec3(0., 0., 0.);
114+
vec3 slab_fuzz_ibl = vec3(0., 0., 0.);
115+
116+
slab_diffuse_ibl *= base_color.rgb;
117+
118+
// _____________________________ IBL Material Layer Composition ______________________________________
119+
#define CUSTOM_FRAGMENT_BEFORE_IBLLAYERCOMPOSITION
120+
vec3 material_opaque_base_ibl = mix(slab_diffuse_ibl, slab_subsurface_ibl, subsurface_weight);
121+
vec3 material_dielectric_base_ibl = mix(material_opaque_base_ibl, slab_translucent_base_ibl, transmission_weight);
122+
vec3 material_dielectric_gloss_ibl = layer(material_dielectric_base_ibl, slab_glossy_ibl, dielectricIblFresnel, vec3(1.0), specular_color);
123+
vec3 material_base_substrate_ibl = mix(material_dielectric_gloss_ibl, slab_metal_ibl, base_metalness);
124+
vec3 material_coated_base_ibl = layer(material_base_substrate_ibl, slab_coat_ibl, coatIblFresnel, coat_color, vec3(1.0));
125+
material_surface_ibl = mix(material_coated_base_ibl, slab_fuzz_ibl, fuzz_weight);
126+
127+
#endif

packages/dev/core/src/Shaders/ShadersInclude/openpbrIblFunctions.fx

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
vec3 sampleIrradiance(
66
in vec3 surfaceNormal
77
#if defined(NORMAL) && defined(USESPHERICALINVERTEX)
8-
, in vec3 vEnvironmentIrradiance
8+
, in vec3 vEnvironmentIrradianceSH
99
#endif
1010
#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))
1111
, in mat4 iblMatrix
@@ -34,8 +34,8 @@
3434
vec3 environmentIrradiance = vec3(0., 0., 0.);
3535

3636
#if (defined(USESPHERICALFROMREFLECTIONMAP) && (!defined(NORMAL) || !defined(USESPHERICALINVERTEX))) || (defined(USEIRRADIANCEMAP) && defined(REFLECTIONMAP_3D))
37-
vec3 irradianceVector = vec3(iblMatrix * vec4(surfaceNormal, 0)).xyz;
38-
vec3 irradianceView = vec3(iblMatrix * vec4(viewDirectionW, 0)).xyz;
37+
vec3 irradianceVector = (iblMatrix * vec4(surfaceNormal, 0)).xyz;
38+
vec3 irradianceView = (iblMatrix * vec4(viewDirectionW, 0)).xyz;
3939
#if !defined(USE_IRRADIANCE_DOMINANT_DIRECTION) && !defined(REALTIME_FILTERING)
4040
// Approximate diffuse roughness by bending the surface normal away from the view.
4141
#if BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LAMBERT && BASE_DIFFUSE_MODEL != BRDF_DIFFUSE_MODEL_LEGACY
@@ -56,7 +56,7 @@
5656
#endif
5757
#ifdef USESPHERICALFROMREFLECTIONMAP
5858
#if defined(NORMAL) && defined(USESPHERICALINVERTEX)
59-
environmentIrradiance = vEnvironmentIrradiance;
59+
environmentIrradiance = vEnvironmentIrradianceSH;
6060
#else
6161
#if defined(REALTIME_FILTERING)
6262
environmentIrradiance = irradiance(reflectionSampler, irradianceVector, vReflectionFilteringInfo, diffuseRoughness, surfaceAlbedo, irradianceView
@@ -182,22 +182,6 @@
182182
// Apply environment convolution scale/offset filter tuning parameters to the mipmap LOD selection
183183
reflectionLOD = reflectionLOD * vReflectionMicrosurfaceInfos.y + vReflectionMicrosurfaceInfos.z;
184184

185-
#ifdef LODINREFLECTIONALPHA
186-
// Automatic LOD adjustment to ensure that the smoothness-based environment LOD selection
187-
// is constrained to appropriate LOD levels in order to prevent aliasing.
188-
// The environment map is first sampled without custom LOD selection to determine
189-
// the hardware-selected LOD, and this is then used to constrain the final LOD selection
190-
// so that excessive surface smoothness does not cause aliasing (e.g. on curved geometry
191-
// where the normal is varying rapidly).
192-
193-
// Note: Shader Model 4.1 or higher can provide this directly via CalculateLevelOfDetail(), and
194-
// manual calculation via derivatives is also possible, but for simplicity we use the
195-
// hardware LOD calculation with the alpha channel containing the LOD for each mipmap.
196-
float automaticReflectionLOD = UNPACK_LOD(sampleReflection(reflectionSampler, reflectionCoords).a);
197-
float requestedReflectionLOD = max(automaticReflectionLOD, reflectionLOD);
198-
#else
199-
float requestedReflectionLOD = reflectionLOD;
200-
#endif
201185
#ifdef REALTIME_FILTERING
202186
environmentRadiance = vec4(radiance(alphaG, reflectionSampler, reflectionCoords, vReflectionFilteringInfo), 1.0);
203187
#else
@@ -213,7 +197,7 @@
213197
#endif
214198

215199
// _____________________________ Levels _____________________________________
216-
environmentRadiance.rgb *= vReflectionInfos.x;
200+
environmentRadiance.rgb *= vec3(vReflectionInfos.x);
217201
return environmentRadiance.rgb;
218202
}
219203

packages/dev/core/src/Shaders/ShadersInclude/openpbrNormalMapFragment.js

Lines changed: 0 additions & 63 deletions
This file was deleted.

packages/dev/core/src/Shaders/ShadersInclude/openpbrNormalMapFragment.js.map

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)