@driftengine/core 4.8.1 → 4.8.3
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 +142 -0
- package/README.md +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +8 -0
- package/dist/input/actionMap.d.ts +6 -1
- package/dist/input/actionMap.js +20 -7
- package/dist/input/input.d.ts +28 -0
- package/dist/input/input.js +71 -9
- package/dist/input/inputHarness.d.ts +9 -0
- package/dist/input/inputHarness.js +34 -2
- package/dist/render/backend/materialChanges.d.ts +7 -2
- package/dist/render/backend/materialChanges.js +8 -3
- package/dist/render/backend/webgl2/renderer.d.ts +75 -3
- package/dist/render/backend/webgl2/renderer.js +209 -22
- package/dist/render/backend/webgpu/buffers.d.ts +2 -0
- package/dist/render/backend/webgpu/buffers.js +2 -0
- package/dist/render/backend/webgpu/causticsPass.js +2 -1
- package/dist/render/backend/webgpu/depthPass.d.ts +13 -3
- package/dist/render/backend/webgpu/depthPass.js +4 -3
- package/dist/render/backend/webgpu/filmPass.js +2 -1
- package/dist/render/backend/webgpu/flatPass.d.ts +5 -0
- package/dist/render/backend/webgpu/flatPass.js +18 -8
- package/dist/render/backend/webgpu/linePass.js +2 -1
- package/dist/render/backend/webgpu/panelPass.js +2 -1
- package/dist/render/backend/webgpu/particlePass.js +2 -1
- package/dist/render/backend/webgpu/pipelineCache.d.ts +40 -8
- package/dist/render/backend/webgpu/pipelineCache.js +76 -9
- package/dist/render/backend/webgpu/plumePass.js +2 -1
- package/dist/render/backend/webgpu/postPass.d.ts +12 -2
- package/dist/render/backend/webgpu/postPass.js +19 -5
- package/dist/render/backend/webgpu/renderer.d.ts +66 -2
- package/dist/render/backend/webgpu/renderer.js +189 -38
- package/dist/render/backend/webgpu/sdfTextPass.js +2 -1
- package/dist/render/backend/webgpu/textPass.js +2 -1
- package/dist/render/backend/webgpu/waterPass.js +2 -1
- package/dist/render/backend/webgpu/windStreakPass.js +2 -1
- package/dist/render/boltBatch.js +2 -1
- package/dist/render/causticsRenderer.js +2 -1
- package/dist/render/cutoutCaster.d.ts +3 -1
- package/dist/render/cutoutCaster.js +4 -0
- package/dist/render/decalPass.js +2 -1
- package/dist/render/globalMediumPass.js +3 -2
- package/dist/render/lineBatch.js +5 -1
- package/dist/render/mapsWithoutUvs.d.ts +24 -0
- package/dist/render/mapsWithoutUvs.js +24 -0
- package/dist/render/mesh.d.ts +2 -0
- package/dist/render/mesh.js +3 -0
- package/dist/render/oitPass.js +2 -1
- package/dist/render/particleBatch.js +3 -2
- package/dist/render/particlePool.d.ts +21 -2
- package/dist/render/particlePool.js +72 -37
- package/dist/render/pass.d.ts +12 -0
- package/dist/render/plumeRenderer.js +3 -2
- package/dist/render/renderQuality.d.ts +16 -8
- package/dist/render/sceneCoverage.d.ts +54 -0
- package/dist/render/sceneCoverage.js +72 -0
- package/dist/render/sdfTextRenderer.js +2 -1
- package/dist/render/shaders/depth.js +3 -2
- package/dist/render/shaders/flat/glassTint.d.ts +28 -0
- package/dist/render/shaders/flat/glassTint.js +31 -0
- package/dist/render/shaders/flat/index.d.ts +12 -0
- package/dist/render/shaders/flat/index.js +13 -2
- package/dist/render/shaders/flat/main.d.ts +1 -1
- package/dist/render/shaders/flat/main.js +60 -25
- package/dist/render/shaders/flat/surfaceEffects.d.ts +1 -1
- package/dist/render/shaders/flat/surfaceEffects.js +6 -2
- package/dist/render/shaders/generated/depth.wgsl.d.ts +32 -12
- package/dist/render/shaders/generated/depth.wgsl.js +32 -12
- package/dist/render/shaders/generated/flat.wgsl.d.ts +89 -0
- package/dist/render/shaders/generated/flat.wgsl.js +127 -38
- package/dist/render/shaders/generated/line.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/line.wgsl.js +1 -1
- package/dist/render/shaders/generated/particle.wgsl.d.ts +3 -3
- package/dist/render/shaders/generated/particle.wgsl.js +3 -3
- package/dist/render/shaders/generated/rush.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/rush.wgsl.js +1 -1
- package/dist/render/shaders/generated/sdfText.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/sdfText.wgsl.js +1 -1
- package/dist/render/shaders/generated/temporalResolve.wgsl.d.ts +1 -1
- package/dist/render/shaders/generated/temporalResolve.wgsl.js +1 -1
- package/dist/render/shaders/line.d.ts +1 -1
- package/dist/render/shaders/outputTransform.d.ts +14 -1
- package/dist/render/shaders/outputTransform.js +23 -1
- package/dist/render/shaders/particle.d.ts +3 -3
- package/dist/render/shaders/recon/resolve.wgsl.js +15 -1
- package/dist/render/shaders/rush.js +13 -2
- package/dist/render/shaders/sdfText.d.ts +1 -1
- package/dist/render/shaders/temporalResolve.js +12 -5
- package/dist/render/ssrPass.js +2 -1
- package/dist/render/surfaceTexture.d.ts +13 -0
- package/dist/render/surfaceTexture.js +4 -0
- package/dist/render/textRenderer.js +2 -1
- package/dist/render/vertexDefaults.js +1 -0
- package/dist/render/viewModel.d.ts +29 -0
- package/dist/render/viewModel.js +35 -0
- package/dist/render/waterRenderer.js +2 -1
- package/dist/render/windStreakRenderer.js +2 -1
- package/package.json +6 -6
- package/src/index.ts +22 -1
- package/src/input/actionMap.ts +23 -8
- package/src/input/input.ts +79 -9
- package/src/input/inputHarness.ts +27 -2
- package/src/render/backend/materialChanges.ts +8 -3
- package/src/render/backend/webgl2/renderer.ts +223 -29
- package/src/render/backend/webgpu/buffers.ts +5 -0
- package/src/render/backend/webgpu/causticsPass.ts +2 -1
- package/src/render/backend/webgpu/depthPass.ts +4 -3
- package/src/render/backend/webgpu/filmPass.ts +2 -1
- package/src/render/backend/webgpu/flatPass.ts +43 -26
- package/src/render/backend/webgpu/linePass.ts +2 -1
- package/src/render/backend/webgpu/panelPass.ts +2 -1
- package/src/render/backend/webgpu/particlePass.ts +2 -1
- package/src/render/backend/webgpu/pipelineCache.ts +82 -8
- package/src/render/backend/webgpu/plumePass.ts +2 -1
- package/src/render/backend/webgpu/postPass.ts +20 -5
- package/src/render/backend/webgpu/renderer.ts +191 -37
- package/src/render/backend/webgpu/sdfTextPass.ts +2 -1
- package/src/render/backend/webgpu/textPass.ts +2 -1
- package/src/render/backend/webgpu/waterPass.ts +2 -1
- package/src/render/backend/webgpu/windStreakPass.ts +2 -1
- package/src/render/boltBatch.ts +2 -1
- package/src/render/causticsRenderer.ts +2 -1
- package/src/render/cutoutCaster.ts +15 -2
- package/src/render/decalPass.ts +2 -1
- package/src/render/globalMediumPass.ts +3 -2
- package/src/render/lineBatch.ts +3 -1
- package/src/render/mapsWithoutUvs.ts +43 -0
- package/src/render/mesh.ts +3 -0
- package/src/render/oitPass.ts +2 -1
- package/src/render/particleBatch.ts +3 -2
- package/src/render/particlePool.ts +107 -56
- package/src/render/pass.ts +12 -0
- package/src/render/plumeRenderer.ts +3 -2
- package/src/render/renderQuality.ts +16 -8
- package/src/render/sceneCoverage.ts +78 -0
- package/src/render/sdfTextRenderer.ts +2 -1
- package/src/render/shaders/depth.ts +3 -2
- package/src/render/shaders/flat/glassTint.ts +48 -0
- package/src/render/shaders/flat/index.ts +25 -2
- package/src/render/shaders/flat/main.ts +60 -25
- package/src/render/shaders/flat/surfaceEffects.ts +6 -2
- package/src/render/shaders/generated/depth.wgsl.ts +32 -12
- package/src/render/shaders/generated/flat.wgsl.ts +127 -38
- package/src/render/shaders/generated/line.wgsl.ts +1 -1
- package/src/render/shaders/generated/particle.wgsl.ts +3 -3
- package/src/render/shaders/generated/rush.wgsl.ts +1 -1
- package/src/render/shaders/generated/sdfText.wgsl.ts +1 -1
- package/src/render/shaders/generated/temporalResolve.wgsl.ts +1 -1
- package/src/render/shaders/outputTransform.ts +24 -1
- package/src/render/shaders/recon/resolve.wgsl.ts +15 -1
- package/src/render/shaders/rush.ts +13 -2
- package/src/render/shaders/temporalResolve.ts +12 -5
- package/src/render/ssrPass.ts +2 -1
- package/src/render/surfaceTexture.ts +16 -0
- package/src/render/textRenderer.ts +2 -1
- package/src/render/vertexDefaults.ts +1 -0
- package/src/render/viewModel.ts +41 -0
- package/src/render/waterRenderer.ts +2 -1
- package/src/render/windStreakRenderer.ts +2 -1
|
@@ -25,6 +25,7 @@ import { DEPTH_OF_FIELD_GLSL } from './depthOfField.ts';
|
|
|
25
25
|
import { AUTO_EXPOSURE_GLSL } from './exposure.ts';
|
|
26
26
|
import { LOCAL_EXPOSURE_GLSL } from './localExposure.ts';
|
|
27
27
|
import { FILM_LOOK_GLSL } from './filmLook.ts';
|
|
28
|
+
import { HIGHLIGHT_SHOULDER_GLSL } from './outputTransform.ts';
|
|
28
29
|
|
|
29
30
|
export const RUSH_FRAG = `#version 300 es
|
|
30
31
|
precision highp float;
|
|
@@ -242,9 +243,11 @@ vec3 acesFilmic(vec3 x) {
|
|
|
242
243
|
return clamp(ACES_OUTPUT * (a / b), 0.0, 1.0);
|
|
243
244
|
}
|
|
244
245
|
|
|
246
|
+
${HIGHLIGHT_SHOULDER_GLSL}
|
|
245
247
|
vec3 grade(vec3 c) {
|
|
246
248
|
if (uOutputTransform == 0) return c;
|
|
247
249
|
if (uOutputTransform == 2) c = acesFilmic(c);
|
|
250
|
+
if (uOutputTransform == 3) c = highlightShoulder(c * uOutputExposure);
|
|
248
251
|
return linearToSrgb(c);
|
|
249
252
|
}
|
|
250
253
|
|
|
@@ -335,7 +338,8 @@ vec3 finish(vec3 light) {
|
|
|
335
338
|
}
|
|
336
339
|
|
|
337
340
|
void main() {
|
|
338
|
-
|
|
341
|
+
vec4 sampled = textureLod(uScene, vUv, 0.0);
|
|
342
|
+
vec3 scene = sampled.rgb;
|
|
339
343
|
if (uMotionStrength > 0.0) scene = cameraBlur(scene);
|
|
340
344
|
/*
|
|
341
345
|
* Defocus after the camera smear and before everything else, because a lens is the last thing
|
|
@@ -350,8 +354,15 @@ void main() {
|
|
|
350
354
|
* not then darkened again along its own trail. mix from 1 rather than a multiply by the
|
|
351
355
|
* strength, so the parameter reads as "how much of this occlusion", and 0 is exactly the
|
|
352
356
|
* frame that existed before the effect did.
|
|
357
|
+
*
|
|
358
|
+
* **Scaled by the surface's share of the pixel**, which the scene carries in its alpha
|
|
359
|
+
* (sceneCoverage.ts): the occlusion was measured from the depth the opaque world left, and a
|
|
360
|
+
* pane, a puff of smoke or a caption in front of a corner wrote no depth, so darkening all of the
|
|
361
|
+
* pixel darkened them by a corner they hide. Where nothing blended landed the share is 1 and
|
|
362
|
+
* this is the frame it was.
|
|
353
363
|
*/
|
|
354
|
-
float
|
|
364
|
+
float share = clamp(sampled.a, 0.0, 1.0);
|
|
365
|
+
float ao = mix(1.0, textureLod(uAo, vUv + uAoOffset, 0.0).r, uAoStrength * share);
|
|
355
366
|
|
|
356
367
|
/*
|
|
357
368
|
* Distance from the centre, corrected so the falloff is a circle on screen rather than
|
|
@@ -211,11 +211,18 @@ vec3 historyCatmullRom(vec2 uv) {
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
void main() {
|
|
214
|
-
|
|
214
|
+
/*
|
|
215
|
+
* **The alpha is this frame's and takes no history.** It is how much of the pixel is still the
|
|
216
|
+
* opaque surface (sceneCoverage.ts), which the composite's occlusion reads after this has
|
|
217
|
+
* replaced the scene, so it passes through untouched. The history is read for its colour alone.
|
|
218
|
+
*/
|
|
219
|
+
vec4 sampled = textureLod(uScene, vUv, 0.0);
|
|
220
|
+
vec3 current = sampled.rgb;
|
|
221
|
+
float share = sampled.a;
|
|
215
222
|
|
|
216
223
|
/* Nothing to blend towards: the first frame, a resize, a cut, or the effect switched off. */
|
|
217
224
|
if (uHistoryBlend <= 0.0) {
|
|
218
|
-
fragColor = vec4(current,
|
|
225
|
+
fragColor = vec4(current, share);
|
|
219
226
|
flickerOut = freshRecord(current);
|
|
220
227
|
flickerMotionOut = vec4(0.0);
|
|
221
228
|
return;
|
|
@@ -248,7 +255,7 @@ void main() {
|
|
|
248
255
|
vec4 previous = uReprojection * clip;
|
|
249
256
|
/* Behind the previous eye: there is no last-frame position to sample. */
|
|
250
257
|
if (previous.w <= 0.0) {
|
|
251
|
-
fragColor = vec4(current,
|
|
258
|
+
fragColor = vec4(current, share);
|
|
252
259
|
flickerOut = freshRecord(current);
|
|
253
260
|
flickerMotionOut = vec4(metres, 0.0, 0.0, 0.0);
|
|
254
261
|
return;
|
|
@@ -261,7 +268,7 @@ void main() {
|
|
|
261
268
|
* as a smear for as long as the camera kept turning.
|
|
262
269
|
*/
|
|
263
270
|
if (wasUv.x < 0.0 || wasUv.x > 1.0 || wasUv.y < 0.0 || wasUv.y > 1.0) {
|
|
264
|
-
fragColor = vec4(current,
|
|
271
|
+
fragColor = vec4(current, share);
|
|
265
272
|
flickerOut = freshRecord(current);
|
|
266
273
|
flickerMotionOut = vec4(metres, 0.0, 0.0, 0.0);
|
|
267
274
|
return;
|
|
@@ -320,6 +327,6 @@ void main() {
|
|
|
320
327
|
repeated * still
|
|
321
328
|
);
|
|
322
329
|
flickerMotionOut = vec4(metres, swingOut, 0.0, 0.0);
|
|
323
|
-
fragColor = vec4(mix(current, bounded, blend),
|
|
330
|
+
fragColor = vec4(mix(current, bounded, blend), share);
|
|
324
331
|
}
|
|
325
332
|
`;
|
package/src/render/ssrPass.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { compileProgram, uniformLocations } from './shader.ts';
|
|
|
8
8
|
import { FULLSCREEN_VERT } from './shaders/fullscreen.ts';
|
|
9
9
|
import { SSR_RESOLVE_FRAG } from './shaders/ssrResolve.ts';
|
|
10
10
|
import { SSR_TRACE_FRAG } from './shaders/ssrTrace.ts';
|
|
11
|
+
import { blendKeeping } from './sceneCoverage.ts';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Screen-space reflection on WebGL2: a scissored trace per surface, then one composite.
|
|
@@ -202,7 +203,7 @@ export class SsrPass {
|
|
|
202
203
|
gl.disable(gl.CULL_FACE);
|
|
203
204
|
gl.enable(gl.BLEND);
|
|
204
205
|
/* Premultiplied `over`: the trace already multiplied its colour by the coverage it found. */
|
|
205
|
-
|
|
206
|
+
blendKeeping(gl, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
|
206
207
|
|
|
207
208
|
gl.useProgram(this.resolve);
|
|
208
209
|
gl.activeTexture(gl.TEXTURE0);
|
|
@@ -70,6 +70,17 @@ export interface SurfaceMaterial<Texture = SurfaceTexture> {
|
|
|
70
70
|
/** Repeats across the mesh's own UV range, per axis. Applies to every map the material holds. */
|
|
71
71
|
uScale?: number;
|
|
72
72
|
vScale?: number;
|
|
73
|
+
/**
|
|
74
|
+
* Where the texture starts, per axis, added after the scale: a surface samples
|
|
75
|
+
* `uv · scale + offset`. Applies to every map, and to a cutout's shadow and depth as well.
|
|
76
|
+
*
|
|
77
|
+
* **What picks a cell of a flipbook or an atlas through the material**, so one quad draws any
|
|
78
|
+
* cell: a strip of four frames is `uScale: 0.25` and `uOffset: frame * 0.25`. Without it a
|
|
79
|
+
* consumer built one quad mesh per cell — 106 meshes for four strips — because the only way to
|
|
80
|
+
* move a texture was to move the geometry's own coordinates.
|
|
81
|
+
*/
|
|
82
|
+
uOffset?: number;
|
|
83
|
+
vOffset?: number;
|
|
73
84
|
/** Alpha below which a fragment is discarded. See `uAlbedoCutout`. */
|
|
74
85
|
cutout?: number;
|
|
75
86
|
/**
|
|
@@ -335,6 +346,11 @@ export class SurfaceTexture {
|
|
|
335
346
|
}
|
|
336
347
|
|
|
337
348
|
/** Bind the effects table to `unit`, or `fallback` for a texture given none. */
|
|
349
|
+
/** Whether this texture carries an effects table, which the lit program reads only once one exists. */
|
|
350
|
+
get hasEffects(): boolean {
|
|
351
|
+
return this.effectsTable !== null;
|
|
352
|
+
}
|
|
353
|
+
|
|
338
354
|
bindEffects(gl: WebGL2RenderingContext, unit: number, fallback: WebGLTexture): void {
|
|
339
355
|
gl.activeTexture(gl.TEXTURE0 + unit);
|
|
340
356
|
gl.bindTexture(gl.TEXTURE_2D, this.effectsTable ?? fallback);
|
|
@@ -2,6 +2,7 @@ import type { TextStyle } from './textLayout.ts';
|
|
|
2
2
|
import { MAX_CELLS, TEXT_CUBE, TextLayout, deviceSnappedOrigin } from './textLayout.ts';
|
|
3
3
|
import { compileProgram, uniformLocations } from './shader.ts';
|
|
4
4
|
import { TEXT_FRAG, TEXT_VERT } from './shaders/text.ts';
|
|
5
|
+
import { blendCovering } from './sceneCoverage.ts';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Text as geometry, on WebGL2.
|
|
@@ -112,7 +113,7 @@ export class TextRenderer {
|
|
|
112
113
|
const reversed = current === gl.GREATER || current === gl.GEQUAL;
|
|
113
114
|
gl.depthFunc(reversed ? gl.GEQUAL : gl.LEQUAL);
|
|
114
115
|
gl.enable(gl.BLEND);
|
|
115
|
-
|
|
116
|
+
blendCovering(gl, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
116
117
|
|
|
117
118
|
setVec2(gl, this.uniforms['uViewport'], viewportWidth, viewportHeight);
|
|
118
119
|
/* Snapped with the cell below: a whole pitch on a fractional origin still splits a stroke.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The slice of depth a view model is drawn into: the nearest share of the range.
|
|
3
|
+
*
|
|
4
|
+
* **A first-person view model — arms and a held weapon — must never go into the wall it is pushed
|
|
5
|
+
* against**, and clearing depth to draw it on top costs every pass that reads depth afterwards:
|
|
6
|
+
* ambient occlusion, depth of field and the fog all see a hole where the world was. Squeezing the
|
|
7
|
+
* view model's depth into the nearest sliver of the range does neither. Anything past the near
|
|
8
|
+
* plane in the world lands behind it, the world's depth is kept, and the view model still sorts
|
|
9
|
+
* against itself, at a fraction of the precision.
|
|
10
|
+
*
|
|
11
|
+
* **The near end is where the convention says it is**: 1 under reversed depth and 0 under the
|
|
12
|
+
* conventional sense, which a WebGL2 context without `EXT_clip_control` runs. Taken from the
|
|
13
|
+
* renderer's own `reversedDepth`, never from the constant, for the reason `depthConvention.ts`
|
|
14
|
+
* gives at length.
|
|
15
|
+
*
|
|
16
|
+
* **What it gives up**: a view model is in front of everything, so it cannot be drawn reaching
|
|
17
|
+
* behind a world object in its own frame — which is what a view model is for. And under temporal
|
|
18
|
+
* reconstruction its pixels take no motion of their own, because the motion pass matches the frame's
|
|
19
|
+
* depth exactly and a squeezed draw matches nothing; draw a view model with multisampling.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/** The share of depth a view model is drawn into when the caller names none: the nearest 1%. */
|
|
23
|
+
export const VIEW_MODEL_DEPTH_SHARE = 0.01;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Fill `out` with the `[min, max]` window depth a view model's draws are squeezed into.
|
|
27
|
+
*
|
|
28
|
+
* `share` is clamped to `[1e-4, 1]`: zero would collapse every view-model fragment onto one depth
|
|
29
|
+
* and lose its own sorting, and more than the whole range is no squeeze.
|
|
30
|
+
*/
|
|
31
|
+
export function viewModelDepthRange(
|
|
32
|
+
reversed: boolean,
|
|
33
|
+
share: number,
|
|
34
|
+
out: [number, number] | Float32Array,
|
|
35
|
+
): void {
|
|
36
|
+
const width = Number.isFinite(share)
|
|
37
|
+
? Math.min(1, Math.max(1e-4, share))
|
|
38
|
+
: VIEW_MODEL_DEPTH_SHARE;
|
|
39
|
+
out[0] = reversed ? 1 - width : 0;
|
|
40
|
+
out[1] = reversed ? 1 : width;
|
|
41
|
+
}
|
|
@@ -10,6 +10,7 @@ import { bindPointLights } from './lightBudget.ts';
|
|
|
10
10
|
import type { PointLightSet } from './lightBudget.ts';
|
|
11
11
|
import { DEFAULT_RENDER_QUALITY } from './renderQuality.ts';
|
|
12
12
|
import { createResolvedWater, resolveWater, waterAppearance } from './waterDraw.ts';
|
|
13
|
+
import { blendCovering } from './sceneCoverage.ts';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* An endless wave surface. Game-agnostic: it takes a height, colours and a
|
|
@@ -325,7 +326,7 @@ export class WaterRenderer {
|
|
|
325
326
|
gl.uniform1i(u['uReflectionFilterTaps'] ?? null, this.reflectionFilterTaps);
|
|
326
327
|
|
|
327
328
|
gl.enable(gl.BLEND);
|
|
328
|
-
|
|
329
|
+
blendCovering(gl, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
329
330
|
// Waves are displaced far enough that back faces show at grazing angles.
|
|
330
331
|
gl.disable(gl.CULL_FACE);
|
|
331
332
|
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
type WindStreakSettings,
|
|
12
12
|
} from './windStreakDraw.ts';
|
|
13
13
|
import type { WindField } from './windField.ts';
|
|
14
|
+
import { blendCovering } from './sceneCoverage.ts';
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Makes the wind visible once it is strong enough to be worth seeing.
|
|
@@ -112,7 +113,7 @@ export class WindStreakRenderer {
|
|
|
112
113
|
gl.uniform3fv(u['uTint'] ?? null, tint);
|
|
113
114
|
|
|
114
115
|
gl.enable(gl.BLEND);
|
|
115
|
-
|
|
116
|
+
blendCovering(gl, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
116
117
|
gl.depthMask(false);
|
|
117
118
|
gl.disable(gl.CULL_FACE);
|
|
118
119
|
gl.bindVertexArray(this.vao);
|