@zephyr3d/scene 0.9.23 → 0.9.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.
@@ -28,29 +28,29 @@ const fogTypeMap = {
28
28
  none: Fog.FOG_TYPE_NONE
29
29
  };
30
30
  const defaultSkyWorldMatrix = Matrix4x4.identity();
31
- /**
32
- * The sky renderer
33
- * @public
31
+ /**
32
+ * The sky renderer
33
+ * @public
34
34
  */ class SkyRenderer extends Disposable {
35
- /**
36
- * @internal
37
- *
38
- * The atmospheric scattering model predates photometric lighting and was authored around a
39
- * sun input of 10. This normalization maps the physical daylight reference (100,000 lux at
40
- * Sunny 16, whose camera exposure is 1 / 38,400) onto that model reference: 10 / (100000 / 38400).
35
+ /**
36
+ * @internal
37
+ *
38
+ * The atmospheric scattering model predates photometric lighting and was authored around a
39
+ * sun input of 10. This normalization maps the physical daylight reference (100,000 lux at
40
+ * Sunny 16, whose camera exposure is 1 / 38,400) onto that model reference: 10 / (100000 / 38400).
41
41
  */ static PHYSICAL_ATMOSPHERE_LUMINANCE_SCALE = 3.84;
42
- /**
43
- * @internal
44
- * Fixed exposure the physical sky bake is stored at. See {@link PHYSICAL_BAKE_EXPOSURE}.
42
+ /**
43
+ * @internal
44
+ * Fixed exposure the physical sky bake is stored at. See {@link PHYSICAL_BAKE_EXPOSURE}.
45
45
  */ static PHYSICAL_BAKE_EXPOSURE = PHYSICAL_BAKE_EXPOSURE;
46
- /**
47
- * @internal
48
- *
49
- * Reference-exposure anchor previously used to lift authored fog colors into photometric space.
50
- *
51
- * @deprecated Physical fog now derives its luminance from `EnvLightWrapper.intensity`, mirroring
52
- * Filament, which scales fog color by `iblLuminance`. Retained only because it documents the
53
- * Sunny-16 equivalence: 38,400 = 1 / exposure(f/16, 1/125s, ISO 100).
46
+ /**
47
+ * @internal
48
+ *
49
+ * Reference-exposure anchor previously used to lift authored fog colors into photometric space.
50
+ *
51
+ * @deprecated Physical fog now derives its luminance from `EnvLightWrapper.intensity`, mirroring
52
+ * Filament, which scales fog color by `iblLuminance`. Retained only because it documents the
53
+ * Sunny-16 equivalence: 38,400 = 1 / exposure(f/16, 1/125s, ISO 100).
54
54
  */ static FOG_PHYSICAL_LUMINANCE = 38400;
55
55
  static _skyCamera = (()=>{
56
56
  return new PerspectiveCamera(null, Math.PI * 0.5, 1, 20, 1);
@@ -110,16 +110,16 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
110
110
  _bindgroupFog = null;
111
111
  _bindgroupFogNoDepth = null;
112
112
  _format;
113
- /**
114
- * @internal Scale lifting the authored 0..1 height-fog colors into the pre-exposed space for the
115
- * current frame (1 in legacy, `EnvLightWrapper.intensity * cameraExposure` in physical).
113
+ /**
114
+ * @internal Scale lifting the authored 0..1 height-fog colors into the pre-exposed space for the
115
+ * current frame (1 in legacy, `EnvLightWrapper.intensity * cameraExposure` in physical).
116
116
  */ _fogLuminanceScale;
117
- /**
118
- * @internal Ratio converting the fog shader's atmosphere-derived LUT samples from the fixed bake
119
- * exposure to the live one (1 in legacy).
117
+ /**
118
+ * @internal Ratio converting the fog shader's atmosphere-derived LUT samples from the fixed bake
119
+ * exposure to the live one (1 in legacy).
120
120
  */ _fogPreExposure;
121
- /**
122
- * Creates an instance of SkyRenderer
121
+ /**
122
+ * Creates an instance of SkyRenderer
123
123
  */ constructor(){
124
124
  super();
125
125
  this._skyType = 'scatter';
@@ -166,8 +166,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
166
166
  /** @internal */ getHash(_ctx) {
167
167
  return `${this.skyType}:${this.fogType}`;
168
168
  }
169
- /**
170
- * Gets the preferred environment texture format.
169
+ /**
170
+ * Gets the preferred environment texture format.
171
171
  */ get envTextureFormat() {
172
172
  if (!this._format) {
173
173
  const texCaps = getDevice().getDeviceCaps().textureCaps;
@@ -212,8 +212,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
212
212
  }
213
213
  return this._bakedSkyboxTexture.get();
214
214
  }
215
- /**
216
- * The color used when sky type is `image`
215
+ /**
216
+ * The color used when sky type is `image`
217
217
  */ get skyColor() {
218
218
  return this._skyColor;
219
219
  }
@@ -223,8 +223,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
223
223
  this.invalidate();
224
224
  }
225
225
  }
226
- /**
227
- * The image used when sky type is `image`
226
+ /**
227
+ * The image used when sky type is `image`
228
228
  */ get skyImage() {
229
229
  return this._skyImage.get();
230
230
  }
@@ -234,8 +234,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
234
234
  this.invalidate();
235
235
  }
236
236
  }
237
- /**
238
- * Window weights for SH projection
237
+ /**
238
+ * Window weights for SH projection
239
239
  */ get shWindowWeights() {
240
240
  return this._shWindowWeights;
241
241
  }
@@ -243,8 +243,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
243
243
  this._shWindowWeights.set(weights);
244
244
  this.invalidate();
245
245
  }
246
- /**
247
- * Sample count for radiance convolution
246
+ /**
247
+ * Sample count for radiance convolution
248
248
  */ get radianceConvSamples() {
249
249
  return this._radianceConvSamples;
250
250
  }
@@ -254,8 +254,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
254
254
  this.invalidate();
255
255
  }
256
256
  }
257
- /**
258
- * Sample count for irradiance convolution
257
+ /**
258
+ * Sample count for irradiance convolution
259
259
  */ get irradianceConvSamples() {
260
260
  return this._irradianceConvSamples;
261
261
  }
@@ -382,12 +382,12 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
382
382
  this.invalidate();
383
383
  }
384
384
  }
385
- /**
386
- * Light density of the sky.
387
- *
388
- * @remarks
389
- * This value controls how much cloud should be rendered when the sky type is scatter.
390
- * Typically, the value should be in the range of 0 to 1.
385
+ /**
386
+ * Light density of the sky.
387
+ *
388
+ * @remarks
389
+ * This value controls how much cloud should be rendered when the sky type is scatter.
390
+ * Typically, the value should be in the range of 0 to 1.
391
391
  */ get cloudy() {
392
392
  return this._cloudy;
393
393
  }
@@ -397,8 +397,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
397
397
  this.invalidate();
398
398
  }
399
399
  }
400
- /**
401
- * Intensity of the sky color
400
+ /**
401
+ * Intensity of the sky color
402
402
  */ get cloudIntensity() {
403
403
  return this._cloudIntensity;
404
404
  }
@@ -408,19 +408,19 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
408
408
  this.invalidate();
409
409
  }
410
410
  }
411
- /**
412
- * Wind velocity
413
- *
414
- * @remarks
415
- * This value affects the movement of the cloud
411
+ /**
412
+ * Wind velocity
413
+ *
414
+ * @remarks
415
+ * This value affects the movement of the cloud
416
416
  */ get wind() {
417
417
  return this._wind;
418
418
  }
419
419
  set wind(val) {
420
420
  this._wind.set(val);
421
421
  }
422
- /**
423
- * Radiance map of the sky.
422
+ /**
423
+ * Radiance map of the sky.
424
424
  */ get radianceMap() {
425
425
  if (!this._radianceMap.get()) {
426
426
  this._radianceMap.set(getDevice().createCubeTexture(this.envTextureFormat, this._radianceMapWidth));
@@ -428,11 +428,11 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
428
428
  }
429
429
  return this._radianceMap.get();
430
430
  }
431
- /**
432
- * Radiance map of the sky reused for sheen.
433
- *
434
- * @remarks
435
- * Dynamic sky is smooth enough that the GGX-prefiltered radiance map is a practical approximation for sheen.
431
+ /**
432
+ * Radiance map of the sky reused for sheen.
433
+ *
434
+ * @remarks
435
+ * Dynamic sky is smooth enough that the GGX-prefiltered radiance map is a practical approximation for sheen.
436
436
  */ get sheenRadianceMap() {
437
437
  return this.radianceMap;
438
438
  }
@@ -450,8 +450,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
450
450
  }
451
451
  return this._radianceFrameBuffer.get();
452
452
  }
453
- /**
454
- * Irradiance SH coeffecients buffer
453
+ /**
454
+ * Irradiance SH coeffecients buffer
455
455
  */ get irradianceSH() {
456
456
  if (!this._irradianceSH.get()) {
457
457
  const buffer = getDevice().createBuffer(4 * 4 * 9, {
@@ -461,8 +461,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
461
461
  }
462
462
  return this._irradianceSH.get();
463
463
  }
464
- /**
465
- * Irradiance SH coeffecients texture
464
+ /**
465
+ * Irradiance SH coeffecients texture
466
466
  */ get irradianceSHFB() {
467
467
  if (!this._irradianceSHFB.get()) {
468
468
  const device = getDevice();
@@ -477,8 +477,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
477
477
  }
478
478
  return this._irradianceSHFB.get();
479
479
  }
480
- /**
481
- * Cube texture for skybox.
480
+ /**
481
+ * Cube texture for skybox.
482
482
  */ get skyboxTexture() {
483
483
  return this._skyboxTexture.get();
484
484
  }
@@ -490,8 +490,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
490
490
  }
491
491
  }
492
492
  }
493
- /**
494
- * Additional euler rotation (in degrees) applied to skybox.
493
+ /**
494
+ * Additional euler rotation (in degrees) applied to skybox.
495
495
  */ get skyboxRotation() {
496
496
  return this._skyboxRotation;
497
497
  }
@@ -534,8 +534,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
534
534
  /** @internal */ get fogPresents() {
535
535
  return this._skyType === 'scatter' || this._fogType !== 'none';
536
536
  }
537
- /**
538
- * Force the radiance map and irradiance map to be regenerated.
537
+ /**
538
+ * Force the radiance map and irradiance map to be regenerated.
539
539
  */ invalidate() {
540
540
  this._bakedSkyboxDirty = true;
541
541
  }
@@ -701,11 +701,11 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
701
701
  device.popDeviceStates();
702
702
  device.setRenderStates(saveRenderStates);
703
703
  }
704
- /**
705
- * @internal
706
- * Updates the scene's IBL (GGX-prefiltered specular radiance map + irradiance SH) from the given
707
- * cubemap, provided the scene environment light is still driven by this dynamic sky. Must be called
708
- * with the fog-free cubemap so height fog does not leak into the environment lighting.
704
+ /**
705
+ * @internal
706
+ * Updates the scene's IBL (GGX-prefiltered specular radiance map + irradiance SH) from the given
707
+ * cubemap, provided the scene environment light is still driven by this dynamic sky. Must be called
708
+ * with the fog-free cubemap so height fog does not leak into the environment lighting.
709
709
  */ _updateIBLFromBakedSky(ctx, skybox) {
710
710
  if (ctx.scene.env.light.radianceMap && (ctx.scene.env.light.radianceMap === this.radianceMap || this._irradianceSH.get() && ctx.scene.env.light.irradianceSH === this.irradianceSH || this._irradianceSHFB.get() && ctx.scene.env.light.irradianceSHFB === this.irradianceSHFB)) {
711
711
  prefilterCubemap(skybox, 'ggx', this.radianceFramebuffer, this._radianceConvSamples);
@@ -741,12 +741,12 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
741
741
  device.setRenderStates(renderStates);
742
742
  device.draw('triangle-strip', 0, 4);
743
743
  }
744
- /**
745
- * @internal
746
- * Height-fog upload params with the authored base/directional colors lifted into the pre-exposed
747
- * physical space when physical lighting is active, plus the pre-exposure the shader applies to its
748
- * atmosphere-derived LUT samples. Legacy returns the stored params untouched so its upload stays
749
- * byte-identical. Stored authored values are never mutated.
744
+ /**
745
+ * @internal
746
+ * Height-fog upload params with the authored base/directional colors lifted into the pre-exposed
747
+ * physical space when physical lighting is active, plus the pre-exposure the shader applies to its
748
+ * atmosphere-derived LUT samples. Legacy returns the stored params untouched so its upload stays
749
+ * byte-identical. Stored authored values are never mutated.
750
750
  */ _getUploadHeightFogParams() {
751
751
  const scale = this._fogLuminanceScale;
752
752
  const p = this._heightFogParams;
@@ -779,14 +779,14 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
779
779
  const savedRenderStates = device.getRenderStates();
780
780
  this._prepareSkyBox(device);
781
781
  this.renderUberFog(camera, depthBuffer);
782
- /*
783
- if (this._skyType === 'scatter') {
784
- this.renderAtmosphericFog(ctx, depthBuffer);
785
- }
786
- */ /*
787
- if (this._fogType === 'height_fog') {
788
- this.renderHeightFog(ctx, depthBuffer);
789
- }
782
+ /*
783
+ if (this._skyType === 'scatter') {
784
+ this.renderAtmosphericFog(ctx, depthBuffer);
785
+ }
786
+ */ /*
787
+ if (this._fogType === 'height_fog') {
788
+ this.renderHeightFog(ctx, depthBuffer);
789
+ }
790
790
  */ device.setRenderStates(savedRenderStates);
791
791
  if (fogFramebuffer) {
792
792
  device.popDeviceStates();
@@ -888,33 +888,33 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
888
888
  }
889
889
  device.setRenderStates(savedRenderStates);
890
890
  }
891
- /**
892
- * @internal
893
- *
894
- * Converts a value stored at {@link PHYSICAL_BAKE_EXPOSURE} into the live pre-exposed space.
895
- *
896
- * @remarks
897
- * Everything derived from the cached sky bake (the IBL, the distant-light LUT, the visible baked
898
- * skybox) is stored at the fixed reference exposure. Multiplying by this ratio yields the same
899
- * result as if the live camera exposure had been baked in, without invalidating the cache when
900
- * the camera stops down. Returns 1 in legacy.
891
+ /**
892
+ * @internal
893
+ *
894
+ * Converts a value stored at {@link PHYSICAL_BAKE_EXPOSURE} into the live pre-exposed space.
895
+ *
896
+ * @remarks
897
+ * Everything derived from the cached sky bake (the IBL, the distant-light LUT, the visible baked
898
+ * skybox) is stored at the fixed reference exposure. Multiplying by this ratio yields the same
899
+ * result as if the live camera exposure had been baked in, without invalidating the cache when
900
+ * the camera stops down. Returns 1 in legacy.
901
901
  */ static getBakeToPreExposedScale(ctx) {
902
902
  return ctx.scene.lightingMode === 'physical' ? ShaderHelper.getPreExposure(ctx) / SkyRenderer.PHYSICAL_BAKE_EXPOSURE : 1;
903
903
  }
904
- /**
905
- * @internal
906
- *
907
- * Scale that normalizes a sky into the IBL bake's storage space.
908
- *
909
- * @remarks
910
- * An authored 0..1 `skybox` / `image` is treated as an emitter of `EnvLightWrapper.intensity` lux.
911
- * The scattering atmosphere needs no lift: its LUTs already carry photometric sun illuminance.
912
- *
913
- * Both are then scaled to {@link PHYSICAL_BAKE_EXPOSURE}. The bake is cached and only invalidated
914
- * by sun changes, so it must be exposure-independent; storing it at raw photometric magnitude
915
- * would overflow the environment cubemap's float range (see {@link PHYSICAL_BAKE_EXPOSURE}).
916
- *
917
- * Returns 1 in legacy so its bake stays byte-identical.
904
+ /**
905
+ * @internal
906
+ *
907
+ * Scale that normalizes a sky into the IBL bake's storage space.
908
+ *
909
+ * @remarks
910
+ * An authored 0..1 `skybox` / `image` is treated as an emitter of `EnvLightWrapper.intensity` lux.
911
+ * The scattering atmosphere needs no lift: its LUTs already carry photometric sun illuminance.
912
+ *
913
+ * Both are then scaled to {@link PHYSICAL_BAKE_EXPOSURE}. The bake is cached and only invalidated
914
+ * by sun changes, so it must be exposure-independent; storing it at raw photometric magnitude
915
+ * would overflow the environment cubemap's float range (see {@link PHYSICAL_BAKE_EXPOSURE}).
916
+ *
917
+ * Returns 1 in legacy so its bake stays byte-identical.
918
918
  */ _getSkyBakeLuminanceScale(ctx) {
919
919
  if (ctx.scene.lightingMode !== 'physical') {
920
920
  return 1;
@@ -922,11 +922,11 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
922
922
  // scatter already includes the bake exposure via renderAtmosphereLUTs().
923
923
  return this._skyType === 'scatter' ? 1 : ctx.scene.env.light.intensity * SkyRenderer.PHYSICAL_BAKE_EXPOSURE;
924
924
  }
925
- /**
926
- * @internal
927
- *
928
- * On-screen sky scale: the bake-time normalization converted from the stored reference exposure
929
- * to the live one, so the visible sky lands in the same pre-exposed space as every lit surface.
925
+ /**
926
+ * @internal
927
+ *
928
+ * On-screen sky scale: the bake-time normalization converted from the stored reference exposure
929
+ * to the live one, so the visible sky lands in the same pre-exposed space as every lit surface.
930
930
  */ _getSkyScreenLuminanceScale(ctx) {
931
931
  return this._getSkyBakeLuminanceScale(ctx) * SkyRenderer.getBakeToPreExposedScale(ctx);
932
932
  }
@@ -1402,11 +1402,11 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
1402
1402
  this.noiseValue = pb.smoothStep(1, pb.add(1, this.cloudy), this.noiseValue);
1403
1403
  });
1404
1404
  // use sun color as cloud color
1405
- /*
1406
- this.$l.sunColor = pb.mul(
1407
- pb.textureSampleLevel(this.skyLut, viewDirToUV(this, this.sunDir), 0),
1408
- this.sunIntensity
1409
- );
1405
+ /*
1406
+ this.$l.sunColor = pb.mul(
1407
+ pb.textureSampleLevel(this.skyLut, viewDirToUV(this, this.sunDir), 0),
1408
+ this.sunIntensity
1409
+ );
1410
1410
  */ this.$l.cloudColor = pb.mul(this.sunColor.rgb, this.sunIntensity, pb.mul(this.noiseValue, this.cloudIntensity));
1411
1411
  }
1412
1412
  // Compute sky color