fix: Use dynamic loop count for VolumetricFog and TSL soft particles#1167
Conversation
VolumetricFog.ts: - Replace hardcoded Loop(32) with Loop(128) + early exit based on uSteps uniform - Quality presets now properly control raymarch step count at runtime AdvancedParticleSystem.ts: - Replace MeshBasicMaterial with TSL MeshBasicNodeMaterial - Implement soft particle depth-aware alpha fade - Add setDepthTexture(), updateCamera(), setSoftness() methods for integration - Particles now properly fade when approaching scene geometry https://claude.ai/code/session_01AKCzEWNpJbJo9dZjBTcNgV
MeshBasicNodeMaterial doesn't accept constructor arguments like regular materials - properties must be set individually after instantiation. https://claude.ai/code/session_01AKCzEWNpJbJo9dZjBTcNgV
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1f17cebbcd
ℹ️ 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".
| // Get screen-space coordinates for depth sampling | ||
| const screenUV = viewportCoordinate.xy; | ||
|
|
||
| // Sample scene depth and convert to linear | ||
| const sceneDepthSample = texture(depthTex, screenUV).r; |
There was a problem hiding this comment.
Sample depth with normalized viewport UVs
viewportCoordinate is defined in TSL as pixel-space coordinates (see node_modules/three/src/nodes/display/ScreenNode.js around the viewportCoordinate/viewportUV definitions). Passing pixel units directly into texture() means the depth lookup will be out of [0,1] for most fragments and clamp to edges, so the soft-fade will read a near-constant depth and won’t correctly fade near geometry. Use viewportUV (or divide by viewportSize) for normalized sampling.
Useful? React with 👍 / 👎.
| // Get particle's linear depth from gl_FragCoord.z | ||
| const particleNDC = viewportCoordinate.z.mul(2.0).sub(1.0); | ||
| const particleLinearDepth = near.mul(far).div( |
There was a problem hiding this comment.
Avoid swizzling .z from viewportCoordinate
viewportCoordinate is a vec2 in TSL (pixel-space x/y), so viewportCoordinate.z is an invalid swizzle. This will emit an invalid shader expression or undefined value for the particle depth, breaking the linear-depth calculation and potentially failing material compilation. Use a depth-specific node like viewportDepth/viewportLinearDepth or another supported fragment-depth source instead.
Useful? React with 👍 / 👎.
VolumetricFog.ts:
AdvancedParticleSystem.ts:
https://claude.ai/code/session_01AKCzEWNpJbJo9dZjBTcNgV