@luma.gl/gltf 9.1.0-alpha.9 → 9.1.0-beta.11

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
@@ -51,6 +51,13 @@ var __exports__ = (() => {
51
51
  }
52
52
  });
53
53
 
54
+ // external-global-plugin:@luma.gl/shadertools
55
+ var require_shadertools = __commonJS({
56
+ "external-global-plugin:@luma.gl/shadertools"(exports, module) {
57
+ module.exports = globalThis.luma;
58
+ }
59
+ });
60
+
54
61
  // bundle.ts
55
62
  var bundle_exports = {};
56
63
  __export(bundle_exports, {
@@ -73,9 +80,9 @@ var __exports__ = (() => {
73
80
  bindings: {},
74
81
  uniforms: {
75
82
  // TODO: find better values?
76
- u_Camera: [0, 0, 0],
83
+ camera: [0, 0, 0],
77
84
  // Model should override
78
- u_MetallicRoughnessValues: [1, 1]
85
+ metallicRoughnessValues: [1, 1]
79
86
  // Default is 1 and 1
80
87
  },
81
88
  parameters: {},
@@ -85,15 +92,15 @@ var __exports__ = (() => {
85
92
  parsedMaterial.defines.USE_TEX_LOD = 1;
86
93
  const { imageBasedLightingEnvironment } = options;
87
94
  if (imageBasedLightingEnvironment) {
88
- parsedMaterial.bindings.u_DiffuseEnvSampler = imageBasedLightingEnvironment.diffuseEnvSampler.texture;
89
- parsedMaterial.bindings.u_SpecularEnvSampler = imageBasedLightingEnvironment.specularEnvSampler.texture;
90
- parsedMaterial.bindings.u_brdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;
91
- parsedMaterial.uniforms.u_ScaleIBLAmbient = [1, 1];
95
+ parsedMaterial.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.diffuseEnvSampler.texture;
96
+ parsedMaterial.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.specularEnvSampler.texture;
97
+ parsedMaterial.bindings.pbr_BrdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;
98
+ parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];
92
99
  }
93
100
  if (options?.pbrDebug) {
94
101
  parsedMaterial.defines.PBR_DEBUG = 1;
95
- parsedMaterial.uniforms.u_ScaleDiffBaseMR = [0, 0, 0, 0];
96
- parsedMaterial.uniforms.u_ScaleFGDSpec = [0, 0, 0, 0];
102
+ parsedMaterial.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];
103
+ parsedMaterial.uniforms.scaleFGDSpec = [0, 0, 0, 0];
97
104
  }
98
105
  if (attributes.NORMAL)
99
106
  parsedMaterial.defines.HAS_NORMALS = 1;
@@ -111,41 +118,47 @@ var __exports__ = (() => {
111
118
  return parsedMaterial;
112
119
  }
113
120
  function parseMaterial(device, material, parsedMaterial) {
114
- parsedMaterial.uniforms.pbr_uUnlit = Boolean(material.unlit);
121
+ parsedMaterial.uniforms.unlit = Boolean(material.unlit);
115
122
  if (material.pbrMetallicRoughness) {
116
123
  parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial);
117
124
  }
118
125
  if (material.normalTexture) {
119
- addTexture(device, material.normalTexture, "u_NormalSampler", "HAS_NORMALMAP", parsedMaterial);
126
+ addTexture(
127
+ device,
128
+ material.normalTexture,
129
+ "pbr_normalSampler",
130
+ "HAS_NORMALMAP",
131
+ parsedMaterial
132
+ );
120
133
  const { scale: scale4 = 1 } = material.normalTexture;
121
- parsedMaterial.uniforms.u_NormalScale = scale4;
134
+ parsedMaterial.uniforms.normalScale = scale4;
122
135
  }
123
136
  if (material.occlusionTexture) {
124
137
  addTexture(
125
138
  device,
126
139
  material.occlusionTexture,
127
- "u_OcclusionSampler",
140
+ "pbr_occlusionSampler",
128
141
  "HAS_OCCLUSIONMAP",
129
142
  parsedMaterial
130
143
  );
131
144
  const { strength = 1 } = material.occlusionTexture;
132
- parsedMaterial.uniforms.u_OcclusionStrength = strength;
145
+ parsedMaterial.uniforms.occlusionStrength = strength;
133
146
  }
134
147
  if (material.emissiveTexture) {
135
148
  addTexture(
136
149
  device,
137
150
  material.emissiveTexture,
138
- "u_EmissiveSampler",
151
+ "pbr_emissiveSampler",
139
152
  "HAS_EMISSIVEMAP",
140
153
  parsedMaterial
141
154
  );
142
- parsedMaterial.uniforms.u_EmissiveFactor = material.emissiveFactor || [0, 0, 0];
155
+ parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];
143
156
  }
144
157
  switch (material.alphaMode) {
145
158
  case "MASK":
146
159
  const { alphaCutoff = 0.5 } = material;
147
160
  parsedMaterial.defines.ALPHA_CUTOFF = 1;
148
- parsedMaterial.uniforms.u_AlphaCutoff = alphaCutoff;
161
+ parsedMaterial.uniforms.alphaCutoff = alphaCutoff;
149
162
  break;
150
163
  case "BLEND":
151
164
  import_core.log.warn("glTF BLEND alphaMode might not work well because it requires mesh sorting")();
@@ -171,23 +184,23 @@ var __exports__ = (() => {
171
184
  addTexture(
172
185
  device,
173
186
  pbrMetallicRoughness.baseColorTexture,
174
- "u_BaseColorSampler",
187
+ "pbr_baseColorSampler",
175
188
  "HAS_BASECOLORMAP",
176
189
  parsedMaterial
177
190
  );
178
191
  }
179
- parsedMaterial.uniforms.u_BaseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];
192
+ parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];
180
193
  if (pbrMetallicRoughness.metallicRoughnessTexture) {
181
194
  addTexture(
182
195
  device,
183
196
  pbrMetallicRoughness.metallicRoughnessTexture,
184
- "u_MetallicRoughnessSampler",
197
+ "pbr_metallicRoughnessSampler",
185
198
  "HAS_METALROUGHNESSMAP",
186
199
  parsedMaterial
187
200
  );
188
201
  }
189
202
  const { metallicFactor = 1, roughnessFactor = 1 } = pbrMetallicRoughness;
190
- parsedMaterial.uniforms.u_MetallicRoughnessValues = [metallicFactor, roughnessFactor];
203
+ parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];
191
204
  }
192
205
  function addTexture(device, gltfTexture, uniformName, define = null, parsedMaterial) {
193
206
  const parameters = gltfTexture?.texture?.sampler?.parameters || {};
@@ -3574,571 +3587,7 @@ var __exports__ = (() => {
3574
3587
 
3575
3588
  // src/gltf/create-gltf-model.ts
3576
3589
  var import_core4 = __toESM(require_core(), 1);
3577
-
3578
- // ../shadertools/src/modules-webgl1/lighting/lights/lights-glsl.ts
3579
- var lightingShader = (
3580
- /* glsl */
3581
- `#if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))
3582
-
3583
- struct AmbientLight {
3584
- vec3 color;
3585
- };
3586
-
3587
- struct PointLight {
3588
- vec3 color;
3589
- vec3 position;
3590
-
3591
- // Constant-Linear-Exponential
3592
- vec3 attenuation;
3593
- };
3594
-
3595
- struct DirectionalLight {
3596
- vec3 color;
3597
- vec3 direction;
3598
- };
3599
-
3600
- uniform AmbientLight lighting_uAmbientLight;
3601
- uniform PointLight lighting_uPointLight[MAX_LIGHTS];
3602
- uniform DirectionalLight lighting_uDirectionalLight[MAX_LIGHTS];
3603
- uniform int lighting_uPointLightCount;
3604
- uniform int lighting_uDirectionalLightCount;
3605
-
3606
- uniform bool lighting_uEnabled;
3607
-
3608
- float getPointLightAttenuation(PointLight pointLight, float distance) {
3609
- return pointLight.attenuation.x
3610
- + pointLight.attenuation.y * distance
3611
- + pointLight.attenuation.z * distance * distance;
3612
- }
3613
-
3614
- #endif
3615
- `
3616
- );
3617
-
3618
- // ../shadertools/src/modules-webgl1/lighting/lights/lights.ts
3619
- var INITIAL_MODULE_OPTIONS = {
3620
- lightSources: {}
3621
- };
3622
- function convertColor(colorDef = {}) {
3623
- const { color = [0, 0, 0], intensity = 1 } = colorDef;
3624
- return color.map((component) => component * intensity / 255);
3625
- }
3626
- function getLightSourceUniforms({
3627
- ambientLight,
3628
- pointLights = [],
3629
- directionalLights = []
3630
- }) {
3631
- const lightSourceUniforms = {};
3632
- if (ambientLight) {
3633
- lightSourceUniforms["lighting_uAmbientLight.color"] = convertColor(ambientLight);
3634
- } else {
3635
- lightSourceUniforms["lighting_uAmbientLight.color"] = [0, 0, 0];
3636
- }
3637
- pointLights.forEach((pointLight, index) => {
3638
- lightSourceUniforms[`lighting_uPointLight[${index}].color`] = convertColor(pointLight);
3639
- lightSourceUniforms[`lighting_uPointLight[${index}].position`] = pointLight.position;
3640
- lightSourceUniforms[`lighting_uPointLight[${index}].attenuation`] = pointLight.attenuation || [
3641
- 1,
3642
- 0,
3643
- 0
3644
- ];
3645
- });
3646
- lightSourceUniforms.lighting_uPointLightCount = pointLights.length;
3647
- directionalLights.forEach((directionalLight, index) => {
3648
- lightSourceUniforms[`lighting_uDirectionalLight[${index}].color`] = convertColor(directionalLight);
3649
- lightSourceUniforms[`lighting_uDirectionalLight[${index}].direction`] = directionalLight.direction;
3650
- });
3651
- lightSourceUniforms.lighting_uDirectionalLightCount = directionalLights.length;
3652
- return lightSourceUniforms;
3653
- }
3654
- function getUniforms(opts = INITIAL_MODULE_OPTIONS) {
3655
- if ("lightSources" in opts) {
3656
- const { ambientLight, pointLights, directionalLights } = opts.lightSources || {};
3657
- const hasLights = ambientLight || pointLights && pointLights.length > 0 || directionalLights && directionalLights.length > 0;
3658
- if (!hasLights) {
3659
- return { lighting_uEnabled: false };
3660
- }
3661
- return Object.assign(
3662
- {},
3663
- getLightSourceUniforms({ ambientLight, pointLights, directionalLights }),
3664
- {
3665
- lighting_uEnabled: true
3666
- }
3667
- );
3668
- }
3669
- if ("lights" in opts) {
3670
- const lightSources = { pointLights: [], directionalLights: [] };
3671
- for (const light of opts.lights || []) {
3672
- switch (light.type) {
3673
- case "ambient":
3674
- lightSources.ambientLight = light;
3675
- break;
3676
- case "directional":
3677
- lightSources.directionalLights?.push(light);
3678
- break;
3679
- case "point":
3680
- lightSources.pointLights?.push(light);
3681
- break;
3682
- default:
3683
- }
3684
- }
3685
- return getUniforms({ lightSources });
3686
- }
3687
- return {};
3688
- }
3689
- var lights = {
3690
- name: "lights",
3691
- vs: lightingShader,
3692
- fs: lightingShader,
3693
- getUniforms,
3694
- defines: {
3695
- MAX_LIGHTS: 3
3696
- }
3697
- };
3698
-
3699
- // ../shadertools/src/modules-webgl1/lighting/pbr/pbr-vertex-glsl.ts
3700
- var vs = (
3701
- /* glsl */
3702
- `uniform mat4 u_MVPMatrix;
3703
- uniform mat4 u_ModelMatrix;
3704
- uniform mat4 u_NormalMatrix;
3705
-
3706
- out vec3 pbr_vPosition;
3707
- out vec2 pbr_vUV;
3708
-
3709
- #ifdef HAS_NORMALS
3710
- # ifdef HAS_TANGENTS
3711
- out mat3 pbr_vTBN;
3712
- # else
3713
- out vec3 pbr_vNormal;
3714
- # endif
3715
- #endif
3716
-
3717
- void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, vec2 uv)
3718
- {
3719
- vec4 pos = u_ModelMatrix * position;
3720
- pbr_vPosition = vec3(pos.xyz) / pos.w;
3721
-
3722
- #ifdef HAS_NORMALS
3723
- #ifdef HAS_TANGENTS
3724
- vec3 normalW = normalize(vec3(u_NormalMatrix * vec4(normal.xyz, 0.0)));
3725
- vec3 tangentW = normalize(vec3(u_ModelMatrix * vec4(tangent.xyz, 0.0)));
3726
- vec3 bitangentW = cross(normalW, tangentW) * tangent.w;
3727
- pbr_vTBN = mat3(tangentW, bitangentW, normalW);
3728
- #else // HAS_TANGENTS != 1
3729
- pbr_vNormal = normalize(vec3(u_ModelMatrix * vec4(normal.xyz, 0.0)));
3730
- #endif
3731
- #endif
3732
-
3733
- #ifdef HAS_UV
3734
- pbr_vUV = uv;
3735
- #else
3736
- pbr_vUV = vec2(0.,0.);
3737
- #endif
3738
- }
3739
- `
3740
- );
3741
-
3742
- // ../shadertools/src/modules-webgl1/lighting/pbr/pbr-fragment-glsl.ts
3743
- var fs = (
3744
- /* glsl */
3745
- `precision highp float;
3746
-
3747
- uniform bool pbr_uUnlit;
3748
-
3749
- #ifdef USE_IBL
3750
- uniform samplerCube u_DiffuseEnvSampler;
3751
- uniform samplerCube u_SpecularEnvSampler;
3752
- uniform sampler2D u_brdfLUT;
3753
- uniform vec2 u_ScaleIBLAmbient;
3754
- #endif
3755
-
3756
- #ifdef HAS_BASECOLORMAP
3757
- uniform sampler2D u_BaseColorSampler;
3758
- #endif
3759
- #ifdef HAS_NORMALMAP
3760
- uniform sampler2D u_NormalSampler;
3761
- uniform float u_NormalScale;
3762
- #endif
3763
- #ifdef HAS_EMISSIVEMAP
3764
- uniform sampler2D u_EmissiveSampler;
3765
- uniform vec3 u_EmissiveFactor;
3766
- #endif
3767
- #ifdef HAS_METALROUGHNESSMAP
3768
- uniform sampler2D u_MetallicRoughnessSampler;
3769
- #endif
3770
- #ifdef HAS_OCCLUSIONMAP
3771
- uniform sampler2D u_OcclusionSampler;
3772
- uniform float u_OcclusionStrength;
3773
- #endif
3774
-
3775
- #ifdef ALPHA_CUTOFF
3776
- uniform float u_AlphaCutoff;
3777
- #endif
3778
-
3779
- uniform vec2 u_MetallicRoughnessValues;
3780
- uniform vec4 u_BaseColorFactor;
3781
-
3782
- uniform vec3 u_Camera;
3783
-
3784
- // debugging flags used for shader output of intermediate PBR variables
3785
- #ifdef PBR_DEBUG
3786
- uniform vec4 u_ScaleDiffBaseMR;
3787
- uniform vec4 u_ScaleFGDSpec;
3788
- #endif
3789
-
3790
- in vec3 pbr_vPosition;
3791
-
3792
- in vec2 pbr_vUV;
3793
-
3794
- #ifdef HAS_NORMALS
3795
- #ifdef HAS_TANGENTS
3796
- in mat3 pbr_vTBN;
3797
- #else
3798
- in vec3 pbr_vNormal;
3799
- #endif
3800
- #endif
3801
-
3802
- // Encapsulate the various inputs used by the various functions in the shading equation
3803
- // We store values in this struct to simplify the integration of alternative implementations
3804
- // of the shading terms, outlined in the Readme.MD Appendix.
3805
- struct PBRInfo
3806
- {
3807
- float NdotL; // cos angle between normal and light direction
3808
- float NdotV; // cos angle between normal and view direction
3809
- float NdotH; // cos angle between normal and half vector
3810
- float LdotH; // cos angle between light direction and half vector
3811
- float VdotH; // cos angle between view direction and half vector
3812
- float perceptualRoughness; // roughness value, as authored by the model creator (input to shader)
3813
- float metalness; // metallic value at the surface
3814
- vec3 reflectance0; // full reflectance color (normal incidence angle)
3815
- vec3 reflectance90; // reflectance color at grazing angle
3816
- float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2])
3817
- vec3 diffuseColor; // color contribution from diffuse lighting
3818
- vec3 specularColor; // color contribution from specular lighting
3819
- vec3 n; // normal at surface point
3820
- vec3 v; // vector from surface point to camera
3821
- };
3822
-
3823
- const float M_PI = 3.141592653589793;
3824
- const float c_MinRoughness = 0.04;
3825
-
3826
- vec4 SRGBtoLINEAR(vec4 srgbIn)
3827
- {
3828
- #ifdef MANUAL_SRGB
3829
- #ifdef SRGB_FAST_APPROXIMATION
3830
- vec3 linOut = pow(srgbIn.xyz,vec3(2.2));
3831
- #else //SRGB_FAST_APPROXIMATION
3832
- vec3 bLess = step(vec3(0.04045),srgbIn.xyz);
3833
- vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess );
3834
- #endif //SRGB_FAST_APPROXIMATION
3835
- return vec4(linOut,srgbIn.w);;
3836
- #else //MANUAL_SRGB
3837
- return srgbIn;
3838
- #endif //MANUAL_SRGB
3839
- }
3840
-
3841
- // Find the normal for this fragment, pulling either from a predefined normal map
3842
- // or from the interpolated mesh normal and tangent attributes.
3843
- vec3 getNormal()
3844
- {
3845
- // Retrieve the tangent space matrix
3846
- #ifndef HAS_TANGENTS
3847
- vec3 pos_dx = dFdx(pbr_vPosition);
3848
- vec3 pos_dy = dFdy(pbr_vPosition);
3849
- vec3 tex_dx = dFdx(vec3(pbr_vUV, 0.0));
3850
- vec3 tex_dy = dFdy(vec3(pbr_vUV, 0.0));
3851
- vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t);
3852
-
3853
- #ifdef HAS_NORMALS
3854
- vec3 ng = normalize(pbr_vNormal);
3855
- #else
3856
- vec3 ng = cross(pos_dx, pos_dy);
3857
- #endif
3858
-
3859
- t = normalize(t - ng * dot(ng, t));
3860
- vec3 b = normalize(cross(ng, t));
3861
- mat3 tbn = mat3(t, b, ng);
3862
- #else // HAS_TANGENTS
3863
- mat3 tbn = pbr_vTBN;
3864
- #endif
3865
-
3866
- #ifdef HAS_NORMALMAP
3867
- vec3 n = texture(u_NormalSampler, pbr_vUV).rgb;
3868
- n = normalize(tbn * ((2.0 * n - 1.0) * vec3(u_NormalScale, u_NormalScale, 1.0)));
3869
- #else
3870
- // The tbn matrix is linearly interpolated, so we need to re-normalize
3871
- vec3 n = normalize(tbn[2].xyz);
3872
- #endif
3873
-
3874
- return n;
3875
- }
3876
-
3877
- // Calculation of the lighting contribution from an optional Image Based Light source.
3878
- // Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
3879
- // See our README.md on Environment Maps [3] for additional discussion.
3880
- #ifdef USE_IBL
3881
- vec3 getIBLContribution(PBRInfo pbrInputs, vec3 n, vec3 reflection)
3882
- {
3883
- float mipCount = 9.0; // resolution of 512x512
3884
- float lod = (pbrInputs.perceptualRoughness * mipCount);
3885
- // retrieve a scale and bias to F0. See [1], Figure 3
3886
- vec3 brdf = SRGBtoLINEAR(texture(u_brdfLUT,
3887
- vec2(pbrInputs.NdotV, 1.0 - pbrInputs.perceptualRoughness))).rgb;
3888
- vec3 diffuseLight = SRGBtoLINEAR(textureCube(u_DiffuseEnvSampler, n)).rgb;
3889
-
3890
- #ifdef USE_TEX_LOD
3891
- vec3 specularLight = SRGBtoLINEAR(textureCubeLod(u_SpecularEnvSampler, reflection, lod)).rgb;
3892
- #else
3893
- vec3 specularLight = SRGBtoLINEAR(textureCube(u_SpecularEnvSampler, reflection)).rgb;
3894
- #endif
3895
-
3896
- vec3 diffuse = diffuseLight * pbrInputs.diffuseColor;
3897
- vec3 specular = specularLight * (pbrInputs.specularColor * brdf.x + brdf.y);
3898
-
3899
- // For presentation, this allows us to disable IBL terms
3900
- diffuse *= u_ScaleIBLAmbient.x;
3901
- specular *= u_ScaleIBLAmbient.y;
3902
-
3903
- return diffuse + specular;
3904
- }
3905
- #endif
3906
-
3907
- // Basic Lambertian diffuse
3908
- // Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog
3909
- // See also [1], Equation 1
3910
- vec3 diffuse(PBRInfo pbrInputs)
3911
- {
3912
- return pbrInputs.diffuseColor / M_PI;
3913
- }
3914
-
3915
- // The following equation models the Fresnel reflectance term of the spec equation (aka F())
3916
- // Implementation of fresnel from [4], Equation 15
3917
- vec3 specularReflection(PBRInfo pbrInputs)
3918
- {
3919
- return pbrInputs.reflectance0 +
3920
- (pbrInputs.reflectance90 - pbrInputs.reflectance0) *
3921
- pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0);
3922
- }
3923
-
3924
- // This calculates the specular geometric attenuation (aka G()),
3925
- // where rougher material will reflect less light back to the viewer.
3926
- // This implementation is based on [1] Equation 4, and we adopt their modifications to
3927
- // alphaRoughness as input as originally proposed in [2].
3928
- float geometricOcclusion(PBRInfo pbrInputs)
3929
- {
3930
- float NdotL = pbrInputs.NdotL;
3931
- float NdotV = pbrInputs.NdotV;
3932
- float r = pbrInputs.alphaRoughness;
3933
-
3934
- float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
3935
- float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
3936
- return attenuationL * attenuationV;
3937
- }
3938
-
3939
- // The following equation(s) model the distribution of microfacet normals across
3940
- // the area being drawn (aka D())
3941
- // Implementation from "Average Irregularity Representation of a Roughened Surface
3942
- // for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz
3943
- // Follows the distribution function recommended in the SIGGRAPH 2013 course notes
3944
- // from EPIC Games [1], Equation 3.
3945
- float microfacetDistribution(PBRInfo pbrInputs)
3946
- {
3947
- float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness;
3948
- float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;
3949
- return roughnessSq / (M_PI * f * f);
3950
- }
3951
-
3952
- void PBRInfo_setAmbientLight(inout PBRInfo pbrInputs) {
3953
- pbrInputs.NdotL = 1.0;
3954
- pbrInputs.NdotH = 0.0;
3955
- pbrInputs.LdotH = 0.0;
3956
- pbrInputs.VdotH = 1.0;
3957
- }
3958
-
3959
- void PBRInfo_setDirectionalLight(inout PBRInfo pbrInputs, vec3 lightDirection) {
3960
- vec3 n = pbrInputs.n;
3961
- vec3 v = pbrInputs.v;
3962
- vec3 l = normalize(lightDirection); // Vector from surface point to light
3963
- vec3 h = normalize(l+v); // Half vector between both l and v
3964
-
3965
- pbrInputs.NdotL = clamp(dot(n, l), 0.001, 1.0);
3966
- pbrInputs.NdotH = clamp(dot(n, h), 0.0, 1.0);
3967
- pbrInputs.LdotH = clamp(dot(l, h), 0.0, 1.0);
3968
- pbrInputs.VdotH = clamp(dot(v, h), 0.0, 1.0);
3969
- }
3970
-
3971
- void PBRInfo_setPointLight(inout PBRInfo pbrInputs, PointLight pointLight) {
3972
- vec3 light_direction = normalize(pointLight.position - pbr_vPosition);
3973
- PBRInfo_setDirectionalLight(pbrInputs, light_direction);
3974
- }
3975
-
3976
- vec3 calculateFinalColor(PBRInfo pbrInputs, vec3 lightColor) {
3977
- // Calculate the shading terms for the microfacet specular shading model
3978
- vec3 F = specularReflection(pbrInputs);
3979
- float G = geometricOcclusion(pbrInputs);
3980
- float D = microfacetDistribution(pbrInputs);
3981
-
3982
- // Calculation of analytical lighting contribution
3983
- vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
3984
- vec3 specContrib = F * G * D / (4.0 * pbrInputs.NdotL * pbrInputs.NdotV);
3985
- // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
3986
- return pbrInputs.NdotL * lightColor * (diffuseContrib + specContrib);
3987
- }
3988
-
3989
- vec4 pbr_filterColor(vec4 colorUnused)
3990
- {
3991
- // The albedo may be defined from a base texture or a flat color
3992
- #ifdef HAS_BASECOLORMAP
3993
- vec4 baseColor = SRGBtoLINEAR(texture(u_BaseColorSampler, pbr_vUV)) * u_BaseColorFactor;
3994
- #else
3995
- vec4 baseColor = u_BaseColorFactor;
3996
- #endif
3997
-
3998
- #ifdef ALPHA_CUTOFF
3999
- if (baseColor.a < u_AlphaCutoff) {
4000
- discard;
4001
- }
4002
- #endif
4003
-
4004
- vec3 color = vec3(0, 0, 0);
4005
-
4006
- if(pbr_uUnlit){
4007
- color.rgb = baseColor.rgb;
4008
- }
4009
- else{
4010
- // Metallic and Roughness material properties are packed together
4011
- // In glTF, these factors can be specified by fixed scalar values
4012
- // or from a metallic-roughness map
4013
- float perceptualRoughness = u_MetallicRoughnessValues.y;
4014
- float metallic = u_MetallicRoughnessValues.x;
4015
- #ifdef HAS_METALROUGHNESSMAP
4016
- // Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
4017
- // This layout intentionally reserves the 'r' channel for (optional) occlusion map data
4018
- vec4 mrSample = texture(u_MetallicRoughnessSampler, pbr_vUV);
4019
- perceptualRoughness = mrSample.g * perceptualRoughness;
4020
- metallic = mrSample.b * metallic;
4021
- #endif
4022
- perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
4023
- metallic = clamp(metallic, 0.0, 1.0);
4024
- // Roughness is authored as perceptual roughness; as is convention,
4025
- // convert to material roughness by squaring the perceptual roughness [2].
4026
- float alphaRoughness = perceptualRoughness * perceptualRoughness;
4027
-
4028
- vec3 f0 = vec3(0.04);
4029
- vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
4030
- diffuseColor *= 1.0 - metallic;
4031
- vec3 specularColor = mix(f0, baseColor.rgb, metallic);
4032
-
4033
- // Compute reflectance.
4034
- float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
4035
-
4036
- // For typical incident reflectance range (between 4% to 100%) set the grazing
4037
- // reflectance to 100% for typical fresnel effect.
4038
- // For very low reflectance range on highly diffuse objects (below 4%),
4039
- // incrementally reduce grazing reflecance to 0%.
4040
- float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
4041
- vec3 specularEnvironmentR0 = specularColor.rgb;
4042
- vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
4043
-
4044
- vec3 n = getNormal(); // normal at surface point
4045
- vec3 v = normalize(u_Camera - pbr_vPosition); // Vector from surface point to camera
4046
-
4047
- float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
4048
- vec3 reflection = -normalize(reflect(v, n));
4049
-
4050
- PBRInfo pbrInputs = PBRInfo(
4051
- 0.0, // NdotL
4052
- NdotV,
4053
- 0.0, // NdotH
4054
- 0.0, // LdotH
4055
- 0.0, // VdotH
4056
- perceptualRoughness,
4057
- metallic,
4058
- specularEnvironmentR0,
4059
- specularEnvironmentR90,
4060
- alphaRoughness,
4061
- diffuseColor,
4062
- specularColor,
4063
- n,
4064
- v
4065
- );
4066
-
4067
- #ifdef USE_LIGHTS
4068
- // Apply ambient light
4069
- PBRInfo_setAmbientLight(pbrInputs);
4070
- color += calculateFinalColor(pbrInputs, lighting_uAmbientLight.color);
4071
-
4072
- // Apply directional light
4073
- for(int i = 0; i < lighting_uDirectionalLightCount; i++) {
4074
- if (i < lighting_uDirectionalLightCount) {
4075
- PBRInfo_setDirectionalLight(pbrInputs, lighting_uDirectionalLight[i].direction);
4076
- color += calculateFinalColor(pbrInputs, lighting_uDirectionalLight[i].color);
4077
- }
4078
- }
4079
-
4080
- // Apply point light
4081
- for(int i = 0; i < lighting_uPointLightCount; i++) {
4082
- if (i < lighting_uPointLightCount) {
4083
- PBRInfo_setPointLight(pbrInputs, lighting_uPointLight[i]);
4084
- float attenuation = getPointLightAttenuation(lighting_uPointLight[i], distance(lighting_uPointLight[i].position, pbr_vPosition));
4085
- color += calculateFinalColor(pbrInputs, lighting_uPointLight[i].color / attenuation);
4086
- }
4087
- }
4088
- #endif
4089
-
4090
- // Calculate lighting contribution from image based lighting source (IBL)
4091
- #ifdef USE_IBL
4092
- color += getIBLContribution(pbrInputs, n, reflection);
4093
- #endif
4094
-
4095
- // Apply optional PBR terms for additional (optional) shading
4096
- #ifdef HAS_OCCLUSIONMAP
4097
- float ao = texture(u_OcclusionSampler, pbr_vUV).r;
4098
- color = mix(color, color * ao, u_OcclusionStrength);
4099
- #endif
4100
-
4101
- #ifdef HAS_EMISSIVEMAP
4102
- vec3 emissive = SRGBtoLINEAR(texture(u_EmissiveSampler, pbr_vUV)).rgb * u_EmissiveFactor;
4103
- color += emissive;
4104
- #endif
4105
-
4106
- // This section uses mix to override final color for reference app visualization
4107
- // of various parameters in the lighting equation.
4108
- #ifdef PBR_DEBUG
4109
- // TODO: Figure out how to debug multiple lights
4110
-
4111
- // color = mix(color, F, u_ScaleFGDSpec.x);
4112
- // color = mix(color, vec3(G), u_ScaleFGDSpec.y);
4113
- // color = mix(color, vec3(D), u_ScaleFGDSpec.z);
4114
- // color = mix(color, specContrib, u_ScaleFGDSpec.w);
4115
-
4116
- // color = mix(color, diffuseContrib, u_ScaleDiffBaseMR.x);
4117
- color = mix(color, baseColor.rgb, u_ScaleDiffBaseMR.y);
4118
- color = mix(color, vec3(metallic), u_ScaleDiffBaseMR.z);
4119
- color = mix(color, vec3(perceptualRoughness), u_ScaleDiffBaseMR.w);
4120
- #endif
4121
-
4122
- }
4123
-
4124
- return vec4(pow(color,vec3(1.0/2.2)), baseColor.a);
4125
- }
4126
- `
4127
- );
4128
-
4129
- // ../shadertools/src/modules-webgl1/lighting/pbr/pbr.ts
4130
- var pbr = {
4131
- name: "pbr",
4132
- vs,
4133
- fs,
4134
- defines: {
4135
- LIGHTING_FRAGMENT: 1
4136
- },
4137
- dependencies: [lights],
4138
- getUniforms: (props) => props
4139
- };
4140
-
4141
- // src/gltf/create-gltf-model.ts
3590
+ var import_shadertools = __toESM(require_shadertools(), 1);
4142
3591
  var import_engine2 = __toESM(require_engine(), 1);
4143
3592
  var SHADER = (
4144
3593
  /* WGSL */
@@ -4189,7 +3638,7 @@ layout(0) positions: vec4; // in vec4 POSITION;
4189
3638
  }
4190
3639
  `
4191
3640
  );
4192
- var vs2 = (
3641
+ var vs = (
4193
3642
  /* glsl */
4194
3643
  `#version 300 es
4195
3644
 
@@ -4228,11 +3677,11 @@ layout(0) positions: vec4; // in vec4 POSITION;
4228
3677
  #endif
4229
3678
 
4230
3679
  pbr_setPositionNormalTangentUV(positions, _NORMAL, _TANGENT, _TEXCOORD_0);
4231
- gl_Position = u_MVPMatrix * positions;
3680
+ gl_Position = pbrProjection.modelViewProjectionMatrix * positions;
4232
3681
  }
4233
3682
  `
4234
3683
  );
4235
- var fs2 = (
3684
+ var fs = (
4236
3685
  /* glsl */
4237
3686
  `#version 300 es
4238
3687
  out vec4 fragmentColor;
@@ -4257,19 +3706,24 @@ layout(0) positions: vec4; // in vec4 POSITION;
4257
3706
  const modelProps = {
4258
3707
  id,
4259
3708
  source: SHADER,
4260
- vs: vs2,
4261
- fs: fs2,
3709
+ vs,
3710
+ fs,
4262
3711
  geometry,
4263
3712
  topology: geometry.topology,
4264
3713
  vertexCount,
4265
- modules: [pbr],
3714
+ modules: [import_shadertools.pbrMaterial],
4266
3715
  ...modelOptions,
4267
- bindings: { ...parsedMaterial.bindings, ...modelOptions.bindings },
4268
3716
  defines: { ...parsedMaterial.defines, ...modelOptions.defines },
4269
- parameters: { ...parameters, ...parsedMaterial.parameters, ...modelOptions.parameters },
4270
- uniforms: { ...parsedMaterial.uniforms, ...modelOptions.uniforms }
3717
+ parameters: { ...parameters, ...parsedMaterial.parameters, ...modelOptions.parameters }
4271
3718
  };
4272
3719
  const model = new import_engine2.Model(device, modelProps);
3720
+ const { camera, ...pbrMaterialProps } = {
3721
+ ...parsedMaterial.uniforms,
3722
+ ...modelOptions.uniforms,
3723
+ ...parsedMaterial.bindings,
3724
+ ...modelOptions.bindings
3725
+ };
3726
+ model.shaderInputs.setProps({ pbrMaterial: pbrMaterialProps, pbrProjection: { camera } });
4273
3727
  return new import_engine2.ModelNode({ managedResources, model });
4274
3728
  }
4275
3729
 
@@ -4308,8 +3762,8 @@ layout(0) positions: vec4; // in vec4 POSITION;
4308
3762
  this.options = { ...DEFAULT_OPTIONS, ...options };
4309
3763
  }
4310
3764
  instantiate(gltf) {
4311
- this.gltf = gltf;
4312
- const scenes = (gltf.scenes || []).map((scene) => this.createScene(scene));
3765
+ this.gltf = deepCopy(gltf);
3766
+ const scenes = (this.gltf.scenes || []).map((scene) => this.createScene(scene));
4313
3767
  return scenes;
4314
3768
  }
4315
3769
  createAnimator() {
@@ -4355,6 +3809,8 @@ layout(0) positions: vec4; // in vec4 POSITION;
4355
3809
  }
4356
3810
  gltfNode._node = node;
4357
3811
  }
3812
+ const topLevelNode = this.gltf.nodes.find((node) => node.id === gltfNode.id);
3813
+ topLevelNode._node = gltfNode._node;
4358
3814
  return gltfNode._node;
4359
3815
  }
4360
3816
  createMesh(gltfMesh) {
@@ -4431,6 +3887,22 @@ layout(0) positions: vec4; // in vec4 POSITION;
4431
3887
  return false;
4432
3888
  }
4433
3889
  };
3890
+ function deepCopy(object) {
3891
+ if (ArrayBuffer.isView(object) || object instanceof ArrayBuffer || object instanceof ImageBitmap) {
3892
+ return object;
3893
+ }
3894
+ if (Array.isArray(object)) {
3895
+ return object.map(deepCopy);
3896
+ }
3897
+ if (object && typeof object === "object") {
3898
+ const result = {};
3899
+ for (const key in object) {
3900
+ result[key] = deepCopy(object[key]);
3901
+ }
3902
+ return result;
3903
+ }
3904
+ return object;
3905
+ }
4434
3906
 
4435
3907
  // src/gltf/create-gltf-objects.ts
4436
3908
  function createScenegraphsFromGLTF(device, gltf, options) {