@driftengine/core 4.13.4 → 4.13.5
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/CHANGELOG.json +36 -0
- package/README.md +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/render/anisotropicLobe.d.ts +5 -0
- package/dist/render/anisotropicLobe.js +13 -0
- package/dist/render/atmosphere.d.ts +79 -1
- package/dist/render/atmosphere.js +66 -19
- package/dist/render/backend/webgl2/renderer.d.ts +34 -2
- package/dist/render/backend/webgl2/renderer.js +44 -12
- package/dist/render/backend/webgpu/boltPass.d.ts +1 -1
- package/dist/render/backend/webgpu/causticsPass.d.ts +1 -1
- package/dist/render/backend/webgpu/filmPass.d.ts +1 -1
- package/dist/render/backend/webgpu/gpuDrivenPass.js +20 -3
- package/dist/render/backend/webgpu/linePass.d.ts +1 -1
- package/dist/render/backend/webgpu/mediumFields.d.ts +17 -0
- package/dist/render/backend/webgpu/mediumFields.js +74 -0
- package/dist/render/backend/webgpu/plumePass.d.ts +3 -3
- package/dist/render/backend/webgpu/postPass.d.ts +7 -2
- package/dist/render/backend/webgpu/renderer.d.ts +13 -3
- package/dist/render/backend/webgpu/renderer.js +86 -150
- package/dist/render/backend/webgpu/scatterPass.d.ts +1 -1
- package/dist/render/backend/webgpu/waterPass.d.ts +1 -1
- package/dist/render/environmentMixing.d.ts +18 -0
- package/dist/render/environmentMixing.js +40 -0
- package/dist/render/fog.d.ts +43 -1
- package/dist/render/fog.js +87 -22
- package/dist/render/globalMedium.d.ts +112 -10
- package/dist/render/globalMedium.js +96 -1
- package/dist/render/globalMediumPass.d.ts +7 -3
- package/dist/render/globalMediumPass.js +22 -1
- package/dist/render/hairLobes.d.ts +5 -3
- package/dist/render/hairLobes.js +11 -7
- package/dist/render/lightBudget.d.ts +12 -0
- package/dist/render/lightBudget.js +24 -0
- package/dist/render/sceneTarget.d.ts +5 -3
- package/dist/render/sceneTarget.js +14 -8
- package/dist/render/shaders/arcane.d.ts +1 -1
- package/dist/render/shaders/bolt.d.ts +1 -1
- package/dist/render/shaders/caustics.d.ts +1 -1
- package/dist/render/shaders/film.d.ts +1 -1
- package/dist/render/shaders/film.js +4 -1
- package/dist/render/shaders/fire.d.ts +1 -1
- package/dist/render/shaders/flat/anisotropic.d.ts +8 -1
- package/dist/render/shaders/flat/anisotropic.js +25 -3
- package/dist/render/shaders/flat/hair.js +31 -7
- package/dist/render/shaders/flat/main.d.ts +1 -1
- package/dist/render/shaders/flat/main.js +20 -1
- package/dist/render/shaders/flat/models.js +1 -1
- package/dist/render/shaders/flat/preamble.js +7 -0
- package/dist/render/shaders/fog.d.ts +4 -4
- package/dist/render/shaders/fog.js +81 -32
- package/dist/render/shaders/generated/arcane.wgsl.d.ts +29 -39
- package/dist/render/shaders/generated/arcane.wgsl.js +29 -39
- package/dist/render/shaders/generated/bolt.wgsl.d.ts +26 -36
- package/dist/render/shaders/generated/bolt.wgsl.js +26 -36
- package/dist/render/shaders/generated/caustics.wgsl.d.ts +25 -35
- package/dist/render/shaders/generated/caustics.wgsl.js +25 -35
- package/dist/render/shaders/generated/film.wgsl.d.ts +28 -38
- package/dist/render/shaders/generated/film.wgsl.js +28 -38
- package/dist/render/shaders/generated/fire.wgsl.d.ts +28 -38
- package/dist/render/shaders/generated/fire.wgsl.js +28 -38
- package/dist/render/shaders/generated/flat.wgsl.d.ts +1466 -1546
- package/dist/render/shaders/generated/flat.wgsl.js +1489 -1569
- package/dist/render/shaders/generated/globalMedium.wgsl.d.ts +98 -12
- package/dist/render/shaders/generated/globalMedium.wgsl.js +98 -12
- package/dist/render/shaders/generated/line.wgsl.d.ts +25 -35
- package/dist/render/shaders/generated/line.wgsl.js +25 -35
- package/dist/render/shaders/generated/particle.wgsl.d.ts +100 -140
- package/dist/render/shaders/generated/particle.wgsl.js +100 -140
- package/dist/render/shaders/generated/rush.wgsl.d.ts +20 -10
- package/dist/render/shaders/generated/rush.wgsl.js +20 -10
- package/dist/render/shaders/generated/scatter.wgsl.d.ts +25 -35
- package/dist/render/shaders/generated/scatter.wgsl.js +25 -35
- package/dist/render/shaders/generated/smoke.wgsl.d.ts +28 -38
- package/dist/render/shaders/generated/smoke.wgsl.js +28 -38
- package/dist/render/shaders/generated/water.wgsl.d.ts +29 -39
- package/dist/render/shaders/generated/water.wgsl.js +29 -39
- package/dist/render/shaders/globalMedium.js +114 -10
- package/dist/render/shaders/gpudriven/blendRaster.wgsl.js +2 -1
- package/dist/render/shaders/gpudriven/fog.wgsl.d.ts +10 -4
- package/dist/render/shaders/gpudriven/fog.wgsl.js +77 -19
- package/dist/render/shaders/gpudriven/frameBlock.wgsl.d.ts +1 -1
- package/dist/render/shaders/gpudriven/frameBlock.wgsl.js +12 -1
- package/dist/render/shaders/gpudriven/shade.wgsl.js +3 -1
- package/dist/render/shaders/line.d.ts +1 -1
- package/dist/render/shaders/line.js +4 -2
- package/dist/render/shaders/localExposure.d.ts +42 -1
- package/dist/render/shaders/localExposure.js +73 -6
- package/dist/render/shaders/particle.d.ts +3 -3
- package/dist/render/shaders/particle.js +10 -6
- package/dist/render/shaders/scatter.d.ts +1 -1
- package/dist/render/shaders/scatter.js +4 -2
- package/dist/render/shaders/smoke.d.ts +1 -1
- package/dist/render/shaders/water.d.ts +1 -1
- package/dist/render/shaders/water.js +2 -1
- package/dist/render/surfaceModel.d.ts +23 -4
- package/dist/render/surfaceModel.js +12 -2
- package/package.json +6 -6
- package/src/index.ts +12 -2
- package/src/render/anisotropicLobe.ts +20 -0
- package/src/render/atmosphere.ts +153 -20
- package/src/render/backend/webgl2/renderer.ts +63 -13
- package/src/render/backend/webgpu/gpuDrivenPass.ts +20 -3
- package/src/render/backend/webgpu/mediumFields.ts +87 -0
- package/src/render/backend/webgpu/renderer.ts +109 -157
- package/src/render/environmentMixing.ts +48 -0
- package/src/render/fog.ts +125 -25
- package/src/render/globalMedium.ts +214 -11
- package/src/render/globalMediumPass.ts +29 -4
- package/src/render/hairLobes.ts +35 -4
- package/src/render/lightBudget.ts +32 -0
- package/src/render/sceneTarget.ts +15 -11
- package/src/render/shaders/film.ts +4 -1
- package/src/render/shaders/flat/anisotropic.ts +25 -3
- package/src/render/shaders/flat/hair.ts +31 -7
- package/src/render/shaders/flat/main.ts +20 -1
- package/src/render/shaders/flat/models.ts +1 -1
- package/src/render/shaders/flat/preamble.ts +7 -0
- package/src/render/shaders/fog.ts +81 -32
- package/src/render/shaders/generated/arcane.wgsl.ts +29 -39
- package/src/render/shaders/generated/bolt.wgsl.ts +26 -36
- package/src/render/shaders/generated/caustics.wgsl.ts +25 -35
- package/src/render/shaders/generated/film.wgsl.ts +28 -38
- package/src/render/shaders/generated/fire.wgsl.ts +28 -38
- package/src/render/shaders/generated/flat.wgsl.ts +1489 -1569
- package/src/render/shaders/generated/globalMedium.wgsl.ts +98 -12
- package/src/render/shaders/generated/line.wgsl.ts +25 -35
- package/src/render/shaders/generated/particle.wgsl.ts +100 -140
- package/src/render/shaders/generated/rush.wgsl.ts +20 -10
- package/src/render/shaders/generated/scatter.wgsl.ts +25 -35
- package/src/render/shaders/generated/smoke.wgsl.ts +28 -38
- package/src/render/shaders/generated/water.wgsl.ts +29 -39
- package/src/render/shaders/globalMedium.ts +114 -10
- package/src/render/shaders/gpudriven/blendRaster.wgsl.ts +2 -1
- package/src/render/shaders/gpudriven/fog.wgsl.ts +78 -19
- package/src/render/shaders/gpudriven/frameBlock.wgsl.ts +12 -1
- package/src/render/shaders/gpudriven/shade.wgsl.ts +3 -1
- package/src/render/shaders/line.ts +4 -2
- package/src/render/shaders/localExposure.ts +115 -6
- package/src/render/shaders/particle.ts +10 -6
- package/src/render/shaders/scatter.ts +4 -2
- package/src/render/shaders/water.ts +2 -1
- package/src/render/surfaceModel.ts +41 -6
|
@@ -60,7 +60,13 @@ import type {
|
|
|
60
60
|
TranslucentMeshOptions,
|
|
61
61
|
} from '../webgl2/renderer.ts';
|
|
62
62
|
import type { IncrementalMeshHandle, MeshOptions, PrepareOptions } from '../api.ts';
|
|
63
|
-
import {
|
|
63
|
+
import { writeMediumFields, writeMediumSlot } from './mediumFields.ts';
|
|
64
|
+
import { noEnvironmentMixing, resolveEnvironmentMixing } from '../../environmentMixing.ts';
|
|
65
|
+
import {
|
|
66
|
+
createResolvedAtmosphere,
|
|
67
|
+
resolveAtmosphere,
|
|
68
|
+
type ResolvedAtmosphere,
|
|
69
|
+
} from '../../atmosphere.ts';
|
|
64
70
|
import { AMBIENT_SH_FLOATS, packAmbientSH } from '../../ambientHarmonics.ts';
|
|
65
71
|
import {
|
|
66
72
|
lightmapTexels,
|
|
@@ -286,7 +292,8 @@ import {
|
|
|
286
292
|
import { ExposurePass } from './exposurePass.ts';
|
|
287
293
|
import { AO_STORE } from '../../shaders/ambientOcclusion.ts';
|
|
288
294
|
import { clampAutoExposure } from '../../shaders/exposure.ts';
|
|
289
|
-
import {
|
|
295
|
+
import { LOCAL_EXPOSURE_FLOATS, resolveLocalExposure } from '../../shaders/localExposure.ts';
|
|
296
|
+
import type { LocalExposureOptions } from '../../shaders/localExposure.ts';
|
|
290
297
|
import type { UniformFields } from './scatterPass.ts';
|
|
291
298
|
import {
|
|
292
299
|
createDepthResolveLayout,
|
|
@@ -425,16 +432,23 @@ import {
|
|
|
425
432
|
resolveScatterDeform,
|
|
426
433
|
type ScatterDeform,
|
|
427
434
|
} from '../../scatterDeform.ts';
|
|
428
|
-
import {
|
|
435
|
+
import {
|
|
436
|
+
createResolvedPointLights,
|
|
437
|
+
resolvePointLights,
|
|
438
|
+
type ResolvedPointLights,
|
|
439
|
+
} from '../../lightBudget.ts';
|
|
429
440
|
import { resolveRenderQuality, type RenderQuality } from '../../renderQuality.ts';
|
|
430
441
|
import {
|
|
431
442
|
DEFAULT_GLOBAL_MEDIUM,
|
|
443
|
+
WEAK_GPU_MEDIUM_STEPS,
|
|
444
|
+
createResolvedMediumLamps,
|
|
432
445
|
mediumActive,
|
|
433
446
|
mediumTargetSize,
|
|
434
|
-
WEAK_GPU_MEDIUM_STEPS,
|
|
435
447
|
resolveGlobalMedium,
|
|
448
|
+
resolveGlobalMediumSettings,
|
|
449
|
+
resolveMediumLamps,
|
|
436
450
|
} from '../../globalMedium.ts';
|
|
437
|
-
import type {
|
|
451
|
+
import type { GlobalMediumSettings, ResolvedGlobalMedium } from '../../globalMedium.ts';
|
|
438
452
|
import type { MeshData } from '../../mesh.ts';
|
|
439
453
|
import { castsDepth, glassOf } from '../../shadowCasters.ts';
|
|
440
454
|
import { materialHasMaps, noteMapsWithoutUvs } from '../../mapsWithoutUvs.ts';
|
|
@@ -2242,7 +2256,10 @@ export class WebGPURenderer implements RendererApi {
|
|
|
2242
2256
|
/** The inverse projection the composite linearises a depth with, built once per frame. */
|
|
2243
2257
|
private readonly mediumInvProjection = mat4.create();
|
|
2244
2258
|
/** This frame's medium. Off until a caller says otherwise. See `setGlobalMedium`. */
|
|
2245
|
-
private mediumOptions:
|
|
2259
|
+
private mediumOptions: ResolvedGlobalMedium = resolveGlobalMedium(DEFAULT_GLOBAL_MEDIUM);
|
|
2260
|
+
/** The lamps the medium is lit by, and the lit stage's lamps they come from, refilled a frame. */
|
|
2261
|
+
private readonly mediumLamps = createResolvedMediumLamps();
|
|
2262
|
+
private readonly mediumLights = createResolvedPointLights();
|
|
2246
2263
|
/**
|
|
2247
2264
|
* The temporal resolve: its block, its ping-pong pair, and the jitter state.
|
|
2248
2265
|
*
|
|
@@ -2948,16 +2965,7 @@ export class WebGPURenderer implements RendererApi {
|
|
|
2948
2965
|
this.quality.underwaterAtmosphere,
|
|
2949
2966
|
this.medium,
|
|
2950
2967
|
);
|
|
2951
|
-
|
|
2952
|
-
f[atF('uFogDensity')] = medium.fogDensity;
|
|
2953
|
-
f[atF('uFogHeightFalloff')] = medium.fogHeightFalloff;
|
|
2954
|
-
f[atF('uFogEyeY')] = medium.fogEyeY;
|
|
2955
|
-
f.set(medium.underwaterColor, atF('uUnderwaterColor'));
|
|
2956
|
-
f[atF('uUnderwaterFogDensity')] = medium.underwaterFogDensity;
|
|
2957
|
-
f[atF('uUnderwaterFactor')] = medium.underwaterFactor;
|
|
2958
|
-
i[atF('uFogMode')] = medium.fogMode;
|
|
2959
|
-
f[atF('uFogNear')] = medium.fogNear;
|
|
2960
|
-
f[atF('uFogFar')] = medium.fogFar;
|
|
2968
|
+
writeMediumFields(FILM_FRAG_FIELDS, f, medium);
|
|
2961
2969
|
this.filmFrags.writeBlock(fragmentSlot, this.filmFragInts);
|
|
2962
2970
|
|
|
2963
2971
|
const filmPipe = filmPipeline(
|
|
@@ -3791,6 +3799,17 @@ export class WebGPURenderer implements RendererApi {
|
|
|
3791
3799
|
this.writeEnvironmentDials();
|
|
3792
3800
|
}
|
|
3793
3801
|
|
|
3802
|
+
/** The environment brought to the light where a surface stands. See `renderer.ts`. */
|
|
3803
|
+
setEnvironmentMixing(weight: number, roughnessLow = 0.1, roughnessHigh = 0.3): void {
|
|
3804
|
+
resolveEnvironmentMixing(weight, roughnessLow, roughnessHigh, this.environmentMixing);
|
|
3805
|
+
this.material((f) => {
|
|
3806
|
+
f.set(this.environmentMixing, this.materialField('uEnvironmentMixing'));
|
|
3807
|
+
});
|
|
3808
|
+
}
|
|
3809
|
+
|
|
3810
|
+
/** `uEnvironmentMixing` as it stands; none until a draw asks. See `setEnvironmentMixing`. */
|
|
3811
|
+
private readonly environmentMixing = noEnvironmentMixing(new Float32Array(4));
|
|
3812
|
+
|
|
3794
3813
|
/**
|
|
3795
3814
|
* The reflectivity and environment gain the setters gave the pass, and the ones the material
|
|
3796
3815
|
* set now states, or null where it states none (`SurfaceMaterial.reflectivity`). A draw wears the
|
|
@@ -4683,16 +4702,7 @@ export class WebGPURenderer implements RendererApi {
|
|
|
4683
4702
|
this.quality.underwaterAtmosphere,
|
|
4684
4703
|
this.medium,
|
|
4685
4704
|
);
|
|
4686
|
-
|
|
4687
|
-
f[atF('uFogDensity')] = medium.fogDensity;
|
|
4688
|
-
f[atF('uFogHeightFalloff')] = medium.fogHeightFalloff;
|
|
4689
|
-
f[atF('uFogEyeY')] = medium.fogEyeY;
|
|
4690
|
-
f.set(medium.underwaterColor, atF('uUnderwaterColor'));
|
|
4691
|
-
f[atF('uUnderwaterFogDensity')] = medium.underwaterFogDensity;
|
|
4692
|
-
f[atF('uUnderwaterFactor')] = medium.underwaterFactor;
|
|
4693
|
-
i[atF('uFogMode')] = medium.fogMode;
|
|
4694
|
-
f[atF('uFogNear')] = medium.fogNear;
|
|
4695
|
-
f[atF('uFogFar')] = medium.fogFar;
|
|
4705
|
+
writeMediumFields(fields, f, medium);
|
|
4696
4706
|
/* Only the mote fragment declares this — spark and smoke stay unconditionally fogged and
|
|
4697
4707
|
have no such field. See ParticleBatchOptions.fog. */
|
|
4698
4708
|
if (has('uFogEnabled')) i[atF('uFogEnabled')] = batch.fog ? 1 : 0;
|
|
@@ -4943,16 +4953,7 @@ export class WebGPURenderer implements RendererApi {
|
|
|
4943
4953
|
this.quality.underwaterAtmosphere,
|
|
4944
4954
|
this.medium,
|
|
4945
4955
|
);
|
|
4946
|
-
frags
|
|
4947
|
-
frags.writeFloat(fragmentSlot, atF('uFogDensity'), medium.fogDensity);
|
|
4948
|
-
frags.writeFloat(fragmentSlot, atF('uFogHeightFalloff'), medium.fogHeightFalloff);
|
|
4949
|
-
frags.writeFloat(fragmentSlot, atF('uFogEyeY'), medium.fogEyeY);
|
|
4950
|
-
frags.writeFloats(fragmentSlot, atF('uUnderwaterColor'), medium.underwaterColor);
|
|
4951
|
-
frags.writeFloat(fragmentSlot, atF('uUnderwaterFogDensity'), medium.underwaterFogDensity);
|
|
4952
|
-
frags.writeFloat(fragmentSlot, atF('uUnderwaterFactor'), medium.underwaterFactor);
|
|
4953
|
-
frags.writeInt(fragmentSlot, atF('uFogMode'), medium.fogMode);
|
|
4954
|
-
frags.writeFloat(fragmentSlot, atF('uFogNear'), medium.fogNear);
|
|
4955
|
-
frags.writeFloat(fragmentSlot, atF('uFogFar'), medium.fogFar);
|
|
4956
|
+
writeMediumSlot(frags, fragmentSlot, PLUME_FRAG_FIELDS, medium);
|
|
4956
4957
|
frags.writeInt(fragmentSlot, atF('uOutputTransform'), this.passGrade());
|
|
4957
4958
|
frags.writeFloat(fragmentSlot, atF('uOutputExposure'), this.passGradeExposure());
|
|
4958
4959
|
/*
|
|
@@ -5141,16 +5142,7 @@ export class WebGPURenderer implements RendererApi {
|
|
|
5141
5142
|
this.quality.underwaterAtmosphere,
|
|
5142
5143
|
this.medium,
|
|
5143
5144
|
);
|
|
5144
|
-
|
|
5145
|
-
f[atF('uFogDensity')] = medium.fogDensity;
|
|
5146
|
-
f[atF('uFogHeightFalloff')] = medium.fogHeightFalloff;
|
|
5147
|
-
f[atF('uFogEyeY')] = medium.fogEyeY;
|
|
5148
|
-
f.set(medium.underwaterColor, atF('uUnderwaterColor'));
|
|
5149
|
-
f[atF('uUnderwaterFogDensity')] = medium.underwaterFogDensity;
|
|
5150
|
-
f[atF('uUnderwaterFactor')] = medium.underwaterFactor;
|
|
5151
|
-
i[atF('uFogMode')] = medium.fogMode;
|
|
5152
|
-
f[atF('uFogNear')] = medium.fogNear;
|
|
5153
|
-
f[atF('uFogFar')] = medium.fogFar;
|
|
5145
|
+
writeMediumFields(WATER_FRAG_FIELDS, f, medium);
|
|
5154
5146
|
|
|
5155
5147
|
/* No reflection pass yet: the shader's own "off" path, not an improvised one. */
|
|
5156
5148
|
i[atF('uReflectionEnabled')] = mirror === null ? 0 : 1;
|
|
@@ -5766,16 +5758,7 @@ export class WebGPURenderer implements RendererApi {
|
|
|
5766
5758
|
this.quality.underwaterAtmosphere,
|
|
5767
5759
|
this.medium,
|
|
5768
5760
|
);
|
|
5769
|
-
|
|
5770
|
-
f[atF('uFogDensity')] = medium.fogDensity;
|
|
5771
|
-
f[atF('uFogHeightFalloff')] = medium.fogHeightFalloff;
|
|
5772
|
-
f[atF('uFogEyeY')] = medium.fogEyeY;
|
|
5773
|
-
f.set(medium.underwaterColor, atF('uUnderwaterColor'));
|
|
5774
|
-
f[atF('uUnderwaterFogDensity')] = medium.underwaterFogDensity;
|
|
5775
|
-
f[atF('uUnderwaterFactor')] = medium.underwaterFactor;
|
|
5776
|
-
i[atF('uFogMode')] = medium.fogMode;
|
|
5777
|
-
f[atF('uFogNear')] = medium.fogNear;
|
|
5778
|
-
f[atF('uFogFar')] = medium.fogFar;
|
|
5761
|
+
writeMediumFields(BOLT_FRAG_FIELDS, f, medium);
|
|
5779
5762
|
|
|
5780
5763
|
this.boltVerts.writeBlock(vertexSlot, this.boltVertBlock);
|
|
5781
5764
|
this.boltFrags.writeBlock(fragmentSlot, this.boltFragInts);
|
|
@@ -5903,20 +5886,7 @@ export class WebGPURenderer implements RendererApi {
|
|
|
5903
5886
|
this.quality.underwaterAtmosphere,
|
|
5904
5887
|
this.medium,
|
|
5905
5888
|
);
|
|
5906
|
-
this.lineFrags
|
|
5907
|
-
this.lineFrags.writeFloat(fragmentSlot, atF('uFogDensity'), medium.fogDensity);
|
|
5908
|
-
this.lineFrags.writeFloat(fragmentSlot, atF('uFogHeightFalloff'), medium.fogHeightFalloff);
|
|
5909
|
-
this.lineFrags.writeFloat(fragmentSlot, atF('uFogEyeY'), medium.fogEyeY);
|
|
5910
|
-
this.lineFrags.writeFloats(fragmentSlot, atF('uUnderwaterColor'), medium.underwaterColor);
|
|
5911
|
-
this.lineFrags.writeFloat(
|
|
5912
|
-
fragmentSlot,
|
|
5913
|
-
atF('uUnderwaterFogDensity'),
|
|
5914
|
-
medium.underwaterFogDensity,
|
|
5915
|
-
);
|
|
5916
|
-
this.lineFrags.writeFloat(fragmentSlot, atF('uUnderwaterFactor'), medium.underwaterFactor);
|
|
5917
|
-
this.lineFrags.writeInt(fragmentSlot, atF('uFogMode'), medium.fogMode);
|
|
5918
|
-
this.lineFrags.writeFloat(fragmentSlot, atF('uFogNear'), medium.fogNear);
|
|
5919
|
-
this.lineFrags.writeFloat(fragmentSlot, atF('uFogFar'), medium.fogFar);
|
|
5889
|
+
writeMediumSlot(this.lineFrags, fragmentSlot, LINE_FRAG_FIELDS, medium);
|
|
5920
5890
|
|
|
5921
5891
|
const linePipe = linePipeline(
|
|
5922
5892
|
this.blendedPipelines(),
|
|
@@ -6079,39 +6049,11 @@ export class WebGPURenderer implements RendererApi {
|
|
|
6079
6049
|
}
|
|
6080
6050
|
|
|
6081
6051
|
/** Refilled per frame rather than allocated; see `resolvePointLights`. */
|
|
6082
|
-
private readonly lights: ResolvedPointLights =
|
|
6083
|
-
count: 0,
|
|
6084
|
-
falloff: 0,
|
|
6085
|
-
positions: new Float32Array(0),
|
|
6086
|
-
colors: new Float32Array(0),
|
|
6087
|
-
radii: new Float32Array(0),
|
|
6088
|
-
sourceRadii: new Float32Array(0),
|
|
6089
|
-
weights: new Float32Array(0),
|
|
6090
|
-
directions: new Float32Array(0),
|
|
6091
|
-
coneCos: new Float32Array(0),
|
|
6092
|
-
iesProfiles: new Float32Array(0),
|
|
6093
|
-
iesAxes: new Float32Array(0),
|
|
6094
|
-
cookies: new Float32Array(0),
|
|
6095
|
-
heldSourceRadii: new Float32Array(MAX_POINT_LIGHTS),
|
|
6096
|
-
axesAndChannels: new Float32Array(MAX_POINT_LIGHTS * 4),
|
|
6097
|
-
conesAndFalloffs: new Float32Array(MAX_POINT_LIGHTS * 4),
|
|
6098
|
-
heldWeights: new Float32Array(MAX_POINT_LIGHTS),
|
|
6099
|
-
};
|
|
6052
|
+
private readonly lights: ResolvedPointLights = createResolvedPointLights();
|
|
6100
6053
|
/** The fixed arm's rectangles as `uAreaLightSize` holds them. See `packAreaSizesAndDoors`. */
|
|
6101
6054
|
private readonly areaSizesAndDoors = new Float32Array(MAX_AREA_LIGHTS * 4);
|
|
6102
6055
|
/** Refilled per frame rather than allocated; see `resolveAtmosphere`. */
|
|
6103
|
-
private readonly medium: ResolvedAtmosphere =
|
|
6104
|
-
fogColor: new Float32Array(3),
|
|
6105
|
-
underwaterColor: new Float32Array(3),
|
|
6106
|
-
fogDensity: 0,
|
|
6107
|
-
fogHeightFalloff: 0,
|
|
6108
|
-
fogEyeY: 0,
|
|
6109
|
-
fogMode: 0,
|
|
6110
|
-
fogNear: 0,
|
|
6111
|
-
fogFar: 1,
|
|
6112
|
-
underwaterFogDensity: 0,
|
|
6113
|
-
underwaterFactor: 0,
|
|
6114
|
-
};
|
|
6056
|
+
private readonly medium: ResolvedAtmosphere = createResolvedAtmosphere();
|
|
6115
6057
|
/* -- Overlays: panels and text ------------------------------------------------------ */
|
|
6116
6058
|
|
|
6117
6059
|
private readonly panelLayout: GPUBindGroupLayout;
|
|
@@ -7779,6 +7721,7 @@ export class WebGPURenderer implements RendererApi {
|
|
|
7779
7721
|
this.mediumLayout = createPostStageLayout(device, MEDIUM_UNIFORMS, MEDIUM_FRAG_SIZE, [
|
|
7780
7722
|
{ binding: MEDIUM_TEXTURES.uDepth, filterable: false },
|
|
7781
7723
|
{ binding: MEDIUM_TEXTURES.uSunShadows, filterable: false, dimension: '2d-array' },
|
|
7724
|
+
{ binding: MEDIUM_TEXTURES.uPointShadows, filterable: false, dimension: '2d-array' },
|
|
7782
7725
|
]);
|
|
7783
7726
|
this.mediumUniforms = device.createBuffer({
|
|
7784
7727
|
label: 'post.mediumUniforms',
|
|
@@ -9178,16 +9121,7 @@ export class WebGPURenderer implements RendererApi {
|
|
|
9178
9121
|
this.quality.underwaterAtmosphere,
|
|
9179
9122
|
this.medium,
|
|
9180
9123
|
);
|
|
9181
|
-
|
|
9182
|
-
f[at('uFogDensity')] = meshMedium.fogDensity;
|
|
9183
|
-
f[at('uFogHeightFalloff')] = meshMedium.fogHeightFalloff;
|
|
9184
|
-
f[at('uFogEyeY')] = meshMedium.fogEyeY;
|
|
9185
|
-
i[at('uFogMode')] = meshMedium.fogMode;
|
|
9186
|
-
f[at('uFogNear')] = meshMedium.fogNear;
|
|
9187
|
-
f[at('uFogFar')] = meshMedium.fogFar;
|
|
9188
|
-
f.set(meshMedium.underwaterColor, at('uUnderwaterColor'));
|
|
9189
|
-
f[at('uUnderwaterFogDensity')] = meshMedium.underwaterFogDensity;
|
|
9190
|
-
f[at('uUnderwaterFactor')] = meshMedium.underwaterFactor;
|
|
9124
|
+
writeMediumFields(this.fragment.fields, f, meshMedium);
|
|
9191
9125
|
/*
|
|
9192
9126
|
* The mirror's half-space, and only while the mirror is being drawn.
|
|
9193
9127
|
*
|
|
@@ -9236,6 +9170,8 @@ export class WebGPURenderer implements RendererApi {
|
|
|
9236
9170
|
f[at('uWriteMode') + 2] = 0;
|
|
9237
9171
|
/* 1, not 0: a multiplier's identity is one. See `setEnvironmentGain`. */
|
|
9238
9172
|
f[at('uEnvironmentDials') + 2] = 1;
|
|
9173
|
+
/* And no mixing, which is stored less one. See `setEnvironmentMixing`. */
|
|
9174
|
+
f.set(noEnvironmentMixing(this.environmentMixing), at('uEnvironmentMixing'));
|
|
9239
9175
|
/* No overlay until a draw sets one. See `setSurfaceOverlay`. */
|
|
9240
9176
|
this.overlayFloats.fill(0);
|
|
9241
9177
|
f.fill(0, at('uOverlay'), at('uOverlay') + OVERLAY_FLOATS);
|
|
@@ -9491,16 +9427,7 @@ export class WebGPURenderer implements RendererApi {
|
|
|
9491
9427
|
this.quality.underwaterAtmosphere,
|
|
9492
9428
|
this.medium,
|
|
9493
9429
|
);
|
|
9494
|
-
|
|
9495
|
-
f[at('uFogDensity')] = medium.fogDensity;
|
|
9496
|
-
f[at('uFogHeightFalloff')] = medium.fogHeightFalloff;
|
|
9497
|
-
f[at('uFogEyeY')] = medium.fogEyeY;
|
|
9498
|
-
i[at('uFogMode')] = medium.fogMode;
|
|
9499
|
-
f[at('uFogNear')] = medium.fogNear;
|
|
9500
|
-
f[at('uFogFar')] = medium.fogFar;
|
|
9501
|
-
f.set(medium.underwaterColor, at('uUnderwaterColor'));
|
|
9502
|
-
f[at('uUnderwaterFogDensity')] = medium.underwaterFogDensity;
|
|
9503
|
-
f[at('uUnderwaterFactor')] = medium.underwaterFactor;
|
|
9430
|
+
writeMediumFields(this.fragment.fields, f, medium);
|
|
9504
9431
|
|
|
9505
9432
|
/*
|
|
9506
9433
|
* The shadow terms, matching what `renderer.ts` binds at default quality.
|
|
@@ -11120,16 +11047,7 @@ export class WebGPURenderer implements RendererApi {
|
|
|
11120
11047
|
this.quality.underwaterAtmosphere,
|
|
11121
11048
|
this.medium,
|
|
11122
11049
|
);
|
|
11123
|
-
|
|
11124
|
-
f[atF('uFogDensity')] = medium.fogDensity;
|
|
11125
|
-
f[atF('uFogHeightFalloff')] = medium.fogHeightFalloff;
|
|
11126
|
-
f[atF('uFogEyeY')] = medium.fogEyeY;
|
|
11127
|
-
f.set(medium.underwaterColor, atF('uUnderwaterColor'));
|
|
11128
|
-
f[atF('uUnderwaterFogDensity')] = medium.underwaterFogDensity;
|
|
11129
|
-
f[atF('uUnderwaterFactor')] = medium.underwaterFactor;
|
|
11130
|
-
i[atF('uFogMode')] = medium.fogMode;
|
|
11131
|
-
f[atF('uFogNear')] = medium.fogNear;
|
|
11132
|
-
f[atF('uFogFar')] = medium.fogFar;
|
|
11050
|
+
writeMediumFields(SCATTER_FRAG_FIELDS, f, medium);
|
|
11133
11051
|
i[atF('uOutputTransform')] = this.passGrade();
|
|
11134
11052
|
f[atF('uOutputExposure')] = this.passGradeExposure();
|
|
11135
11053
|
|
|
@@ -12034,6 +11952,8 @@ export class WebGPURenderer implements RendererApi {
|
|
|
12034
11952
|
* resolve, which is what sampling a stand-in does.
|
|
12035
11953
|
*/
|
|
12036
11954
|
this.rebuildFlatBindGroup();
|
|
11955
|
+
/* The medium reads the same array: see `buildMediumBindGroup`. */
|
|
11956
|
+
this.mediumBindGroup = this.buildMediumBindGroup();
|
|
12037
11957
|
}
|
|
12038
11958
|
this.pointShadows.prepareStaticMaps(lights.length);
|
|
12039
11959
|
this.preparedPointLightCount = lights.length;
|
|
@@ -12351,6 +12271,8 @@ export class WebGPURenderer implements RendererApi {
|
|
|
12351
12271
|
if (old !== null) {
|
|
12352
12272
|
this.retiredPointTexture = old;
|
|
12353
12273
|
this.rebuildFlatBindGroup();
|
|
12274
|
+
/* The medium reads the same array: see `buildMediumBindGroup`. */
|
|
12275
|
+
this.mediumBindGroup = this.buildMediumBindGroup();
|
|
12354
12276
|
}
|
|
12355
12277
|
}
|
|
12356
12278
|
}
|
|
@@ -12892,7 +12814,7 @@ export class WebGPURenderer implements RendererApi {
|
|
|
12892
12814
|
* it. The held brightness is kept for either, since local exposure moves regions relative to it.
|
|
12893
12815
|
* See `setAutoExposure` and `setLocalExposure`.
|
|
12894
12816
|
*/
|
|
12895
|
-
const localising = this.localExposure
|
|
12817
|
+
const localising = this.localExposure;
|
|
12896
12818
|
const measuring = (this.autoExposure > 0 || localising) && this.exposurePass !== null;
|
|
12897
12819
|
const adapting = measuring && this.autoExposure > 0;
|
|
12898
12820
|
const shownScene = this.reconstructing ? this.reconShownView : this.sceneColorView;
|
|
@@ -12966,7 +12888,13 @@ export class WebGPURenderer implements RendererApi {
|
|
|
12966
12888
|
f[at('uVignette')] = this.vignette;
|
|
12967
12889
|
f.set(this.fringe, at('uFringe'));
|
|
12968
12890
|
f[at('uAutoExposure')] = adapting ? this.autoExposure : 0;
|
|
12969
|
-
f[at('uLocalExposure')] = measuring && localising ?
|
|
12891
|
+
f[at('uLocalExposure')] = measuring && localising ? 1 : 0;
|
|
12892
|
+
const shapeAt = at('uLocalShape');
|
|
12893
|
+
const pivotAt = at('uLocalPivot');
|
|
12894
|
+
for (let k = 0; k < 4; k++) {
|
|
12895
|
+
f[shapeAt + k] = this.localExposureShape[k] as number;
|
|
12896
|
+
f[pivotAt + k] = this.localExposureShape[4 + k] as number;
|
|
12897
|
+
}
|
|
12970
12898
|
f[at('uGrain')] = this.grain;
|
|
12971
12899
|
f[at('uGrain') + 1] = this.grainSeed;
|
|
12972
12900
|
device.queue.writeBuffer(this.rushUniforms, 0, this.rushStaging);
|
|
@@ -14404,7 +14332,17 @@ export class WebGPURenderer implements RendererApi {
|
|
|
14404
14332
|
f.set(env?.directionalColor ?? [0, 0, 0], at('uSunColor'));
|
|
14405
14333
|
f.set(env?.ambient ?? [0, 0, 0], at('uAmbient'));
|
|
14406
14334
|
f[at('uDensity')] = options.density;
|
|
14407
|
-
|
|
14335
|
+
const height = at('uHeight');
|
|
14336
|
+
f[height] = options.heightFalloff;
|
|
14337
|
+
f[height + 1] = options.baseY;
|
|
14338
|
+
const layer2 = at('uLayer2');
|
|
14339
|
+
f[layer2] = options.density2;
|
|
14340
|
+
f[layer2 + 1] = options.heightFalloff2;
|
|
14341
|
+
f[layer2 + 2] = options.baseY2;
|
|
14342
|
+
f.set(options.albedo, at('uAlbedo'));
|
|
14343
|
+
const scatter = at('uScatter');
|
|
14344
|
+
f[scatter] = options.sunScatter;
|
|
14345
|
+
f[scatter + 1] = options.skyScatter;
|
|
14408
14346
|
f[at('uAnisotropy')] = options.anisotropy;
|
|
14409
14347
|
f[at('uMaxDistance')] = options.maxDistance;
|
|
14410
14348
|
ints[at('uSteps')] = this.quality.globalMediumSteps;
|
|
@@ -14425,6 +14363,26 @@ export class WebGPURenderer implements RendererApi {
|
|
|
14425
14363
|
at('uMovingLightViewProj'),
|
|
14426
14364
|
);
|
|
14427
14365
|
ints[at('uPeeledShadowEnabled')] = this.peelView === null || !this.peelFilled ? 0 : 1;
|
|
14366
|
+
/* The lit stage's lamps and the shadows it resolved for them, this frame's. */
|
|
14367
|
+
const lamps = resolveMediumLamps(
|
|
14368
|
+
options,
|
|
14369
|
+
resolvePointLights(env, this.quality.pointLightFalloff, this.mediumLights),
|
|
14370
|
+
this.pointShadows === null ? null : this.resolvedPointShadows,
|
|
14371
|
+
env?.lightMediumScatter,
|
|
14372
|
+
this.mediumLamps,
|
|
14373
|
+
);
|
|
14374
|
+
ints[at('uLampCount')] = lamps.count;
|
|
14375
|
+
ints[at('uLampFalloff')] = lamps.falloff;
|
|
14376
|
+
if (lamps.count > 0) {
|
|
14377
|
+
f.set(lamps.position, at('uLampPosition'));
|
|
14378
|
+
f.set(lamps.color, at('uLampColor'));
|
|
14379
|
+
f.set(lamps.aim, at('uLampAim'));
|
|
14380
|
+
f.set(lamps.cone, at('uLampCone'));
|
|
14381
|
+
f.set(lamps.shadow, at('uLampShadow'));
|
|
14382
|
+
f.set(lamps.shadowAt, at('uLampShadowAt'));
|
|
14383
|
+
f.set(lamps.live, at('uLampLive'));
|
|
14384
|
+
f.set(lamps.liveAt, at('uLampLiveAt'));
|
|
14385
|
+
}
|
|
14428
14386
|
device.queue.writeBuffer(this.mediumUniforms, 0, this.mediumStaging);
|
|
14429
14387
|
|
|
14430
14388
|
const g = this.mediumUpsampleFloats;
|
|
@@ -17147,8 +17105,9 @@ export class WebGPURenderer implements RendererApi {
|
|
|
17147
17105
|
/** Eye adaptation: how far, this frame's time step, and the pass once asked for. */
|
|
17148
17106
|
private autoExposure = 0;
|
|
17149
17107
|
private autoExposureDt = 0;
|
|
17150
|
-
/**
|
|
17151
|
-
private localExposure =
|
|
17108
|
+
/** Whether regions move, and how, as `resolveLocalExposure` packs it. See `setLocalExposure`. */
|
|
17109
|
+
private localExposure = false;
|
|
17110
|
+
private readonly localExposureShape = new Float32Array(LOCAL_EXPOSURE_FLOATS);
|
|
17152
17111
|
private exposurePass: ExposurePass | null = null;
|
|
17153
17112
|
|
|
17154
17113
|
/**
|
|
@@ -17312,17 +17271,12 @@ export class WebGPURenderer implements RendererApi {
|
|
|
17312
17271
|
* draws nothing, and the three optional arguments are held until changed.
|
|
17313
17272
|
*/
|
|
17314
17273
|
setGlobalMedium(
|
|
17315
|
-
density: number,
|
|
17316
|
-
albedo?: number,
|
|
17274
|
+
density: number | GlobalMediumSettings,
|
|
17275
|
+
albedo?: number | Vec3,
|
|
17317
17276
|
anisotropy?: number,
|
|
17318
17277
|
maxDistance?: number,
|
|
17319
17278
|
): void {
|
|
17320
|
-
this.mediumOptions =
|
|
17321
|
-
density: Number.isFinite(density) ? density : 0,
|
|
17322
|
-
albedo,
|
|
17323
|
-
anisotropy,
|
|
17324
|
-
maxDistance,
|
|
17325
|
-
});
|
|
17279
|
+
this.mediumOptions = resolveGlobalMediumSettings(density, albedo, anisotropy, maxDistance);
|
|
17326
17280
|
}
|
|
17327
17281
|
|
|
17328
17282
|
/** How much speed blur the frame should resolve with, 0 to 1. */
|
|
@@ -17397,13 +17351,13 @@ export class WebGPURenderer implements RendererApi {
|
|
|
17397
17351
|
* the same setter over the same state, sharing eye adaptation's pass, which is built the first
|
|
17398
17352
|
* time either is asked for.
|
|
17399
17353
|
*/
|
|
17400
|
-
setLocalExposure(
|
|
17354
|
+
setLocalExposure(setting: number | LocalExposureOptions): void {
|
|
17401
17355
|
if (!this.hasComposite || !this.quality.hdrScene) {
|
|
17402
|
-
this.warnLookWithoutComposite(
|
|
17356
|
+
this.warnLookWithoutComposite(typeof setting === 'number' ? setting : 1);
|
|
17403
17357
|
return;
|
|
17404
17358
|
}
|
|
17405
|
-
this.localExposure =
|
|
17406
|
-
if (this.localExposure
|
|
17359
|
+
this.localExposure = resolveLocalExposure(setting, this.localExposureShape);
|
|
17360
|
+
if (this.localExposure) this.ensureExposurePass();
|
|
17407
17361
|
}
|
|
17408
17362
|
|
|
17409
17363
|
/** The exposure pass, built once; the composite's group holds placeholders until it exists. */
|
|
@@ -17572,16 +17526,7 @@ export class WebGPURenderer implements RendererApi {
|
|
|
17572
17526
|
this.quality.underwaterAtmosphere,
|
|
17573
17527
|
this.medium,
|
|
17574
17528
|
);
|
|
17575
|
-
|
|
17576
|
-
f[atF('uFogDensity')] = medium.fogDensity;
|
|
17577
|
-
f[atF('uFogHeightFalloff')] = medium.fogHeightFalloff;
|
|
17578
|
-
f[atF('uFogEyeY')] = medium.fogEyeY;
|
|
17579
|
-
f.set(medium.underwaterColor, atF('uUnderwaterColor'));
|
|
17580
|
-
f[atF('uUnderwaterFogDensity')] = medium.underwaterFogDensity;
|
|
17581
|
-
f[atF('uUnderwaterFactor')] = medium.underwaterFactor;
|
|
17582
|
-
i[atF('uFogMode')] = medium.fogMode;
|
|
17583
|
-
f[atF('uFogNear')] = medium.fogNear;
|
|
17584
|
-
f[atF('uFogFar')] = medium.fogFar;
|
|
17529
|
+
writeMediumFields(CAUSTICS_FRAG_FIELDS, f, medium);
|
|
17585
17530
|
|
|
17586
17531
|
this.causticsVerts.writeBlock(vertexSlot, this.causticsVertBlock);
|
|
17587
17532
|
this.causticsFrags.writeBlock(fragmentSlot, this.causticsFragInts);
|
|
@@ -18658,6 +18603,13 @@ export class WebGPURenderer implements RendererApi {
|
|
|
18658
18603
|
{ binding: MEDIUM_TEXTURES.uDepth.sampler, resource: this.postDepthSampler },
|
|
18659
18604
|
{ binding: MEDIUM_TEXTURES.uSunShadows.texture, resource: this.sunArrayView },
|
|
18660
18605
|
{ binding: MEDIUM_TEXTURES.uSunShadows.sampler, resource: this.volumeShadowSampler },
|
|
18606
|
+
/* The lamps' maps, the lit stage's own array, rebuilt here whenever that array is
|
|
18607
|
+
replaced; the white stand-in reads as nothing in the way, and no lamp reads it. */
|
|
18608
|
+
{
|
|
18609
|
+
binding: MEDIUM_TEXTURES.uPointShadows.texture,
|
|
18610
|
+
resource: this.pointShadowArray?.view ?? (this.shadowBlankView as GPUTextureView),
|
|
18611
|
+
},
|
|
18612
|
+
{ binding: MEDIUM_TEXTURES.uPointShadows.sampler, resource: this.volumeShadowSampler },
|
|
18661
18613
|
],
|
|
18662
18614
|
});
|
|
18663
18615
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The environment a surface reflects brought to the light where it stands: `setEnvironmentMixing`'s
|
|
3
|
+
* numbers as the lit stage reads them, `uEnvironmentMixing`. Both backends fill it here and upload
|
|
4
|
+
* it, so a clamp cannot differ between them.
|
|
5
|
+
*
|
|
6
|
+
* **The weight is stored less one**, so a program a binder never wrote, all zeros, reflects exactly
|
|
7
|
+
* as it did before the field existed; the two roughnesses beside it are where the weight is mixed in
|
|
8
|
+
* between, smooth to rough.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** `uEnvironmentMixing` mixing nothing: a weight of 1, between the default roughnesses. */
|
|
12
|
+
export function noEnvironmentMixing(out: Float32Array): Float32Array {
|
|
13
|
+
out[0] = 0;
|
|
14
|
+
out[1] = 0.1;
|
|
15
|
+
out[2] = 0.3;
|
|
16
|
+
out[3] = 0;
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A caller's weight and roughnesses, into `out`: a weight that is not a number at or above zero is
|
|
22
|
+
* 1, the roughnesses are held to 0 to 1, and the upper never below the lower.
|
|
23
|
+
*/
|
|
24
|
+
export function resolveEnvironmentMixing(
|
|
25
|
+
weight: number,
|
|
26
|
+
roughnessLow: number,
|
|
27
|
+
roughnessHigh: number,
|
|
28
|
+
out: Float32Array,
|
|
29
|
+
): Float32Array {
|
|
30
|
+
const unit = (value: number, fallback: number): number =>
|
|
31
|
+
Number.isFinite(value) ? Math.min(1, Math.max(0, value)) : fallback;
|
|
32
|
+
out[0] = (Number.isFinite(weight) && weight >= 0 ? weight : 1) - 1;
|
|
33
|
+
const low = unit(roughnessLow, 0.1);
|
|
34
|
+
out[1] = low;
|
|
35
|
+
out[2] = Math.max(low, unit(roughnessHigh, 0.3));
|
|
36
|
+
out[3] = 0;
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** The factor a surface of `roughness` reflects by, as the lit stage computes it. */
|
|
41
|
+
export function environmentMixingFactor(mixing: ArrayLike<number>, roughness: number): number {
|
|
42
|
+
const less = mixing[0] as number;
|
|
43
|
+
if (less === 0) return 1;
|
|
44
|
+
const low = mixing[1] as number;
|
|
45
|
+
const span = Math.max((mixing[2] as number) - low, 1e-4);
|
|
46
|
+
const t = Math.min(1, Math.max(0, (roughness - low) / span));
|
|
47
|
+
return 1 + less * t * t * (3 - 2 * t);
|
|
48
|
+
}
|