feat: restore and document the GPU-powered wind showcase - #699
Conversation
CoverageStmts: 51.03% ▼-0.14% | Branch: 42.11% ▼-0.07% | Funcs: 49.21% ▼-0.08% | Lines: 51.14% ▼-0.14%
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ae9a0c7da5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| nextParticlePosition = vec4( | ||
| nextPosition, | ||
| wind.z * windParticle.elevationScale + windParticle.surfaceOffset, | ||
| age |
There was a problem hiding this comment.
Resample elevation after choosing a respawn position
When a particle expires or leaves valid coverage, the shader chooses a new nextPosition but still derives its elevation from wind, which was sampled at the old position. Invalid particles therefore respawn at surfaceOffset, while expired particles inherit unrelated terrain elevation; on the next update the altitude is corrected and can produce a large vertical trail segment. The WGSL path mirrors this logic, so both backends should resample elevation at the selected candidate position.
Useful? React with 👍 / 👎.
| const fromDirection = from[0] % WIND_DIRECTION_EAST.length; | ||
| const toDirection = to[0] % WIND_DIRECTION_EAST.length; | ||
| east += | ||
| weight * | ||
| ((1 - frameMix) * WIND_DIRECTION_EAST[fromDirection] + | ||
| frameMix * WIND_DIRECTION_EAST[toDirection]); |
There was a problem hiding this comment.
Compute fractional direction vectors instead of indexing the table
When callers construct a WindField with fractional direction values, which are allowed by the public WindMeasurement number type and were supported by the previous trigonometric calculation, WIND_DIRECTION_EAST[fromDirection] and its peers evaluate to undefined. The subsequent zero-vector guard does not catch the resulting NaNs, so sampleWindField returns a non-null sample with invalid direction and velocity. Compute these values trigonometrically or restrict and validate the public input before indexing.
Useful? React with 👍 / 👎.
| modules: [ | ||
| ...shaders.modules, | ||
| windParticleTrailClip, | ||
| ...(this.context.device.type === 'webgl' ? [windParticleAgeFade] : []) | ||
| ] |
There was a problem hiding this comment.
Add lifetime fading on the WebGPU path
On a WebGPU device this conditional omits windParticleAgeFade from the trail shader, and the analogous head-layer conditional does the same; no other WebGPU shader consumes getParticleAge. Consequently WebGPU particles retain constant alpha and pop when respawned rather than receiving the lifetime fade promised by the ParticleLayer API documentation. Add a WGSL-compatible fade or explicitly limit the documented behavior to WebGL.
Useful? React with 👍 / 👎.
| model.shaderInputs.setProps({ | ||
| windParticlePoint: { | ||
| color: [color[0] / 255, color[1] / 255, color[2] / 255, (color[3] ?? 255) / 255], | ||
| pointSize: Math.max(1, pointRadiusPixels * 2) |
There was a problem hiding this comment.
Apply inherited opacity to WebGL particle heads
When a consumer sets ParticleLayer's inherited opacity below 1 on WebGL, this custom point shader receives alpha derived only from color; unlike the trail LineLayer and the WebGPU ScatterplotLayer, it never multiplies by the layer opacity. This leaves particle heads brighter or visible while their trails correctly fade, so the uniform alpha should incorporate this.props.opacity or use deck.gl's standard layer/color shader handling.
Useful? React with 👍 / 👎.
Summary
Restore Nicolas Belmonte's historical deck.gl wind showcase as reusable, documented
@deck.gl-community/geo-layersAPIs, preserving the original 72-hour United States weather-station forecast while moving particle advection back onto the GPU.The reference implementation is the historical deck.gl wind showcase. The standalone and website examples import the reusable public community layers instead of carrying a second private showcase implementation.
GPU particles and performance
Terrain, data, and review feedback
delaunatorstation triangulation, including skinny-hull regression coverage.Documentation and public API
All new wind surfaces are explicitly marked work in progress.
ParticleLayer,WindLayer,ElevationLayer,DelaunayCoverLayer, andDelaunayInterpolationreferences with working code and live inline examples.WindFieldOptionsand complete public field-utility import coverage.Validation
yarn lint-fixand whitespace/diff review.WebGPU compatibility
ParticleLayerand the backend-independent forecast utilities are verified on WebGL2 and WebGPU. The complete mountain-and-arrows showcase remains work in progress on WebGPU becauseTerrainLayer,SolidPolygonLayer, andPathLayerdepend on upstream backend support.