@zephyr3d/scene 0.9.22 → 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.
- 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 -8740
- package/dist/index.js +10 -2
- 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 +512 -334
- 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 +22 -16
- 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 +257 -95
- 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 +149 -40
- 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 +16 -11
- package/dist/shadow/pcss.js.map +1 -1
- package/dist/shadow/shadow_impl.js +29 -3
- 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 +59 -65
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
|
@@ -25,12 +25,16 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
25
25
|
let FEATURE_IRIDESCENCE = 0;
|
|
26
26
|
const EMISSIVE_COLOR_UNIFORM = S.defineInstanceUniform('emissiveColor', 'rgb', 'EmissiveColor');
|
|
27
27
|
const EMISSIVE_STRENGTH_UNIFORM = S.defineInstanceUniform('emissiveStrength', 'float', 'EmissiveStrength');
|
|
28
|
+
const EMISSIVE_LUMINANCE_UNIFORM = S.defineInstanceUniform('emissiveLuminance', 'float', 'EmissiveLuminance');
|
|
29
|
+
const EMISSIVE_EXPOSURE_WEIGHT_UNIFORM = S.defineInstanceUniform('emissiveExposureWeight', 'float', 'EmissiveExposureWeight');
|
|
28
30
|
const RECT_SPECULAR_SCALE_UNIFORM = S.defineInstanceUniform('rectSpecularScale', 'float', 'RectSpecularScale');
|
|
29
31
|
const cls = class extends S {
|
|
30
32
|
static pbrCommonMixed = true;
|
|
31
33
|
_f0;
|
|
32
34
|
_emissiveColor;
|
|
33
35
|
_emissiveStrength;
|
|
36
|
+
_emissiveLuminance;
|
|
37
|
+
_emissiveExposureWeight;
|
|
34
38
|
_occlusionStrength;
|
|
35
39
|
_rectSpecularScale;
|
|
36
40
|
_sheenFactor;
|
|
@@ -46,6 +50,11 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
46
50
|
this._occlusionStrength = 1;
|
|
47
51
|
this._emissiveColor = new Vector3(0, 0, 0);
|
|
48
52
|
this._emissiveStrength = 1;
|
|
53
|
+
// 1000 cd/m² is a lit-display-class emitter: clearly visible at interior exposures and still
|
|
54
|
+
// readable under the Sunny-16 default, unlike the 1 nit that `emissiveStrength` would mean.
|
|
55
|
+
this._emissiveLuminance = 1000;
|
|
56
|
+
// Default 1: emissive is a photometric luminance that follows camera exposure, like Filament.
|
|
57
|
+
this._emissiveExposureWeight = 1;
|
|
49
58
|
this._rectSpecularScale = 1;
|
|
50
59
|
this._sheenFactor = Vector4.zero();
|
|
51
60
|
this._clearcoatFactor = new Vector4(0, 0, 1, 0);
|
|
@@ -70,6 +79,8 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
70
79
|
this.rectSpecularScale = other.rectSpecularScale;
|
|
71
80
|
this.emissiveColor = other.emissiveColor;
|
|
72
81
|
this.emissiveStrength = other.emissiveStrength;
|
|
82
|
+
this.emissiveLuminance = other.emissiveLuminance;
|
|
83
|
+
this.emissiveExposureWeight = other.emissiveExposureWeight;
|
|
73
84
|
this.transmission = other.transmission;
|
|
74
85
|
this.iridescence = other.iridescence;
|
|
75
86
|
this.clearcoat = other.clearcoat;
|
|
@@ -171,7 +182,14 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
171
182
|
this.uniformChanged();
|
|
172
183
|
}
|
|
173
184
|
}
|
|
174
|
-
|
|
185
|
+
/**
|
|
186
|
+
* Artistic multiplier on the rect-light specular term.
|
|
187
|
+
*
|
|
188
|
+
* @remarks
|
|
189
|
+
* 1 is neutral. Physical lighting normalizes the LTC integral by `1/(2*pi)`, which is the
|
|
190
|
+
* reference implementation's factor, so the default needs no calibration fudge there. Legacy
|
|
191
|
+
* keeps its historical weighting, where existing scenes may have tuned this value.
|
|
192
|
+
*/ get rectSpecularScale() {
|
|
175
193
|
return this._rectSpecularScale;
|
|
176
194
|
}
|
|
177
195
|
set rectSpecularScale(val) {
|
|
@@ -189,7 +207,15 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
189
207
|
this.uniformChanged();
|
|
190
208
|
}
|
|
191
209
|
}
|
|
192
|
-
|
|
210
|
+
/**
|
|
211
|
+
* Display-referred multiplier on {@link emissiveColor}, used by legacy lighting.
|
|
212
|
+
*
|
|
213
|
+
* @remarks
|
|
214
|
+
* This is the glTF authoring quantity (`KHR_materials_emissive_strength`) and is unitless: the
|
|
215
|
+
* product with {@link emissiveColor} lands directly in the render target. Physical lighting
|
|
216
|
+
* ignores it and uses {@link emissiveLuminance} instead, exactly as a light's unitless
|
|
217
|
+
* `intensity` gives way to its photometric counterpart.
|
|
218
|
+
*/ get emissiveStrength() {
|
|
193
219
|
return this._emissiveStrength;
|
|
194
220
|
}
|
|
195
221
|
set emissiveStrength(val) {
|
|
@@ -198,6 +224,67 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
198
224
|
this.uniformChanged();
|
|
199
225
|
}
|
|
200
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Multiplier on {@link emissiveColor} used by physical lighting. Legacy ignores it and uses
|
|
229
|
+
* {@link emissiveStrength}.
|
|
230
|
+
*
|
|
231
|
+
* @remarks
|
|
232
|
+
* The physical counterpart of {@link emissiveStrength}, mirroring how
|
|
233
|
+
* {@link DirectionalLight.illuminance} and {@link RectLight.luminance} shadow a light's unitless
|
|
234
|
+
* `intensity`. Keeping the two separate means switching {@link Scene.lightingMode} never
|
|
235
|
+
* reinterprets one authored number as two different quantities.
|
|
236
|
+
*
|
|
237
|
+
* **Its unit depends on {@link emissiveExposureWeight}**, because the shaded value is
|
|
238
|
+
* `emissiveColor * emissiveLuminance * mix(1, cameraExposure, emissiveExposureWeight)`:
|
|
239
|
+
*
|
|
240
|
+
* - At weight 1 (the constructor default) this is a photometric luminance in cd/m² (nit).
|
|
241
|
+
* Anchors: an office display is 200-1000, a lit interior wall a few hundred, an overcast sky
|
|
242
|
+
* ~2000, a neon sign 5,000-20,000. The default is 1000. Values around 1 are genuinely
|
|
243
|
+
* invisible, since a sunlit white surface is ~25,000 cd/m².
|
|
244
|
+
* - At weight 0 the camera exposure cancels out and this is a display-referred multiplier
|
|
245
|
+
* landing straight in the render target, so the useful range is around [0, 1] and 1 is very
|
|
246
|
+
* bright. **Materials imported from glTF/FBX are in this state**: the importer writes weight 0
|
|
247
|
+
* to preserve glTF's display-referred emissive, matching Filament's gltfio. Raise the weight
|
|
248
|
+
* to 1 (and rescale to nits) to author such a material photometrically.
|
|
249
|
+
*/ get emissiveLuminance() {
|
|
250
|
+
return this._emissiveLuminance;
|
|
251
|
+
}
|
|
252
|
+
set emissiveLuminance(val) {
|
|
253
|
+
const luminance = Math.max(0, val);
|
|
254
|
+
if (this._emissiveLuminance !== luminance) {
|
|
255
|
+
this._emissiveLuminance = luminance;
|
|
256
|
+
this.uniformChanged();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* How strongly the emissive term follows the camera exposure, in [0, 1].
|
|
261
|
+
*
|
|
262
|
+
* @remarks
|
|
263
|
+
* Mirrors Filament's `emissive.w`: the emitter is attenuated by
|
|
264
|
+
* `mix(1, cameraExposure, emissiveExposureWeight)`.
|
|
265
|
+
*
|
|
266
|
+
* At 1, the constructor default, {@link emissiveLuminance} is read as the cd/m² value it claims
|
|
267
|
+
* to be: a neon sign keeps a constant real-world brightness and darkens as the camera stops
|
|
268
|
+
* down, like every other lit surface.
|
|
269
|
+
*
|
|
270
|
+
* At 0 the exposure cancels out of the product and {@link emissiveLuminance} becomes a
|
|
271
|
+
* display-referred multiplier instead — bright at 1, and completely unresponsive to aperture,
|
|
272
|
+
* shutter and ISO. That is what a UI-like overlay wants, and what glTF content expects, so
|
|
273
|
+
* {@link Model} writes 0 on every imported material (Filament's gltfio writes `emissive.w = 0`
|
|
274
|
+
* for the same reason). Keep this in mind when an imported emitter looks far brighter than an
|
|
275
|
+
* authored one at the same {@link emissiveLuminance}.
|
|
276
|
+
*
|
|
277
|
+
* Has no effect in legacy lighting, where the pre-exposure is always 1.
|
|
278
|
+
*/ get emissiveExposureWeight() {
|
|
279
|
+
return this._emissiveExposureWeight;
|
|
280
|
+
}
|
|
281
|
+
set emissiveExposureWeight(val) {
|
|
282
|
+
const weight = Math.max(0, Math.min(1, val));
|
|
283
|
+
if (this._emissiveExposureWeight !== weight) {
|
|
284
|
+
this._emissiveExposureWeight = weight;
|
|
285
|
+
this.uniformChanged();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
201
288
|
get transmission() {
|
|
202
289
|
return this.featureUsed(FEATURE_TRANSMISSION);
|
|
203
290
|
}
|
|
@@ -265,6 +352,8 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
265
352
|
if (this.needFragmentColor() && this.drawContext.materialFlags & MaterialVaryingFlags.INSTANCING) {
|
|
266
353
|
scope.$outputs.zEmissiveColor = this.getInstancedUniform(scope, EMISSIVE_COLOR_UNIFORM);
|
|
267
354
|
scope.$outputs.zEmissiveStrength = this.getInstancedUniform(scope, EMISSIVE_STRENGTH_UNIFORM);
|
|
355
|
+
scope.$outputs.zEmissiveLuminance = this.getInstancedUniform(scope, EMISSIVE_LUMINANCE_UNIFORM);
|
|
356
|
+
scope.$outputs.zEmissiveExposureWeight = this.getInstancedUniform(scope, EMISSIVE_EXPOSURE_WEIGHT_UNIFORM);
|
|
268
357
|
scope.$outputs.zRectSpecularScale = this.getInstancedUniform(scope, RECT_SPECULAR_SCALE_UNIFORM);
|
|
269
358
|
}
|
|
270
359
|
}
|
|
@@ -276,6 +365,8 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
276
365
|
if (!(this.drawContext.materialFlags & MaterialVaryingFlags.INSTANCING)) {
|
|
277
366
|
scope.zEmissiveColor = pb.vec3().uniform(2);
|
|
278
367
|
scope.zEmissiveStrength = pb.float().uniform(2);
|
|
368
|
+
scope.zEmissiveLuminance = pb.float().uniform(2);
|
|
369
|
+
scope.zEmissiveExposureWeight = pb.float().uniform(2);
|
|
279
370
|
scope.zRectSpecularScale = pb.float().uniform(2);
|
|
280
371
|
}
|
|
281
372
|
if (this.occlusionTexture) {
|
|
@@ -314,6 +405,8 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
314
405
|
if (!(ctx.materialFlags & MaterialVaryingFlags.INSTANCING)) {
|
|
315
406
|
bindGroup.setValue('zEmissiveColor', this._emissiveColor);
|
|
316
407
|
bindGroup.setValue('zEmissiveStrength', this._emissiveStrength);
|
|
408
|
+
bindGroup.setValue('zEmissiveLuminance', this._emissiveLuminance);
|
|
409
|
+
bindGroup.setValue('zEmissiveExposureWeight', this._emissiveExposureWeight);
|
|
317
410
|
bindGroup.setValue('zRectSpecularScale', this._rectSpecularScale);
|
|
318
411
|
}
|
|
319
412
|
if (this.occlusionTexture) {
|
|
@@ -455,10 +548,18 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
455
548
|
const instancing = !!(this.drawContext.materialFlags & MaterialVaryingFlags.INSTANCING);
|
|
456
549
|
return instancing ? scope.$inputs.zEmissiveColor : scope.zEmissiveColor;
|
|
457
550
|
}
|
|
551
|
+
getEmissiveLuminance(scope) {
|
|
552
|
+
const instancing = !!(this.drawContext.materialFlags & MaterialVaryingFlags.INSTANCING);
|
|
553
|
+
return instancing ? scope.$inputs.zEmissiveLuminance : scope.zEmissiveLuminance;
|
|
554
|
+
}
|
|
458
555
|
getEmissiveStrength(scope) {
|
|
459
556
|
const instancing = !!(this.drawContext.materialFlags & MaterialVaryingFlags.INSTANCING);
|
|
460
557
|
return instancing ? scope.$inputs.zEmissiveStrength : scope.zEmissiveStrength;
|
|
461
558
|
}
|
|
559
|
+
getEmissiveExposureWeight(scope) {
|
|
560
|
+
const instancing = !!(this.drawContext.materialFlags & MaterialVaryingFlags.INSTANCING);
|
|
561
|
+
return instancing ? scope.$inputs.zEmissiveExposureWeight : scope.zEmissiveExposureWeight;
|
|
562
|
+
}
|
|
462
563
|
getRectSpecularScale(scope) {
|
|
463
564
|
const instancing = !!(this.drawContext.materialFlags & MaterialVaryingFlags.INSTANCING);
|
|
464
565
|
return instancing ? scope.$inputs.zRectSpecularScale : scope.zRectSpecularScale;
|
|
@@ -471,11 +572,18 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
471
572
|
}
|
|
472
573
|
calculateEmissiveColor(scope) {
|
|
473
574
|
const pb = scope.$builder;
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
575
|
+
// Legacy multiplies by the unitless emissiveStrength, physical by the cd/m² emissiveLuminance.
|
|
576
|
+
// Same split as a light's `intensity` vs `illuminance`/`luminance`, so switching lightingMode
|
|
577
|
+
// never reinterprets one authored number as two different quantities. Safe to branch here
|
|
578
|
+
// because emissive is only evaluated in the light pass, whose program hash includes
|
|
579
|
+
// lightingMode (see LightPass._getGlobalBindGroupHash).
|
|
580
|
+
const strength = this.drawContext.scene.lightingMode === 'physical' ? this.getEmissiveLuminance(scope) : this.getEmissiveStrength(scope);
|
|
581
|
+
const base = this.emissiveTexture ? pb.mul(this.sampleEmissiveTexture(scope).rgb, this.getEmissiveColor(scope), strength) : pb.mul(this.getEmissiveColor(scope), strength);
|
|
582
|
+
// Filament's emissive attenuation: mix(1, exposure, exposureWeight). Lights are pre-exposed on
|
|
583
|
+
// the CPU, but a material-authored emitter is not, so it is exposed here. In legacy the
|
|
584
|
+
// pre-exposure is 1, which leaves this a no-op regardless of the weight.
|
|
585
|
+
const attenuation = pb.mix(pb.float(1), ShaderHelper.getPreExposureUniform(scope), this.getEmissiveExposureWeight(scope));
|
|
586
|
+
return pb.mul(base, attenuation);
|
|
479
587
|
}
|
|
480
588
|
getSheenAlbedoScaling(scope, Ndot, sheenColor, sheenRoughness) {
|
|
481
589
|
const pb = scope.$builder;
|
|
@@ -748,7 +856,10 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
748
856
|
directRectLight(scope, worldPos, normal, viewVec, commonData, posRange, axisX, axisY, colorIntensity, outColor) {
|
|
749
857
|
const pb = scope.$builder;
|
|
750
858
|
const that = this;
|
|
751
|
-
const
|
|
859
|
+
const physical = this.drawContext.scene.lightingMode === 'physical';
|
|
860
|
+
// The two modes normalize the LTC integral differently, so they must not share a cached
|
|
861
|
+
// function body under one name.
|
|
862
|
+
const funcName = physical ? 'Z_PBRRectLightPhysical' : 'Z_PBRRectLight';
|
|
752
863
|
const LUT_SIZE = 64;
|
|
753
864
|
const LUT_SCALE = (LUT_SIZE - 1) / LUT_SIZE;
|
|
754
865
|
const LUT_BIAS = 0.5 / LUT_SIZE;
|
|
@@ -939,8 +1050,17 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
939
1050
|
this.$l.lightColor = pb.mul(this.colorIntensity.rgb, this.colorIntensity.a, this.falloff);
|
|
940
1051
|
this.$l.baseF0 = this.data.f0.rgb;
|
|
941
1052
|
this.$l.rectSpecularScale = that.getRectSpecularScale(this);
|
|
942
|
-
|
|
943
|
-
|
|
1053
|
+
// Z_LTCEvaluateRect returns the raw edge sum; the reference implementation normalizes
|
|
1054
|
+
// it by 1/(2*pi). Physical applies that so the authored luminance (cd/m²) is
|
|
1055
|
+
// reproduced and diffuse/specular keep their correct ratio -- previously diffuse was
|
|
1056
|
+
// divided by pi and specular by nothing, leaving specular pi times too strong.
|
|
1057
|
+
//
|
|
1058
|
+
// Legacy deliberately keeps the historical (unnormalized) weighting: its rect
|
|
1059
|
+
// intensity is unitless and existing scenes are calibrated against it.
|
|
1060
|
+
const ltcNormalization = physical ? 1 / (2 * Math.PI) : 1;
|
|
1061
|
+
const diffuseNormalization = physical ? 1 / (2 * Math.PI) : 1 / Math.PI;
|
|
1062
|
+
this.$l.specularLtc = pb.mul(this.spec, pb.add(pb.mul(this.baseF0, this.t2.x), pb.mul(pb.sub(pb.vec3(1), this.baseF0), this.t2.y)), this.data.specularWeight, this.rectSpecularScale, ltcNormalization);
|
|
1063
|
+
this.$l.diffuseLtc = pb.mul(this.diff, pb.mul(this.data.diffuse.rgb, diffuseNormalization));
|
|
944
1064
|
this.outColor = pb.add(this.outColor, pb.mul(this.lightColor, pb.add(this.diffuseLtc, this.specularLtc)));
|
|
945
1065
|
});
|
|
946
1066
|
});
|
|
@@ -1077,6 +1197,7 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
1077
1197
|
const pb = scope.$builder;
|
|
1078
1198
|
const that = this;
|
|
1079
1199
|
const ctx = that.drawContext;
|
|
1200
|
+
const useReprojectedSSGI = !!(ctx.SSGI && ctx.SSGIIrradianceHistoryTexture && ctx.SSGISurfaceHistoryTexture && (ctx.device.type !== 'webgpu' || ctx.motionVectorTexture));
|
|
1080
1201
|
const funcName = 'Z_PBRIndirectLighting';
|
|
1081
1202
|
pb.func(funcName, [
|
|
1082
1203
|
pb.vec3('normal'),
|
|
@@ -1097,10 +1218,13 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
1097
1218
|
const envLightSpecularStrength = ShaderHelper.getEnvLightSpecularStrength(this);
|
|
1098
1219
|
if (that.occlusionTexture) {
|
|
1099
1220
|
const occlusionSample = that.sampleOcclusionTexture(this).r;
|
|
1100
|
-
this.$l.
|
|
1221
|
+
this.$l.ambientOcclusion = pb.add(pb.mul(this.zOcclusionStrength, pb.sub(occlusionSample, 1)), 1);
|
|
1222
|
+
this.$l.occlusion = pb.mul(this.ambientOcclusion, envLightStrength);
|
|
1101
1223
|
} else {
|
|
1224
|
+
this.$l.ambientOcclusion = pb.float(1);
|
|
1102
1225
|
this.$l.occlusion = envLightStrength;
|
|
1103
1226
|
}
|
|
1227
|
+
this.$l.diffuseOcclusion = useReprojectedSSGI ? this.ambientOcclusion : this.occlusion;
|
|
1104
1228
|
this.$l.NoV = pb.clamp(pb.dot(this.normal, this.viewVec), 0.0001, 1);
|
|
1105
1229
|
if (that.sheen) {
|
|
1106
1230
|
this.$l.sheenLutSample = pb.clamp(pb.textureSampleLevel(this.zSheenLut, pb.clamp(pb.vec2(this.NoV, this.data.sheenRoughness), pb.vec2(0), pb.vec2(1)), 0), pb.vec4(0), pb.vec4(1));
|
|
@@ -1127,13 +1251,24 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
1127
1251
|
}
|
|
1128
1252
|
if (outRoughness) {
|
|
1129
1253
|
this.outRoughness = pb.vec4(this.specularFactor /*this.data.f0.rgb*/ , this.data.roughness);
|
|
1130
|
-
}
|
|
1254
|
+
}
|
|
1255
|
+
// Skip specular IBL only when the roughness target exists, since SSR
|
|
1256
|
+
// is its only requester and resolves the reflection from it; adding
|
|
1257
|
+
// it here too would count it twice. `outRoughness` alone is not that
|
|
1258
|
+
// signal: SSGI requests the scene normal target and materials raise
|
|
1259
|
+
// the roughness and normal flags together, so an SSGI-only frame
|
|
1260
|
+
// wrote outRoughness with nobody to resolve the reflection, which
|
|
1261
|
+
// silently dropped specular highlights. Keyed on the flag rather
|
|
1262
|
+
// than ctx.SSR because the flag is part of the light pass shader
|
|
1263
|
+
// hash, so cached programs cannot outlive a change here.
|
|
1264
|
+
const ssrResolvesSpecular = !!(ctx.materialFlags & MaterialVaryingFlags.SCENE_STORE_ROUGHNESS);
|
|
1265
|
+
if (!ssrResolvesSpecular && ctx.env.light.envLight.hasRadiance()) {
|
|
1131
1266
|
this.$l.radiance = ctx.env.light.envLight.getRadiance(this, pb.reflect(pb.neg(this.viewVec), this.normal), this.data.roughness);
|
|
1132
1267
|
this.outColor = pb.add(this.outColor, pb.mul(this.radiance, this.specularFactor, envLightSpecularStrength));
|
|
1133
1268
|
}
|
|
1134
1269
|
}
|
|
1135
1270
|
if (ctx.env.light.envLight.hasIrradiance()) {
|
|
1136
|
-
this.$l.irradiance = ctx.env.light.envLight.getIrradiance(this, this.normal);
|
|
1271
|
+
this.$l.irradiance = ctx.env.light.envLight.getIrradiance(this, this.normal, ctx);
|
|
1137
1272
|
if (that.iridescence) {
|
|
1138
1273
|
this.$l.iridescenceF0Max = pb.vec3(pb.max(pb.max(this.data.iridescenceF0.r, this.data.iridescenceF0.g), this.data.iridescenceF0.b));
|
|
1139
1274
|
this.$l.mixedF0 = pb.mix(this.data.f0.rgb, this.iridescenceF0Max, this.data.iridescenceFactor.x);
|
|
@@ -1147,7 +1282,7 @@ import { mixinPBRBRDF } from './brdf.js';
|
|
|
1147
1282
|
this.$l.F_avg = pb.mul(pb.add(this.mixedF0, pb.div(pb.sub(pb.vec3(1), this.mixedF0), 21)), this.data.specularWeight);
|
|
1148
1283
|
this.$l.FmsEms = pb.div(pb.mul(this.FssEss, this.F_avg, this.Ems), pb.sub(pb.vec3(1), pb.mul(this.F_avg, this.Ems)));
|
|
1149
1284
|
this.$l.k_D = pb.mul(this.data.diffuse.rgb, pb.add(pb.sub(pb.vec3(1), this.FssEss), this.FmsEms));
|
|
1150
|
-
this.$l.iblDiffuse = pb.mul(pb.add(this.FmsEms, this.k_D), this.irradiance, this.
|
|
1285
|
+
this.$l.iblDiffuse = pb.mul(pb.add(this.FmsEms, this.k_D), this.irradiance, this.diffuseOcclusion);
|
|
1151
1286
|
if (that.clearcoat) {
|
|
1152
1287
|
this.$if(pb.greaterThan(this.data.ccFactor.x, 0), function() {
|
|
1153
1288
|
this.iblDiffuse = pb.mul(this.iblDiffuse, pb.clamp(pb.sub(1, pb.mul(this.data.ccFresnel, this.data.ccFactor.x)), 0, 1));
|