Update 3D lights shadows and fogs when the world scale changes (#9169)

This commit is contained in:
Florian Rival
2026-09-30 20:41:37 +02:00
committed by GitHub
parent cadfd2dfda
commit efc2aa09d0
3 changed files with 48 additions and 23 deletions
+10 -3
View File
@@ -30,6 +30,7 @@ namespace gdjs {
private _light: THREE.DirectionalLight;
private _shadowMapDirty = true;
private _shadowCameraDirty = true;
private _shadowCameraInverseWorldScale: float = 0;
private _shadowCameraHelper: THREE.CameraHelper | null;
constructor() {
@@ -47,12 +48,16 @@ namespace gdjs {
}
private _updateShadowCamera(scene: gdjs.RuntimeScene): void {
if (!this._shadowCameraDirty) {
const inverseWorldScale = scene.getRenderer3DInverseWorldScale();
// The world scale can be changed in the editor.
if (
!this._shadowCameraDirty &&
this._shadowCameraInverseWorldScale === inverseWorldScale
) {
return;
}
this._shadowCameraDirty = false;
const inverseWorldScale = scene.getRenderer3DInverseWorldScale();
this._shadowCameraInverseWorldScale = inverseWorldScale;
const frustumSize = this._frustumSize * inverseWorldScale;
this._light.shadow.camera.near = 1 * inverseWorldScale;
@@ -62,6 +67,8 @@ namespace gdjs {
this._light.shadow.camera.left = -frustumSize / 2;
this._light.shadow.camera.top = frustumSize / 2;
this._light.shadow.camera.bottom = -frustumSize / 2;
// Three.js only updates it when the shadow map is created.
this._light.shadow.camera.updateProjectionMatrix();
}
private _updateShadowMapSize(): void {
+16 -8
View File
@@ -15,6 +15,9 @@ namespace gdjs {
}
return new (class implements gdjs.PixiFiltersTools.Filter {
fog: THREE.FogExp2;
// In scene units: the fog is converted to the Three.js world units
// before each rendering, as the world scale can change in the editor.
private _density: float = 0.0012;
constructor() {
this.fog = new THREE.FogExp2(0xffffff);
@@ -56,19 +59,23 @@ namespace gdjs {
scene.fog = null;
return true;
}
updatePreRender(target: gdjs.EffectsTarget): any {}
updateDoubleParameter(parameterName: string, value: number): void {
updatePreRender(target: gdjs.EffectsTarget): any {
this._updateFogDensity();
}
private _updateFogDensity(): void {
const scene = target.getRuntimeScene().getScene();
const worldScale = scene.getRenderer3DWorldScale();
this.fog.density = this._density * worldScale;
}
updateDoubleParameter(parameterName: string, value: number): void {
if (parameterName === 'density') {
this.fog.density = value * worldScale;
this._density = value;
this._updateFogDensity();
}
}
getDoubleParameter(parameterName: string): number {
const scene = target.getRuntimeScene().getScene();
const inverseWorldScale = scene.getRenderer3DInverseWorldScale();
if (parameterName === 'density') {
return this.fog.density * inverseWorldScale;
return this._density;
}
return 0;
}
@@ -93,14 +100,15 @@ namespace gdjs {
updateBooleanParameter(parameterName: string, value: boolean): void {}
getNetworkSyncData(): ExponentialFogFilterNetworkSyncData {
return {
d: this.fog.density,
d: this._density,
c: this.fog.color.getHex(),
};
}
updateFromNetworkSyncData(
syncData: ExponentialFogFilterNetworkSyncData
): void {
this.fog.density = syncData.d;
this._density = syncData.d;
this._updateFogDensity();
this.fog.color.setHex(syncData.c);
}
})();
+22 -12
View File
@@ -16,6 +16,10 @@ namespace gdjs {
}
return new (class implements gdjs.PixiFiltersTools.Filter {
fog: THREE.Fog;
// In scene units: the fog is converted to the Three.js world units
// before each rendering, as the world scale can change in the editor.
private _near: float = 200;
private _far: float = 2000;
constructor() {
this.fog = new THREE.Fog(0xffffff);
@@ -57,23 +61,28 @@ namespace gdjs {
scene.fog = null;
return true;
}
updatePreRender(target: gdjs.EffectsTarget): any {}
updateDoubleParameter(parameterName: string, value: number): void {
updatePreRender(target: gdjs.EffectsTarget): any {
this._updateFogDistances();
}
private _updateFogDistances(): void {
const scene = target.getRuntimeScene().getScene();
const inverseWorldScale = scene.getRenderer3DInverseWorldScale();
this.fog.near = this._near * inverseWorldScale;
this.fog.far = this._far * inverseWorldScale;
}
updateDoubleParameter(parameterName: string, value: number): void {
if (parameterName === 'near') {
this.fog.near = value * inverseWorldScale;
this._near = value;
} else if (parameterName === 'far') {
this.fog.far = value * inverseWorldScale;
this._far = value;
}
this._updateFogDistances();
}
getDoubleParameter(parameterName: string): number {
const scene = target.getRuntimeScene().getScene();
const worldScale = scene.getRenderer3DWorldScale();
if (parameterName === 'near') {
return this.fog.near * worldScale;
return this._near;
} else if (parameterName === 'far') {
return this.fog.far * worldScale;
return this._far;
}
return 0;
}
@@ -98,16 +107,17 @@ namespace gdjs {
updateBooleanParameter(parameterName: string, value: boolean): void {}
getNetworkSyncData(): LinearFogFilterNetworkSyncData {
return {
n: this.fog.near,
f: this.fog.far,
n: this._near,
f: this._far,
c: this.fog.color.getHex(),
};
}
updateFromNetworkSyncData(
data: LinearFogFilterNetworkSyncData
): void {
this.fog.near = data.n;
this.fog.far = data.f;
this._near = data.n;
this._far = data.f;
this._updateFogDistances();
this.fog.color.setHex(data.c);
}
})();