@zephyr3d/scene 0.9.22 → 0.9.23
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/animation/joint_dynamics/collision.js +1 -7
- package/dist/animation/joint_dynamics/collision.js.map +1 -1
- package/dist/animation/joint_dynamics/constraints.js +2 -17
- package/dist/animation/joint_dynamics/constraints.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +2 -20
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +1 -3
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +14 -60
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics/types.js +3 -3
- package/dist/animation/joint_dynamics/types.js.map +1 -1
- package/dist/app/app.js +23 -0
- package/dist/app/app.js.map +1 -1
- package/dist/app/scriptregistry.js +16 -53
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +2 -0
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/model.js +22 -0
- package/dist/asset/model.js.map +1 -1
- package/dist/blitter/bilateralblur.js +3 -1
- package/dist/blitter/bilateralblur.js.map +1 -1
- package/dist/blitter/blitter.js +3 -3
- package/dist/blitter/blitter.js.map +1 -1
- package/dist/camera/camera.js +398 -45
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/perspectivecamera.js +69 -2
- package/dist/camera/perspectivecamera.js.map +1 -1
- package/dist/index.d.ts +9113 -8734
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js +1 -1
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/lambert.js +3 -3
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +8 -5
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +17 -10
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +1 -1
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +21 -6
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +33 -11
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/brdf.js +44 -12
- package/dist/material/mixins/pbr/brdf.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +149 -14
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mtoon.js +7 -4
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrblueprint.js +5 -1
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/pbrmr.js +1 -1
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js +1 -1
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/shader/helper.js +186 -11
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/skin.js +2 -2
- package/dist/material/skin.js.map +1 -1
- package/dist/material/terrain-cm.js +5 -5
- package/dist/material/terrain-cm.js.map +1 -1
- package/dist/material/water.js +6 -4
- package/dist/material/water.js.map +1 -1
- package/dist/posteffect/bloom.js +54 -4
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/compositor.js +41 -0
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/posteffect.js +35 -0
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/sao.js +7 -6
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/skinsss.js +3 -3
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +988 -436
- package/dist/posteffect/ssgi.js.map +1 -1
- package/dist/posteffect/ssr.js +83 -45
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +18 -15
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js +5 -4
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/posteffect/tonemap.js +15 -3
- package/dist/posteffect/tonemap.js.map +1 -1
- package/dist/render/abuffer_oit.js +2 -2
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/cluster_light.js +12 -6
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/drawable_mixin.js +8 -5
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +10 -5
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +298 -5
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/gpu_picking.js +7 -5
- package/dist/render/gpu_picking.js.map +1 -1
- package/dist/render/hzb.js +28 -19
- package/dist/render/hzb.js.map +1 -1
- package/dist/render/lightpass.js +18 -4
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/render_queue.js +37 -4
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +8 -3
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +20 -48
- package/dist/render/rendergraph/blackboard.js.map +1 -1
- package/dist/render/rendergraph/device_pool_allocator.js +18 -58
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
- package/dist/render/rendergraph/executor.js +89 -115
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +1003 -715
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/frame_graph_context.js +1 -1
- package/dist/render/rendergraph/frame_graph_context.js.map +1 -1
- package/dist/render/rendergraph/frame_resource_requirements.js +14 -0
- package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -0
- package/dist/render/rendergraph/history_resource_manager.js +74 -140
- package/dist/render/rendergraph/history_resource_manager.js.map +1 -1
- package/dist/render/rendergraph/history_resources.js +7 -5
- package/dist/render/rendergraph/history_resources.js.map +1 -1
- package/dist/render/rendergraph/render_context.js +19 -0
- package/dist/render/rendergraph/render_context.js.map +1 -0
- package/dist/render/rendergraph/render_pipeline.js +315 -0
- package/dist/render/rendergraph/render_pipeline.js.map +1 -0
- package/dist/render/rendergraph/rendergraph.js +158 -141
- package/dist/render/rendergraph/rendergraph.js.map +1 -1
- package/dist/render/rendergraph/scene_render_context.js +267 -0
- package/dist/render/rendergraph/scene_render_context.js.map +1 -0
- package/dist/render/rendergraph/texture_affinity_cache.js +19 -0
- package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -0
- package/dist/render/rendergraph/types.js +19 -31
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/renderpass.js +3 -3
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/shadow_mask_pass.js +7 -6
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/sky.js +197 -35
- package/dist/render/sky.js.map +1 -1
- package/dist/render/weightedblended_oit.js +4 -3
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +2 -0
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +10 -0
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +61 -2
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/light.js +178 -10
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/meshdrawable.js +89 -2
- package/dist/scene/meshdrawable.js.map +1 -1
- package/dist/scene/msdftext.js +2 -0
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +2 -0
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +2 -0
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene.js +34 -1
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/terrain-cm/grass.js +2 -1
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +2 -0
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/water.js +2 -0
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/atmosphere.js +5 -4
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/fog.js +10 -3
- package/dist/shaders/fog.js.map +1 -1
- package/dist/shaders/shadow.js +96 -29
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/ssgi_reprojection.js +118 -0
- package/dist/shaders/ssgi_reprojection.js.map +1 -0
- package/dist/shaders/ssr.js +322 -154
- package/dist/shaders/ssr.js.map +1 -1
- package/dist/shadow/esm.js +10 -7
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +12 -12
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +12 -12
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/pcss.js +15 -11
- package/dist/shadow/pcss.js.map +1 -1
- package/dist/shadow/shadow_impl.js +20 -2
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadowmapper.js +5 -2
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js +13 -13
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js +7 -7
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/utility/physical.js +74 -0
- package/dist/utility/physical.js.map +1 -0
- package/dist/utility/rendermipmap.js +2 -2
- package/dist/utility/rendermipmap.js.map +1 -1
- package/dist/utility/serialization/manager.js +3 -1
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +3 -1
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +3 -1
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +598 -2
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +180 -9
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +43 -3
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +3 -1
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +3 -1
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +3 -1
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +2 -0
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +70 -0
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +3 -1
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +3 -1
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +3 -0
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +3 -1
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/values.js +2 -3
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
package/dist/render/sky.js
CHANGED
|
@@ -2,7 +2,7 @@ import { linearToGamma } from '../shaders/misc.js';
|
|
|
2
2
|
import { smoothNoise3D } from '../shaders/noise.js';
|
|
3
3
|
import { getDevice, getEngine } from '../app/api.js';
|
|
4
4
|
import { getDefaultAtmosphereParams, getAerialPerspectiveLut, renderAtmosphereLUTs, getAtmosphereParamsStruct, createTransmittanceLutProgram, createMultiScatteringLutProgram, createSkyViewLutProgram, createAPLutProgram, skyBox, atmosphereLUTRendered, getTransmittanceLut, getSkyViewLut } from '../shaders/atmosphere.js';
|
|
5
|
-
import { Matrix4x4, Disposable, DRef, Vector4, Vector2, Vector3, CubeFace, objectKeys } from '@zephyr3d/base';
|
|
5
|
+
import { Matrix4x4, Disposable, DRef, Vector4, Vector2, Vector3, CubeFace, objectKeys, DEPTH_FARTHEST, DEPTH_COMPARE_DEFAULT, DEPTH_COMPARE_FARTHER } from '@zephyr3d/base';
|
|
6
6
|
import { Primitive } from './primitive.js';
|
|
7
7
|
import { BoxShape } from '../shapes/box.js';
|
|
8
8
|
import '../shapes/capsule.js';
|
|
@@ -13,6 +13,7 @@ import '../shapes/sphere.js';
|
|
|
13
13
|
import '../shapes/tetrahedron.js';
|
|
14
14
|
import { prefilterCubemap } from '../utility/pmrem.js';
|
|
15
15
|
import { ShaderHelper } from '../material/shader/helper.js';
|
|
16
|
+
import { PHYSICAL_BAKE_EXPOSURE } from '../utility/physical.js';
|
|
16
17
|
import { fetchSampler } from '../utility/misc.js';
|
|
17
18
|
import { CubemapSHProjector } from '../utility/shprojector.js';
|
|
18
19
|
import { uniformSphereSamples, Fog } from '../values.js';
|
|
@@ -31,6 +32,26 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
31
32
|
* The sky renderer
|
|
32
33
|
* @public
|
|
33
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).
|
|
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}.
|
|
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).
|
|
54
|
+
*/ static FOG_PHYSICAL_LUMINANCE = 38400;
|
|
34
55
|
static _skyCamera = (()=>{
|
|
35
56
|
return new PerspectiveCamera(null, Math.PI * 0.5, 1, 20, 1);
|
|
36
57
|
})();
|
|
@@ -90,6 +111,14 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
90
111
|
_bindgroupFogNoDepth = null;
|
|
91
112
|
_format;
|
|
92
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
|
+
*/ _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).
|
|
120
|
+
*/ _fogPreExposure;
|
|
121
|
+
/**
|
|
93
122
|
* Creates an instance of SkyRenderer
|
|
94
123
|
*/ constructor(){
|
|
95
124
|
super();
|
|
@@ -131,6 +160,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
131
160
|
this._bindgroupFog = new DRef();
|
|
132
161
|
this._bindgroupFogNoDepth = new DRef();
|
|
133
162
|
this._format = null;
|
|
163
|
+
this._fogLuminanceScale = 1;
|
|
164
|
+
this._fogPreExposure = 1;
|
|
134
165
|
}
|
|
135
166
|
/** @internal */ getHash(_ctx) {
|
|
136
167
|
return `${this.skyType}:${this.fogType}`;
|
|
@@ -518,6 +549,18 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
518
549
|
return this._skyDistantLightLut.get().getColorAttachments()[0];
|
|
519
550
|
}
|
|
520
551
|
update(ctx) {
|
|
552
|
+
// Latch the fog scales for this frame. The bake path (updateBakedSkyMap) uses the sky camera
|
|
553
|
+
// whose scene is null, so it cannot read lightingMode itself; both bake and main pass run after
|
|
554
|
+
// update(), so caching them here keeps them consistent.
|
|
555
|
+
// The fog shader mixes two differently-scaled sources, so it needs both factors:
|
|
556
|
+
// - the atmosphere-derived LUTs (distant sky, aerial perspective) are stored at the fixed bake
|
|
557
|
+
// exposure, so they convert with the bake-to-live ratio;
|
|
558
|
+
// - the authored 0..1 fog colors are lifted by the environment intensity (lux) -- the same
|
|
559
|
+
// anchor the sky and IBL use, mirroring Filament's `fogColor *= iblLuminance` -- and then
|
|
560
|
+
// take the plain camera pre-exposure.
|
|
561
|
+
// Legacy leaves both at 1 so its authored colors are untouched.
|
|
562
|
+
this._fogPreExposure = SkyRenderer.getBakeToPreExposedScale(ctx);
|
|
563
|
+
this._fogLuminanceScale = ctx.scene.lightingMode === 'physical' ? ctx.scene.env.light.intensity * ShaderHelper.getPreExposure(ctx) : 1;
|
|
521
564
|
const useScatter = this._skyType === 'scatter';
|
|
522
565
|
if (useScatter || !atmosphereLUTRendered()) {
|
|
523
566
|
this.renderAtmosphereLUTs(ctx);
|
|
@@ -545,16 +588,11 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
545
588
|
}
|
|
546
589
|
if (this._bakedSkyboxDirty) {
|
|
547
590
|
this._bakedSkyboxDirty = false;
|
|
591
|
+
// updateBakedSkyMap derives the IBL (specular prefilter + irradiance SH) from the fog-free
|
|
592
|
+
// cubemap internally, before compositing fog. The distant-light LUT is re-baked here against
|
|
593
|
+
// the fogged cubemap to preserve the pre-refactor fog shading appearance.
|
|
548
594
|
this.updateBakedSkyMap(ctx);
|
|
549
595
|
this.renderSkyDistantLut(ctx, this._bakedSkyboxTexture.get());
|
|
550
|
-
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)) {
|
|
551
|
-
prefilterCubemap(this._bakedSkyboxTexture.get(), 'ggx', this.radianceFramebuffer, this._radianceConvSamples);
|
|
552
|
-
ctx.scene.env.light.sheenRadianceMap = this.radianceMap;
|
|
553
|
-
this._shProjector.projectCubemapToTexture(this._bakedSkyboxTexture.get(), this.irradianceSHFB);
|
|
554
|
-
ctx.scene.env.light.irradianceSHFB = this.irradianceSHFB;
|
|
555
|
-
ctx.scene.env.light.irradianceSH = null;
|
|
556
|
-
ctx.scene.env.light.irradianceWindow = this._shWindowWeights;
|
|
557
|
-
}
|
|
558
596
|
}
|
|
559
597
|
const newSunLight = oldSunLight ? Vector3.mul(ctx.sunLight.color.xyz(), this.sunTransmittance(ctx.sunLight)) : Vector3.zero();
|
|
560
598
|
if (oldSunLight) {
|
|
@@ -565,7 +603,14 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
565
603
|
const cameraY = Math.min(this._heightFogParams.parameter2.y + MAX_FOG_HEIGHT, ctx.camera.getWorldPosition().y);
|
|
566
604
|
const p = Math.max(-125, Math.min(126, -this._heightFogParams.parameter1.w * (cameraY - this._heightFogParams.parameter2.y)));
|
|
567
605
|
this._heightFogParams.parameter3.z = this._heightFogParams.parameter2.x * Math.pow(2, p);
|
|
568
|
-
|
|
606
|
+
// The legacy directional fog term expects a display-relative 0..1 light color. It cannot be
|
|
607
|
+
// mixed directly with photometric illuminance; physical fog instead receives its radiance
|
|
608
|
+
// from the distant-sky integration below.
|
|
609
|
+
if (ctx.scene.lightingMode === 'physical') {
|
|
610
|
+
this._heightFogParams.lightColor.setXYZ(0, 0, 0);
|
|
611
|
+
} else {
|
|
612
|
+
this._heightFogParams.lightColor.set(newSunLight);
|
|
613
|
+
}
|
|
569
614
|
this._heightFogParams.lightDir.set(SkyRenderer._getSunDir(ctx.sunLight));
|
|
570
615
|
}
|
|
571
616
|
return oldSunLight;
|
|
@@ -573,7 +618,12 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
573
618
|
renderAtmosphereLUTs(ctx) {
|
|
574
619
|
this._atmosphereParams.lightDir.set(SkyRenderer._getSunDir(ctx.sunLight));
|
|
575
620
|
this._atmosphereParams.lightColor.set(SkyRenderer._getSunColor(ctx.sunLight));
|
|
576
|
-
|
|
621
|
+
// Physical: the sun input is photometric (lux), normalized onto the model's authored reference
|
|
622
|
+
// and stored at the fixed PHYSICAL_BAKE_EXPOSURE rather than the live camera exposure. That
|
|
623
|
+
// keeps the cached IBL bake exposure-independent while staying inside the environment cubemap's
|
|
624
|
+
// limited float range -- raw luminance would overflow it to Inf. Consumers rescale to the live
|
|
625
|
+
// exposure via getBakeToPreExposedScale().
|
|
626
|
+
this._atmosphereParams.lightColor.w *= this._atmosphereExposure * (ctx.scene.lightingMode === 'physical' ? SkyRenderer.PHYSICAL_ATMOSPHERE_LUMINANCE_SCALE * SkyRenderer.PHYSICAL_BAKE_EXPOSURE : 1);
|
|
577
627
|
this._atmosphereParams.cameraAspect = ctx.camera.getAspect();
|
|
578
628
|
this._atmosphereParams.cameraWorldMatrix.set(ctx.camera.worldMatrix);
|
|
579
629
|
renderAtmosphereLUTs(this._atmosphereParams);
|
|
@@ -586,6 +636,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
586
636
|
ctx.device.setFramebuffer(this._skyDistantLightLut.get());
|
|
587
637
|
ctx.device.clearFrameBuffer(new Vector4(0, 0, 0, 1), null, null);
|
|
588
638
|
this._bindgroupDistantLight.get().setTexture('skybox', skybox, fetchSampler('clamp_linear_nomip'));
|
|
639
|
+
this._bindgroupDistantLight.get().setValue('physical', ctx.scene.lightingMode === 'physical' ? 1 : 0);
|
|
589
640
|
ctx.device.setBindGroup(0, this._bindgroupDistantLight.get());
|
|
590
641
|
SkyRenderer._primitiveDistantLight.draw();
|
|
591
642
|
ctx.device.popDeviceStates();
|
|
@@ -615,10 +666,24 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
615
666
|
]){
|
|
616
667
|
camera.lookAtCubeFace(face);
|
|
617
668
|
this._bakedSkyboxFrameBuffer.get().setColorAttachmentCubeFace(0, face);
|
|
618
|
-
|
|
669
|
+
// Direct sunlight is represented by the scene's directional sun light. Keep the analytic
|
|
670
|
+
// sun disk out of both diffuse and specular IBL to avoid baking that direct contribution a
|
|
671
|
+
// second time. Atmospheric scattering and clouds remain in the cubemap.
|
|
672
|
+
this._renderSky(camera, false, false, this._getSkyBakeLuminanceScale(ctx));
|
|
619
673
|
}
|
|
620
674
|
device.popDeviceStates();
|
|
621
675
|
this.renderSkyDistantLut(ctx, tex);
|
|
676
|
+
// Publish the texture reference before deriving IBL so _updateIBLFromBakedSky reads the
|
|
677
|
+
// current cubemap.
|
|
678
|
+
this._bakedSkyboxTexture.set(tex);
|
|
679
|
+
// Derive the IBL from the fog-free cubemap. Height fog is a view/position-dependent participating
|
|
680
|
+
// medium applied per-pixel in screen space (see lightpass renderFog); baking it into the distant
|
|
681
|
+
// environment probe would both double-count it against that screen-space pass and wrongly lift the
|
|
682
|
+
// lower hemisphere (ground direction) from the atmosphere's dark value to a bright fog color. The
|
|
683
|
+
// same reasoning that keeps the sun disk out of the IBL applies to fog, for diffuse and specular alike.
|
|
684
|
+
this._updateIBLFromBakedSky(ctx, tex);
|
|
685
|
+
// Composite fog into the cubemap afterwards. This copy is only used as the visible skybox
|
|
686
|
+
// background (UNIFORM_NAME_BAKED_SKY_MAP), where the fogged distant sky is desired.
|
|
622
687
|
device.pushDeviceStates();
|
|
623
688
|
device.setFramebuffer(this._bakedSkyboxFrameBuffer.get());
|
|
624
689
|
for (const face of [
|
|
@@ -635,7 +700,21 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
635
700
|
}
|
|
636
701
|
device.popDeviceStates();
|
|
637
702
|
device.setRenderStates(saveRenderStates);
|
|
638
|
-
|
|
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.
|
|
709
|
+
*/ _updateIBLFromBakedSky(ctx, skybox) {
|
|
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
|
+
prefilterCubemap(skybox, 'ggx', this.radianceFramebuffer, this._radianceConvSamples);
|
|
712
|
+
ctx.scene.env.light.sheenRadianceMap = this.radianceMap;
|
|
713
|
+
this._shProjector.projectCubemapToTexture(skybox, this.irradianceSHFB);
|
|
714
|
+
ctx.scene.env.light.irradianceSHFB = this.irradianceSHFB;
|
|
715
|
+
ctx.scene.env.light.irradianceSH = null;
|
|
716
|
+
ctx.scene.env.light.irradianceWindow = this._shWindowWeights;
|
|
717
|
+
}
|
|
639
718
|
}
|
|
640
719
|
renderUberFog(camera, depthTexture) {
|
|
641
720
|
const device = getDevice();
|
|
@@ -655,13 +734,34 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
655
734
|
bindgroup.setValue('withAerialPerspective', this.skyType === 'scatter' ? 1 : 0);
|
|
656
735
|
bindgroup.setValue('fogType', this.mappedFogType);
|
|
657
736
|
bindgroup.setValue('atmosphereParams', this._atmosphereParams);
|
|
658
|
-
bindgroup.setValue('heightFogParams', this.
|
|
737
|
+
bindgroup.setValue('heightFogParams', this._getUploadHeightFogParams());
|
|
659
738
|
device.setProgram(fogProgram);
|
|
660
739
|
device.setBindGroup(0, bindgroup);
|
|
661
740
|
device.setVertexLayout(SkyRenderer._vertexLayout);
|
|
662
741
|
device.setRenderStates(renderStates);
|
|
663
742
|
device.draw('triangle-strip', 0, 4);
|
|
664
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.
|
|
750
|
+
*/ _getUploadHeightFogParams() {
|
|
751
|
+
const scale = this._fogLuminanceScale;
|
|
752
|
+
const p = this._heightFogParams;
|
|
753
|
+
if (scale === 1 && this._fogPreExposure === 1) {
|
|
754
|
+
return p;
|
|
755
|
+
}
|
|
756
|
+
const p1 = p.parameter1;
|
|
757
|
+
const p4 = p.parameter4;
|
|
758
|
+
return {
|
|
759
|
+
...p,
|
|
760
|
+
parameter1: new Vector4(p1.x * scale, p1.y * scale, p1.z * scale, p1.w),
|
|
761
|
+
parameter4: new Vector4(p4.x * scale, p4.y * scale, p4.z * scale, p4.w),
|
|
762
|
+
preExposure: this._fogPreExposure
|
|
763
|
+
};
|
|
764
|
+
}
|
|
665
765
|
/** @internal */ renderFog(camera) {
|
|
666
766
|
const device = getDevice();
|
|
667
767
|
const currentFramebuffer = device.getFramebuffer();
|
|
@@ -726,7 +826,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
726
826
|
}
|
|
727
827
|
const framebuffer = this._beginSingleColorPass(true);
|
|
728
828
|
try {
|
|
729
|
-
this._renderSky(skyCamera, true);
|
|
829
|
+
this._renderSky(skyCamera, true, true, this._getSkyScreenLuminanceScale(ctx));
|
|
730
830
|
} finally{
|
|
731
831
|
this._endSingleColorPass(framebuffer);
|
|
732
832
|
}
|
|
@@ -774,23 +874,67 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
774
874
|
});
|
|
775
875
|
}
|
|
776
876
|
}
|
|
777
|
-
/** @internal */ _renderSky(camera, depthTest) {
|
|
877
|
+
/** @internal */ _renderSky(camera, depthTest, includeSunDisk, luminanceScale = 1) {
|
|
778
878
|
const device = getDevice();
|
|
779
879
|
const savedRenderStates = device.getRenderStates();
|
|
780
880
|
this._prepareSkyBox(device);
|
|
781
881
|
if (this._skyType === 'scatter') {
|
|
782
|
-
|
|
882
|
+
// The atmosphere LUTs already hold physical luminance, so only the caller's exposure applies.
|
|
883
|
+
this._drawScattering(camera, depthTest, includeSunDisk, luminanceScale);
|
|
783
884
|
} else if (this._skyType === 'skybox' && this.skyboxTexture) {
|
|
784
|
-
this._drawSkybox(camera, depthTest);
|
|
885
|
+
this._drawSkybox(camera, depthTest, luminanceScale);
|
|
785
886
|
} else {
|
|
786
|
-
this._drawSkyColor(camera, depthTest);
|
|
887
|
+
this._drawSkyColor(camera, depthTest, luminanceScale);
|
|
787
888
|
}
|
|
788
889
|
device.setRenderStates(savedRenderStates);
|
|
789
890
|
}
|
|
790
|
-
/**
|
|
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
|
+
*/ static getBakeToPreExposedScale(ctx) {
|
|
902
|
+
return ctx.scene.lightingMode === 'physical' ? ShaderHelper.getPreExposure(ctx) / SkyRenderer.PHYSICAL_BAKE_EXPOSURE : 1;
|
|
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.
|
|
918
|
+
*/ _getSkyBakeLuminanceScale(ctx) {
|
|
919
|
+
if (ctx.scene.lightingMode !== 'physical') {
|
|
920
|
+
return 1;
|
|
921
|
+
}
|
|
922
|
+
// scatter already includes the bake exposure via renderAtmosphereLUTs().
|
|
923
|
+
return this._skyType === 'scatter' ? 1 : ctx.scene.env.light.intensity * SkyRenderer.PHYSICAL_BAKE_EXPOSURE;
|
|
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.
|
|
930
|
+
*/ _getSkyScreenLuminanceScale(ctx) {
|
|
931
|
+
return this._getSkyBakeLuminanceScale(ctx) * SkyRenderer.getBakeToPreExposedScale(ctx);
|
|
932
|
+
}
|
|
933
|
+
/** @internal */ _drawSkyColor(camera, depthTest, luminanceScale) {
|
|
791
934
|
const device = getDevice();
|
|
792
935
|
const bindgroup = this._bindgroupSky.image.get();
|
|
793
936
|
bindgroup.setValue('color', this._skyColor);
|
|
937
|
+
bindgroup.setValue('luminanceScale', luminanceScale);
|
|
794
938
|
bindgroup.setTexture('texture', this._skyImage.get() ?? SkyRenderer._defaultSkyImage.get(), fetchSampler('clamp_linear_nomip'));
|
|
795
939
|
bindgroup.setValue('flip', device.getFramebuffer() && device.type === 'webgpu' ? -1 : 1);
|
|
796
940
|
bindgroup.setValue('srgbOut', device.getFramebuffer() ? 0 : 1);
|
|
@@ -798,10 +942,11 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
798
942
|
device.setBindGroup(0, bindgroup);
|
|
799
943
|
drawFullscreenQuad(depthTest ? SkyRenderer._renderStatesSky : SkyRenderer._renderStatesSkyNoDepthTest);
|
|
800
944
|
}
|
|
801
|
-
/** @internal */ _drawSkybox(camera, depthTest) {
|
|
945
|
+
/** @internal */ _drawSkybox(camera, depthTest, luminanceScale) {
|
|
802
946
|
const device = getDevice();
|
|
803
947
|
const bindgroup = this._bindgroupSky.skybox.get();
|
|
804
948
|
bindgroup.setTexture('skyCubeMap', this.skyboxTexture, fetchSampler('clamp_linear_nomip'));
|
|
949
|
+
bindgroup.setValue('luminanceScale', luminanceScale);
|
|
805
950
|
bindgroup.setValue('flip', device.getFramebuffer() && device.type === 'webgpu' ? new Vector4(1, -1, 1, 1) : new Vector4(1, 1, 1, 1));
|
|
806
951
|
bindgroup.setValue('viewProjMatrix', camera.viewProjectionMatrix);
|
|
807
952
|
bindgroup.setValue('worldMatrix', this._skyWorldMatrix);
|
|
@@ -877,7 +1022,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
877
1022
|
}
|
|
878
1023
|
return new Vector3(Math.exp(-sum.x), Math.exp(-sum.y), Math.exp(-sum.z));
|
|
879
1024
|
}
|
|
880
|
-
/** @internal */ _drawScattering(camera, depthTest) {
|
|
1025
|
+
/** @internal */ _drawScattering(camera, depthTest, includeSunDisk, luminanceScale) {
|
|
881
1026
|
const device = getDevice();
|
|
882
1027
|
const tLut = getTransmittanceLut();
|
|
883
1028
|
const skyLut = getSkyViewLut();
|
|
@@ -890,6 +1035,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
890
1035
|
bindgroup.setValue('worldMatrix', this._skyWorldMatrix);
|
|
891
1036
|
bindgroup.setValue('cameraPos', camera.getWorldPosition());
|
|
892
1037
|
bindgroup.setValue('srgbOut', device.getFramebuffer() ? 0 : 1);
|
|
1038
|
+
bindgroup.setValue('includeSunDisk', includeSunDisk ? 1 : 0);
|
|
1039
|
+
bindgroup.setValue('luminanceScale', luminanceScale);
|
|
893
1040
|
bindgroup.setTexture('tLut', tLut, fetchSampler('clamp_linear_nomip'));
|
|
894
1041
|
bindgroup.setTexture('skyLut', skyLut, fetchSampler('clamp_linear_nomip'));
|
|
895
1042
|
bindgroup.setValue('cloudy', this._cloudy);
|
|
@@ -930,9 +1077,14 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
930
1077
|
fragment (pb) {
|
|
931
1078
|
this.$outputs.color = pb.vec4();
|
|
932
1079
|
this.skybox = pb.texCube().uniform(0);
|
|
1080
|
+
this.physical = pb.int().uniform(0);
|
|
933
1081
|
pb.main(function() {
|
|
934
1082
|
this.$l.sunColor = pb.vec4();
|
|
935
|
-
|
|
1083
|
+
// Height-fog in-scattering is lit by the sky hemisphere. The old full-sphere average
|
|
1084
|
+
// is retained verbatim in legacy mode; in physical mode, mirror lower samples into the
|
|
1085
|
+
// upper hemisphere so a dark ground/lower sky cannot turn the horizon into a black band.
|
|
1086
|
+
this.$l.sampleDirection = this.$choice(pb.notEqual(this.physical, 0), pb.vec3(this.$inputs.vector.x, pb.abs(this.$inputs.vector.y), this.$inputs.vector.z), this.$inputs.vector);
|
|
1087
|
+
this.$l.skyColor = pb.textureSampleLevel(this.skybox, this.sampleDirection, 0).rgb;
|
|
936
1088
|
this.$outputs.color = pb.vec4(pb.mul(this.skyColor, 1 / 64), 1);
|
|
937
1089
|
});
|
|
938
1090
|
}
|
|
@@ -962,7 +1114,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
962
1114
|
this.$outputs.uv = pb.vec2();
|
|
963
1115
|
this.flip = pb.int().uniform(0);
|
|
964
1116
|
pb.main(function() {
|
|
965
|
-
this.$builtins.position = pb.vec4(this.$inputs.pos,
|
|
1117
|
+
this.$builtins.position = pb.vec4(this.$inputs.pos, DEPTH_FARTHEST, 1);
|
|
966
1118
|
this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
|
|
967
1119
|
if (device.type !== 'webgpu') {
|
|
968
1120
|
this.$builtins.position.y = pb.neg(this.$builtins.position.y);
|
|
@@ -974,9 +1126,12 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
974
1126
|
this.color = pb.vec4().uniform(0);
|
|
975
1127
|
this.texture = pb.tex2D().uniform(0);
|
|
976
1128
|
this.srgbOut = pb.int().uniform(0);
|
|
1129
|
+
this.luminanceScale = pb.float().uniform(0);
|
|
977
1130
|
pb.main(function() {
|
|
978
1131
|
this.$l.sampleColor = pb.textureSampleLevel(this.texture, this.$inputs.uv, 0);
|
|
979
|
-
|
|
1132
|
+
// luminanceScale is 1 in legacy and for the IBL bake; on screen in physical mode it
|
|
1133
|
+
// carries the environment intensity (lux) pre-multiplied by the camera exposure.
|
|
1134
|
+
this.$l.outColor = pb.mul(this.sampleColor, this.color, this.luminanceScale);
|
|
980
1135
|
this.$if(pb.equal(this.srgbOut, 0), function() {
|
|
981
1136
|
this.$outputs.outColor = pb.vec4(this.outColor.rgb, 1);
|
|
982
1137
|
}).$else(function() {
|
|
@@ -1010,16 +1165,19 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
1010
1165
|
this.$outputs.texCoord = this.$inputs.pos;
|
|
1011
1166
|
this.$l.worldPos = pb.add(this.cameraPos, pb.mul(this.worldMatrix, pb.vec4(this.$inputs.pos, 0)).xyz);
|
|
1012
1167
|
this.$builtins.position = pb.mul(this.viewProjMatrix, pb.vec4(this.worldPos, 1), this.flip);
|
|
1013
|
-
this.$builtins.position.z = this.$builtins.position.w;
|
|
1168
|
+
this.$builtins.position.z = ShaderHelper.farthestClipZ(this, this.$builtins.position.w);
|
|
1014
1169
|
});
|
|
1015
1170
|
},
|
|
1016
1171
|
fragment (pb) {
|
|
1017
1172
|
this.$outputs.outColor = pb.vec4();
|
|
1018
1173
|
this.skyCubeMap = pb.texCube().uniform(0);
|
|
1019
1174
|
this.srgbOut = pb.int().uniform(0);
|
|
1175
|
+
this.luminanceScale = pb.float().uniform(0);
|
|
1020
1176
|
pb.main(function() {
|
|
1021
1177
|
this.$l.texCoord = pb.normalize(this.$inputs.texCoord);
|
|
1022
|
-
|
|
1178
|
+
// luminanceScale is 1 in legacy and for the IBL bake; on screen in physical mode it
|
|
1179
|
+
// carries the environment intensity (lux) pre-multiplied by the camera exposure.
|
|
1180
|
+
this.$l.color = pb.mul(pb.textureSampleLevel(this.skyCubeMap, this.texCoord, 0).rgb, this.luminanceScale);
|
|
1023
1181
|
this.$if(pb.equal(this.srgbOut, 0), function() {
|
|
1024
1182
|
this.$outputs.outColor = pb.vec4(this.color, 1);
|
|
1025
1183
|
}).$else(function() {
|
|
@@ -1035,7 +1193,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
1035
1193
|
}
|
|
1036
1194
|
if (!SkyRenderer._renderStatesSky) {
|
|
1037
1195
|
SkyRenderer._renderStatesSky = device.createRenderStateSet();
|
|
1038
|
-
SkyRenderer._renderStatesSky.useDepthState().enableTest(true).enableWrite(false).setCompareFunc(
|
|
1196
|
+
SkyRenderer._renderStatesSky.useDepthState().enableTest(true).enableWrite(false).setCompareFunc(DEPTH_COMPARE_DEFAULT);
|
|
1039
1197
|
SkyRenderer._renderStatesSky.useRasterizerState().setCullMode('none');
|
|
1040
1198
|
}
|
|
1041
1199
|
if (!SkyRenderer._renderStatesSkyNoDepthTest) {
|
|
@@ -1053,7 +1211,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
1053
1211
|
SkyRenderer._renderStatesFogScatter = device.createRenderStateSet();
|
|
1054
1212
|
SkyRenderer._renderStatesFogScatter.useRasterizerState().setCullMode('none');
|
|
1055
1213
|
SkyRenderer._renderStatesFogScatter.useBlendingState().enable(true).setBlendFunc('one', 'src-alpha');
|
|
1056
|
-
SkyRenderer._renderStatesFogScatter.useDepthState().enableTest(true).enableWrite(false).setCompareFunc(
|
|
1214
|
+
SkyRenderer._renderStatesFogScatter.useDepthState().enableTest(true).enableWrite(false).setCompareFunc(DEPTH_COMPARE_FARTHER);
|
|
1057
1215
|
}
|
|
1058
1216
|
if (!SkyRenderer._renderStatesDistantLight) {
|
|
1059
1217
|
SkyRenderer._renderStatesDistantLight = device.createRenderStateSet();
|
|
@@ -1107,7 +1265,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
1107
1265
|
this.$inputs.pos = pb.vec2().attrib('position');
|
|
1108
1266
|
this.$outputs.uv = pb.vec2();
|
|
1109
1267
|
pb.main(function() {
|
|
1110
|
-
this.$builtins.position = pb.vec4(this.$inputs.pos,
|
|
1268
|
+
this.$builtins.position = pb.vec4(this.$inputs.pos, DEPTH_FARTHEST, 1);
|
|
1111
1269
|
this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
|
|
1112
1270
|
if (device.type === 'webgpu') {
|
|
1113
1271
|
this.$if(pb.notEqual(this.rt, 0), function() {
|
|
@@ -1134,11 +1292,11 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
1134
1292
|
this.srgbOut = pb.int().uniform(0);
|
|
1135
1293
|
this.$outputs.outColor = pb.vec4();
|
|
1136
1294
|
pb.main(function() {
|
|
1137
|
-
this.$l.depthValue = noDepth ? pb.float(
|
|
1138
|
-
this.$l.clipSpacePos = pb.vec4(pb.sub(pb.mul(this.$inputs.uv, 2), pb.vec2(1)),
|
|
1295
|
+
this.$l.depthValue = noDepth ? pb.float(DEPTH_FARTHEST) : pb.textureSample(this.depthTex, this.$inputs.uv).r;
|
|
1296
|
+
this.$l.clipSpacePos = pb.vec4(pb.sub(pb.mul(this.$inputs.uv, 2), pb.vec2(1)), ShaderHelper.deviceDepthToClipZ(this, this.depthValue), 1);
|
|
1139
1297
|
this.$l.hPos = pb.mul(this.invProjViewMatrix, this.clipSpacePos);
|
|
1140
1298
|
this.$l.worldPos = pb.div(this.$l.hPos, this.$l.hPos.w).xyz;
|
|
1141
|
-
this.$l.isSky =
|
|
1299
|
+
this.$l.isSky = ShaderHelper.isFarthestDepth(this, this.$l.depthValue);
|
|
1142
1300
|
this.$l.color = calculateFog(this, this.withAerialPerspective, this.fogType, this.atmosphereParams, this.heightFogParams, this.$inputs.uv, this.isSky, this.cameraPosition, this.worldPos, 0, this.apLut, this.skyDistantLightLut);
|
|
1143
1301
|
this.$if(pb.equal(this.srgbOut, 0), function() {
|
|
1144
1302
|
this.$outputs.outColor = this.color;
|
|
@@ -1184,7 +1342,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
1184
1342
|
pb.main(function() {
|
|
1185
1343
|
this.$outputs.worldDirection = pb.mul(this.worldMatrix, pb.vec4(this.$inputs.pos, 0)).xyz;
|
|
1186
1344
|
this.$builtins.position = pb.mul(this.viewProjMatrix, pb.vec4(pb.add(this.$outputs.worldDirection, this.cameraPos), 1), this.flip);
|
|
1187
|
-
this.$builtins.position.z = this.$builtins.position.w;
|
|
1345
|
+
this.$builtins.position.z = ShaderHelper.farthestClipZ(this, this.$builtins.position.w);
|
|
1188
1346
|
});
|
|
1189
1347
|
},
|
|
1190
1348
|
fragment (pb) {
|
|
@@ -1192,6 +1350,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
1192
1350
|
this.tLut = pb.tex2D().uniform(0);
|
|
1193
1351
|
this.skyLut = pb.tex2D().uniform(0);
|
|
1194
1352
|
this.params = getAtmosphereParamsStruct(pb)().uniform(0);
|
|
1353
|
+
this.includeSunDisk = pb.int().uniform(0);
|
|
1195
1354
|
if (cloud) {
|
|
1196
1355
|
this.cloudy = pb.float().uniform(0);
|
|
1197
1356
|
this.cloudIntensity = pb.float().uniform(0);
|
|
@@ -1199,6 +1358,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
1199
1358
|
this.velocity = pb.vec2().uniform(0);
|
|
1200
1359
|
}
|
|
1201
1360
|
this.srgbOut = pb.int().uniform(0);
|
|
1361
|
+
this.luminanceScale = pb.float().uniform(0);
|
|
1202
1362
|
pb.func('noise', [
|
|
1203
1363
|
pb.vec3('p'),
|
|
1204
1364
|
pb.float('t')
|
|
@@ -1222,7 +1382,7 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
1222
1382
|
pb.main(function() {
|
|
1223
1383
|
// Calculate sky color
|
|
1224
1384
|
this.$l.sunColor = pb.vec4();
|
|
1225
|
-
this.$l.skyColor = skyBox(this, this.params, this.sunColor, this.$inputs.worldDirection, pb.float(0.01), this.tLut, this.skyLut).rgb;
|
|
1385
|
+
this.$l.skyColor = skyBox(this, this.params, this.sunColor, this.$inputs.worldDirection, pb.float(0.01), this.includeSunDisk, this.tLut, this.skyLut).rgb;
|
|
1226
1386
|
this.$l.rayDir = pb.normalize(this.$inputs.worldDirection);
|
|
1227
1387
|
this.$l.sunDir = this.params.lightDir;
|
|
1228
1388
|
// ad-hoc
|
|
@@ -1258,6 +1418,8 @@ const defaultSkyWorldMatrix = Matrix4x4.identity();
|
|
|
1258
1418
|
} else {
|
|
1259
1419
|
this.$l.color = this.skyColor;
|
|
1260
1420
|
}
|
|
1421
|
+
// 1 for legacy and for the IBL bake; the camera pre-exposure when drawn on screen.
|
|
1422
|
+
this.color = pb.mul(this.color, this.luminanceScale);
|
|
1261
1423
|
this.$if(pb.equal(this.srgbOut, 0), function() {
|
|
1262
1424
|
this.$outputs.outColor = pb.vec4(this.color, 1);
|
|
1263
1425
|
}).$else(function() {
|