@luma.gl/gltf 9.0.23 → 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 CHANGED
@@ -73,9 +73,9 @@ var __exports__ = (() => {
73
73
  bindings: {},
74
74
  uniforms: {
75
75
  // TODO: find better values?
76
- u_Camera: [0, 0, 0],
76
+ camera: [0, 0, 0],
77
77
  // Model should override
78
- u_MetallicRoughnessValues: [1, 1]
78
+ metallicRoughnessValues: [1, 1]
79
79
  // Default is 1 and 1
80
80
  },
81
81
  parameters: {},
@@ -85,15 +85,15 @@ var __exports__ = (() => {
85
85
  parsedMaterial.defines.USE_TEX_LOD = 1;
86
86
  const { imageBasedLightingEnvironment } = options;
87
87
  if (imageBasedLightingEnvironment) {
88
- parsedMaterial.bindings.u_DiffuseEnvSampler = imageBasedLightingEnvironment.diffuseEnvSampler;
89
- parsedMaterial.bindings.u_SpecularEnvSampler = imageBasedLightingEnvironment.specularEnvSampler;
90
- parsedMaterial.bindings.u_brdfLUT = imageBasedLightingEnvironment.brdfLutTexture;
91
- parsedMaterial.uniforms.u_ScaleIBLAmbient = [1, 1];
88
+ parsedMaterial.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.diffuseEnvSampler;
89
+ parsedMaterial.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.specularEnvSampler;
90
+ parsedMaterial.bindings.pbr_BrdfLUT = imageBasedLightingEnvironment.brdfLutTexture;
91
+ parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];
92
92
  }
93
93
  if (options?.pbrDebug) {
94
94
  parsedMaterial.defines.PBR_DEBUG = 1;
95
- parsedMaterial.uniforms.u_ScaleDiffBaseMR = [0, 0, 0, 0];
96
- parsedMaterial.uniforms.u_ScaleFGDSpec = [0, 0, 0, 0];
95
+ parsedMaterial.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];
96
+ parsedMaterial.uniforms.scaleFGDSpec = [0, 0, 0, 0];
97
97
  }
98
98
  if (attributes.NORMAL)
99
99
  parsedMaterial.defines.HAS_NORMALS = 1;
@@ -111,41 +111,47 @@ var __exports__ = (() => {
111
111
  return parsedMaterial;
112
112
  }
113
113
  function parseMaterial(device, material, parsedMaterial) {
114
- parsedMaterial.uniforms.pbr_uUnlit = Boolean(material.unlit);
114
+ parsedMaterial.uniforms.unlit = Boolean(material.unlit);
115
115
  if (material.pbrMetallicRoughness) {
116
116
  parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial);
117
117
  }
118
118
  if (material.normalTexture) {
119
- addTexture(device, material.normalTexture, "u_NormalSampler", "HAS_NORMALMAP", parsedMaterial);
119
+ addTexture(
120
+ device,
121
+ material.normalTexture,
122
+ "pbr_normalSampler",
123
+ "HAS_NORMALMAP",
124
+ parsedMaterial
125
+ );
120
126
  const { scale: scale4 = 1 } = material.normalTexture;
121
- parsedMaterial.uniforms.u_NormalScale = scale4;
127
+ parsedMaterial.uniforms.normalScale = scale4;
122
128
  }
123
129
  if (material.occlusionTexture) {
124
130
  addTexture(
125
131
  device,
126
132
  material.occlusionTexture,
127
- "u_OcclusionSampler",
133
+ "pbr_occlusionSampler",
128
134
  "HAS_OCCLUSIONMAP",
129
135
  parsedMaterial
130
136
  );
131
137
  const { strength = 1 } = material.occlusionTexture;
132
- parsedMaterial.uniforms.u_OcclusionStrength = strength;
138
+ parsedMaterial.uniforms.occlusionStrength = strength;
133
139
  }
134
140
  if (material.emissiveTexture) {
135
141
  addTexture(
136
142
  device,
137
143
  material.emissiveTexture,
138
- "u_EmissiveSampler",
144
+ "pbr_emissiveSampler",
139
145
  "HAS_EMISSIVEMAP",
140
146
  parsedMaterial
141
147
  );
142
- parsedMaterial.uniforms.u_EmissiveFactor = material.emissiveFactor || [0, 0, 0];
148
+ parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
143
149
  }
144
150
  switch (material.alphaMode) {
145
151
  case "MASK":
146
152
  const { alphaCutoff = 0.5 } = material;
147
153
  parsedMaterial.defines.ALPHA_CUTOFF = 1;
148
- parsedMaterial.uniforms.u_AlphaCutoff = alphaCutoff;
154
+ parsedMaterial.uniforms.alphaCutoff = alphaCutoff;
149
155
  break;
150
156
  case "BLEND":
151
157
  import_core.log.warn("glTF BLEND alphaMode might not work well because it requires mesh sorting")();
@@ -171,23 +177,23 @@ var __exports__ = (() => {
171
177
  addTexture(
172
178
  device,
173
179
  pbrMetallicRoughness.baseColorTexture,
174
- "u_BaseColorSampler",
180
+ "pbr_baseColorSampler",
175
181
  "HAS_BASECOLORMAP",
176
182
  parsedMaterial
177
183
  );
178
184
  }
179
- parsedMaterial.uniforms.u_BaseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];
185
+ parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];
180
186
  if (pbrMetallicRoughness.metallicRoughnessTexture) {
181
187
  addTexture(
182
188
  device,
183
189
  pbrMetallicRoughness.metallicRoughnessTexture,
184
- "u_MetallicRoughnessSampler",
190
+ "pbr_metallicRoughnessSampler",
185
191
  "HAS_METALROUGHNESSMAP",
186
192
  parsedMaterial
187
193
  );
188
194
  }
189
195
  const { metallicFactor = 1, roughnessFactor = 1 } = pbrMetallicRoughness;
190
- parsedMaterial.uniforms.u_MetallicRoughnessValues = [metallicFactor, roughnessFactor];
196
+ parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];
191
197
  }
192
198
  function addTexture(device, gltfTexture, uniformName, define = null, parsedMaterial) {
193
199
  const parameters = gltfTexture?.texture?.sampler?.parameters || {};
@@ -3570,25 +3576,24 @@ var __exports__ = (() => {
3570
3576
  }
3571
3577
 
3572
3578
  // src/gltf/create-gltf-model.ts
3573
- var import_core4 = __toESM(require_core(), 1);
3579
+ var import_core5 = __toESM(require_core(), 1);
3574
3580
 
3575
3581
  // ../shadertools/src/lib/glsl-utils/highlight.ts
3576
3582
  var glsl = (x) => `${x}`;
3577
3583
 
3578
- // ../shadertools/src/modules-webgl1/lighting/lights/lights-glsl.ts
3579
- var lightingShader = glsl`\
3580
- #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))
3584
+ // ../shadertools/src/modules/lighting/lights/lighting-uniforms-glsl.ts
3585
+ var lightingUniforms = glsl`\
3586
+ precision highp int;
3581
3587
 
3588
+ // #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))
3582
3589
  struct AmbientLight {
3583
- vec3 color;
3590
+ vec3 color;
3584
3591
  };
3585
3592
 
3586
3593
  struct PointLight {
3587
- vec3 color;
3588
- vec3 position;
3589
-
3590
- // Constant-Linear-Exponential
3591
- vec3 attenuation;
3594
+ vec3 color;
3595
+ vec3 position;
3596
+ vec3 attenuation; // 2nd order x:Constant-y:Linear-z:Exponential
3592
3597
  };
3593
3598
 
3594
3599
  struct DirectionalLight {
@@ -3596,13 +3601,54 @@ struct DirectionalLight {
3596
3601
  vec3 direction;
3597
3602
  };
3598
3603
 
3599
- uniform AmbientLight lighting_uAmbientLight;
3600
- uniform PointLight lighting_uPointLight[MAX_LIGHTS];
3601
- uniform DirectionalLight lighting_uDirectionalLight[MAX_LIGHTS];
3602
- uniform int lighting_uPointLightCount;
3603
- uniform int lighting_uDirectionalLightCount;
3604
+ uniform lightingUniforms {
3605
+ int enabled;
3606
+ int lightType;
3607
+
3608
+ int directionalLightCount;
3609
+ int pointLightCount;
3610
+
3611
+ vec3 ambientColor;
3612
+
3613
+ vec3 lightColor0;
3614
+ vec3 lightPosition0;
3615
+ vec3 lightDirection0;
3616
+ vec3 lightAttenuation0;
3617
+
3618
+ vec3 lightColor1;
3619
+ vec3 lightPosition1;
3620
+ vec3 lightDirection1;
3621
+ vec3 lightAttenuation1;
3622
+
3623
+ vec3 lightColor2;
3624
+ vec3 lightPosition2;
3625
+ vec3 lightDirection2;
3626
+ vec3 lightAttenuation2;
3627
+ } lighting;
3628
+
3629
+ PointLight lighting_getPointLight(int index) {
3630
+ switch (index) {
3631
+ case 0:
3632
+ return PointLight(lighting.lightColor0, lighting.lightPosition0, lighting.lightAttenuation0);
3633
+ case 1:
3634
+ return PointLight(lighting.lightColor1, lighting.lightPosition1, lighting.lightAttenuation1);
3635
+ case 2:
3636
+ default:
3637
+ return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2);
3638
+ }
3639
+ }
3604
3640
 
3605
- uniform bool lighting_uEnabled;
3641
+ DirectionalLight lighting_getDirectionalLight(int index) {
3642
+ switch (index) {
3643
+ case 0:
3644
+ return DirectionalLight(lighting.lightColor0, lighting.lightDirection0);
3645
+ case 1:
3646
+ return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
3647
+ case 2:
3648
+ default:
3649
+ return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);
3650
+ }
3651
+ }
3606
3652
 
3607
3653
  float getPointLightAttenuation(PointLight pointLight, float distance) {
3608
3654
  return pointLight.attenuation.x
@@ -3610,16 +3656,87 @@ float getPointLightAttenuation(PointLight pointLight, float distance) {
3610
3656
  + pointLight.attenuation.z * distance * distance;
3611
3657
  }
3612
3658
 
3613
- #endif
3659
+ // #endif
3614
3660
  `;
3615
3661
 
3616
- // ../shadertools/src/modules-webgl1/lighting/lights/lights.ts
3617
- var INITIAL_MODULE_OPTIONS = {
3618
- lightSources: {}
3662
+ // ../shadertools/src/modules/lighting/lights/lighting-uniforms.ts
3663
+ var import_core4 = __toESM(require_core(), 1);
3664
+ var MAX_LIGHTS = 3;
3665
+ var COLOR_FACTOR = 255;
3666
+ var lighting = {
3667
+ name: "lighting",
3668
+ vs: lightingUniforms,
3669
+ fs: lightingUniforms,
3670
+ getUniforms(props, prevUniforms) {
3671
+ return getUniforms(props);
3672
+ },
3673
+ defines: {
3674
+ MAX_LIGHTS
3675
+ },
3676
+ uniformTypes: {
3677
+ enabled: "i32",
3678
+ lightType: "i32",
3679
+ directionalLightCount: "i32",
3680
+ pointLightCount: "i32",
3681
+ ambientLightColor: "vec3<f32>",
3682
+ // TODO define as arrays once we have appropriate uniformTypes
3683
+ lightColor0: "vec3<f32>",
3684
+ lightPosition0: "vec3<f32>",
3685
+ // TODO - could combine direction and attenuation
3686
+ lightDirection0: "vec3<f32>",
3687
+ lightAttenuation0: "vec3<f32>",
3688
+ lightColor1: "vec3<f32>",
3689
+ lightPosition1: "vec3<f32>",
3690
+ lightDirection1: "vec3<f32>",
3691
+ lightAttenuation1: "vec3<f32>",
3692
+ lightColor2: "vec3<f32>",
3693
+ lightPosition2: "vec3<f32>",
3694
+ lightDirection2: "vec3<f32>",
3695
+ lightAttenuation2: "vec3<f32>"
3696
+ },
3697
+ defaultUniforms: {
3698
+ enabled: 1,
3699
+ lightType: 0 /* POINT */,
3700
+ directionalLightCount: 0,
3701
+ pointLightCount: 0,
3702
+ ambientLightColor: [0.1, 0.1, 0.1],
3703
+ lightColor0: [1, 1, 1],
3704
+ lightPosition0: [1, 1, 2],
3705
+ // TODO - could combine direction and attenuation
3706
+ lightDirection0: [1, 1, 1],
3707
+ lightAttenuation0: [1, 0, 0],
3708
+ lightColor1: [1, 1, 1],
3709
+ lightPosition1: [1, 1, 2],
3710
+ lightDirection1: [1, 1, 1],
3711
+ lightAttenuation1: [1, 0, 0],
3712
+ lightColor2: [1, 1, 1],
3713
+ lightPosition2: [1, 1, 2],
3714
+ lightDirection2: [1, 1, 1],
3715
+ lightAttenuation2: [1, 0, 0]
3716
+ }
3619
3717
  };
3620
- function convertColor(colorDef = {}) {
3621
- const { color = [0, 0, 0], intensity = 1 } = colorDef;
3622
- return color.map((component) => component * intensity / 255);
3718
+ function getUniforms(props, prevUniforms = {}) {
3719
+ props = props ? { ...props } : props;
3720
+ if (!props) {
3721
+ return { ...lighting.defaultUniforms };
3722
+ }
3723
+ if (props.lights) {
3724
+ props = { ...props, ...extractLightTypes(props.lights), lights: void 0 };
3725
+ }
3726
+ const { ambientLight, pointLights, directionalLights } = props || {};
3727
+ const hasLights = ambientLight || pointLights && pointLights.length > 0 || directionalLights && directionalLights.length > 0;
3728
+ if (!hasLights) {
3729
+ return { ...lighting.defaultUniforms, enabled: 0 };
3730
+ }
3731
+ const uniforms = {
3732
+ ...lighting.defaultUniforms,
3733
+ ...prevUniforms,
3734
+ ...getLightSourceUniforms({ ambientLight, pointLights, directionalLights })
3735
+ };
3736
+ if (props.enabled !== void 0) {
3737
+ uniforms.enabled = props.enabled ? 1 : 0;
3738
+ }
3739
+ return uniforms;
3623
3740
  }
3624
3741
  function getLightSourceUniforms({
3625
3742
  ambientLight,
@@ -3627,79 +3744,55 @@ float getPointLightAttenuation(PointLight pointLight, float distance) {
3627
3744
  directionalLights = []
3628
3745
  }) {
3629
3746
  const lightSourceUniforms = {};
3630
- if (ambientLight) {
3631
- lightSourceUniforms["lighting_uAmbientLight.color"] = convertColor(ambientLight);
3632
- } else {
3633
- lightSourceUniforms["lighting_uAmbientLight.color"] = [0, 0, 0];
3634
- }
3635
- pointLights.forEach((pointLight, index) => {
3636
- lightSourceUniforms[`lighting_uPointLight[${index}].color`] = convertColor(pointLight);
3637
- lightSourceUniforms[`lighting_uPointLight[${index}].position`] = pointLight.position;
3638
- lightSourceUniforms[`lighting_uPointLight[${index}].attenuation`] = pointLight.attenuation || [
3639
- 1,
3640
- 0,
3641
- 0
3642
- ];
3643
- });
3644
- lightSourceUniforms.lighting_uPointLightCount = pointLights.length;
3645
- directionalLights.forEach((directionalLight, index) => {
3646
- lightSourceUniforms[`lighting_uDirectionalLight[${index}].color`] = convertColor(directionalLight);
3647
- lightSourceUniforms[`lighting_uDirectionalLight[${index}].direction`] = directionalLight.direction;
3648
- });
3649
- lightSourceUniforms.lighting_uDirectionalLightCount = directionalLights.length;
3747
+ lightSourceUniforms.ambientLightColor = convertColor(ambientLight);
3748
+ let currentLight = 0;
3749
+ for (const pointLight of pointLights) {
3750
+ lightSourceUniforms.lightType = 0 /* POINT */;
3751
+ const i = currentLight;
3752
+ lightSourceUniforms[`lightColor${i}`] = convertColor(pointLight);
3753
+ lightSourceUniforms[`lightPosition${i}`] = pointLight.position;
3754
+ lightSourceUniforms[`lightAttenuation${i}`] = pointLight.attenuation || [1, 0, 0];
3755
+ currentLight++;
3756
+ }
3757
+ for (const directionalLight of directionalLights) {
3758
+ lightSourceUniforms.lightType = 1 /* DIRECTIONAL */;
3759
+ const i = currentLight;
3760
+ lightSourceUniforms[`lightColor${i}`] = convertColor(directionalLight);
3761
+ lightSourceUniforms[`lightDirection${i}`] = directionalLight.direction;
3762
+ currentLight++;
3763
+ }
3764
+ if (currentLight > MAX_LIGHTS) {
3765
+ import_core4.log.warn("MAX_LIGHTS exceeded")();
3766
+ }
3767
+ lightSourceUniforms.directionalLightCount = directionalLights.length;
3768
+ lightSourceUniforms.pointLightCount = pointLights.length;
3650
3769
  return lightSourceUniforms;
3651
3770
  }
3652
- function getUniforms(opts = INITIAL_MODULE_OPTIONS) {
3653
- if ("lightSources" in opts) {
3654
- const { ambientLight, pointLights, directionalLights } = opts.lightSources || {};
3655
- const hasLights = ambientLight || pointLights && pointLights.length > 0 || directionalLights && directionalLights.length > 0;
3656
- if (!hasLights) {
3657
- return { lighting_uEnabled: false };
3658
- }
3659
- return Object.assign(
3660
- {},
3661
- getLightSourceUniforms({ ambientLight, pointLights, directionalLights }),
3662
- {
3663
- lighting_uEnabled: true
3664
- }
3665
- );
3666
- }
3667
- if ("lights" in opts) {
3668
- const lightSources = { pointLights: [], directionalLights: [] };
3669
- for (const light of opts.lights || []) {
3670
- switch (light.type) {
3671
- case "ambient":
3672
- lightSources.ambientLight = light;
3673
- break;
3674
- case "directional":
3675
- lightSources.directionalLights?.push(light);
3676
- break;
3677
- case "point":
3678
- lightSources.pointLights?.push(light);
3679
- break;
3680
- default:
3681
- }
3771
+ function extractLightTypes(lights) {
3772
+ const lightSources = { pointLights: [], directionalLights: [] };
3773
+ for (const light of lights || []) {
3774
+ switch (light.type) {
3775
+ case "ambient":
3776
+ lightSources.ambientLight = light;
3777
+ break;
3778
+ case "directional":
3779
+ lightSources.directionalLights?.push(light);
3780
+ break;
3781
+ case "point":
3782
+ lightSources.pointLights?.push(light);
3783
+ break;
3784
+ default:
3682
3785
  }
3683
- return getUniforms({ lightSources });
3684
3786
  }
3685
- return {};
3787
+ return lightSources;
3788
+ }
3789
+ function convertColor(colorDef = {}) {
3790
+ const { color = [0, 0, 0], intensity = 1 } = colorDef;
3791
+ return color.map((component) => component * intensity / COLOR_FACTOR);
3686
3792
  }
3687
- var lights = {
3688
- name: "lights",
3689
- vs: lightingShader,
3690
- fs: lightingShader,
3691
- getUniforms,
3692
- defines: {
3693
- MAX_LIGHTS: 3
3694
- }
3695
- };
3696
3793
 
3697
- // ../shadertools/src/modules-webgl1/lighting/pbr/pbr-vertex-glsl.ts
3794
+ // ../shadertools/src/modules/lighting/pbr-material/pbr-vertex-glsl.ts
3698
3795
  var vs = glsl`\
3699
- uniform mat4 u_MVPMatrix;
3700
- uniform mat4 u_ModelMatrix;
3701
- uniform mat4 u_NormalMatrix;
3702
-
3703
3796
  out vec3 pbr_vPosition;
3704
3797
  out vec2 pbr_vUV;
3705
3798
 
@@ -3713,17 +3806,17 @@ out vec3 pbr_vNormal;
3713
3806
 
3714
3807
  void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, vec2 uv)
3715
3808
  {
3716
- vec4 pos = u_ModelMatrix * position;
3809
+ vec4 pos = pbrProjection.modelMatrix * position;
3717
3810
  pbr_vPosition = vec3(pos.xyz) / pos.w;
3718
3811
 
3719
3812
  #ifdef HAS_NORMALS
3720
3813
  #ifdef HAS_TANGENTS
3721
- vec3 normalW = normalize(vec3(u_NormalMatrix * vec4(normal.xyz, 0.0)));
3722
- vec3 tangentW = normalize(vec3(u_ModelMatrix * vec4(tangent.xyz, 0.0)));
3814
+ vec3 normalW = normalize(vec3(pbrProjection.normalMatrix * vec4(normal.xyz, 0.0)));
3815
+ vec3 tangentW = normalize(vec3(pbrProjection.modelMatrix * vec4(tangent.xyz, 0.0)));
3723
3816
  vec3 bitangentW = cross(normalW, tangentW) * tangent.w;
3724
3817
  pbr_vTBN = mat3(tangentW, bitangentW, normalW);
3725
3818
  #else // HAS_TANGENTS != 1
3726
- pbr_vNormal = normalize(vec3(u_ModelMatrix * vec4(normal.xyz, 0.0)));
3819
+ pbr_vNormal = normalize(vec3(pbrProjection.modelMatrix * vec4(normal.xyz, 0.0)));
3727
3820
  #endif
3728
3821
  #endif
3729
3822
 
@@ -3735,55 +3828,69 @@ void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, ve
3735
3828
  }
3736
3829
  `;
3737
3830
 
3738
- // ../shadertools/src/modules-webgl1/lighting/pbr/pbr-fragment-glsl.ts
3831
+ // ../shadertools/src/modules/lighting/pbr-material/pbr-fragment-glsl.ts
3739
3832
  var fs = glsl`\
3740
3833
  precision highp float;
3741
3834
 
3742
- uniform bool pbr_uUnlit;
3743
-
3744
- #ifdef USE_IBL
3745
- uniform samplerCube u_DiffuseEnvSampler;
3746
- uniform samplerCube u_SpecularEnvSampler;
3747
- uniform sampler2D u_brdfLUT;
3748
- uniform vec2 u_ScaleIBLAmbient;
3749
- #endif
3750
-
3835
+ uniform pbrMaterialUniforms {
3836
+ // Material is unlit
3837
+ bool unlit;
3838
+
3839
+ // Base color map
3840
+ bool baseColorMapEnabled;
3841
+ vec4 baseColorFactor;
3842
+
3843
+ bool normalMapEnabled;
3844
+ float normalScale; // #ifdef HAS_NORMALMAP
3845
+
3846
+ bool emissiveMapEnabled;
3847
+ vec3 emissiveFactor; // #ifdef HAS_EMISSIVEMAP
3848
+
3849
+ vec2 metallicRoughnessValues;
3850
+ bool metallicRoughnessMapEnabled;
3851
+
3852
+ bool occlusionMapEnabled;
3853
+ float occlusionStrength; // #ifdef HAS_OCCLUSIONMAP
3854
+
3855
+ bool alphaCutoffEnabled;
3856
+ float alphaCutoff; // #ifdef ALPHA_CUTOFF
3857
+
3858
+ // IBL
3859
+ bool IBLenabled;
3860
+ vec2 scaleIBLAmbient; // #ifdef USE_IBL
3861
+
3862
+ // debugging flags used for shader output of intermediate PBR variables
3863
+ // #ifdef PBR_DEBUG
3864
+ vec4 scaleDiffBaseMR;
3865
+ vec4 scaleFGDSpec;
3866
+ // #endif
3867
+ } pbrMaterial;
3868
+
3869
+ // Samplers
3751
3870
  #ifdef HAS_BASECOLORMAP
3752
- uniform sampler2D u_BaseColorSampler;
3871
+ uniform sampler2D pbr_baseColorSampler;
3753
3872
  #endif
3754
3873
  #ifdef HAS_NORMALMAP
3755
- uniform sampler2D u_NormalSampler;
3756
- uniform float u_NormalScale;
3874
+ uniform sampler2D pbr_normalSampler;
3757
3875
  #endif
3758
3876
  #ifdef HAS_EMISSIVEMAP
3759
- uniform sampler2D u_EmissiveSampler;
3760
- uniform vec3 u_EmissiveFactor;
3877
+ uniform sampler2D pbr_emissiveSampler;
3761
3878
  #endif
3762
3879
  #ifdef HAS_METALROUGHNESSMAP
3763
- uniform sampler2D u_MetallicRoughnessSampler;
3880
+ uniform sampler2D pbr_metallicRoughnessSampler;
3764
3881
  #endif
3765
3882
  #ifdef HAS_OCCLUSIONMAP
3766
- uniform sampler2D u_OcclusionSampler;
3767
- uniform float u_OcclusionStrength;
3883
+ uniform sampler2D pbr_occlusionSampler;
3768
3884
  #endif
3769
-
3770
- #ifdef ALPHA_CUTOFF
3771
- uniform float u_AlphaCutoff;
3885
+ #ifdef USE_IBL
3886
+ uniform samplerCube pbr_diffuseEnvSampler;
3887
+ uniform samplerCube pbr_specularEnvSampler;
3888
+ uniform sampler2D pbr_brdfLUT;
3772
3889
  #endif
3773
3890
 
3774
- uniform vec2 u_MetallicRoughnessValues;
3775
- uniform vec4 u_BaseColorFactor;
3776
-
3777
- uniform vec3 u_Camera;
3778
-
3779
- // debugging flags used for shader output of intermediate PBR variables
3780
- #ifdef PBR_DEBUG
3781
- uniform vec4 u_ScaleDiffBaseMR;
3782
- uniform vec4 u_ScaleFGDSpec;
3783
- #endif
3891
+ // Inputs from vertex shader
3784
3892
 
3785
3893
  in vec3 pbr_vPosition;
3786
-
3787
3894
  in vec2 pbr_vUV;
3788
3895
 
3789
3896
  #ifdef HAS_NORMALS
@@ -3797,8 +3904,7 @@ in vec3 pbr_vNormal;
3797
3904
  // Encapsulate the various inputs used by the various functions in the shading equation
3798
3905
  // We store values in this struct to simplify the integration of alternative implementations
3799
3906
  // of the shading terms, outlined in the Readme.MD Appendix.
3800
- struct PBRInfo
3801
- {
3907
+ struct PBRInfo {
3802
3908
  float NdotL; // cos angle between normal and light direction
3803
3909
  float NdotV; // cos angle between normal and view direction
3804
3910
  float NdotH; // cos angle between normal and half vector
@@ -3823,7 +3929,7 @@ vec4 SRGBtoLINEAR(vec4 srgbIn)
3823
3929
  #ifdef MANUAL_SRGB
3824
3930
  #ifdef SRGB_FAST_APPROXIMATION
3825
3931
  vec3 linOut = pow(srgbIn.xyz,vec3(2.2));
3826
- #else //SRGB_FAST_APPROXIMATION
3932
+ #else // SRGB_FAST_APPROXIMATION
3827
3933
  vec3 bLess = step(vec3(0.04045),srgbIn.xyz);
3828
3934
  vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess );
3829
3935
  #endif //SRGB_FAST_APPROXIMATION
@@ -3859,8 +3965,8 @@ vec3 getNormal()
3859
3965
  #endif
3860
3966
 
3861
3967
  #ifdef HAS_NORMALMAP
3862
- vec3 n = texture(u_NormalSampler, pbr_vUV).rgb;
3863
- n = normalize(tbn * ((2.0 * n - 1.0) * vec3(u_NormalScale, u_NormalScale, 1.0)));
3968
+ vec3 n = texture(pbr_normalSampler, pbr_vUV).rgb;
3969
+ n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
3864
3970
  #else
3865
3971
  // The tbn matrix is linearly interpolated, so we need to re-normalize
3866
3972
  vec3 n = normalize(tbn[2].xyz);
@@ -3873,27 +3979,27 @@ vec3 getNormal()
3873
3979
  // Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
3874
3980
  // See our README.md on Environment Maps [3] for additional discussion.
3875
3981
  #ifdef USE_IBL
3876
- vec3 getIBLContribution(PBRInfo pbrInputs, vec3 n, vec3 reflection)
3982
+ vec3 getIBLContribution(PBRInfo pbrInfo, vec3 n, vec3 reflection)
3877
3983
  {
3878
3984
  float mipCount = 9.0; // resolution of 512x512
3879
- float lod = (pbrInputs.perceptualRoughness * mipCount);
3985
+ float lod = (pbrInfo.perceptualRoughness * mipCount);
3880
3986
  // retrieve a scale and bias to F0. See [1], Figure 3
3881
- vec3 brdf = SRGBtoLINEAR(texture(u_brdfLUT,
3882
- vec2(pbrInputs.NdotV, 1.0 - pbrInputs.perceptualRoughness))).rgb;
3883
- vec3 diffuseLight = SRGBtoLINEAR(textureCube(u_DiffuseEnvSampler, n)).rgb;
3987
+ vec3 brdf = SRGBtoLINEAR(texture(pbr_brdfLUT,
3988
+ vec2(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness))).rgb;
3989
+ vec3 diffuseLight = SRGBtoLINEAR(texture(pbr_diffuseEnvSampler, n)).rgb;
3884
3990
 
3885
3991
  #ifdef USE_TEX_LOD
3886
- vec3 specularLight = SRGBtoLINEAR(textureCubeLod(u_SpecularEnvSampler, reflection, lod)).rgb;
3992
+ vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection, lod)).rgb;
3887
3993
  #else
3888
- vec3 specularLight = SRGBtoLINEAR(textureCube(u_SpecularEnvSampler, reflection)).rgb;
3994
+ vec3 specularLight = SRGBtoLINEAR(texture(pbr_specularEnvSampler, reflection)).rgb;
3889
3995
  #endif
3890
3996
 
3891
- vec3 diffuse = diffuseLight * pbrInputs.diffuseColor;
3892
- vec3 specular = specularLight * (pbrInputs.specularColor * brdf.x + brdf.y);
3997
+ vec3 diffuse = diffuseLight * pbrInfo.diffuseColor;
3998
+ vec3 specular = specularLight * (pbrInfo.specularColor * brdf.x + brdf.y);
3893
3999
 
3894
4000
  // For presentation, this allows us to disable IBL terms
3895
- diffuse *= u_ScaleIBLAmbient.x;
3896
- specular *= u_ScaleIBLAmbient.y;
4001
+ diffuse *= pbrMaterial.scaleIBLAmbient.x;
4002
+ specular *= pbrMaterial.scaleIBLAmbient.y;
3897
4003
 
3898
4004
  return diffuse + specular;
3899
4005
  }
@@ -3902,29 +4008,29 @@ vec3 getIBLContribution(PBRInfo pbrInputs, vec3 n, vec3 reflection)
3902
4008
  // Basic Lambertian diffuse
3903
4009
  // Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog
3904
4010
  // See also [1], Equation 1
3905
- vec3 diffuse(PBRInfo pbrInputs)
4011
+ vec3 diffuse(PBRInfo pbrInfo)
3906
4012
  {
3907
- return pbrInputs.diffuseColor / M_PI;
4013
+ return pbrInfo.diffuseColor / M_PI;
3908
4014
  }
3909
4015
 
3910
4016
  // The following equation models the Fresnel reflectance term of the spec equation (aka F())
3911
4017
  // Implementation of fresnel from [4], Equation 15
3912
- vec3 specularReflection(PBRInfo pbrInputs)
4018
+ vec3 specularReflection(PBRInfo pbrInfo)
3913
4019
  {
3914
- return pbrInputs.reflectance0 +
3915
- (pbrInputs.reflectance90 - pbrInputs.reflectance0) *
3916
- pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0);
4020
+ return pbrInfo.reflectance0 +
4021
+ (pbrInfo.reflectance90 - pbrInfo.reflectance0) *
4022
+ pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
3917
4023
  }
3918
4024
 
3919
4025
  // This calculates the specular geometric attenuation (aka G()),
3920
4026
  // where rougher material will reflect less light back to the viewer.
3921
4027
  // This implementation is based on [1] Equation 4, and we adopt their modifications to
3922
4028
  // alphaRoughness as input as originally proposed in [2].
3923
- float geometricOcclusion(PBRInfo pbrInputs)
4029
+ float geometricOcclusion(PBRInfo pbrInfo)
3924
4030
  {
3925
- float NdotL = pbrInputs.NdotL;
3926
- float NdotV = pbrInputs.NdotV;
3927
- float r = pbrInputs.alphaRoughness;
4031
+ float NdotL = pbrInfo.NdotL;
4032
+ float NdotV = pbrInfo.NdotV;
4033
+ float r = pbrInfo.alphaRoughness;
3928
4034
 
3929
4035
  float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
3930
4036
  float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
@@ -3937,80 +4043,80 @@ float geometricOcclusion(PBRInfo pbrInputs)
3937
4043
  // for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz
3938
4044
  // Follows the distribution function recommended in the SIGGRAPH 2013 course notes
3939
4045
  // from EPIC Games [1], Equation 3.
3940
- float microfacetDistribution(PBRInfo pbrInputs)
4046
+ float microfacetDistribution(PBRInfo pbrInfo)
3941
4047
  {
3942
- float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness;
3943
- float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;
4048
+ float roughnessSq = pbrInfo.alphaRoughness * pbrInfo.alphaRoughness;
4049
+ float f = (pbrInfo.NdotH * roughnessSq - pbrInfo.NdotH) * pbrInfo.NdotH + 1.0;
3944
4050
  return roughnessSq / (M_PI * f * f);
3945
4051
  }
3946
4052
 
3947
- void PBRInfo_setAmbientLight(inout PBRInfo pbrInputs) {
3948
- pbrInputs.NdotL = 1.0;
3949
- pbrInputs.NdotH = 0.0;
3950
- pbrInputs.LdotH = 0.0;
3951
- pbrInputs.VdotH = 1.0;
4053
+ void PBRInfo_setAmbientLight(inout PBRInfo pbrInfo) {
4054
+ pbrInfo.NdotL = 1.0;
4055
+ pbrInfo.NdotH = 0.0;
4056
+ pbrInfo.LdotH = 0.0;
4057
+ pbrInfo.VdotH = 1.0;
3952
4058
  }
3953
4059
 
3954
- void PBRInfo_setDirectionalLight(inout PBRInfo pbrInputs, vec3 lightDirection) {
3955
- vec3 n = pbrInputs.n;
3956
- vec3 v = pbrInputs.v;
4060
+ void PBRInfo_setDirectionalLight(inout PBRInfo pbrInfo, vec3 lightDirection) {
4061
+ vec3 n = pbrInfo.n;
4062
+ vec3 v = pbrInfo.v;
3957
4063
  vec3 l = normalize(lightDirection); // Vector from surface point to light
3958
4064
  vec3 h = normalize(l+v); // Half vector between both l and v
3959
4065
 
3960
- pbrInputs.NdotL = clamp(dot(n, l), 0.001, 1.0);
3961
- pbrInputs.NdotH = clamp(dot(n, h), 0.0, 1.0);
3962
- pbrInputs.LdotH = clamp(dot(l, h), 0.0, 1.0);
3963
- pbrInputs.VdotH = clamp(dot(v, h), 0.0, 1.0);
4066
+ pbrInfo.NdotL = clamp(dot(n, l), 0.001, 1.0);
4067
+ pbrInfo.NdotH = clamp(dot(n, h), 0.0, 1.0);
4068
+ pbrInfo.LdotH = clamp(dot(l, h), 0.0, 1.0);
4069
+ pbrInfo.VdotH = clamp(dot(v, h), 0.0, 1.0);
3964
4070
  }
3965
4071
 
3966
- void PBRInfo_setPointLight(inout PBRInfo pbrInputs, PointLight pointLight) {
4072
+ void PBRInfo_setPointLight(inout PBRInfo pbrInfo, PointLight pointLight) {
3967
4073
  vec3 light_direction = normalize(pointLight.position - pbr_vPosition);
3968
- PBRInfo_setDirectionalLight(pbrInputs, light_direction);
4074
+ PBRInfo_setDirectionalLight(pbrInfo, light_direction);
3969
4075
  }
3970
4076
 
3971
- vec3 calculateFinalColor(PBRInfo pbrInputs, vec3 lightColor) {
4077
+ vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor) {
3972
4078
  // Calculate the shading terms for the microfacet specular shading model
3973
- vec3 F = specularReflection(pbrInputs);
3974
- float G = geometricOcclusion(pbrInputs);
3975
- float D = microfacetDistribution(pbrInputs);
4079
+ vec3 F = specularReflection(pbrInfo);
4080
+ float G = geometricOcclusion(pbrInfo);
4081
+ float D = microfacetDistribution(pbrInfo);
3976
4082
 
3977
4083
  // Calculation of analytical lighting contribution
3978
- vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
3979
- vec3 specContrib = F * G * D / (4.0 * pbrInputs.NdotL * pbrInputs.NdotV);
4084
+ vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInfo);
4085
+ vec3 specContrib = F * G * D / (4.0 * pbrInfo.NdotL * pbrInfo.NdotV);
3980
4086
  // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
3981
- return pbrInputs.NdotL * lightColor * (diffuseContrib + specContrib);
4087
+ return pbrInfo.NdotL * lightColor * (diffuseContrib + specContrib);
3982
4088
  }
3983
4089
 
3984
4090
  vec4 pbr_filterColor(vec4 colorUnused)
3985
4091
  {
3986
4092
  // The albedo may be defined from a base texture or a flat color
3987
4093
  #ifdef HAS_BASECOLORMAP
3988
- vec4 baseColor = SRGBtoLINEAR(texture(u_BaseColorSampler, pbr_vUV)) * u_BaseColorFactor;
4094
+ vec4 baseColor = SRGBtoLINEAR(texture(pbr_baseColorSampler, pbr_vUV)) * pbrMaterial.baseColorFactor;
3989
4095
  #else
3990
- vec4 baseColor = u_BaseColorFactor;
4096
+ vec4 baseColor = pbrMaterial.baseColorFactor;
3991
4097
  #endif
3992
4098
 
3993
4099
  #ifdef ALPHA_CUTOFF
3994
- if (baseColor.a < u_AlphaCutoff) {
4100
+ if (baseColor.a < pbrMaterial.alphaCutoff) {
3995
4101
  discard;
3996
4102
  }
3997
4103
  #endif
3998
4104
 
3999
4105
  vec3 color = vec3(0, 0, 0);
4000
4106
 
4001
- if(pbr_uUnlit){
4107
+ if(pbrMaterial.unlit){
4002
4108
  color.rgb = baseColor.rgb;
4003
4109
  }
4004
4110
  else{
4005
4111
  // Metallic and Roughness material properties are packed together
4006
4112
  // In glTF, these factors can be specified by fixed scalar values
4007
4113
  // or from a metallic-roughness map
4008
- float perceptualRoughness = u_MetallicRoughnessValues.y;
4009
- float metallic = u_MetallicRoughnessValues.x;
4114
+ float perceptualRoughness = pbrMaterial.metallicRoughnessValues.y;
4115
+ float metallic = pbrMaterial.metallicRoughnessValues.x;
4010
4116
  #ifdef HAS_METALROUGHNESSMAP
4011
4117
  // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
4012
4118
  // This layout intentionally reserves the 'r' channel for (optional) occlusion map data
4013
- vec4 mrSample = texture(u_MetallicRoughnessSampler, pbr_vUV);
4119
+ vec4 mrSample = texture(pbr_metallicRoughnessSampler, pbr_vUV);
4014
4120
  perceptualRoughness = mrSample.g * perceptualRoughness;
4015
4121
  metallic = mrSample.b * metallic;
4016
4122
  #endif
@@ -4037,12 +4143,12 @@ vec4 pbr_filterColor(vec4 colorUnused)
4037
4143
  vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
4038
4144
 
4039
4145
  vec3 n = getNormal(); // normal at surface point
4040
- vec3 v = normalize(u_Camera - pbr_vPosition); // Vector from surface point to camera
4146
+ vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
4041
4147
 
4042
4148
  float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
4043
4149
  vec3 reflection = -normalize(reflect(v, n));
4044
4150
 
4045
- PBRInfo pbrInputs = PBRInfo(
4151
+ PBRInfo pbrInfo = PBRInfo(
4046
4152
  0.0, // NdotL
4047
4153
  NdotV,
4048
4154
  0.0, // NdotH
@@ -4059,43 +4165,50 @@ vec4 pbr_filterColor(vec4 colorUnused)
4059
4165
  v
4060
4166
  );
4061
4167
 
4168
+
4062
4169
  #ifdef USE_LIGHTS
4063
4170
  // Apply ambient light
4064
- PBRInfo_setAmbientLight(pbrInputs);
4065
- color += calculateFinalColor(pbrInputs, lighting_uAmbientLight.color);
4171
+ PBRInfo_setAmbientLight(pbrInfo);
4172
+ color += calculateFinalColor(pbrInfo, lighting.ambientColor);
4066
4173
 
4067
4174
  // Apply directional light
4068
- for(int i = 0; i < lighting_uDirectionalLightCount; i++) {
4069
- if (i < lighting_uDirectionalLightCount) {
4070
- PBRInfo_setDirectionalLight(pbrInputs, lighting_uDirectionalLight[i].direction);
4071
- color += calculateFinalColor(pbrInputs, lighting_uDirectionalLight[i].color);
4175
+ for(int i = 0; i < lighting.directionalLightCount; i++) {
4176
+ if (i < lighting.directionalLightCount) {
4177
+ PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
4178
+ color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
4072
4179
  }
4073
4180
  }
4074
4181
 
4075
4182
  // Apply point light
4076
- for(int i = 0; i < lighting_uPointLightCount; i++) {
4077
- if (i < lighting_uPointLightCount) {
4078
- PBRInfo_setPointLight(pbrInputs, lighting_uPointLight[i]);
4079
- float attenuation = getPointLightAttenuation(lighting_uPointLight[i], distance(lighting_uPointLight[i].position, pbr_vPosition));
4080
- color += calculateFinalColor(pbrInputs, lighting_uPointLight[i].color / attenuation);
4183
+ for(int i = 0; i < lighting.pointLightCount; i++) {
4184
+ if (i < lighting.pointLightCount) {
4185
+ PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
4186
+ float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
4187
+ color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
4081
4188
  }
4082
4189
  }
4083
4190
  #endif
4084
4191
 
4085
4192
  // Calculate lighting contribution from image based lighting source (IBL)
4086
4193
  #ifdef USE_IBL
4087
- color += getIBLContribution(pbrInputs, n, reflection);
4194
+ if (pbrMaterial.IBLenabled) {
4195
+ color += getIBLContribution(pbrInfo, n, reflection);
4196
+ }
4088
4197
  #endif
4089
4198
 
4090
- // Apply optional PBR terms for additional (optional) shading
4199
+ // Apply optional PBR terms for additional (optional) shading
4091
4200
  #ifdef HAS_OCCLUSIONMAP
4092
- float ao = texture(u_OcclusionSampler, pbr_vUV).r;
4093
- color = mix(color, color * ao, u_OcclusionStrength);
4201
+ if (pbrMaterial.occlusionMapEnabled) {
4202
+ float ao = texture(pbr_occlusionSampler, pbr_vUV).r;
4203
+ color = mix(color, color * ao, pbrMaterial.occlusionStrength);
4204
+ }
4094
4205
  #endif
4095
4206
 
4096
4207
  #ifdef HAS_EMISSIVEMAP
4097
- vec3 emissive = SRGBtoLINEAR(texture(u_EmissiveSampler, pbr_vUV)).rgb * u_EmissiveFactor;
4098
- color += emissive;
4208
+ if (pbrMaterial.emissiveMapEnabled) {
4209
+ vec3 emissive = SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb * pbrMaterial.emissiveFactor;
4210
+ color += emissive;
4211
+ }
4099
4212
  #endif
4100
4213
 
4101
4214
  // This section uses mix to override final color for reference app visualization
@@ -4103,15 +4216,15 @@ vec4 pbr_filterColor(vec4 colorUnused)
4103
4216
  #ifdef PBR_DEBUG
4104
4217
  // TODO: Figure out how to debug multiple lights
4105
4218
 
4106
- // color = mix(color, F, u_ScaleFGDSpec.x);
4107
- // color = mix(color, vec3(G), u_ScaleFGDSpec.y);
4108
- // color = mix(color, vec3(D), u_ScaleFGDSpec.z);
4109
- // color = mix(color, specContrib, u_ScaleFGDSpec.w);
4219
+ // color = mix(color, F, pbr_scaleFGDSpec.x);
4220
+ // color = mix(color, vec3(G), pbr_scaleFGDSpec.y);
4221
+ // color = mix(color, vec3(D), pbr_scaleFGDSpec.z);
4222
+ // color = mix(color, specContrib, pbr_scaleFGDSpec.w);
4110
4223
 
4111
- // color = mix(color, diffuseContrib, u_ScaleDiffBaseMR.x);
4112
- color = mix(color, baseColor.rgb, u_ScaleDiffBaseMR.y);
4113
- color = mix(color, vec3(metallic), u_ScaleDiffBaseMR.z);
4114
- color = mix(color, vec3(perceptualRoughness), u_ScaleDiffBaseMR.w);
4224
+ // color = mix(color, diffuseContrib, pbr_scaleDiffBaseMR.x);
4225
+ color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
4226
+ color = mix(color, vec3(metallic), pbrMaterial.scaleDiffBaseMR.z);
4227
+ color = mix(color, vec3(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
4115
4228
  #endif
4116
4229
 
4117
4230
  }
@@ -4120,15 +4233,77 @@ vec4 pbr_filterColor(vec4 colorUnused)
4120
4233
  }
4121
4234
  `;
4122
4235
 
4123
- // ../shadertools/src/modules-webgl1/lighting/pbr/pbr.ts
4124
- var pbr = {
4125
- name: "pbr",
4236
+ // ../shadertools/src/modules/lighting/pbr-material/pbr-projection.ts
4237
+ var uniformBlock = glsl`\
4238
+ uniform pbrProjectionUniforms {
4239
+ mat4 modelViewProjectionMatrix;
4240
+ mat4 modelMatrix;
4241
+ mat4 normalMatrix;
4242
+ vec3 camera;
4243
+ } pbrProjection;
4244
+ `;
4245
+ var pbrProjection = {
4246
+ name: "pbrProjection",
4247
+ vs: uniformBlock,
4248
+ fs: uniformBlock,
4249
+ // TODO why is this needed?
4250
+ getUniforms: (props) => props,
4251
+ uniformTypes: {
4252
+ modelViewProjectionMatrix: "mat4x4<f32>",
4253
+ modelMatrix: "mat4x4<f32>",
4254
+ normalMatrix: "mat4x4<f32>",
4255
+ camera: "vec3<i32>"
4256
+ }
4257
+ };
4258
+
4259
+ // ../shadertools/src/modules/lighting/pbr-material/pbr-material.ts
4260
+ var pbrMaterial = {
4261
+ name: "pbrMaterial",
4126
4262
  vs,
4127
4263
  fs,
4128
4264
  defines: {
4129
4265
  LIGHTING_FRAGMENT: 1
4266
+ // TODO defining these as 0 breaks shader
4267
+ // HAS_NORMALMAP: 0
4268
+ // HAS_EMISSIVEMAP: 0,
4269
+ // HAS_OCCLUSIONMAP: 0,
4270
+ // HAS_BASECOLORMAP: 0,
4271
+ // HAS_METALROUGHNESSMAP: 0,
4272
+ // ALPHA_CUTOFF: 0
4273
+ // USE_IBL: 0
4274
+ // PBR_DEBUG: 0
4130
4275
  },
4131
- dependencies: [lights]
4276
+ getUniforms: (props) => props,
4277
+ uniformTypes: {
4278
+ // Material is unlit
4279
+ unlit: "i32",
4280
+ // Base color map
4281
+ baseColorMapEnabled: "i32",
4282
+ baseColorFactor: "vec4<f32>",
4283
+ normalMapEnabled: "i32",
4284
+ normalScale: "f32",
4285
+ // #ifdef HAS_NORMALMAP
4286
+ emissiveMapEnabled: "i32",
4287
+ emissiveFactor: "vec3<f32>",
4288
+ // #ifdef HAS_EMISSIVEMAP
4289
+ metallicRoughnessValues: "vec2<f32>",
4290
+ metallicRoughnessMapEnabled: "i32",
4291
+ occlusionMapEnabled: "i32",
4292
+ occlusionStrength: "f32",
4293
+ // #ifdef HAS_OCCLUSIONMAP
4294
+ alphaCutoffEnabled: "i32",
4295
+ alphaCutoff: "f32",
4296
+ // #ifdef ALPHA_CUTOFF
4297
+ // IBL
4298
+ IBLenabled: "i32",
4299
+ scaleIBLAmbient: "vec2<f32>",
4300
+ // #ifdef USE_IBL
4301
+ // debugging flags used for shader output of intermediate PBR variables
4302
+ // #ifdef PBR_DEBUG
4303
+ scaleDiffBaseMR: "vec4<f32>",
4304
+ scaleFGDSpec: "vec4<f32>"
4305
+ },
4306
+ dependencies: [lighting, pbrProjection]
4132
4307
  };
4133
4308
 
4134
4309
  // src/gltf/create-gltf-model.ts
@@ -4176,7 +4351,7 @@ vec4 pbr_filterColor(vec4 colorUnused)
4176
4351
  #endif
4177
4352
 
4178
4353
  pbr_setPositionNormalTangentUV(positions, _NORMAL, _TANGENT, _TEXCOORD_0);
4179
- gl_Position = u_MVPMatrix * positions;
4354
+ gl_Position = pbrProjection.modelViewProjectionMatrix * positions;
4180
4355
  }
4181
4356
  `;
4182
4357
  var fs2 = `
@@ -4195,7 +4370,7 @@ vec4 pbr_filterColor(vec4 colorUnused)
4195
4370
  function createGLTFModel(device, options) {
4196
4371
  const { id, geometry, material, vertexCount, materialOptions, modelOptions } = options;
4197
4372
  const parsedMaterial = parsePBRMaterial(device, material, geometry.attributes, materialOptions);
4198
- import_core4.log.info(4, "createGLTFModel defines: ", parsedMaterial.defines)();
4373
+ import_core5.log.info(4, "createGLTFModel defines: ", parsedMaterial.defines)();
4199
4374
  const managedResources = [];
4200
4375
  const parameters = {
4201
4376
  depthWriteEnabled: true,
@@ -4208,16 +4383,22 @@ vec4 pbr_filterColor(vec4 colorUnused)
4208
4383
  geometry,
4209
4384
  topology: geometry.topology,
4210
4385
  vertexCount,
4211
- modules: [pbr],
4386
+ modules: [pbrMaterial],
4212
4387
  vs: addVersionToShader(device, vs2),
4213
4388
  fs: addVersionToShader(device, fs2),
4389
+ // TODO can this be removed? Does deck need it?
4214
4390
  ...modelOptions,
4215
- bindings: { ...parsedMaterial.bindings, ...modelOptions.bindings },
4216
4391
  defines: { ...parsedMaterial.defines, ...modelOptions.defines },
4217
- parameters: { ...parameters, ...parsedMaterial.parameters, ...modelOptions.parameters },
4218
- uniforms: { ...parsedMaterial.uniforms, ...modelOptions.uniforms }
4392
+ parameters: { ...parameters, ...parsedMaterial.parameters, ...modelOptions.parameters }
4219
4393
  };
4220
4394
  const model = new import_engine.Model(device, modelProps);
4395
+ const { camera, ...pbrMaterialProps } = {
4396
+ ...parsedMaterial.uniforms,
4397
+ ...modelOptions.uniforms,
4398
+ ...parsedMaterial.bindings,
4399
+ ...modelOptions.bindings
4400
+ };
4401
+ model.shaderInputs.setProps({ pbrMaterial: pbrMaterialProps, pbrProjection: { camera } });
4221
4402
  return new import_engine.ModelNode({ managedResources, model });
4222
4403
  }
4223
4404
  function addVersionToShader(device, source) {