@luma.gl/shadertools 9.0.21 → 9.0.24
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 +102 -90
- package/dist/dist.min.js +127 -130
- package/dist/index.cjs +94 -79
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/modules/lighting/gouraud-material/gouraud-material.js +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 +49 -52
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts +10 -29
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material.js +14 -11
- 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 +25 -0
- 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 -14
- package/dist/modules/lighting/phong-material/phong-material.js +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +7 -1
- package/src/modules/lighting/gouraud-material/gouraud-material.ts +1 -1
- package/src/modules/lighting/pbr-material/pbr-fragment-glsl.ts +56 -60
- package/src/modules/lighting/pbr-material/pbr-material.ts +25 -52
- package/src/modules/lighting/pbr-material/pbr-projection.ts +41 -0
- package/src/modules/lighting/pbr-material/pbr-vertex-glsl.ts +8 -16
- package/src/modules/lighting/phong-material/phong-material.ts +1 -1
- package/src/modules/lighting/phong-material/phong-shaders-glsl.ts +0 -1
- package/dist/modules/lighting/pbr-material/pbr-uniforms-glsl.d.ts +0 -2
- package/dist/modules/lighting/pbr-material/pbr-uniforms-glsl.d.ts.map +0 -1
- package/dist/modules/lighting/pbr-material/pbr-uniforms-glsl.js +0 -48
- package/src/modules/lighting/pbr-material/pbr-uniforms-glsl.ts +0 -69
package/dist/index.d.ts
CHANGED
|
@@ -33,6 +33,8 @@ export type { GouraudMaterialProps } from "./modules/lighting/gouraud-material/g
|
|
|
33
33
|
export { gouraudMaterial } from "./modules/lighting/gouraud-material/gouraud-material.js";
|
|
34
34
|
export type { PhongMaterialProps } from "./modules/lighting/phong-material/phong-material.js";
|
|
35
35
|
export { phongMaterial } from "./modules/lighting/phong-material/phong-material.js";
|
|
36
|
+
export type { PBRMaterialBindings, PBRMaterialProps, PBRMaterialUniforms } from "./modules/lighting/pbr-material/pbr-material.js";
|
|
37
|
+
export type { PBRProjectionProps } from "./modules/lighting/pbr-material/pbr-projection.js";
|
|
36
38
|
export { pbrMaterial } from "./modules/lighting/pbr-material/pbr-material.js";
|
|
37
39
|
export type { BrightnessContrastProps } from "./modules/postprocessing/image-adjust-filters/brightnesscontrast.js";
|
|
38
40
|
export { brightnessContrast } from "./modules/postprocessing/image-adjust-filters/brightnesscontrast.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,OAAO,EAAC,IAAI,EAAC,sCAAmC;AAEhD,YAAY,EAAC,YAAY,EAAC,+CAA4C;AAEtE,YAAY,EAAC,YAAY,EAAC,6CAA0C;AACpE,YAAY,EAAC,UAAU,EAAC,2CAAwC;AAChE,YAAY,EAAC,UAAU,EAAC,8CAA2C;AACnE,YAAY,EAAC,eAAe,EAAC,mDAAgD;AAC7E,OAAO,EAAC,oBAAoB,EAAC,sDAAmD;AAGhF,OAAO,EAAC,eAAe,EAAC,kCAA+B;AAEvD,OAAO,EAAC,qBAAqB,EAAC,uDAAoD;AAKlF,OAAO,EAAC,aAAa,EAAC,4CAAyC;AAC/D,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACd,yCAAsC;AAGvC,YAAY,EAAC,uBAAuB,EAAC,kDAA+C;AACpF,OAAO,EAAC,uBAAuB,EAAC,kDAA+C;AAC/E,OAAO,EAAC,UAAU,EAAC,mDAAgD;AAGnE,OAAO,EAAC,sBAAsB,EAAC,kDAA+C;AAC9E,OAAO,EAAC,oBAAoB,IAAI,qBAAqB,EAAC,sDAAmD;AACzG,OAAO,EAAC,cAAc,EAAC,mDAAgD;AACvE,OAAO,EAAC,cAAc,IAAI,eAAe,EAAC,iDAA8C;AACxF,OAAO,EAAC,kBAAkB,IAAI,mBAAmB,EAAC,iDAA8C;AAGhG,OAAO,EAAC,uBAAuB,EAAC,6CAA0C;AAO1E,OAAO,EAAC,MAAM,EAAC,wCAAqC;AACpD,OAAO,EAAC,IAAI,EAAC,oCAAiC;AAQ9C,YAAY,EAAC,YAAY,EAAC,4CAAyC;AACnE,OAAO,EAAC,OAAO,EAAC,4CAAyC;AAGzD,YAAY,EAAC,aAAa,EAAC,uDAAoD;AAC/E,OAAO,EAAC,QAAQ,EAAC,uDAAoD;AACrE,OAAO,EAAC,QAAQ,EAAC,mDAAgD;AACjE,YAAY,EAAC,oBAAoB,EAAC,gEAA6D;AAC/F,OAAO,EAAC,eAAe,EAAC,gEAA6D;AACrF,YAAY,EAAC,kBAAkB,EAAC,4DAAyD;AACzF,OAAO,EAAC,aAAa,EAAC,4DAAyD;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -35,7 +35,6 @@ export { lighting } from "./modules/lighting/lights/lighting-uniforms.js";
|
|
|
35
35
|
export { dirlight } from "./modules/lighting/no-material/dirlight.js";
|
|
36
36
|
export { gouraudMaterial } from "./modules/lighting/gouraud-material/gouraud-material.js";
|
|
37
37
|
export { phongMaterial } from "./modules/lighting/phong-material/phong-material.js";
|
|
38
|
-
// export type {PBRMaterialSettings, PBRMaterialUniforms} from './modules/lighting/pbr-material/pbr';
|
|
39
38
|
export { pbrMaterial } from "./modules/lighting/pbr-material/pbr-material.js";
|
|
40
39
|
export { brightnessContrast } from "./modules/postprocessing/image-adjust-filters/brightnesscontrast.js";
|
|
41
40
|
export { denoise } from "./modules/postprocessing/image-adjust-filters/denoise.js";
|
|
@@ -30,6 +30,6 @@ export const gouraudMaterial = {
|
|
|
30
30
|
if (uniforms.specularColor) {
|
|
31
31
|
uniforms.specularColor = uniforms.specularColor.map(x => x / 255);
|
|
32
32
|
}
|
|
33
|
-
return { ...gouraudMaterial.defaultUniforms, ...
|
|
33
|
+
return { ...gouraudMaterial.defaultUniforms, ...uniforms };
|
|
34
34
|
}
|
|
35
35
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pbr-fragment-glsl.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/pbr-material/pbr-fragment-glsl.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"pbr-fragment-glsl.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/pbr-material/pbr-fragment-glsl.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,EAAE,QAkZd,CAAC"}
|
|
@@ -9,10 +9,7 @@
|
|
|
9
9
|
import { glsl } from "../../../lib/glsl-utils/highlight.js";
|
|
10
10
|
export const fs = `\
|
|
11
11
|
precision highp float;
|
|
12
|
-
uniform
|
|
13
|
-
uniform vec3 u_Camera;
|
|
14
|
-
};
|
|
15
|
-
uniform pbrMaterial {
|
|
12
|
+
uniform pbrMaterialUniforms {
|
|
16
13
|
bool unlit;
|
|
17
14
|
bool baseColorMapEnabled;
|
|
18
15
|
vec4 baseColorFactor;
|
|
@@ -30,34 +27,34 @@ bool IBLenabled;
|
|
|
30
27
|
vec2 scaleIBLAmbient;
|
|
31
28
|
vec4 scaleDiffBaseMR;
|
|
32
29
|
vec4 scaleFGDSpec;
|
|
33
|
-
}
|
|
30
|
+
} pbrMaterial;
|
|
34
31
|
#ifdef HAS_BASECOLORMAP
|
|
35
|
-
uniform sampler2D
|
|
32
|
+
uniform sampler2D pbr_baseColorSampler;
|
|
36
33
|
#endif
|
|
37
34
|
#ifdef HAS_NORMALMAP
|
|
38
|
-
uniform sampler2D
|
|
35
|
+
uniform sampler2D pbr_normalSampler;
|
|
39
36
|
#endif
|
|
40
37
|
#ifdef HAS_EMISSIVEMAP
|
|
41
|
-
uniform sampler2D
|
|
38
|
+
uniform sampler2D pbr_emissiveSampler;
|
|
42
39
|
#endif
|
|
43
40
|
#ifdef HAS_METALROUGHNESSMAP
|
|
44
|
-
uniform sampler2D
|
|
41
|
+
uniform sampler2D pbr_metallicRoughnessSampler;
|
|
45
42
|
#endif
|
|
46
43
|
#ifdef HAS_OCCLUSIONMAP
|
|
47
|
-
uniform sampler2D
|
|
44
|
+
uniform sampler2D pbr_occlusionSampler;
|
|
48
45
|
#endif
|
|
49
46
|
#ifdef USE_IBL
|
|
50
|
-
uniform samplerCube
|
|
51
|
-
uniform samplerCube
|
|
52
|
-
uniform sampler2D
|
|
47
|
+
uniform samplerCube pbr_diffuseEnvSampler;
|
|
48
|
+
uniform samplerCube pbr_specularEnvSampler;
|
|
49
|
+
uniform sampler2D pbr_brdfLUT;
|
|
53
50
|
#endif
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
in vec3 pbr_vPosition;
|
|
52
|
+
in vec2 pbr_vUV;
|
|
56
53
|
#ifdef HAS_NORMALS
|
|
57
54
|
#ifdef HAS_TANGENTS
|
|
58
|
-
|
|
55
|
+
in mat3 pbr_vTBN;
|
|
59
56
|
#else
|
|
60
|
-
|
|
57
|
+
in vec3 pbr_vNormal;
|
|
61
58
|
#endif
|
|
62
59
|
#endif
|
|
63
60
|
struct PBRInfo {
|
|
@@ -112,8 +109,8 @@ mat3 tbn = mat3(t, b, ng);
|
|
|
112
109
|
mat3 tbn = pbr_vTBN;
|
|
113
110
|
#endif
|
|
114
111
|
#ifdef HAS_NORMALMAP
|
|
115
|
-
vec3 n =
|
|
116
|
-
n = normalize(tbn * ((2.0 * n - 1.0) * vec3(
|
|
112
|
+
vec3 n = texture(pbr_normalSampler, pbr_vUV).rgb;
|
|
113
|
+
n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
|
|
117
114
|
#else
|
|
118
115
|
vec3 n = normalize(tbn[2].xyz);
|
|
119
116
|
#endif
|
|
@@ -124,18 +121,18 @@ vec3 getIBLContribution(PBRInfo pbrInfo, vec3 n, vec3 reflection)
|
|
|
124
121
|
{
|
|
125
122
|
float mipCount = 9.0;
|
|
126
123
|
float lod = (pbrInfo.perceptualRoughness * mipCount);
|
|
127
|
-
vec3 brdf = SRGBtoLINEAR(
|
|
124
|
+
vec3 brdf = SRGBtoLINEAR(texture(pbr_brdfLUT,
|
|
128
125
|
vec2(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness))).rgb;
|
|
129
|
-
vec3 diffuseLight = SRGBtoLINEAR(
|
|
126
|
+
vec3 diffuseLight = SRGBtoLINEAR(texture(pbr_diffuseEnvSampler, n)).rgb;
|
|
130
127
|
#ifdef USE_TEX_LOD
|
|
131
|
-
vec3 specularLight = SRGBtoLINEAR(
|
|
128
|
+
vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection, lod)).rgb;
|
|
132
129
|
#else
|
|
133
|
-
vec3 specularLight = SRGBtoLINEAR(
|
|
130
|
+
vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection)).rgb;
|
|
134
131
|
#endif
|
|
135
132
|
vec3 diffuse = diffuseLight * pbrInfo.diffuseColor;
|
|
136
133
|
vec3 specular = specularLight * (pbrInfo.specularColor * brdf.x + brdf.y);
|
|
137
|
-
diffuse *=
|
|
138
|
-
specular *=
|
|
134
|
+
diffuse *= pbrMaterial.scaleIBLAmbient.x;
|
|
135
|
+
specular *= pbrMaterial.scaleIBLAmbient.y;
|
|
139
136
|
return diffuse + specular;
|
|
140
137
|
}
|
|
141
138
|
#endif
|
|
@@ -195,24 +192,24 @@ return pbrInfo.NdotL * lightColor * (diffuseContrib + specContrib);
|
|
|
195
192
|
vec4 pbr_filterColor(vec4 colorUnused)
|
|
196
193
|
{
|
|
197
194
|
#ifdef HAS_BASECOLORMAP
|
|
198
|
-
vec4 baseColor = SRGBtoLINEAR(
|
|
195
|
+
vec4 baseColor = SRGBtoLINEAR(texture(pbr_baseColorSampler, pbr_vUV)) * pbrMaterial.baseColorFactor;
|
|
199
196
|
#else
|
|
200
|
-
vec4 baseColor =
|
|
197
|
+
vec4 baseColor = pbrMaterial.baseColorFactor;
|
|
201
198
|
#endif
|
|
202
199
|
#ifdef ALPHA_CUTOFF
|
|
203
|
-
if (baseColor.a <
|
|
200
|
+
if (baseColor.a < pbrMaterial.alphaCutoff) {
|
|
204
201
|
discard;
|
|
205
202
|
}
|
|
206
203
|
#endif
|
|
207
204
|
vec3 color = vec3(0, 0, 0);
|
|
208
|
-
if(
|
|
205
|
+
if(pbrMaterial.unlit){
|
|
209
206
|
color.rgb = baseColor.rgb;
|
|
210
207
|
}
|
|
211
208
|
else{
|
|
212
|
-
float perceptualRoughness =
|
|
213
|
-
float metallic =
|
|
209
|
+
float perceptualRoughness = pbrMaterial.metallicRoughnessValues.y;
|
|
210
|
+
float metallic = pbrMaterial.metallicRoughnessValues.x;
|
|
214
211
|
#ifdef HAS_METALROUGHNESSMAP
|
|
215
|
-
vec4 mrSample =
|
|
212
|
+
vec4 mrSample = texture(pbr_metallicRoughnessSampler, pbr_vUV);
|
|
216
213
|
perceptualRoughness = mrSample.g * perceptualRoughness;
|
|
217
214
|
metallic = mrSample.b * metallic;
|
|
218
215
|
#endif
|
|
@@ -228,7 +225,7 @@ float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
|
228
225
|
vec3 specularEnvironmentR0 = specularColor.rgb;
|
|
229
226
|
vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
|
|
230
227
|
vec3 n = getNormal();
|
|
231
|
-
vec3 v = normalize(
|
|
228
|
+
vec3 v = normalize(pbrProjection.camera - pbr_vPosition);
|
|
232
229
|
float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
233
230
|
vec3 reflection = -normalize(reflect(v, n));
|
|
234
231
|
PBRInfo pbrInfo = PBRInfo(
|
|
@@ -249,42 +246,42 @@ v
|
|
|
249
246
|
);
|
|
250
247
|
#ifdef USE_LIGHTS
|
|
251
248
|
PBRInfo_setAmbientLight(pbrInfo);
|
|
252
|
-
color += calculateFinalColor(pbrInfo,
|
|
253
|
-
for(int i = 0; i <
|
|
254
|
-
if (i <
|
|
255
|
-
PBRInfo_setDirectionalLight(pbrInfo,
|
|
256
|
-
color += calculateFinalColor(pbrInfo,
|
|
249
|
+
color += calculateFinalColor(pbrInfo, lighting.ambientColor);
|
|
250
|
+
for(int i = 0; i < lighting.directionalLightCount; i++) {
|
|
251
|
+
if (i < lighting.directionalLightCount) {
|
|
252
|
+
PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
253
|
+
color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
|
|
257
254
|
}
|
|
258
255
|
}
|
|
259
|
-
for(int i = 0; i <
|
|
260
|
-
if (i <
|
|
261
|
-
PBRInfo_setPointLight(pbrInfo,
|
|
262
|
-
float attenuation = getPointLightAttenuation(
|
|
263
|
-
color += calculateFinalColor(pbrInfo,
|
|
256
|
+
for(int i = 0; i < lighting.pointLightCount; i++) {
|
|
257
|
+
if (i < lighting.pointLightCount) {
|
|
258
|
+
PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
|
|
259
|
+
float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
|
|
260
|
+
color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
|
|
264
261
|
}
|
|
265
262
|
}
|
|
266
263
|
#endif
|
|
267
264
|
#ifdef USE_IBL
|
|
268
|
-
if (
|
|
265
|
+
if (pbrMaterial.IBLenabled) {
|
|
269
266
|
color += getIBLContribution(pbrInfo, n, reflection);
|
|
270
267
|
}
|
|
271
268
|
#endif
|
|
272
269
|
#ifdef HAS_OCCLUSIONMAP
|
|
273
|
-
if (
|
|
274
|
-
float ao =
|
|
275
|
-
color = mix(color, color * ao,
|
|
270
|
+
if (pbrMaterial.occlusionMapEnabled) {
|
|
271
|
+
float ao = texture(pbr_occlusionSampler, pbr_vUV).r;
|
|
272
|
+
color = mix(color, color * ao, pbrMaterial.occlusionStrength);
|
|
276
273
|
}
|
|
277
274
|
#endif
|
|
278
275
|
#ifdef HAS_EMISSIVEMAP
|
|
279
|
-
if (
|
|
280
|
-
vec3 emissive = SRGBtoLINEAR(
|
|
276
|
+
if (pbrMaterial.emissiveMapEnabled) {
|
|
277
|
+
vec3 emissive = SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb * pbrMaterial.emissiveFactor;
|
|
281
278
|
color += emissive;
|
|
282
279
|
}
|
|
283
280
|
#endif
|
|
284
281
|
#ifdef PBR_DEBUG
|
|
285
|
-
color = mix(color, baseColor.rgb,
|
|
286
|
-
color = mix(color, vec3(metallic),
|
|
287
|
-
color = mix(color, vec3(perceptualRoughness),
|
|
282
|
+
color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
|
|
283
|
+
color = mix(color, vec3(metallic), pbrMaterial.scaleDiffBaseMR.z);
|
|
284
|
+
color = mix(color, vec3(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
|
|
288
285
|
#endif
|
|
289
286
|
}
|
|
290
287
|
return vec4(pow(color,vec3(1.0/2.2)), baseColor.a);
|
|
@@ -2,35 +2,16 @@ import type { Texture } from '@luma.gl/core';
|
|
|
2
2
|
import type { Vector2, Vector3, Vector4 } from '@math.gl/core';
|
|
3
3
|
import type { NumberArray2, NumberArray3, NumberArray4 } from "../../../lib/utils/uniform-types.js";
|
|
4
4
|
import { ShaderModule } from "../../../lib/shader-module/shader-module.js";
|
|
5
|
-
export type PBRMaterialProps = PBRMaterialBindings & {
|
|
6
|
-
unlit: boolean;
|
|
7
|
-
baseColorMapEnabled: boolean;
|
|
8
|
-
baseColorFactor: Readonly<Vector4 | NumberArray4>;
|
|
9
|
-
normalMapEnabled: boolean;
|
|
10
|
-
normalScale: number;
|
|
11
|
-
emissiveMapEnabled: boolean;
|
|
12
|
-
emissiveFactor: Readonly<Vector3 | NumberArray3>;
|
|
13
|
-
metallicRoughnessValues: Readonly<Vector2 | NumberArray2>;
|
|
14
|
-
metallicRoughnessMapEnabled: boolean;
|
|
15
|
-
occlusionMapEnabled: boolean;
|
|
16
|
-
occlusionStrength: number;
|
|
17
|
-
alphaCutoffEnabled: boolean;
|
|
18
|
-
alphaCutoff: number;
|
|
19
|
-
IBLenabled: boolean;
|
|
20
|
-
scaleIBLAmbient: Readonly<Vector2 | NumberArray2>;
|
|
21
|
-
scaleDiffBaseMR: Readonly<Vector4 | NumberArray4>;
|
|
22
|
-
scaleFGDSpec: Readonly<Vector4 | NumberArray4>;
|
|
23
|
-
};
|
|
24
5
|
/** Non-uniform block bindings for pbr module */
|
|
25
|
-
type PBRMaterialBindings = {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
6
|
+
export type PBRMaterialBindings = {
|
|
7
|
+
pbr_baseColorSampler?: Texture | null;
|
|
8
|
+
pbr_normalSampler?: Texture | null;
|
|
9
|
+
pbr_emissiveSampler?: Texture | null;
|
|
10
|
+
pbr_metallicRoughnessSampler?: Texture | null;
|
|
11
|
+
pbr_occlusionSampler?: Texture | null;
|
|
12
|
+
pbr_diffuseEnvSampler?: Texture | null;
|
|
13
|
+
pbr_specularEnvSampler?: Texture | null;
|
|
14
|
+
pbr_BrdfLUT?: Texture | null;
|
|
34
15
|
};
|
|
35
16
|
export type PBRMaterialUniforms = {
|
|
36
17
|
unlit: boolean;
|
|
@@ -51,10 +32,10 @@ export type PBRMaterialUniforms = {
|
|
|
51
32
|
scaleDiffBaseMR: Readonly<Vector4 | NumberArray4>;
|
|
52
33
|
scaleFGDSpec: Readonly<Vector4 | NumberArray4>;
|
|
53
34
|
};
|
|
35
|
+
export type PBRMaterialProps = PBRMaterialBindings & PBRMaterialUniforms;
|
|
54
36
|
/**
|
|
55
37
|
* An implementation of PBR (Physically-Based Rendering).
|
|
56
38
|
* Physically Based Shading of a microfacet surface defined by a glTF material.
|
|
57
39
|
*/
|
|
58
40
|
export declare const pbrMaterial: ShaderModule<PBRMaterialProps, PBRMaterialUniforms>;
|
|
59
|
-
export {};
|
|
60
41
|
//# 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,OAAO,EAAC,MAAM,eAAe,CAAC;AAC3C,OAAO,KAAK,EAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAC,MAAM,eAAe,CAAC;AAC7D,OAAO,KAAK,EAAC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAC,4CAAyC;AAE/F,OAAO,EAAC,YAAY,EAAC,oDAAiD;
|
|
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,EAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAC,MAAM,eAAe,CAAC;AAC7D,OAAO,KAAK,EAAC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAC,4CAAyC;AAE/F,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,EAAE,OAAO,CAAC;IAGf,mBAAmB,EAAE,OAAO,CAAC;IAC7B,eAAe,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAElD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IAEpB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAEjD,uBAAuB,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAC1D,2BAA2B,EAAE,OAAO,CAAC;IAErC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAE1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IAGpB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAIlD,eAAe,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;IAClD,YAAY,EAAE,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAEzE;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,YAAY,CAAC,gBAAgB,EAAE,mBAAmB,CAkD3E,CAAC"}
|
|
@@ -4,25 +4,28 @@
|
|
|
4
4
|
import { lighting } from "../lights/lighting-uniforms.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.
|
|
10
11
|
*/
|
|
11
12
|
export const pbrMaterial = {
|
|
12
|
-
name: '
|
|
13
|
+
name: 'pbrMaterial',
|
|
13
14
|
vs,
|
|
14
15
|
fs,
|
|
15
16
|
defines: {
|
|
16
|
-
LIGHTING_FRAGMENT: 1
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
LIGHTING_FRAGMENT: 1
|
|
18
|
+
// TODO defining these as 0 breaks shader
|
|
19
|
+
// HAS_NORMALMAP: 0
|
|
20
|
+
// HAS_EMISSIVEMAP: 0,
|
|
21
|
+
// HAS_OCCLUSIONMAP: 0,
|
|
22
|
+
// HAS_BASECOLORMAP: 0,
|
|
23
|
+
// HAS_METALROUGHNESSMAP: 0,
|
|
24
|
+
// ALPHA_CUTOFF: 0
|
|
25
|
+
// USE_IBL: 0
|
|
26
|
+
// PBR_DEBUG: 0
|
|
25
27
|
},
|
|
28
|
+
getUniforms: props => props,
|
|
26
29
|
uniformTypes: {
|
|
27
30
|
// Material is unlit
|
|
28
31
|
unlit: 'i32',
|
|
@@ -47,5 +50,5 @@ export const pbrMaterial = {
|
|
|
47
50
|
scaleDiffBaseMR: 'vec4<f32>',
|
|
48
51
|
scaleFGDSpec: 'vec4<f32>'
|
|
49
52
|
},
|
|
50
|
-
dependencies: [lighting]
|
|
53
|
+
dependencies: [lighting, pbrProjection]
|
|
51
54
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { NumberArray3, NumberArray16 } from "../../../lib/utils/uniform-types.js";
|
|
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,4CAAyC;AAElF,OAAO,EAAC,YAAY,EAAC,oDAAiD;AAatE,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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { glsl } from "../../../lib/glsl-utils/highlight.js";
|
|
5
|
+
const uniformBlock = `\
|
|
6
|
+
uniform pbrProjectionUniforms {
|
|
7
|
+
mat4 modelViewProjectionMatrix;
|
|
8
|
+
mat4 modelMatrix;
|
|
9
|
+
mat4 normalMatrix;
|
|
10
|
+
vec3 camera;
|
|
11
|
+
} pbrProjection;
|
|
12
|
+
`;
|
|
13
|
+
export const pbrProjection = {
|
|
14
|
+
name: 'pbrProjection',
|
|
15
|
+
vs: uniformBlock,
|
|
16
|
+
fs: uniformBlock,
|
|
17
|
+
// TODO why is this needed?
|
|
18
|
+
getUniforms: props => props,
|
|
19
|
+
uniformTypes: {
|
|
20
|
+
modelViewProjectionMatrix: 'mat4x4<f32>',
|
|
21
|
+
modelMatrix: 'mat4x4<f32>',
|
|
22
|
+
normalMatrix: 'mat4x4<f32>',
|
|
23
|
+
camera: 'vec3<i32>'
|
|
24
|
+
}
|
|
25
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pbr-vertex-glsl.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/pbr-material/pbr-vertex-glsl.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"pbr-vertex-glsl.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/pbr-material/pbr-vertex-glsl.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,EAAE,QAkCd,CAAC"}
|
|
@@ -3,33 +3,27 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
import { glsl } from "../../../lib/glsl-utils/highlight.js";
|
|
5
5
|
export const vs = `\
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
mat4 u_ModelMatrix;
|
|
9
|
-
mat4 u_NormalMatrix;
|
|
10
|
-
vec3 u_Camera;
|
|
11
|
-
}
|
|
12
|
-
varying vec3 pbr_vPosition;
|
|
13
|
-
varying vec2 pbr_vUV;
|
|
6
|
+
out vec3 pbr_vPosition;
|
|
7
|
+
out vec2 pbr_vUV;
|
|
14
8
|
#ifdef HAS_NORMALS
|
|
15
9
|
# ifdef HAS_TANGENTS
|
|
16
|
-
|
|
10
|
+
out mat3 pbr_vTBN;
|
|
17
11
|
# else
|
|
18
|
-
|
|
12
|
+
out vec3 pbr_vNormal;
|
|
19
13
|
# endif
|
|
20
14
|
#endif
|
|
21
15
|
void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, vec2 uv)
|
|
22
16
|
{
|
|
23
|
-
vec4 pos =
|
|
17
|
+
vec4 pos = pbrProjection.modelMatrix * position;
|
|
24
18
|
pbr_vPosition = vec3(pos.xyz) / pos.w;
|
|
25
19
|
#ifdef HAS_NORMALS
|
|
26
20
|
#ifdef HAS_TANGENTS
|
|
27
|
-
vec3 normalW = normalize(vec3(
|
|
28
|
-
vec3 tangentW = normalize(vec3(
|
|
21
|
+
vec3 normalW = normalize(vec3(pbrProjection.normalMatrix * vec4(normal.xyz, 0.0)));
|
|
22
|
+
vec3 tangentW = normalize(vec3(pbrProjection.modelMatrix * vec4(tangent.xyz, 0.0)));
|
|
29
23
|
vec3 bitangentW = cross(normalW, tangentW) * tangent.w;
|
|
30
24
|
pbr_vTBN = mat3(tangentW, bitangentW, normalW);
|
|
31
25
|
#else
|
|
32
|
-
pbr_vNormal = normalize(vec3(
|
|
26
|
+
pbr_vNormal = normalize(vec3(pbrProjection.modelMatrix * vec4(normal.xyz, 0.0)));
|
|
33
27
|
#endif
|
|
34
28
|
#endif
|
|
35
29
|
#ifdef HAS_UV
|
|
@@ -30,6 +30,6 @@ export const phongMaterial = {
|
|
|
30
30
|
if (uniforms.specularColor) {
|
|
31
31
|
uniforms.specularColor = uniforms.specularColor.map(x => x / 255);
|
|
32
32
|
}
|
|
33
|
-
return { ...phongMaterial.defaultUniforms, ...
|
|
33
|
+
return { ...phongMaterial.defaultUniforms, ...uniforms };
|
|
34
34
|
}
|
|
35
35
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"phong-shaders-glsl.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/phong-material/phong-shaders-glsl.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,QAAQ,QAOpB,CAAC;AAEF,eAAO,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"phong-shaders-glsl.d.ts","sourceRoot":"","sources":["../../../../src/modules/lighting/phong-material/phong-shaders-glsl.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,QAAQ,QAOpB,CAAC;AAEF,eAAO,MAAM,QAAQ,QA8CpB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luma.gl/shadertools",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.24",
|
|
4
4
|
"description": "Shader module system for luma.gl",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"@math.gl/types": "^4.0.0",
|
|
54
54
|
"wgsl_reflect": "^1.0.1"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "7fa4bc29cb5b4eb1997ac33a37139d2186c0a7f0"
|
|
57
57
|
}
|
package/src/index.ts
CHANGED
|
@@ -75,7 +75,13 @@ export type {GouraudMaterialProps} from './modules/lighting/gouraud-material/gou
|
|
|
75
75
|
export {gouraudMaterial} from './modules/lighting/gouraud-material/gouraud-material';
|
|
76
76
|
export type {PhongMaterialProps} from './modules/lighting/phong-material/phong-material';
|
|
77
77
|
export {phongMaterial} from './modules/lighting/phong-material/phong-material';
|
|
78
|
-
|
|
78
|
+
export type {
|
|
79
|
+
PBRMaterialBindings,
|
|
80
|
+
PBRMaterialProps,
|
|
81
|
+
PBRMaterialUniforms
|
|
82
|
+
} from './modules/lighting/pbr-material/pbr-material';
|
|
83
|
+
export type {PBRProjectionProps} from './modules/lighting/pbr-material/pbr-projection';
|
|
84
|
+
|
|
79
85
|
export {pbrMaterial} from './modules/lighting/pbr-material/pbr-material';
|
|
80
86
|
|
|
81
87
|
// POST PROCESSING / SHADER PASS MODULES
|
|
@@ -42,6 +42,6 @@ export const gouraudMaterial: ShaderModule<GouraudMaterialProps> = {
|
|
|
42
42
|
if (uniforms.specularColor) {
|
|
43
43
|
uniforms.specularColor = uniforms.specularColor.map(x => x / 255) as NumberArray3;
|
|
44
44
|
}
|
|
45
|
-
return {...gouraudMaterial.defaultUniforms, ...
|
|
45
|
+
return {...gouraudMaterial.defaultUniforms, ...uniforms};
|
|
46
46
|
}
|
|
47
47
|
};
|