@luma.gl/shadertools 9.1.0-alpha.15 → 9.1.0-alpha.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +322 -389
- package/dist/dist.min.js +229 -336
- package/dist/index.cjs +321 -391
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/lib/shader-module/shader-module.d.ts +25 -15
- package/dist/lib/shader-module/shader-module.d.ts.map +1 -1
- package/dist/lib/shader-module/shader-module.js +18 -4
- package/dist/lib/shader-module/shader-pass.d.ts +4 -2
- package/dist/lib/shader-module/shader-pass.d.ts.map +1 -1
- package/dist/lib/utils/uniform-types.d.ts +11 -0
- package/dist/lib/utils/uniform-types.d.ts.map +1 -0
- package/dist/lib/utils/uniform-types.js +1 -0
- package/dist/module-injectors.d.ts +1 -1
- package/dist/module-injectors.d.ts.map +1 -1
- package/dist/module-injectors.js +5 -5
- package/dist/modules/engine/picking/picking.d.ts +7 -7
- package/dist/modules/engine/picking/picking.d.ts.map +1 -1
- package/dist/modules/engine/picking/picking.js +2 -2
- package/dist/modules/engine/project/project.d.ts +9 -8
- package/dist/modules/engine/project/project.d.ts.map +1 -1
- package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts +3 -57
- package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts.map +1 -1
- package/dist/modules/lighting/gouraud-material/gouraud-material.js +9 -6
- package/dist/modules/lighting/lights/lighting-uniforms-glsl.d.ts +1 -1
- package/dist/modules/lighting/lights/lighting-uniforms-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting-uniforms-glsl.js +35 -12
- package/dist/modules/lighting/lights/lighting.d.ts +55 -29
- package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting.js +47 -35
- package/dist/modules/lighting/no-material/dirlight.d.ts +3 -3
- package/dist/modules/lighting/no-material/dirlight.d.ts.map +1 -1
- package/dist/modules/lighting/no-material/dirlight.js +1 -1
- package/dist/modules/lighting/pbr-material/pbr-fragment-glsl.d.ts +1 -1
- package/dist/modules/lighting/pbr-material/pbr-fragment-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-fragment-glsl.js +56 -60
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts +56 -98
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material.js +14 -22
- package/dist/modules/lighting/pbr-material/pbr-projection.d.ts +10 -0
- package/dist/modules/lighting/pbr-material/pbr-projection.d.ts.map +1 -0
- package/dist/modules/lighting/pbr-material/pbr-projection.js +24 -0
- package/dist/modules/lighting/pbr-material/pbr-vertex-glsl.d.ts +1 -1
- package/dist/modules/lighting/pbr-material/pbr-vertex-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-vertex-glsl.js +8 -16
- package/dist/modules/lighting/phong-material/phong-material.d.ts +5 -59
- package/dist/modules/lighting/phong-material/phong-material.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-material.js +6 -4
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts +1 -40
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.js +8 -87
- package/dist/modules/module-injectors.d.ts +1 -1
- package/dist/modules/module-injectors.d.ts.map +1 -1
- package/dist/modules/module-injectors.js +5 -5
- package/dist/modules-webgl1/project/project.d.ts +6 -4
- package/dist/modules-webgl1/project/project.d.ts.map +1 -1
- package/dist/passes/postprocessing/fxaa/fxaa.d.ts +2 -2
- package/dist/passes/postprocessing/fxaa/fxaa.d.ts.map +1 -1
- package/dist/passes/postprocessing/fxaa/fxaa.js +2 -2
- package/dist/passes/postprocessing/image-adjust-filters/brightnesscontrast.d.ts +7 -4
- package/dist/passes/postprocessing/image-adjust-filters/brightnesscontrast.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/brightnesscontrast.js +7 -4
- package/dist/passes/postprocessing/image-adjust-filters/denoise.d.ts +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/denoise.js +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/huesaturation.d.ts +2 -3
- package/dist/passes/postprocessing/image-adjust-filters/huesaturation.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/huesaturation.js +2 -3
- package/dist/passes/postprocessing/image-adjust-filters/noise.d.ts +2 -2
- package/dist/passes/postprocessing/image-adjust-filters/noise.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/noise.js +2 -6
- package/dist/passes/postprocessing/image-adjust-filters/sepia.d.ts +2 -2
- package/dist/passes/postprocessing/image-adjust-filters/sepia.js +2 -2
- package/dist/passes/postprocessing/image-adjust-filters/vibrance.d.ts +5 -2
- package/dist/passes/postprocessing/image-adjust-filters/vibrance.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/vibrance.js +5 -2
- package/dist/passes/postprocessing/image-adjust-filters/vignette.d.ts +6 -2
- package/dist/passes/postprocessing/image-adjust-filters/vignette.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-adjust-filters/vignette.js +6 -6
- package/dist/passes/postprocessing/image-blur-filters/tiltshift.d.ts +3 -3
- package/dist/passes/postprocessing/image-blur-filters/tiltshift.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-blur-filters/tiltshift.js +1 -1
- package/dist/passes/postprocessing/image-blur-filters/triangleblur.d.ts +2 -2
- package/dist/passes/postprocessing/image-blur-filters/triangleblur.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-blur-filters/triangleblur.js +1 -1
- package/dist/passes/postprocessing/image-blur-filters/zoomblur.d.ts +2 -2
- package/dist/passes/postprocessing/image-blur-filters/zoomblur.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-blur-filters/zoomblur.js +1 -1
- package/dist/passes/postprocessing/image-fun-filters/colorhalftone.d.ts +3 -3
- package/dist/passes/postprocessing/image-fun-filters/colorhalftone.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/colorhalftone.js +2 -2
- package/dist/passes/postprocessing/image-fun-filters/dotscreen.d.ts +3 -3
- package/dist/passes/postprocessing/image-fun-filters/dotscreen.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/dotscreen.js +2 -2
- package/dist/passes/postprocessing/image-fun-filters/edgework.d.ts +16 -12
- package/dist/passes/postprocessing/image-fun-filters/edgework.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/edgework.js +25 -13
- package/dist/passes/postprocessing/image-fun-filters/hexagonalpixelate.d.ts +2 -2
- package/dist/passes/postprocessing/image-fun-filters/hexagonalpixelate.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/hexagonalpixelate.js +1 -1
- package/dist/passes/postprocessing/image-fun-filters/ink.d.ts +1 -1
- package/dist/passes/postprocessing/image-fun-filters/ink.js +1 -1
- package/dist/passes/postprocessing/image-fun-filters/magnify.d.ts +3 -3
- package/dist/passes/postprocessing/image-fun-filters/magnify.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-fun-filters/magnify.js +1 -1
- package/dist/passes/postprocessing/image-warp-filters/bulgepinch.d.ts +2 -2
- package/dist/passes/postprocessing/image-warp-filters/bulgepinch.d.ts.map +1 -1
- package/dist/passes/postprocessing/image-warp-filters/bulgepinch.js +1 -1
- package/dist/passes/postprocessing/image-warp-filters/swirl.d.ts +1 -1
- package/dist/passes/postprocessing/image-warp-filters/swirl.js +1 -1
- package/package.json +3 -3
- package/src/index.ts +9 -3
- package/src/lib/shader-module/shader-module.ts +51 -21
- package/src/lib/shader-module/shader-pass.ts +7 -4
- package/src/lib/utils/uniform-types.ts +66 -0
- package/src/module-injectors.ts +5 -5
- package/src/modules/engine/picking/README.md +9 -9
- package/src/modules/engine/picking/picking.ts +9 -9
- package/src/modules/engine/project/project.ts +10 -9
- package/src/modules/lighting/gouraud-material/gouraud-material.ts +14 -12
- package/src/modules/lighting/lights/lighting-uniforms-glsl.ts +35 -12
- package/src/modules/lighting/lights/lighting.ts +84 -54
- package/src/modules/lighting/no-material/dirlight.ts +3 -3
- package/src/modules/lighting/pbr-material/pbr-fragment-glsl.ts +56 -60
- package/src/modules/lighting/pbr-material/pbr-material.ts +40 -74
- package/src/modules/lighting/pbr-material/pbr-projection.ts +39 -0
- package/src/modules/lighting/pbr-material/pbr-vertex-glsl.ts +8 -16
- package/src/modules/lighting/phong-material/phong-material.ts +12 -12
- package/src/modules/lighting/phong-material/phong-shaders-glsl.ts +8 -88
- package/src/modules/module-injectors.ts +5 -5
- package/src/modules-webgl1/project/project.ts +8 -7
- package/src/passes/postprocessing/fxaa/fxaa.ts +3 -3
- package/src/passes/postprocessing/image-adjust-filters/brightnesscontrast.ts +7 -4
- package/src/passes/postprocessing/image-adjust-filters/denoise.ts +1 -1
- package/src/passes/postprocessing/image-adjust-filters/huesaturation.ts +2 -3
- package/src/passes/postprocessing/image-adjust-filters/noise.ts +2 -6
- package/src/passes/postprocessing/image-adjust-filters/sepia.ts +2 -2
- package/src/passes/postprocessing/image-adjust-filters/vibrance.ts +5 -2
- package/src/passes/postprocessing/image-adjust-filters/vignette.ts +6 -6
- package/src/passes/postprocessing/image-blur-filters/tiltshift.ts +3 -3
- package/src/passes/postprocessing/image-blur-filters/triangleblur.ts +2 -2
- package/src/passes/postprocessing/image-blur-filters/zoomblur.ts +2 -2
- package/src/passes/postprocessing/image-fun-filters/colorhalftone.ts +3 -3
- package/src/passes/postprocessing/image-fun-filters/dotscreen.ts +3 -3
- package/src/passes/postprocessing/image-fun-filters/edgework.ts +27 -16
- package/src/passes/postprocessing/image-fun-filters/hexagonalpixelate.ts +2 -2
- package/src/passes/postprocessing/image-fun-filters/ink.ts +1 -1
- package/src/passes/postprocessing/image-fun-filters/magnify.ts +3 -3
- package/src/passes/postprocessing/image-warp-filters/bulgepinch.ts +2 -2
- package/src/passes/postprocessing/image-warp-filters/swirl.ts +1 -1
- package/dist/modules/lighting/gouraud-material/gouraud-shaders-glsl.d.ts +0 -42
- package/dist/modules/lighting/gouraud-material/gouraud-shaders-glsl.d.ts.map +0 -1
- package/dist/modules/lighting/gouraud-material/gouraud-shaders-glsl.js +0 -134
- package/src/modules/lighting/gouraud-material/gouraud-shaders-glsl.ts +0 -137
|
@@ -9,12 +9,7 @@
|
|
|
9
9
|
export const fs = /* glsl */ `\
|
|
10
10
|
precision highp float;
|
|
11
11
|
|
|
12
|
-
uniform
|
|
13
|
-
// Projection
|
|
14
|
-
uniform vec3 u_Camera;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
uniform pbrMaterial {
|
|
12
|
+
uniform pbrMaterialUniforms {
|
|
18
13
|
// Material is unlit
|
|
19
14
|
bool unlit;
|
|
20
15
|
|
|
@@ -46,40 +41,40 @@ uniform pbrMaterial {
|
|
|
46
41
|
vec4 scaleDiffBaseMR;
|
|
47
42
|
vec4 scaleFGDSpec;
|
|
48
43
|
// #endif
|
|
49
|
-
}
|
|
44
|
+
} pbrMaterial;
|
|
50
45
|
|
|
51
46
|
// Samplers
|
|
52
47
|
#ifdef HAS_BASECOLORMAP
|
|
53
|
-
uniform sampler2D
|
|
48
|
+
uniform sampler2D pbr_baseColorSampler;
|
|
54
49
|
#endif
|
|
55
50
|
#ifdef HAS_NORMALMAP
|
|
56
|
-
uniform sampler2D
|
|
51
|
+
uniform sampler2D pbr_normalSampler;
|
|
57
52
|
#endif
|
|
58
53
|
#ifdef HAS_EMISSIVEMAP
|
|
59
|
-
uniform sampler2D
|
|
54
|
+
uniform sampler2D pbr_emissiveSampler;
|
|
60
55
|
#endif
|
|
61
56
|
#ifdef HAS_METALROUGHNESSMAP
|
|
62
|
-
uniform sampler2D
|
|
57
|
+
uniform sampler2D pbr_metallicRoughnessSampler;
|
|
63
58
|
#endif
|
|
64
59
|
#ifdef HAS_OCCLUSIONMAP
|
|
65
|
-
uniform sampler2D
|
|
60
|
+
uniform sampler2D pbr_occlusionSampler;
|
|
66
61
|
#endif
|
|
67
62
|
#ifdef USE_IBL
|
|
68
|
-
uniform samplerCube
|
|
69
|
-
uniform samplerCube
|
|
70
|
-
uniform sampler2D
|
|
63
|
+
uniform samplerCube pbr_diffuseEnvSampler;
|
|
64
|
+
uniform samplerCube pbr_specularEnvSampler;
|
|
65
|
+
uniform sampler2D pbr_brdfLUT;
|
|
71
66
|
#endif
|
|
72
67
|
|
|
73
68
|
// Inputs from vertex shader
|
|
74
69
|
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
in vec3 pbr_vPosition;
|
|
71
|
+
in vec2 pbr_vUV;
|
|
77
72
|
|
|
78
73
|
#ifdef HAS_NORMALS
|
|
79
74
|
#ifdef HAS_TANGENTS
|
|
80
|
-
|
|
75
|
+
in mat3 pbr_vTBN;
|
|
81
76
|
#else
|
|
82
|
-
|
|
77
|
+
in vec3 pbr_vNormal;
|
|
83
78
|
#endif
|
|
84
79
|
#endif
|
|
85
80
|
|
|
@@ -147,8 +142,8 @@ vec3 getNormal()
|
|
|
147
142
|
#endif
|
|
148
143
|
|
|
149
144
|
#ifdef HAS_NORMALMAP
|
|
150
|
-
vec3 n =
|
|
151
|
-
n = normalize(tbn * ((2.0 * n - 1.0) * vec3(
|
|
145
|
+
vec3 n = texture(pbr_normalSampler, pbr_vUV).rgb;
|
|
146
|
+
n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
|
|
152
147
|
#else
|
|
153
148
|
// The tbn matrix is linearly interpolated, so we need to re-normalize
|
|
154
149
|
vec3 n = normalize(tbn[2].xyz);
|
|
@@ -166,22 +161,22 @@ vec3 getIBLContribution(PBRInfo pbrInfo, vec3 n, vec3 reflection)
|
|
|
166
161
|
float mipCount = 9.0; // resolution of 512x512
|
|
167
162
|
float lod = (pbrInfo.perceptualRoughness * mipCount);
|
|
168
163
|
// retrieve a scale and bias to F0. See [1], Figure 3
|
|
169
|
-
vec3 brdf = SRGBtoLINEAR(
|
|
164
|
+
vec3 brdf = SRGBtoLINEAR(texture(pbr_brdfLUT,
|
|
170
165
|
vec2(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness))).rgb;
|
|
171
|
-
vec3 diffuseLight = SRGBtoLINEAR(
|
|
166
|
+
vec3 diffuseLight = SRGBtoLINEAR(texture(pbr_diffuseEnvSampler, n)).rgb;
|
|
172
167
|
|
|
173
168
|
#ifdef USE_TEX_LOD
|
|
174
|
-
vec3 specularLight = SRGBtoLINEAR(
|
|
169
|
+
vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection, lod)).rgb;
|
|
175
170
|
#else
|
|
176
|
-
vec3 specularLight = SRGBtoLINEAR(
|
|
171
|
+
vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection)).rgb;
|
|
177
172
|
#endif
|
|
178
173
|
|
|
179
174
|
vec3 diffuse = diffuseLight * pbrInfo.diffuseColor;
|
|
180
175
|
vec3 specular = specularLight * (pbrInfo.specularColor * brdf.x + brdf.y);
|
|
181
176
|
|
|
182
177
|
// For presentation, this allows us to disable IBL terms
|
|
183
|
-
diffuse *=
|
|
184
|
-
specular *=
|
|
178
|
+
diffuse *= pbrMaterial.scaleIBLAmbient.x;
|
|
179
|
+
specular *= pbrMaterial.scaleIBLAmbient.y;
|
|
185
180
|
|
|
186
181
|
return diffuse + specular;
|
|
187
182
|
}
|
|
@@ -273,32 +268,32 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
273
268
|
{
|
|
274
269
|
// The albedo may be defined from a base texture or a flat color
|
|
275
270
|
#ifdef HAS_BASECOLORMAP
|
|
276
|
-
vec4 baseColor = SRGBtoLINEAR(
|
|
271
|
+
vec4 baseColor = SRGBtoLINEAR(texture(pbr_baseColorSampler, pbr_vUV)) * pbrMaterial.baseColorFactor;
|
|
277
272
|
#else
|
|
278
|
-
vec4 baseColor =
|
|
273
|
+
vec4 baseColor = pbrMaterial.baseColorFactor;
|
|
279
274
|
#endif
|
|
280
275
|
|
|
281
276
|
#ifdef ALPHA_CUTOFF
|
|
282
|
-
if (baseColor.a <
|
|
277
|
+
if (baseColor.a < pbrMaterial.alphaCutoff) {
|
|
283
278
|
discard;
|
|
284
279
|
}
|
|
285
280
|
#endif
|
|
286
281
|
|
|
287
282
|
vec3 color = vec3(0, 0, 0);
|
|
288
283
|
|
|
289
|
-
if(
|
|
284
|
+
if(pbrMaterial.unlit){
|
|
290
285
|
color.rgb = baseColor.rgb;
|
|
291
286
|
}
|
|
292
287
|
else{
|
|
293
288
|
// Metallic and Roughness material properties are packed together
|
|
294
289
|
// In glTF, these factors can be specified by fixed scalar values
|
|
295
290
|
// or from a metallic-roughness map
|
|
296
|
-
float perceptualRoughness =
|
|
297
|
-
float metallic =
|
|
291
|
+
float perceptualRoughness = pbrMaterial.metallicRoughnessValues.y;
|
|
292
|
+
float metallic = pbrMaterial.metallicRoughnessValues.x;
|
|
298
293
|
#ifdef HAS_METALROUGHNESSMAP
|
|
299
294
|
// Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
|
|
300
295
|
// This layout intentionally reserves the 'r' channel for (optional) occlusion map data
|
|
301
|
-
vec4 mrSample =
|
|
296
|
+
vec4 mrSample = texture(pbr_metallicRoughnessSampler, pbr_vUV);
|
|
302
297
|
perceptualRoughness = mrSample.g * perceptualRoughness;
|
|
303
298
|
metallic = mrSample.b * metallic;
|
|
304
299
|
#endif
|
|
@@ -325,7 +320,7 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
325
320
|
vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
|
|
326
321
|
|
|
327
322
|
vec3 n = getNormal(); // normal at surface point
|
|
328
|
-
vec3 v = normalize(
|
|
323
|
+
vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
|
|
329
324
|
|
|
330
325
|
float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
331
326
|
vec3 reflection = -normalize(reflect(v, n));
|
|
@@ -347,47 +342,48 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
347
342
|
v
|
|
348
343
|
);
|
|
349
344
|
|
|
345
|
+
|
|
350
346
|
#ifdef USE_LIGHTS
|
|
351
347
|
// Apply ambient light
|
|
352
348
|
PBRInfo_setAmbientLight(pbrInfo);
|
|
353
|
-
color += calculateFinalColor(pbrInfo,
|
|
349
|
+
color += calculateFinalColor(pbrInfo, lighting.ambientColor);
|
|
354
350
|
|
|
355
351
|
// Apply directional light
|
|
356
|
-
for(int i = 0; i <
|
|
357
|
-
if (i <
|
|
358
|
-
PBRInfo_setDirectionalLight(pbrInfo,
|
|
359
|
-
color += calculateFinalColor(pbrInfo,
|
|
352
|
+
for(int i = 0; i < lighting.directionalLightCount; i++) {
|
|
353
|
+
if (i < lighting.directionalLightCount) {
|
|
354
|
+
PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
355
|
+
color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
|
|
360
356
|
}
|
|
361
357
|
}
|
|
362
358
|
|
|
363
359
|
// Apply point light
|
|
364
|
-
for(int i = 0; i <
|
|
365
|
-
if (i <
|
|
366
|
-
PBRInfo_setPointLight(pbrInfo,
|
|
367
|
-
float attenuation = getPointLightAttenuation(
|
|
368
|
-
color += calculateFinalColor(pbrInfo,
|
|
360
|
+
for(int i = 0; i < lighting.pointLightCount; i++) {
|
|
361
|
+
if (i < lighting.pointLightCount) {
|
|
362
|
+
PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
|
|
363
|
+
float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
|
|
364
|
+
color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
|
|
369
365
|
}
|
|
370
366
|
}
|
|
371
367
|
#endif
|
|
372
368
|
|
|
373
369
|
// Calculate lighting contribution from image based lighting source (IBL)
|
|
374
370
|
#ifdef USE_IBL
|
|
375
|
-
if (
|
|
371
|
+
if (pbrMaterial.IBLenabled) {
|
|
376
372
|
color += getIBLContribution(pbrInfo, n, reflection);
|
|
377
373
|
}
|
|
378
374
|
#endif
|
|
379
375
|
|
|
380
|
-
|
|
376
|
+
// Apply optional PBR terms for additional (optional) shading
|
|
381
377
|
#ifdef HAS_OCCLUSIONMAP
|
|
382
|
-
if (
|
|
383
|
-
float ao =
|
|
384
|
-
color = mix(color, color * ao,
|
|
378
|
+
if (pbrMaterial.occlusionMapEnabled) {
|
|
379
|
+
float ao = texture(pbr_occlusionSampler, pbr_vUV).r;
|
|
380
|
+
color = mix(color, color * ao, pbrMaterial.occlusionStrength);
|
|
385
381
|
}
|
|
386
382
|
#endif
|
|
387
383
|
|
|
388
384
|
#ifdef HAS_EMISSIVEMAP
|
|
389
|
-
if (
|
|
390
|
-
vec3 emissive = SRGBtoLINEAR(
|
|
385
|
+
if (pbrMaterial.emissiveMapEnabled) {
|
|
386
|
+
vec3 emissive = SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb * pbrMaterial.emissiveFactor;
|
|
391
387
|
color += emissive;
|
|
392
388
|
}
|
|
393
389
|
#endif
|
|
@@ -397,15 +393,15 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
397
393
|
#ifdef PBR_DEBUG
|
|
398
394
|
// TODO: Figure out how to debug multiple lights
|
|
399
395
|
|
|
400
|
-
// color = mix(color, F,
|
|
401
|
-
// color = mix(color, vec3(G),
|
|
402
|
-
// color = mix(color, vec3(D),
|
|
403
|
-
// color = mix(color, specContrib,
|
|
396
|
+
// color = mix(color, F, pbr_scaleFGDSpec.x);
|
|
397
|
+
// color = mix(color, vec3(G), pbr_scaleFGDSpec.y);
|
|
398
|
+
// color = mix(color, vec3(D), pbr_scaleFGDSpec.z);
|
|
399
|
+
// color = mix(color, specContrib, pbr_scaleFGDSpec.w);
|
|
404
400
|
|
|
405
|
-
// color = mix(color, diffuseContrib,
|
|
406
|
-
color = mix(color, baseColor.rgb,
|
|
407
|
-
color = mix(color, vec3(metallic),
|
|
408
|
-
color = mix(color, vec3(perceptualRoughness),
|
|
401
|
+
// color = mix(color, diffuseContrib, pbr_scaleDiffBaseMR.x);
|
|
402
|
+
color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
|
|
403
|
+
color = mix(color, vec3(metallic), pbrMaterial.scaleDiffBaseMR.z);
|
|
404
|
+
color = mix(color, vec3(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
|
|
409
405
|
#endif
|
|
410
406
|
|
|
411
407
|
}
|
|
@@ -1,55 +1,37 @@
|
|
|
1
|
-
import type { NumberArray } from '@math.gl/types';
|
|
2
1
|
import type { Texture } from '@luma.gl/core';
|
|
3
|
-
import type { Vector2, Vector3, Vector4 } from '@math.gl/core';
|
|
4
|
-
|
|
5
|
-
unlit?: boolean;
|
|
6
|
-
baseColorMapEnabled?: boolean;
|
|
7
|
-
baseColorFactor?: Readonly<Vector4 | NumberArray>;
|
|
8
|
-
normalMapEnabled?: boolean;
|
|
9
|
-
normalScale?: number;
|
|
10
|
-
emissiveMapEnabled?: boolean;
|
|
11
|
-
emissiveFactor?: Readonly<Vector3 | NumberArray>;
|
|
12
|
-
metallicRoughnessValues?: Readonly<Vector2 | NumberArray>;
|
|
13
|
-
metallicRoughnessMapEnabled?: boolean;
|
|
14
|
-
occlusionMapEnabled?: boolean;
|
|
15
|
-
occlusionStrength?: number;
|
|
16
|
-
alphaCutoffEnabled?: boolean;
|
|
17
|
-
alphaCutoff?: number;
|
|
18
|
-
IBLenabled?: boolean;
|
|
19
|
-
scaleIBLAmbient?: Readonly<Vector2 | NumberArray>;
|
|
20
|
-
scaleDiffBaseMR?: Readonly<Vector4 | NumberArray>;
|
|
21
|
-
scaleFGDSpec?: Readonly<Vector4 | NumberArray>;
|
|
22
|
-
};
|
|
2
|
+
import type { Vector2, Vector3, Vector4, NumberArray2, NumberArray3, NumberArray4 } from '@math.gl/core';
|
|
3
|
+
import { ShaderModule } from "../../../lib/shader-module/shader-module.js";
|
|
23
4
|
/** Non-uniform block bindings for pbr module */
|
|
24
|
-
type PBRMaterialBindings = {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
5
|
+
export type PBRMaterialBindings = {
|
|
6
|
+
pbr_baseColorSampler?: Texture | null;
|
|
7
|
+
pbr_normalSampler?: Texture | null;
|
|
8
|
+
pbr_emissiveSampler?: Texture | null;
|
|
9
|
+
pbr_metallicRoughnessSampler?: Texture | null;
|
|
10
|
+
pbr_occlusionSampler?: Texture | null;
|
|
11
|
+
pbr_diffuseEnvSampler?: Texture | null;
|
|
12
|
+
pbr_specularEnvSampler?: Texture | null;
|
|
13
|
+
pbr_BrdfLUT?: Texture | null;
|
|
33
14
|
};
|
|
34
15
|
export type PBRMaterialUniforms = {
|
|
35
16
|
unlit?: boolean;
|
|
36
17
|
baseColorMapEnabled?: boolean;
|
|
37
|
-
baseColorFactor?: Readonly<Vector4 |
|
|
18
|
+
baseColorFactor?: Readonly<Vector4 | NumberArray4>;
|
|
38
19
|
normalMapEnabled?: boolean;
|
|
39
20
|
normalScale?: number;
|
|
40
21
|
emissiveMapEnabled?: boolean;
|
|
41
|
-
emissiveFactor?: Readonly<Vector3 |
|
|
42
|
-
metallicRoughnessValues?: Readonly<Vector2 |
|
|
22
|
+
emissiveFactor?: Readonly<Vector3 | NumberArray3>;
|
|
23
|
+
metallicRoughnessValues?: Readonly<Vector2 | NumberArray2>;
|
|
43
24
|
metallicRoughnessMapEnabled?: boolean;
|
|
44
25
|
occlusionMapEnabled?: boolean;
|
|
45
26
|
occlusionStrength?: number;
|
|
46
27
|
alphaCutoffEnabled?: boolean;
|
|
47
28
|
alphaCutoff?: number;
|
|
48
29
|
IBLenabled?: boolean;
|
|
49
|
-
scaleIBLAmbient?: Readonly<Vector2 |
|
|
50
|
-
scaleDiffBaseMR?: Readonly<Vector4 |
|
|
51
|
-
scaleFGDSpec?: Readonly<Vector4 |
|
|
30
|
+
scaleIBLAmbient?: Readonly<Vector2 | NumberArray2>;
|
|
31
|
+
scaleDiffBaseMR?: Readonly<Vector4 | NumberArray4>;
|
|
32
|
+
scaleFGDSpec?: Readonly<Vector4 | NumberArray4>;
|
|
52
33
|
};
|
|
34
|
+
export type PBRMaterialProps = PBRMaterialBindings & PBRMaterialUniforms;
|
|
53
35
|
/**
|
|
54
36
|
* An implementation of PBR (Physically-Based Rendering).
|
|
55
37
|
* Physically Based Shading of a microfacet surface defined by a glTF material.
|
|
@@ -57,52 +39,63 @@ export type PBRMaterialUniforms = {
|
|
|
57
39
|
export declare const pbrMaterial: {
|
|
58
40
|
readonly props: PBRMaterialProps;
|
|
59
41
|
readonly uniforms: PBRMaterialUniforms;
|
|
60
|
-
readonly name: "
|
|
42
|
+
readonly name: "pbrMaterial";
|
|
61
43
|
readonly dependencies: [{
|
|
62
44
|
readonly props: import("../lights/lighting").LightingProps;
|
|
63
45
|
readonly uniforms: import("../lights/lighting").LightingUniforms;
|
|
64
46
|
readonly name: "lighting";
|
|
65
47
|
readonly defines: {
|
|
66
|
-
readonly MAX_LIGHTS:
|
|
48
|
+
readonly MAX_LIGHTS: 3;
|
|
67
49
|
};
|
|
68
50
|
readonly uniformTypes: {
|
|
69
51
|
readonly enabled: "i32";
|
|
70
|
-
readonly ambientLightColor: "vec3<f32>";
|
|
71
|
-
readonly numberOfLights: "i32";
|
|
72
52
|
readonly lightType: "i32";
|
|
73
|
-
readonly
|
|
74
|
-
readonly
|
|
75
|
-
readonly
|
|
76
|
-
readonly
|
|
53
|
+
readonly directionalLightCount: "i32";
|
|
54
|
+
readonly pointLightCount: "i32";
|
|
55
|
+
readonly ambientLightColor: "vec3<f32>";
|
|
56
|
+
readonly lightColor0: "vec3<f32>";
|
|
57
|
+
readonly lightPosition0: "vec3<f32>";
|
|
58
|
+
readonly lightDirection0: "vec3<f32>";
|
|
59
|
+
readonly lightAttenuation0: "vec3<f32>";
|
|
60
|
+
readonly lightColor1: "vec3<f32>";
|
|
61
|
+
readonly lightPosition1: "vec3<f32>";
|
|
62
|
+
readonly lightDirection1: "vec3<f32>";
|
|
63
|
+
readonly lightAttenuation1: "vec3<f32>";
|
|
64
|
+
readonly lightColor2: "vec3<f32>";
|
|
65
|
+
readonly lightPosition2: "vec3<f32>";
|
|
66
|
+
readonly lightDirection2: "vec3<f32>";
|
|
67
|
+
readonly lightAttenuation2: "vec3<f32>";
|
|
77
68
|
};
|
|
78
69
|
readonly defaultUniforms: {
|
|
79
70
|
readonly enabled: 1;
|
|
80
|
-
readonly ambientLightColor: readonly [0.1, 0.1, 0.1];
|
|
81
|
-
readonly numberOfLights: 0;
|
|
82
71
|
readonly lightType: import("../lights/lighting").LIGHT_TYPE.POINT;
|
|
83
|
-
readonly
|
|
84
|
-
readonly
|
|
85
|
-
readonly
|
|
86
|
-
readonly
|
|
72
|
+
readonly directionalLightCount: 0;
|
|
73
|
+
readonly pointLightCount: 0;
|
|
74
|
+
readonly ambientLightColor: readonly [0.1, 0.1, 0.1];
|
|
75
|
+
readonly lightColor0: readonly [1, 1, 1];
|
|
76
|
+
readonly lightPosition0: readonly [1, 1, 2];
|
|
77
|
+
readonly lightDirection0: readonly [1, 1, 1];
|
|
78
|
+
readonly lightAttenuation0: readonly [1, 0, 0];
|
|
79
|
+
readonly lightColor1: readonly [1, 1, 1];
|
|
80
|
+
readonly lightPosition1: readonly [1, 1, 2];
|
|
81
|
+
readonly lightDirection1: readonly [1, 1, 1];
|
|
82
|
+
readonly lightAttenuation1: readonly [1, 0, 0];
|
|
83
|
+
readonly lightColor2: readonly [1, 1, 1];
|
|
84
|
+
readonly lightPosition2: readonly [1, 1, 2];
|
|
85
|
+
readonly lightDirection2: readonly [1, 1, 1];
|
|
86
|
+
readonly lightAttenuation2: readonly [1, 0, 0];
|
|
87
87
|
};
|
|
88
88
|
readonly source: "// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))\nstruct AmbientLight {\n color: vec3<f32>,\n};\n\nstruct PointLight {\n color: vec3<f32>,\n position: vec3<f32>,\n attenuation: vec3<f32>, // 2nd order x:Constant-y:Linear-z:Exponential\n};\n\nstruct DirectionalLight {\n color: vec3<f32>,\n direction: vec3<f32>,\n};\n\nstruct lightingUniforms {\n enabled: i32,\n poightCount: i32,\n directionalLightCount: i32,\n\n ambientColor: vec3<f32>,\n\n // TODO - support multiple lights by uncommenting arrays below\n lightType: i32,\n lightColor: vec3<f32>,\n lightDirection: vec3<f32>,\n lightPosition: vec3<f32>,\n lightAttenuation: vec3<f32>,\n\n // AmbientLight ambientLight;\n // PointLight pointLight[MAX_LIGHTS];\n // DirectionalLight directionalLight[MAX_LIGHTS];\n};\n\n// Binding 0:1 is reserved for lighting (Note: could go into separate bind group as it is stable across draw calls)\n@binding(1) @group(0) var<uniform> lighting : lightingUniforms;\n\nfn lighting_getPointLight(index: i32) -> PointLight {\n return PointLight(lighting.lightColor, lighting.lightPosition, lighting.lightAttenuation);\n}\n\nfn lighting_getDirectionalLight(index: i32) -> DirectionalLight {\n return DirectionalLight(lighting.lightColor, lighting.lightDirection);\n} \n\nfn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {\n return pointLight.attenuation.x\n + pointLight.attenuation.y * distance\n + pointLight.attenuation.z * distance * distance;\n}\n";
|
|
89
|
-
readonly vs: "precision highp int;\n\n// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))\nstruct AmbientLight {\n vec3 color;\n};\n\nstruct PointLight {\n vec3 color;\n vec3 position;\n vec3 attenuation; // 2nd order x:Constant-y:Linear-z:Exponential\n};\n\nstruct DirectionalLight {\n vec3 color;\n vec3 direction;\n};\n\nuniform lightingUniforms {\n int enabled;\n int
|
|
90
|
-
readonly fs: "precision highp int;\n\n// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))\nstruct AmbientLight {\n vec3 color;\n};\n\nstruct PointLight {\n vec3 color;\n vec3 position;\n vec3 attenuation; // 2nd order x:Constant-y:Linear-z:Exponential\n};\n\nstruct DirectionalLight {\n vec3 color;\n vec3 direction;\n};\n\nuniform lightingUniforms {\n int enabled;\n int
|
|
89
|
+
readonly vs: "precision highp int;\n\n// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))\nstruct AmbientLight {\n vec3 color;\n};\n\nstruct PointLight {\n vec3 color;\n vec3 position;\n vec3 attenuation; // 2nd order x:Constant-y:Linear-z:Exponential\n};\n\nstruct DirectionalLight {\n vec3 color;\n vec3 direction;\n};\n\nuniform lightingUniforms {\n int enabled;\n int lightType;\n\n int directionalLightCount;\n int pointLightCount;\n\n vec3 ambientColor;\n\n vec3 lightColor0;\n vec3 lightPosition0;\n vec3 lightDirection0;\n vec3 lightAttenuation0;\n\n vec3 lightColor1;\n vec3 lightPosition1;\n vec3 lightDirection1;\n vec3 lightAttenuation1;\n\n vec3 lightColor2;\n vec3 lightPosition2;\n vec3 lightDirection2;\n vec3 lightAttenuation2;\n} lighting;\n\nPointLight lighting_getPointLight(int index) {\n switch (index) {\n case 0:\n return PointLight(lighting.lightColor0, lighting.lightPosition0, lighting.lightAttenuation0);\n case 1:\n return PointLight(lighting.lightColor1, lighting.lightPosition1, lighting.lightAttenuation1);\n case 2:\n default: \n return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2);\n }\n}\n\nDirectionalLight lighting_getDirectionalLight(int index) {\n switch (index) {\n case 0:\n return DirectionalLight(lighting.lightColor0, lighting.lightDirection0);\n case 1:\n return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);\n case 2:\n default: \n return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);\n }\n} \n\nfloat getPointLightAttenuation(PointLight pointLight, float distance) {\n return pointLight.attenuation.x\n + pointLight.attenuation.y * distance\n + pointLight.attenuation.z * distance * distance;\n}\n\n// #endif\n";
|
|
90
|
+
readonly fs: "precision highp int;\n\n// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))\nstruct AmbientLight {\n vec3 color;\n};\n\nstruct PointLight {\n vec3 color;\n vec3 position;\n vec3 attenuation; // 2nd order x:Constant-y:Linear-z:Exponential\n};\n\nstruct DirectionalLight {\n vec3 color;\n vec3 direction;\n};\n\nuniform lightingUniforms {\n int enabled;\n int lightType;\n\n int directionalLightCount;\n int pointLightCount;\n\n vec3 ambientColor;\n\n vec3 lightColor0;\n vec3 lightPosition0;\n vec3 lightDirection0;\n vec3 lightAttenuation0;\n\n vec3 lightColor1;\n vec3 lightPosition1;\n vec3 lightDirection1;\n vec3 lightAttenuation1;\n\n vec3 lightColor2;\n vec3 lightPosition2;\n vec3 lightDirection2;\n vec3 lightAttenuation2;\n} lighting;\n\nPointLight lighting_getPointLight(int index) {\n switch (index) {\n case 0:\n return PointLight(lighting.lightColor0, lighting.lightPosition0, lighting.lightAttenuation0);\n case 1:\n return PointLight(lighting.lightColor1, lighting.lightPosition1, lighting.lightAttenuation1);\n case 2:\n default: \n return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2);\n }\n}\n\nDirectionalLight lighting_getDirectionalLight(int index) {\n switch (index) {\n case 0:\n return DirectionalLight(lighting.lightColor0, lighting.lightDirection0);\n case 1:\n return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);\n case 2:\n default: \n return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);\n }\n} \n\nfloat getPointLightAttenuation(PointLight pointLight, float distance) {\n return pointLight.attenuation.x\n + pointLight.attenuation.y * distance\n + pointLight.attenuation.z * distance * distance;\n}\n\n// #endif\n";
|
|
91
91
|
readonly getUniforms: (props?: import("../lights/lighting").LightingProps, prevUniforms?: Partial<import("../lights/lighting").LightingUniforms>) => import("../lights/lighting").LightingUniforms;
|
|
92
|
-
}];
|
|
93
|
-
readonly vs: "
|
|
94
|
-
readonly fs: "precision highp float;\n\nuniform Projection {\n // Projection\n uniform vec3 u_Camera;\n};\n\nuniform pbrMaterial {\n // Material is unlit\n bool unlit;\n\n // Base color map\n bool baseColorMapEnabled;\n vec4 baseColorFactor;\n\n bool normalMapEnabled; \n float normalScale; // #ifdef HAS_NORMALMAP\n\n bool emissiveMapEnabled;\n vec3 emissiveFactor; // #ifdef HAS_EMISSIVEMAP\n\n vec2 metallicRoughnessValues;\n bool metallicRoughnessMapEnabled;\n\n bool occlusionMapEnabled;\n float occlusionStrength; // #ifdef HAS_OCCLUSIONMAP\n \n bool alphaCutoffEnabled;\n float alphaCutoff; // #ifdef ALPHA_CUTOFF\n \n // IBL\n bool IBLenabled;\n vec2 scaleIBLAmbient; // #ifdef USE_IBL\n \n // debugging flags used for shader output of intermediate PBR variables\n // #ifdef PBR_DEBUG\n vec4 scaleDiffBaseMR;\n vec4 scaleFGDSpec;\n // #endif\n} u_pbrMaterial;\n\n// Samplers\n#ifdef HAS_BASECOLORMAP\nuniform sampler2D u_BaseColorSampler;\n#endif\n#ifdef HAS_NORMALMAP\nuniform sampler2D u_NormalSampler;\n#endif\n#ifdef HAS_EMISSIVEMAP\nuniform sampler2D u_EmissiveSampler;\n#endif\n#ifdef HAS_METALROUGHNESSMAP\nuniform sampler2D u_MetallicRoughnessSampler;\n#endif\n#ifdef HAS_OCCLUSIONMAP\nuniform sampler2D u_OcclusionSampler;\n#endif\n#ifdef USE_IBL\nuniform samplerCube u_DiffuseEnvSampler;\nuniform samplerCube u_SpecularEnvSampler;\nuniform sampler2D u_brdfLUT;\n#endif\n\n// Inputs from vertex shader\n\nvarying vec3 pbr_vPosition;\nvarying vec2 pbr_vUV;\n\n#ifdef HAS_NORMALS\n#ifdef HAS_TANGENTS\nvarying mat3 pbr_vTBN;\n#else\nvarying vec3 pbr_vNormal;\n#endif\n#endif\n\n// Encapsulate the various inputs used by the various functions in the shading equation\n// We store values in this struct to simplify the integration of alternative implementations\n// of the shading terms, outlined in the Readme.MD Appendix.\nstruct PBRInfo {\n float NdotL; // cos angle between normal and light direction\n float NdotV; // cos angle between normal and view direction\n float NdotH; // cos angle between normal and half vector\n float LdotH; // cos angle between light direction and half vector\n float VdotH; // cos angle between view direction and half vector\n float perceptualRoughness; // roughness value, as authored by the model creator (input to shader)\n float metalness; // metallic value at the surface\n vec3 reflectance0; // full reflectance color (normal incidence angle)\n vec3 reflectance90; // reflectance color at grazing angle\n float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2])\n vec3 diffuseColor; // color contribution from diffuse lighting\n vec3 specularColor; // color contribution from specular lighting\n vec3 n; // normal at surface point\n vec3 v; // vector from surface point to camera\n};\n\nconst float M_PI = 3.141592653589793;\nconst float c_MinRoughness = 0.04;\n\nvec4 SRGBtoLINEAR(vec4 srgbIn)\n{\n#ifdef MANUAL_SRGB\n#ifdef SRGB_FAST_APPROXIMATION\n vec3 linOut = pow(srgbIn.xyz,vec3(2.2));\n#else // SRGB_FAST_APPROXIMATION\n vec3 bLess = step(vec3(0.04045),srgbIn.xyz);\n vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess );\n#endif //SRGB_FAST_APPROXIMATION\n return vec4(linOut,srgbIn.w);;\n#else //MANUAL_SRGB\n return srgbIn;\n#endif //MANUAL_SRGB\n}\n\n// Find the normal for this fragment, pulling either from a predefined normal map\n// or from the interpolated mesh normal and tangent attributes.\nvec3 getNormal()\n{\n // Retrieve the tangent space matrix\n#ifndef HAS_TANGENTS\n vec3 pos_dx = dFdx(pbr_vPosition);\n vec3 pos_dy = dFdy(pbr_vPosition);\n vec3 tex_dx = dFdx(vec3(pbr_vUV, 0.0));\n vec3 tex_dy = dFdy(vec3(pbr_vUV, 0.0));\n vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);\n\n#ifdef HAS_NORMALS\n vec3 ng = normalize(pbr_vNormal);\n#else\n vec3 ng = cross(pos_dx, pos_dy);\n#endif\n\n t = normalize(t - ng * dot(ng, t));\n vec3 b = normalize(cross(ng, t));\n mat3 tbn = mat3(t, b, ng);\n#else // HAS_TANGENTS\n mat3 tbn = pbr_vTBN;\n#endif\n\n#ifdef HAS_NORMALMAP\n vec3 n = texture2D(u_NormalSampler, pbr_vUV).rgb;\n n = normalize(tbn * ((2.0 * n - 1.0) * vec3(u_pbrMaterial.normalScale, u_pbrMaterial.normalScale, 1.0)));\n#else\n // The tbn matrix is linearly interpolated, so we need to re-normalize\n vec3 n = normalize(tbn[2].xyz);\n#endif\n\n return n;\n}\n\n// Calculation of the lighting contribution from an optional Image Based Light source.\n// Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].\n// See our README.md on Environment Maps [3] for additional discussion.\n#ifdef USE_IBL\nvec3 getIBLContribution(PBRInfo pbrInfo, vec3 n, vec3 reflection)\n{\n float mipCount = 9.0; // resolution of 512x512\n float lod = (pbrInfo.perceptualRoughness * mipCount);\n // retrieve a scale and bias to F0. See [1], Figure 3\n vec3 brdf = SRGBtoLINEAR(texture2D(u_brdfLUT,\n vec2(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness))).rgb;\n vec3 diffuseLight = SRGBtoLINEAR(textureCube(u_DiffuseEnvSampler, n)).rgb;\n\n#ifdef USE_TEX_LOD\n vec3 specularLight = SRGBtoLINEAR(textureCubeLod(u_SpecularEnvSampler, reflection, lod)).rgb;\n#else\n vec3 specularLight = SRGBtoLINEAR(textureCube(u_SpecularEnvSampler, reflection)).rgb;\n#endif\n\n vec3 diffuse = diffuseLight * pbrInfo.diffuseColor;\n vec3 specular = specularLight * (pbrInfo.specularColor * brdf.x + brdf.y);\n\n // For presentation, this allows us to disable IBL terms\n diffuse *= u_pbrMaterial.scaleIBLAmbient.x;\n specular *= u_pbrMaterial.scaleIBLAmbient.y;\n\n return diffuse + specular;\n}\n#endif\n\n// Basic Lambertian diffuse\n// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog\n// See also [1], Equation 1\nvec3 diffuse(PBRInfo pbrInfo)\n{\n return pbrInfo.diffuseColor / M_PI;\n}\n\n// The following equation models the Fresnel reflectance term of the spec equation (aka F())\n// Implementation of fresnel from [4], Equation 15\nvec3 specularReflection(PBRInfo pbrInfo)\n{\n return pbrInfo.reflectance0 +\n (pbrInfo.reflectance90 - pbrInfo.reflectance0) *\n pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);\n}\n\n// This calculates the specular geometric attenuation (aka G()),\n// where rougher material will reflect less light back to the viewer.\n// This implementation is based on [1] Equation 4, and we adopt their modifications to\n// alphaRoughness as input as originally proposed in [2].\nfloat geometricOcclusion(PBRInfo pbrInfo)\n{\n float NdotL = pbrInfo.NdotL;\n float NdotV = pbrInfo.NdotV;\n float r = pbrInfo.alphaRoughness;\n\n float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));\n float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));\n return attenuationL * attenuationV;\n}\n\n// The following equation(s) model the distribution of microfacet normals across\n// the area being drawn (aka D())\n// Implementation from \"Average Irregularity Representation of a Roughened Surface\n// for Ray Reflection\" by T. S. Trowbridge, and K. P. Reitz\n// Follows the distribution function recommended in the SIGGRAPH 2013 course notes\n// from EPIC Games [1], Equation 3.\nfloat microfacetDistribution(PBRInfo pbrInfo)\n{\n float roughnessSq = pbrInfo.alphaRoughness * pbrInfo.alphaRoughness;\n float f = (pbrInfo.NdotH * roughnessSq - pbrInfo.NdotH) * pbrInfo.NdotH + 1.0;\n return roughnessSq / (M_PI * f * f);\n}\n\nvoid PBRInfo_setAmbientLight(inout PBRInfo pbrInfo) {\n pbrInfo.NdotL = 1.0;\n pbrInfo.NdotH = 0.0;\n pbrInfo.LdotH = 0.0;\n pbrInfo.VdotH = 1.0;\n}\n\nvoid PBRInfo_setDirectionalLight(inout PBRInfo pbrInfo, vec3 lightDirection) {\n vec3 n = pbrInfo.n;\n vec3 v = pbrInfo.v;\n vec3 l = normalize(lightDirection); // Vector from surface point to light\n vec3 h = normalize(l+v); // Half vector between both l and v\n\n pbrInfo.NdotL = clamp(dot(n, l), 0.001, 1.0);\n pbrInfo.NdotH = clamp(dot(n, h), 0.0, 1.0);\n pbrInfo.LdotH = clamp(dot(l, h), 0.0, 1.0);\n pbrInfo.VdotH = clamp(dot(v, h), 0.0, 1.0);\n}\n\nvoid PBRInfo_setPointLight(inout PBRInfo pbrInfo, PointLight pointLight) {\n vec3 light_direction = normalize(pointLight.position - pbr_vPosition);\n PBRInfo_setDirectionalLight(pbrInfo, light_direction);\n}\n\nvec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor) {\n // Calculate the shading terms for the microfacet specular shading model\n vec3 F = specularReflection(pbrInfo);\n float G = geometricOcclusion(pbrInfo);\n float D = microfacetDistribution(pbrInfo);\n\n // Calculation of analytical lighting contribution\n vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInfo);\n vec3 specContrib = F * G * D / (4.0 * pbrInfo.NdotL * pbrInfo.NdotV);\n // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)\n return pbrInfo.NdotL * lightColor * (diffuseContrib + specContrib);\n}\n\nvec4 pbr_filterColor(vec4 colorUnused)\n{\n // The albedo may be defined from a base texture or a flat color\n#ifdef HAS_BASECOLORMAP\n vec4 baseColor = SRGBtoLINEAR(texture2D(u_BaseColorSampler, pbr_vUV)) * u_pbrMaterial.baseColorFactor;\n#else\n vec4 baseColor = u_pbrMaterial.baseColorFactor;\n#endif\n\n#ifdef ALPHA_CUTOFF\n if (baseColor.a < u_pbrMaterial.alphaCutoff) {\n discard;\n }\n#endif\n\n vec3 color = vec3(0, 0, 0);\n\n if(u_pbrMaterial.unlit){\n color.rgb = baseColor.rgb;\n }\n else{\n // Metallic and Roughness material properties are packed together\n // In glTF, these factors can be specified by fixed scalar values\n // or from a metallic-roughness map\n float perceptualRoughness = u_pbrMaterial.metallicRoughnessValues.y;\n float metallic = u_pbrMaterial.metallicRoughnessValues.x;\n#ifdef HAS_METALROUGHNESSMAP\n // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.\n // This layout intentionally reserves the 'r' channel for (optional) occlusion map data\n vec4 mrSample = texture2D(u_MetallicRoughnessSampler, pbr_vUV);\n perceptualRoughness = mrSample.g * perceptualRoughness;\n metallic = mrSample.b * metallic;\n#endif\n perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);\n metallic = clamp(metallic, 0.0, 1.0);\n // Roughness is authored as perceptual roughness; as is convention,\n // convert to material roughness by squaring the perceptual roughness [2].\n float alphaRoughness = perceptualRoughness * perceptualRoughness;\n\n vec3 f0 = vec3(0.04);\n vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);\n diffuseColor *= 1.0 - metallic;\n vec3 specularColor = mix(f0, baseColor.rgb, metallic);\n\n // Compute reflectance.\n float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\n\n // For typical incident reflectance range (between 4% to 100%) set the grazing\n // reflectance to 100% for typical fresnel effect.\n // For very low reflectance range on highly diffuse objects (below 4%),\n // incrementally reduce grazing reflecance to 0%.\n float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);\n vec3 specularEnvironmentR0 = specularColor.rgb;\n vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;\n\n vec3 n = getNormal(); // normal at surface point\n vec3 v = normalize(u_Camera - pbr_vPosition); // Vector from surface point to camera\n\n float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);\n vec3 reflection = -normalize(reflect(v, n));\n\n PBRInfo pbrInfo = PBRInfo(\n 0.0, // NdotL\n NdotV,\n 0.0, // NdotH\n 0.0, // LdotH\n 0.0, // VdotH\n perceptualRoughness,\n metallic,\n specularEnvironmentR0,\n specularEnvironmentR90,\n alphaRoughness,\n diffuseColor,\n specularColor,\n n,\n v\n );\n\n#ifdef USE_LIGHTS\n // Apply ambient light\n PBRInfo_setAmbientLight(pbrInfo);\n color += calculateFinalColor(pbrInfo, lighting_uAmbientLight.color);\n\n // Apply directional light\n for(int i = 0; i < lighting_uDirectionalLightCount; i++) {\n if (i < lighting_uDirectionalLightCount) {\n PBRInfo_setDirectionalLight(pbrInfo, lighting_uDirectionalLight[i].direction);\n color += calculateFinalColor(pbrInfo, lighting_uDirectionalLight[i].color);\n }\n }\n\n // Apply point light\n for(int i = 0; i < lighting_uPointLightCount; i++) {\n if (i < lighting_uPointLightCount) {\n PBRInfo_setPointLight(pbrInfo, lighting_uPointLight[i]);\n float attenuation = getPointLightAttenuation(lighting_uPointLight[i], distance(lighting_uPointLight[i].position, pbr_vPosition));\n color += calculateFinalColor(pbrInfo, lighting_uPointLight[i].color / attenuation);\n }\n }\n#endif\n\n // Calculate lighting contribution from image based lighting source (IBL)\n#ifdef USE_IBL\n if (u_pbrMateral.IBLEnabled) {\n color += getIBLContribution(pbrInfo, n, reflection);\n }\n#endif\n\n // Apply optional PBR terms for additional (optional) shading\n#ifdef HAS_OCCLUSIONMAP\n if (u_pbrMaterial.occlusionMapEnabled) {\n float ao = texture2D(u_OcclusionSampler, pbr_vUV).r;\n color = mix(color, color * ao, u_pbrMaterial.occlusionStrength);\n }\n#endif\n\n#ifdef HAS_EMISSIVEMAP\n if (u_pbrMaterial.emmissiveMapEnabled) {\n vec3 emissive = SRGBtoLINEAR(texture2D(u_EmissiveSampler, pbr_vUV)).rgb * u_pbrMaterial.emissiveFactor;\n color += emissive;\n }\n#endif\n\n // This section uses mix to override final color for reference app visualization\n // of various parameters in the lighting equation.\n#ifdef PBR_DEBUG\n // TODO: Figure out how to debug multiple lights\n\n // color = mix(color, F, u_ScaleFGDSpec.x);\n // color = mix(color, vec3(G), u_ScaleFGDSpec.y);\n // color = mix(color, vec3(D), u_ScaleFGDSpec.z);\n // color = mix(color, specContrib, u_ScaleFGDSpec.w);\n\n // color = mix(color, diffuseContrib, u_ScaleDiffBaseMR.x);\n color = mix(color, baseColor.rgb, u_pbrMaterial.scaleDiffBaseMR.y);\n color = mix(color, vec3(metallic), u_pbrMaterial.scaleDiffBaseMR.z);\n color = mix(color, vec3(perceptualRoughness), u_pbrMaterial.scaleDiffBaseMR.w);\n#endif\n\n }\n\n return vec4(pow(color,vec3(1.0/2.2)), baseColor.a);\n}\n";
|
|
92
|
+
}, ShaderModule<import("./pbr-projection").PBRProjectionProps>];
|
|
93
|
+
readonly vs: "out vec3 pbr_vPosition;\nout vec2 pbr_vUV;\n\n#ifdef HAS_NORMALS\n# ifdef HAS_TANGENTS\nout mat3 pbr_vTBN;\n# else\nout vec3 pbr_vNormal;\n# endif\n#endif\n\nvoid pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, vec2 uv)\n{\n vec4 pos = pbrProjection.modelMatrix * position;\n pbr_vPosition = vec3(pos.xyz) / pos.w;\n\n#ifdef HAS_NORMALS\n#ifdef HAS_TANGENTS\n vec3 normalW = normalize(vec3(pbrProjection.normalMatrix * vec4(normal.xyz, 0.0)));\n vec3 tangentW = normalize(vec3(pbrProjection.modelMatrix * vec4(tangent.xyz, 0.0)));\n vec3 bitangentW = cross(normalW, tangentW) * tangent.w;\n pbr_vTBN = mat3(tangentW, bitangentW, normalW);\n#else // HAS_TANGENTS != 1\n pbr_vNormal = normalize(vec3(pbrProjection.modelMatrix * vec4(normal.xyz, 0.0)));\n#endif\n#endif\n\n#ifdef HAS_UV\n pbr_vUV = uv;\n#else\n pbr_vUV = vec2(0.,0.);\n#endif\n}\n";
|
|
94
|
+
readonly fs: "precision highp float;\n\nuniform pbrMaterialUniforms {\n // Material is unlit\n bool unlit;\n\n // Base color map\n bool baseColorMapEnabled;\n vec4 baseColorFactor;\n\n bool normalMapEnabled; \n float normalScale; // #ifdef HAS_NORMALMAP\n\n bool emissiveMapEnabled;\n vec3 emissiveFactor; // #ifdef HAS_EMISSIVEMAP\n\n vec2 metallicRoughnessValues;\n bool metallicRoughnessMapEnabled;\n\n bool occlusionMapEnabled;\n float occlusionStrength; // #ifdef HAS_OCCLUSIONMAP\n \n bool alphaCutoffEnabled;\n float alphaCutoff; // #ifdef ALPHA_CUTOFF\n \n // IBL\n bool IBLenabled;\n vec2 scaleIBLAmbient; // #ifdef USE_IBL\n \n // debugging flags used for shader output of intermediate PBR variables\n // #ifdef PBR_DEBUG\n vec4 scaleDiffBaseMR;\n vec4 scaleFGDSpec;\n // #endif\n} pbrMaterial;\n\n// Samplers\n#ifdef HAS_BASECOLORMAP\nuniform sampler2D pbr_baseColorSampler;\n#endif\n#ifdef HAS_NORMALMAP\nuniform sampler2D pbr_normalSampler;\n#endif\n#ifdef HAS_EMISSIVEMAP\nuniform sampler2D pbr_emissiveSampler;\n#endif\n#ifdef HAS_METALROUGHNESSMAP\nuniform sampler2D pbr_metallicRoughnessSampler;\n#endif\n#ifdef HAS_OCCLUSIONMAP\nuniform sampler2D pbr_occlusionSampler;\n#endif\n#ifdef USE_IBL\nuniform samplerCube pbr_diffuseEnvSampler;\nuniform samplerCube pbr_specularEnvSampler;\nuniform sampler2D pbr_brdfLUT;\n#endif\n\n// Inputs from vertex shader\n\nin vec3 pbr_vPosition;\nin vec2 pbr_vUV;\n\n#ifdef HAS_NORMALS\n#ifdef HAS_TANGENTS\nin mat3 pbr_vTBN;\n#else\nin vec3 pbr_vNormal;\n#endif\n#endif\n\n// Encapsulate the various inputs used by the various functions in the shading equation\n// We store values in this struct to simplify the integration of alternative implementations\n// of the shading terms, outlined in the Readme.MD Appendix.\nstruct PBRInfo {\n float NdotL; // cos angle between normal and light direction\n float NdotV; // cos angle between normal and view direction\n float NdotH; // cos angle between normal and half vector\n float LdotH; // cos angle between light direction and half vector\n float VdotH; // cos angle between view direction and half vector\n float perceptualRoughness; // roughness value, as authored by the model creator (input to shader)\n float metalness; // metallic value at the surface\n vec3 reflectance0; // full reflectance color (normal incidence angle)\n vec3 reflectance90; // reflectance color at grazing angle\n float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2])\n vec3 diffuseColor; // color contribution from diffuse lighting\n vec3 specularColor; // color contribution from specular lighting\n vec3 n; // normal at surface point\n vec3 v; // vector from surface point to camera\n};\n\nconst float M_PI = 3.141592653589793;\nconst float c_MinRoughness = 0.04;\n\nvec4 SRGBtoLINEAR(vec4 srgbIn)\n{\n#ifdef MANUAL_SRGB\n#ifdef SRGB_FAST_APPROXIMATION\n vec3 linOut = pow(srgbIn.xyz,vec3(2.2));\n#else // SRGB_FAST_APPROXIMATION\n vec3 bLess = step(vec3(0.04045),srgbIn.xyz);\n vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess );\n#endif //SRGB_FAST_APPROXIMATION\n return vec4(linOut,srgbIn.w);;\n#else //MANUAL_SRGB\n return srgbIn;\n#endif //MANUAL_SRGB\n}\n\n// Find the normal for this fragment, pulling either from a predefined normal map\n// or from the interpolated mesh normal and tangent attributes.\nvec3 getNormal()\n{\n // Retrieve the tangent space matrix\n#ifndef HAS_TANGENTS\n vec3 pos_dx = dFdx(pbr_vPosition);\n vec3 pos_dy = dFdy(pbr_vPosition);\n vec3 tex_dx = dFdx(vec3(pbr_vUV, 0.0));\n vec3 tex_dy = dFdy(vec3(pbr_vUV, 0.0));\n vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);\n\n#ifdef HAS_NORMALS\n vec3 ng = normalize(pbr_vNormal);\n#else\n vec3 ng = cross(pos_dx, pos_dy);\n#endif\n\n t = normalize(t - ng * dot(ng, t));\n vec3 b = normalize(cross(ng, t));\n mat3 tbn = mat3(t, b, ng);\n#else // HAS_TANGENTS\n mat3 tbn = pbr_vTBN;\n#endif\n\n#ifdef HAS_NORMALMAP\n vec3 n = texture(pbr_normalSampler, pbr_vUV).rgb;\n n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));\n#else\n // The tbn matrix is linearly interpolated, so we need to re-normalize\n vec3 n = normalize(tbn[2].xyz);\n#endif\n\n return n;\n}\n\n// Calculation of the lighting contribution from an optional Image Based Light source.\n// Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].\n// See our README.md on Environment Maps [3] for additional discussion.\n#ifdef USE_IBL\nvec3 getIBLContribution(PBRInfo pbrInfo, vec3 n, vec3 reflection)\n{\n float mipCount = 9.0; // resolution of 512x512\n float lod = (pbrInfo.perceptualRoughness * mipCount);\n // retrieve a scale and bias to F0. See [1], Figure 3\n vec3 brdf = SRGBtoLINEAR(texture(pbr_brdfLUT,\n vec2(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness))).rgb;\n vec3 diffuseLight = SRGBtoLINEAR(texture(pbr_diffuseEnvSampler, n)).rgb;\n\n#ifdef USE_TEX_LOD\n vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection, lod)).rgb;\n#else\n vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection)).rgb;\n#endif\n\n vec3 diffuse = diffuseLight * pbrInfo.diffuseColor;\n vec3 specular = specularLight * (pbrInfo.specularColor * brdf.x + brdf.y);\n\n // For presentation, this allows us to disable IBL terms\n diffuse *= pbrMaterial.scaleIBLAmbient.x;\n specular *= pbrMaterial.scaleIBLAmbient.y;\n\n return diffuse + specular;\n}\n#endif\n\n// Basic Lambertian diffuse\n// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog\n// See also [1], Equation 1\nvec3 diffuse(PBRInfo pbrInfo)\n{\n return pbrInfo.diffuseColor / M_PI;\n}\n\n// The following equation models the Fresnel reflectance term of the spec equation (aka F())\n// Implementation of fresnel from [4], Equation 15\nvec3 specularReflection(PBRInfo pbrInfo)\n{\n return pbrInfo.reflectance0 +\n (pbrInfo.reflectance90 - pbrInfo.reflectance0) *\n pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);\n}\n\n// This calculates the specular geometric attenuation (aka G()),\n// where rougher material will reflect less light back to the viewer.\n// This implementation is based on [1] Equation 4, and we adopt their modifications to\n// alphaRoughness as input as originally proposed in [2].\nfloat geometricOcclusion(PBRInfo pbrInfo)\n{\n float NdotL = pbrInfo.NdotL;\n float NdotV = pbrInfo.NdotV;\n float r = pbrInfo.alphaRoughness;\n\n float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));\n float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));\n return attenuationL * attenuationV;\n}\n\n// The following equation(s) model the distribution of microfacet normals across\n// the area being drawn (aka D())\n// Implementation from \"Average Irregularity Representation of a Roughened Surface\n// for Ray Reflection\" by T. S. Trowbridge, and K. P. Reitz\n// Follows the distribution function recommended in the SIGGRAPH 2013 course notes\n// from EPIC Games [1], Equation 3.\nfloat microfacetDistribution(PBRInfo pbrInfo)\n{\n float roughnessSq = pbrInfo.alphaRoughness * pbrInfo.alphaRoughness;\n float f = (pbrInfo.NdotH * roughnessSq - pbrInfo.NdotH) * pbrInfo.NdotH + 1.0;\n return roughnessSq / (M_PI * f * f);\n}\n\nvoid PBRInfo_setAmbientLight(inout PBRInfo pbrInfo) {\n pbrInfo.NdotL = 1.0;\n pbrInfo.NdotH = 0.0;\n pbrInfo.LdotH = 0.0;\n pbrInfo.VdotH = 1.0;\n}\n\nvoid PBRInfo_setDirectionalLight(inout PBRInfo pbrInfo, vec3 lightDirection) {\n vec3 n = pbrInfo.n;\n vec3 v = pbrInfo.v;\n vec3 l = normalize(lightDirection); // Vector from surface point to light\n vec3 h = normalize(l+v); // Half vector between both l and v\n\n pbrInfo.NdotL = clamp(dot(n, l), 0.001, 1.0);\n pbrInfo.NdotH = clamp(dot(n, h), 0.0, 1.0);\n pbrInfo.LdotH = clamp(dot(l, h), 0.0, 1.0);\n pbrInfo.VdotH = clamp(dot(v, h), 0.0, 1.0);\n}\n\nvoid PBRInfo_setPointLight(inout PBRInfo pbrInfo, PointLight pointLight) {\n vec3 light_direction = normalize(pointLight.position - pbr_vPosition);\n PBRInfo_setDirectionalLight(pbrInfo, light_direction);\n}\n\nvec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor) {\n // Calculate the shading terms for the microfacet specular shading model\n vec3 F = specularReflection(pbrInfo);\n float G = geometricOcclusion(pbrInfo);\n float D = microfacetDistribution(pbrInfo);\n\n // Calculation of analytical lighting contribution\n vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInfo);\n vec3 specContrib = F * G * D / (4.0 * pbrInfo.NdotL * pbrInfo.NdotV);\n // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)\n return pbrInfo.NdotL * lightColor * (diffuseContrib + specContrib);\n}\n\nvec4 pbr_filterColor(vec4 colorUnused)\n{\n // The albedo may be defined from a base texture or a flat color\n#ifdef HAS_BASECOLORMAP\n vec4 baseColor = SRGBtoLINEAR(texture(pbr_baseColorSampler, pbr_vUV)) * pbrMaterial.baseColorFactor;\n#else\n vec4 baseColor = pbrMaterial.baseColorFactor;\n#endif\n\n#ifdef ALPHA_CUTOFF\n if (baseColor.a < pbrMaterial.alphaCutoff) {\n discard;\n }\n#endif\n\n vec3 color = vec3(0, 0, 0);\n\n if(pbrMaterial.unlit){\n color.rgb = baseColor.rgb;\n }\n else{\n // Metallic and Roughness material properties are packed together\n // In glTF, these factors can be specified by fixed scalar values\n // or from a metallic-roughness map\n float perceptualRoughness = pbrMaterial.metallicRoughnessValues.y;\n float metallic = pbrMaterial.metallicRoughnessValues.x;\n#ifdef HAS_METALROUGHNESSMAP\n // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.\n // This layout intentionally reserves the 'r' channel for (optional) occlusion map data\n vec4 mrSample = texture(pbr_metallicRoughnessSampler, pbr_vUV);\n perceptualRoughness = mrSample.g * perceptualRoughness;\n metallic = mrSample.b * metallic;\n#endif\n perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);\n metallic = clamp(metallic, 0.0, 1.0);\n // Roughness is authored as perceptual roughness; as is convention,\n // convert to material roughness by squaring the perceptual roughness [2].\n float alphaRoughness = perceptualRoughness * perceptualRoughness;\n\n vec3 f0 = vec3(0.04);\n vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);\n diffuseColor *= 1.0 - metallic;\n vec3 specularColor = mix(f0, baseColor.rgb, metallic);\n\n // Compute reflectance.\n float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);\n\n // For typical incident reflectance range (between 4% to 100%) set the grazing\n // reflectance to 100% for typical fresnel effect.\n // For very low reflectance range on highly diffuse objects (below 4%),\n // incrementally reduce grazing reflecance to 0%.\n float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);\n vec3 specularEnvironmentR0 = specularColor.rgb;\n vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;\n\n vec3 n = getNormal(); // normal at surface point\n vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera\n\n float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);\n vec3 reflection = -normalize(reflect(v, n));\n\n PBRInfo pbrInfo = PBRInfo(\n 0.0, // NdotL\n NdotV,\n 0.0, // NdotH\n 0.0, // LdotH\n 0.0, // VdotH\n perceptualRoughness,\n metallic,\n specularEnvironmentR0,\n specularEnvironmentR90,\n alphaRoughness,\n diffuseColor,\n specularColor,\n n,\n v\n );\n\n\n#ifdef USE_LIGHTS\n // Apply ambient light\n PBRInfo_setAmbientLight(pbrInfo);\n color += calculateFinalColor(pbrInfo, lighting.ambientColor);\n\n // Apply directional light\n for(int i = 0; i < lighting.directionalLightCount; i++) {\n if (i < lighting.directionalLightCount) {\n PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);\n color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);\n }\n }\n\n // Apply point light\n for(int i = 0; i < lighting.pointLightCount; i++) {\n if (i < lighting.pointLightCount) {\n PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));\n float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));\n color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);\n }\n }\n#endif\n\n // Calculate lighting contribution from image based lighting source (IBL)\n#ifdef USE_IBL\n if (pbrMaterial.IBLenabled) {\n color += getIBLContribution(pbrInfo, n, reflection);\n }\n#endif\n\n // Apply optional PBR terms for additional (optional) shading\n#ifdef HAS_OCCLUSIONMAP\n if (pbrMaterial.occlusionMapEnabled) {\n float ao = texture(pbr_occlusionSampler, pbr_vUV).r;\n color = mix(color, color * ao, pbrMaterial.occlusionStrength);\n }\n#endif\n\n#ifdef HAS_EMISSIVEMAP\n if (pbrMaterial.emissiveMapEnabled) {\n vec3 emissive = SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb * pbrMaterial.emissiveFactor;\n color += emissive;\n }\n#endif\n\n // This section uses mix to override final color for reference app visualization\n // of various parameters in the lighting equation.\n#ifdef PBR_DEBUG\n // TODO: Figure out how to debug multiple lights\n\n // color = mix(color, F, pbr_scaleFGDSpec.x);\n // color = mix(color, vec3(G), pbr_scaleFGDSpec.y);\n // color = mix(color, vec3(D), pbr_scaleFGDSpec.z);\n // color = mix(color, specContrib, pbr_scaleFGDSpec.w);\n\n // color = mix(color, diffuseContrib, pbr_scaleDiffBaseMR.x);\n color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);\n color = mix(color, vec3(metallic), pbrMaterial.scaleDiffBaseMR.z);\n color = mix(color, vec3(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);\n#endif\n\n }\n\n return vec4(pow(color,vec3(1.0/2.2)), baseColor.a);\n}\n";
|
|
95
95
|
readonly defines: {
|
|
96
96
|
readonly LIGHTING_FRAGMENT: 1;
|
|
97
|
-
readonly HAS_NORMALMAP: 0;
|
|
98
|
-
readonly HAS_EMISSIVEMAP: 0;
|
|
99
|
-
readonly HAS_OCCLUSIONMAP: 0;
|
|
100
|
-
readonly HAS_BASECOLORMAP: 0;
|
|
101
|
-
readonly HAS_METALROUGHNESSMAP: 0;
|
|
102
|
-
readonly ALPHA_CUTOFF: 0;
|
|
103
|
-
readonly USE_IBL: 0;
|
|
104
|
-
readonly PBR_DEBUG: 0;
|
|
105
97
|
};
|
|
98
|
+
readonly getUniforms: (props: Partial<PBRMaterialProps>) => Partial<PBRMaterialProps>;
|
|
106
99
|
readonly uniformTypes: {
|
|
107
100
|
readonly unlit: "i32";
|
|
108
101
|
readonly baseColorMapEnabled: "i32";
|
|
@@ -122,40 +115,5 @@ export declare const pbrMaterial: {
|
|
|
122
115
|
readonly scaleDiffBaseMR: "vec4<f32>";
|
|
123
116
|
readonly scaleFGDSpec: "vec4<f32>";
|
|
124
117
|
};
|
|
125
|
-
readonly bindings: {
|
|
126
|
-
readonly baseColorSampler: {
|
|
127
|
-
readonly type: "texture";
|
|
128
|
-
readonly location: 8;
|
|
129
|
-
};
|
|
130
|
-
readonly normalSampler: {
|
|
131
|
-
readonly type: "texture";
|
|
132
|
-
readonly location: 9;
|
|
133
|
-
};
|
|
134
|
-
readonly emissiveSampler: {
|
|
135
|
-
readonly type: "texture";
|
|
136
|
-
readonly location: 10;
|
|
137
|
-
};
|
|
138
|
-
readonly metallicRoughnessSampler: {
|
|
139
|
-
readonly type: "texture";
|
|
140
|
-
readonly location: 11;
|
|
141
|
-
};
|
|
142
|
-
readonly occlusionSampler: {
|
|
143
|
-
readonly type: "texture";
|
|
144
|
-
readonly location: 12;
|
|
145
|
-
};
|
|
146
|
-
readonly diffuseEnvSampler: {
|
|
147
|
-
readonly type: "texture";
|
|
148
|
-
readonly location: 13;
|
|
149
|
-
};
|
|
150
|
-
readonly specularEnvSampler: {
|
|
151
|
-
readonly type: "texture";
|
|
152
|
-
readonly location: 14;
|
|
153
|
-
};
|
|
154
|
-
readonly brdfLUT: {
|
|
155
|
-
readonly type: "texture";
|
|
156
|
-
readonly location: 15;
|
|
157
|
-
};
|
|
158
|
-
};
|
|
159
118
|
};
|
|
160
|
-
export {};
|
|
161
119
|
//# sourceMappingURL=pbr-material.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pbr-material.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/pbr-material/pbr-material.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,
|
|
1
|
+
{"version":3,"file":"pbr-material.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/pbr-material/pbr-material.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EACV,OAAO,EACP,OAAO,EACP,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,YAAY,EACb,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAC,YAAY,EAAC,oDAAiD;AAOtE,gDAAgD;AAChD,MAAM,MAAM,mBAAmB,GAAG;IAEhC,oBAAoB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtC,iBAAiB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,mBAAmB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,4BAA4B,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9C,oBAAoB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAGtC,qBAAqB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACvC,sBAAsB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACxC,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,CAAC,EAAE,OAAO,CAAC;IAGhB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAEnD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,cAAc,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAElD,uBAAuB,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAC3D,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAInD,eAAe,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IACnD,YAAY,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAEzE;;;GAGG;AACH,eAAO,MAAM,WAAW;oBACT,gBAAgB;uBACb,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoDwD,CAAC"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { lighting } from "../lights/lighting.js";
|
|
5
5
|
import { vs } from "./pbr-vertex-glsl.js";
|
|
6
6
|
import { fs } from "./pbr-fragment-glsl.js";
|
|
7
|
+
import { pbrProjection } from "./pbr-projection.js";
|
|
7
8
|
/**
|
|
8
9
|
* An implementation of PBR (Physically-Based Rendering).
|
|
9
10
|
* Physically Based Shading of a microfacet surface defined by a glTF material.
|
|
@@ -11,21 +12,23 @@ import { fs } from "./pbr-fragment-glsl.js";
|
|
|
11
12
|
export const pbrMaterial = {
|
|
12
13
|
props: {},
|
|
13
14
|
uniforms: {},
|
|
14
|
-
name: '
|
|
15
|
-
dependencies: [lighting],
|
|
15
|
+
name: 'pbrMaterial',
|
|
16
|
+
dependencies: [lighting, pbrProjection],
|
|
16
17
|
vs,
|
|
17
18
|
fs,
|
|
18
19
|
defines: {
|
|
19
|
-
LIGHTING_FRAGMENT: 1
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
LIGHTING_FRAGMENT: 1
|
|
21
|
+
// TODO defining these as 0 breaks shader
|
|
22
|
+
// HAS_NORMALMAP: 0
|
|
23
|
+
// HAS_EMISSIVEMAP: 0,
|
|
24
|
+
// HAS_OCCLUSIONMAP: 0,
|
|
25
|
+
// HAS_BASECOLORMAP: 0,
|
|
26
|
+
// HAS_METALROUGHNESSMAP: 0,
|
|
27
|
+
// ALPHA_CUTOFF: 0
|
|
28
|
+
// USE_IBL: 0
|
|
29
|
+
// PBR_DEBUG: 0
|
|
28
30
|
},
|
|
31
|
+
getUniforms: props => props,
|
|
29
32
|
uniformTypes: {
|
|
30
33
|
// Material is unlit
|
|
31
34
|
unlit: 'i32',
|
|
@@ -49,16 +52,5 @@ export const pbrMaterial = {
|
|
|
49
52
|
// #ifdef PBR_DEBUG
|
|
50
53
|
scaleDiffBaseMR: 'vec4<f32>',
|
|
51
54
|
scaleFGDSpec: 'vec4<f32>'
|
|
52
|
-
},
|
|
53
|
-
bindings: {
|
|
54
|
-
baseColorSampler: { type: 'texture', location: 8 }, // #ifdef HAS_BASECOLORMAP
|
|
55
|
-
normalSampler: { type: 'texture', location: 9 }, // #ifdef HAS_NORMALMAP
|
|
56
|
-
emissiveSampler: { type: 'texture', location: 10 }, // #ifdef HAS_EMISSIVEMAP
|
|
57
|
-
metallicRoughnessSampler: { type: 'texture', location: 11 }, // #ifdef HAS_METALROUGHNESSMAP
|
|
58
|
-
occlusionSampler: { type: 'texture', location: 12 }, // #ifdef HAS_OCCLUSIONMAP
|
|
59
|
-
// IBL Samplers
|
|
60
|
-
diffuseEnvSampler: { type: 'texture', location: 13 }, // #ifdef USE_IBL (samplerCube)
|
|
61
|
-
specularEnvSampler: { type: 'texture', location: 14 }, // #ifdef USE_IBL (samplerCube)
|
|
62
|
-
brdfLUT: { type: 'texture', location: 15 } // #ifdef USE_IBL
|
|
63
55
|
}
|
|
64
56
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { NumberArray3, NumberArray16 } from '@math.gl/core';
|
|
2
|
+
import { ShaderModule } from "../../../lib/shader-module/shader-module.js";
|
|
3
|
+
export type PBRProjectionProps = {
|
|
4
|
+
modelViewProjectionMatrix: NumberArray16;
|
|
5
|
+
modelMatrix: NumberArray16;
|
|
6
|
+
normalMatrix: NumberArray16;
|
|
7
|
+
camera: NumberArray3;
|
|
8
|
+
};
|
|
9
|
+
export declare const pbrProjection: ShaderModule<PBRProjectionProps>;
|
|
10
|
+
//# sourceMappingURL=pbr-projection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pbr-projection.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/pbr-material/pbr-projection.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAC,YAAY,EAAE,aAAa,EAAC,MAAM,eAAe,CAAC;AAE/D,OAAO,EAAC,YAAY,EAAC,oDAAiD;AAWtE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,yBAAyB,EAAE,aAAa,CAAC;IACzC,WAAW,EAAE,aAAa,CAAC;IAC3B,YAAY,EAAE,aAAa,CAAC;IAC5B,MAAM,EAAE,YAAY,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,YAAY,CAAC,kBAAkB,CAY1D,CAAC"}
|