@onerjs/addons 8.37.6 → 8.37.8

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.
@@ -17,7 +17,6 @@ import "./Shaders/compositeAerialPerspective.fragment.js";
17
17
  import "./Shaders/compositeSky.fragment.js";
18
18
  import "./Shaders/compositeGlobeAtmosphere.fragment.js";
19
19
  import "./Shaders/fullscreenTriangle.vertex.js";
20
- import "./Shaders/multiScattering.fragment.js";
21
20
  import "./Shaders/skyView.fragment.js";
22
21
  import "./Shaders/aerialPerspective.fragment.js";
23
22
  import "./Shaders/ShadersInclude/atmosphereFragmentDeclaration.js";
@@ -501,6 +500,7 @@ export class Atmosphere {
501
500
  this._isEnabled = true;
502
501
  this._aerialPerspectiveLutHasBeenRendered = false;
503
502
  this._hasRenderedMultiScatteringLut = false;
503
+ this._hasEverRenderedMultiScatteringLut = false;
504
504
  this._multiScatteringEffectWrapper = null;
505
505
  this._multiScatteringLutRenderTarget = null;
506
506
  this._aerialPerspectiveLutEffectWrapper = null;
@@ -513,6 +513,7 @@ export class Atmosphere {
513
513
  this._skyCompositorEffectWrapper = null;
514
514
  this._globeAtmosphereCompositorEffectWrapper = null;
515
515
  this._onBeforeCameraRenderObserver = null;
516
+ this._onBeforeRenderObserver = null;
516
517
  this._onBeforeDrawPhaseObserver = null;
517
518
  this._onAfterRenderingGroupObserver = null;
518
519
  /**
@@ -605,6 +606,17 @@ export class Atmosphere {
605
606
  this._minimumMultiScattering.x = minimumMultiScatteringColor.r * this._minimumMultiScatteringIntensity;
606
607
  this._minimumMultiScattering.y = minimumMultiScatteringColor.g * this._minimumMultiScatteringIntensity;
607
608
  this._minimumMultiScattering.z = minimumMultiScatteringColor.b * this._minimumMultiScatteringIntensity;
609
+ // Initialize light direction and color.
610
+ {
611
+ const light = lights[0];
612
+ this._directionToLight.copyFrom(light.direction).scaleInPlace(-1);
613
+ const lightColor = this._linearLightColor.copyFrom(light.diffuse);
614
+ if (!this._isLinearSpaceLight) {
615
+ lightColor.toLinearSpaceToRef(lightColor);
616
+ }
617
+ const intensity = light.intensity;
618
+ this._lightRadianceAtCamera.set(intensity * lightColor.r, intensity * lightColor.g, intensity * lightColor.b);
619
+ }
608
620
  this._effectRenderer = new EffectRenderer(engine, {
609
621
  // Full screen triangle.
610
622
  indices: [0, 2, 1],
@@ -613,7 +625,8 @@ export class Atmosphere {
613
625
  this._transmittanceLut = new TransmittanceLut(this);
614
626
  this._multiScatteringLutRenderTarget = CreateRenderTargetTexture("atmo-multiScattering", { width: 32, height: 32 }, scene);
615
627
  this._multiScatteringEffectWrapper = CreateMultiScatteringEffectWrapper(engine, this.uniformBuffer, this._groundAlbedo);
616
- if (options?.isDiffuseSkyIrradianceLutEnabled ?? true) {
628
+ this._isDiffuseSkyIrradianceLutEnabled = options?.isDiffuseSkyIrradianceLutEnabled ?? true;
629
+ if (this._isDiffuseSkyIrradianceLutEnabled) {
617
630
  this._diffuseSkyIrradianceLut = new DiffuseSkyIrradianceLut(this);
618
631
  }
619
632
  if (this._isSkyViewLutEnabled) {
@@ -622,6 +635,10 @@ export class Atmosphere {
622
635
  if (this._isAerialPerspectiveLutEnabled) {
623
636
  this.aerialPerspectiveLutRenderTarget;
624
637
  }
638
+ // Render global LUTs once per frame (not per camera).
639
+ this._onBeforeRenderObserver = scene.onBeforeRenderObservable.add(() => {
640
+ this.renderGlobalLuts();
641
+ });
625
642
  // Before rendering, make sure the per-camera variables have been updated.
626
643
  this._onBeforeCameraRenderObserver = scene.onBeforeCameraRenderObservable.add((x) => {
627
644
  this._updatePerCameraVariables(x);
@@ -697,6 +714,8 @@ export class Atmosphere {
697
714
  this._onBeforeDrawPhaseObserver = null;
698
715
  this._onAfterRenderingGroupObserver?.remove();
699
716
  this._onAfterRenderingGroupObserver = null;
717
+ this._onBeforeRenderObserver?.remove();
718
+ this._onBeforeRenderObserver = null;
700
719
  this._globeAtmosphereCompositorEffectWrapper?.dispose();
701
720
  this._globeAtmosphereCompositorEffectWrapper = null;
702
721
  this._skyCompositorEffectWrapper?.dispose();
@@ -776,13 +795,16 @@ export class Atmosphere {
776
795
  if (!isEnabled) {
777
796
  return;
778
797
  }
798
+ const engine = this._engine;
799
+ const effectWrapper = (this._aerialPerspectiveCompositorEffectWrapper ?? (this._aerialPerspectiveCompositorEffectWrapper = CreateAerialPerspectiveCompositorEffectWrapper(engine, this.uniformBuffer, this._isAerialPerspectiveLutEnabled, this._isSkyViewLutEnabled, this._isLinearSpaceComposition, this._applyApproximateTransmittance, this._aerialPerspectiveIntensity, this._aerialPerspectiveRadianceBias)));
800
+ if (!this._isGlobalLutsReady) {
801
+ return;
802
+ }
779
803
  // Aerial perspective compositor only renders when inside the atmosphere.
780
804
  const isOutsideAtmosphere = this._cameraAtmosphereVariables.clampedCameraRadius > this._physicalProperties.atmosphereRadius;
781
805
  if (isOutsideAtmosphere) {
782
806
  return;
783
807
  }
784
- const engine = this._engine;
785
- const effectWrapper = (this._aerialPerspectiveCompositorEffectWrapper ?? (this._aerialPerspectiveCompositorEffectWrapper = CreateAerialPerspectiveCompositorEffectWrapper(engine, this.uniformBuffer, this._isAerialPerspectiveLutEnabled, this._isSkyViewLutEnabled, this._isLinearSpaceComposition, this._applyApproximateTransmittance, this._aerialPerspectiveIntensity, this._aerialPerspectiveRadianceBias)));
786
808
  const skyViewLut = this._isSkyViewLutEnabled ? this.skyViewLutRenderTarget : null;
787
809
  const multiScatteringLut = this._multiScatteringLutRenderTarget;
788
810
  const transmittanceLut = this._transmittanceLut.renderTarget;
@@ -827,6 +849,11 @@ export class Atmosphere {
827
849
  if (!isEnabled) {
828
850
  return;
829
851
  }
852
+ const engine = this._engine;
853
+ const effectWrapper = (this._skyCompositorEffectWrapper ?? (this._skyCompositorEffectWrapper = CreateSkyCompositorEffectWrapper(engine, this.uniformBuffer, this._isSkyViewLutEnabled, this._isLinearSpaceComposition, this._applyApproximateTransmittance)));
854
+ if (!this._isGlobalLutsReady) {
855
+ return;
856
+ }
830
857
  // The sky compositor only renders when inside the atmosphere.
831
858
  const isOutsideAtmosphere = this._cameraAtmosphereVariables.clampedCameraRadius > this._physicalProperties.atmosphereRadius;
832
859
  if (isOutsideAtmosphere) {
@@ -835,8 +862,6 @@ export class Atmosphere {
835
862
  if (this.depthTexture !== null && !this.depthTexture.isReady()) {
836
863
  return;
837
864
  }
838
- const engine = this._engine;
839
- const effectWrapper = (this._skyCompositorEffectWrapper ?? (this._skyCompositorEffectWrapper = CreateSkyCompositorEffectWrapper(engine, this.uniformBuffer, this._isSkyViewLutEnabled, this._isLinearSpaceComposition, this._applyApproximateTransmittance)));
840
865
  const skyViewLut = this._isSkyViewLutEnabled ? this.skyViewLutRenderTarget : null;
841
866
  const multiScatteringLut = this._multiScatteringLutRenderTarget;
842
867
  const transmittanceLut = this._transmittanceLut.renderTarget;
@@ -868,13 +893,16 @@ export class Atmosphere {
868
893
  if (!isEnabled) {
869
894
  return;
870
895
  }
896
+ const engine = this._engine;
897
+ const effectWrapper = (this._globeAtmosphereCompositorEffectWrapper ?? (this._globeAtmosphereCompositorEffectWrapper = CreateGlobeAtmosphereCompositorEffectWrapper(engine, this.uniformBuffer, this._isSkyViewLutEnabled, this._isLinearSpaceComposition, this._applyApproximateTransmittance, this._aerialPerspectiveIntensity, this._aerialPerspectiveRadianceBias, this.depthTexture !== null)));
898
+ if (!this._isGlobalLutsReady) {
899
+ return;
900
+ }
871
901
  // Globe atmosphere compositor only renders when outside the atmosphere.
872
902
  const isOutsideAtmosphere = this._cameraAtmosphereVariables.clampedCameraRadius > this._physicalProperties.atmosphereRadius;
873
903
  if (!isOutsideAtmosphere) {
874
904
  return;
875
905
  }
876
- const engine = this._engine;
877
- const effectWrapper = (this._globeAtmosphereCompositorEffectWrapper ?? (this._globeAtmosphereCompositorEffectWrapper = CreateGlobeAtmosphereCompositorEffectWrapper(engine, this.uniformBuffer, this._isSkyViewLutEnabled, this._isLinearSpaceComposition, this._applyApproximateTransmittance, this._aerialPerspectiveIntensity, this._aerialPerspectiveRadianceBias, this.depthTexture !== null)));
878
906
  const skyViewLut = this._isSkyViewLutEnabled ? this.skyViewLutRenderTarget : null;
879
907
  const multiScatteringLut = this._multiScatteringLutRenderTarget;
880
908
  const transmittanceLut = this._transmittanceLut.renderTarget;
@@ -916,20 +944,24 @@ export class Atmosphere {
916
944
  this._globeAtmosphereCompositorEffectWrapper?.dispose();
917
945
  this._globeAtmosphereCompositorEffectWrapper = null;
918
946
  }
947
+ get _isGlobalLutsReady() {
948
+ return (this._hasEverRenderedMultiScatteringLut &&
949
+ !!this._transmittanceLut?.hasLutData &&
950
+ (!this._isDiffuseSkyIrradianceLutEnabled || this._diffuseSkyIrradianceLut.hasLutData));
951
+ }
919
952
  /**
920
953
  * Updates the camera variables that are specific to the atmosphere.
921
954
  * @param camera - The camera to update the variables for.
922
955
  */
923
956
  _updatePerCameraVariables(camera) {
924
957
  const light = this._lights[0];
925
- this._directionToLight.copyFrom(light.direction);
926
- this._directionToLight.scaleInPlace(-1);
958
+ const directionToLight = this._directionToLight.copyFrom(light.direction).scaleInPlace(-1);
927
959
  const properties = this._physicalProperties;
928
960
  const cameraAtmosphereVariables = this._cameraAtmosphereVariables;
929
- cameraAtmosphereVariables.update(camera, properties.planetRadius, properties.planetRadiusWithOffset, properties.atmosphereRadius, this._directionToLight, this.originHeight);
961
+ cameraAtmosphereVariables.update(camera, properties.planetRadius, properties.planetRadiusWithOffset, properties.atmosphereRadius, directionToLight, this.originHeight);
930
962
  this._transmittanceLut.updateLightParameters(light, cameraAtmosphereVariables.clampedCameraRadius, cameraAtmosphereVariables.cameraGeocentricNormal);
931
963
  this._linearLightColor.copyFrom(light.diffuse);
932
- this.getDiffuseSkyIrradianceToRef(this._directionToLight, 0, cameraAtmosphereVariables.cameraGeocentricNormal, this.lights[0].intensity, this._tempSceneAmbient);
964
+ this.getDiffuseSkyIrradianceToRef(directionToLight, 0, cameraAtmosphereVariables.cameraGeocentricNormal, light.intensity, this._tempSceneAmbient);
933
965
  if (!this.isLinearSpaceLight) {
934
966
  this._tempSceneAmbient.toGammaSpaceToRef(this._tempSceneAmbient);
935
967
  }
@@ -959,9 +991,6 @@ export class Atmosphere {
959
991
  const isEnabled = this.isEnabled();
960
992
  {
961
993
  this.onBeforeRenderLutsForCameraObservable.notifyObservers(camera);
962
- // After UBO update we can render the global LUTs which use some of these values on the GPU.
963
- // TODO: Could break out update and UBOs to global vs. per-camera.
964
- this.renderGlobalLuts();
965
994
  // If atmosphere is enabled, render the per-camera LUTs (sky view and aerial perspective).
966
995
  if (isEnabled && !this._transmittanceLut.isDirty && this._hasRenderedMultiScatteringLut) {
967
996
  if (this._isSkyViewLutEnabled) {
@@ -988,6 +1017,9 @@ export class Atmosphere {
988
1017
  * Renders the lookup tables that do not depend on a camera position.
989
1018
  */
990
1019
  renderGlobalLuts() {
1020
+ if (this.uniformBuffer.useUbo) {
1021
+ this.updateUniformBuffer();
1022
+ }
991
1023
  const hasNewTransmittanceLut = this._transmittanceLut.render();
992
1024
  if (hasNewTransmittanceLut) {
993
1025
  this._hasRenderedMultiScatteringLut = false;
@@ -998,6 +1030,7 @@ export class Atmosphere {
998
1030
  if (this._multiScatteringEffectWrapper?.isReady() && this._multiScatteringLutRenderTarget?.isReady()) {
999
1031
  this._drawMultiScatteringLut();
1000
1032
  this._hasRenderedMultiScatteringLut = true;
1033
+ this._hasEverRenderedMultiScatteringLut = true;
1001
1034
  }
1002
1035
  }
1003
1036
  if (!this._transmittanceLut.isDirty && this._hasRenderedMultiScatteringLut) {
@@ -1013,12 +1046,7 @@ export class Atmosphere {
1013
1046
  const isWGSL = effect.shaderLanguage === 1 /* ShaderLanguage.WGSL */;
1014
1047
  const blockName = isWGSL ? "atmosphere" : uniformBuffer.name;
1015
1048
  uniformBuffer.bindToEffect(effect, blockName);
1016
- if (uniformBuffer.useUbo) {
1017
- uniformBuffer.update();
1018
- }
1019
- else {
1020
- this.updateUniformBuffer();
1021
- }
1049
+ uniformBuffer.useUbo ? uniformBuffer.update() : this.updateUniformBuffer();
1022
1050
  }
1023
1051
  /**
1024
1052
  * Updates the values in the atmosphere's uniform buffer.
@@ -1147,6 +1175,8 @@ const CreateEffectWrapper = (engine, name, fragmentShader, uniformNames, sampler
1147
1175
  const CreateMultiScatteringEffectWrapper = (engine, uniformBuffer, groundAlbedo) => {
1148
1176
  const name = "atmo-multiScattering";
1149
1177
  const useUbo = uniformBuffer.useUbo;
1178
+ const useWebGPU = engine.isWebGPU && !EffectWrapper.ForceGLSL;
1179
+ const uboName = useWebGPU ? "atmosphere" : uniformBuffer.name;
1150
1180
  const defines = ["#define POSITION_VEC2"];
1151
1181
  if (!groundAlbedo.equals(Color3.BlackReadOnly)) {
1152
1182
  defines.push("#define USE_GROUND_ALBEDO");
@@ -1158,10 +1188,16 @@ const CreateMultiScatteringEffectWrapper = (engine, uniformBuffer, groundAlbedo)
1158
1188
  fragmentShader: "multiScattering",
1159
1189
  attributeNames: ["position"],
1160
1190
  uniformNames: ["depth", ...(useUbo ? [] : uniformBuffer.getUniformNames())],
1161
- uniformBuffers: useUbo ? [uniformBuffer.name] : [],
1191
+ uniformBuffers: useUbo ? [uboName] : [],
1162
1192
  samplerNames: ["transmittanceLut"],
1163
1193
  defines,
1164
1194
  useShaderStore: true,
1195
+ shaderLanguage: useWebGPU ? 1 /* ShaderLanguage.WGSL */ : 0 /* ShaderLanguage.GLSL */,
1196
+ extraInitializations: (_, list) => {
1197
+ list.push(Promise.all(useWebGPU
1198
+ ? [import("./ShadersWGSL/fullscreenTriangle.vertex.js"), import("./ShadersWGSL/multiScattering.fragment.js")]
1199
+ : [import("./Shaders/fullscreenTriangle.vertex.js"), import("./Shaders/multiScattering.fragment.js")]));
1200
+ },
1165
1201
  });
1166
1202
  };
1167
1203
  const CreateRenderTargetTexture = (name, size, scene, options) => {
@@ -1206,6 +1242,7 @@ const DrawEffect = (engine, effectRenderer, effectWrapper, renderTarget, drawCal
1206
1242
  if ((renderTarget !== null && !renderTarget.isReady()) || !effectWrapper?.isReady()) {
1207
1243
  return;
1208
1244
  }
1245
+ effectRenderer.saveStates();
1209
1246
  // Set additional depth/stencil states before calling applyEffectWrapper.
1210
1247
  const currentDepthWrite = engine.getDepthWrite();
1211
1248
  if (depthWrite !== undefined) {
@@ -1218,10 +1255,9 @@ const DrawEffect = (engine, effectRenderer, effectWrapper, renderTarget, drawCal
1218
1255
  if (alphaMode !== Constants.ALPHA_DISABLE) {
1219
1256
  engine.setAlphaMode(alphaMode);
1220
1257
  }
1221
- effectRenderer.saveStates();
1258
+ const currentCull = engine.depthCullingState.cull;
1222
1259
  effectRenderer.setViewport();
1223
1260
  effectRenderer.applyEffectWrapper(effectWrapper, depthTest); // Note, stencil is false by default.
1224
- const currentCull = engine.depthCullingState.cull;
1225
1261
  engine.depthCullingState.cull = false;
1226
1262
  const effect = effectWrapper.effect;
1227
1263
  effect.setFloat("depth", depth);