Repository navigation
feat: Add planar reflections to StandardMaterial - #9902
Conversation
The polished floor of the area lights room keeps its lit material and replaces only its environment reflection chunk with the planar reflection, blurred by roughness using the mipmaps of the texture. Adds an opt-in hdr attribute to the PlanarRenderer script, rendering linear colors into a half-float texture.
Build size reportThis PR changes the size of the minified bundles.
|
- StandardMaterial#planarReflectionMap and #planarReflectionMatrix replace the environment reflections of the material with a planar reflection texture, while the environment keeps providing the ambient lighting - PlanarRenderer#viewProjectionMatrix returns the matrix projecting world positions into the texture - The planar reflection example uses them instead of overriding the reflection shader chunk
Public API reportThis PR changes the public API surface (+3 / −0), per the docs' rules (@ignore / @Private / undocumented are excluded). Show API diff+StandardMaterial.get planarReflectionMatrix(): Mat4
+StandardMaterial.planarReflectionMap: Texture | null
+StandardMaterial.set planarReflectionMatrix(value: Mat4)Informational only — this never fails the build. |
mvaligursky
left a comment
There was a problem hiding this comment.
Automated PR review by Codex (OpenAI AI agent), posted through the account holder's authorized automated review process.
Reviewed 855234c against b2a7693. Checked material defaults/copying/uniform updates and shader invalidation, environment versus planar reflection selection, ambient/refraction interactions, both shader implementations, and the PlanarRenderer matrix/HDR integration. One actionable P2 is reported inline: disabling HDR does not restore the reflection camera's LDR color-processing state.
Validation: 4,572 unit tests passing (43 pending), 4,570 native WebGPU/Metal tests passing (40 pending), and 81 bundle tests passing. Builds and consumer type tests pass. Eight additional native tests cover seven planar shader variants plus the script's HDR target and view-projection matrix. Chrome/WebGL2 also compiled and drew all seven variants without GL or shader errors: plain, clear coat, sheen, normal mapping, dynamic refraction with a scene-color grab, material ambient, and scene ambient. A browser probe reproduced the HDR toggle issue.
Changed source/script/build-helper ESLint and diff whitespace checks pass. The material test file's lint is not clean because the existing configuration rejects its Mocha/Chai patterns; the same categories of errors occur on the base revision. The Engine conventions skill guided temporary probes; repository source was not modified.
Limitations: shader execution and camera state were validated, but the production reflection example was not visually compared and reflection quality/performance across scenes was not benchmarked.
| if (this._texture.format === PIXELFORMAT_RGBA16F) { | ||
| planarCamera.toneMapping = TONEMAP_NONE; | ||
| planarCamera.gammaCorrection = GAMMA_NONE; | ||
| } |
There was a problem hiding this comment.
[P2] Restore the LDR camera settings when HDR is disabled
This override is one-way, although updateRenderTarget() supports changing hdr at runtime. With a planar camera configured for TONEMAP_ACES / GAMMA_SRGB, I reproduced hdr = false -> true -> false: the texture returns to PIXELFORMAT_SRGBA8, but the camera remains TONEMAP_NONE / GAMMA_NONE rather than its original settings. The LDR pass therefore no longer uses its configured tone mapper (or tone-mapping exposure), and high-intensity colors can clip instead of following the original LDR rendering path. Please preserve and restore the non-HDR camera settings when leaving the HDR format, including a fallback to LDR, and add a toggle regression test.
Automated review by Codex (OpenAI AI agent).
mvaligursky
left a comment
There was a problem hiding this comment.
Automated PR review by Codex (OpenAI AI agent), posted through the account holder's authorized automated review process.
Re-reviewed f1af31e and the follow-up to the HDR transition finding. The previous P2 is fixed; no new actionable findings.
The original Chrome/WebGL2 reproduction now returns to TONEMAP_ACES / GAMMA_SRGB after hdr = false -> true -> false, with the expected LDR/HDR/LDR texture formats. Expanded native WebGPU probes also pass for resizing while HDR is active, restoring settings on half-float capability fallback, entering HDR again after changing the LDR settings, switching back while the camera is disabled, and restoring settings / releasing the target when the script is destroyed. The seven planar shader variants still compile and draw without GL or WebGPU validation errors.
Validation: 4,572 unit tests passing (43 pending), 4,570 native WebGPU/Metal tests passing (40 pending), 81 bundle tests passing, and 9 additional focused native tests passing. Engine builds (cache hits for unchanged engine outputs), consumer type tests, updated-script ESLint, and diff whitespace checks pass. The Engine conventions skill guided the temporary probes; repository source was not modified.
There are no outstanding actionable findings from my reviews. Limitations remain: no visual comparison of the production example or cross-scene reflection quality/performance benchmark.
Adds planar reflection support to
StandardMaterial. A material can reflect a texture rendered by a camera mirrored by the plane of its surface, for example by thePlanarRendererscript, giving exact reflections on floors, mirrors and water while keeping its full lighting.Changes:
StandardMaterialtakes a planar reflection texture and the view projection matrix of the camera that rendered it. The texture replaces only the environment reflections: lights, shadows and fresnel are unchanged, and the environment of the material or the scene keeps providing the ambient lightinguseDynamicRefraction), as the texture holds no environment to refractPlanarRendererscript provides the matrix for the material, and can render a high dynamic range texture, so bright light sources keep their brightness in the reflectionAPI Changes:
StandardMaterial#planarReflectionMap(Texture|null, defaultnull) andStandardMaterial#planarReflectionMatrix(Mat4, copied into the material)PlanarRenderer#viewProjectionMatrixgetter (scripts/esm/planar-renderer.mjs), updated byframeUpdate()PlanarRendererattributehdr,falseby default. When enabled and the device can render to half-float textures, the texture isPIXELFORMAT_RGBA16F, and the camera renders linear colors withTONEMAP_NONEandGAMMA_NONE, leaving tone mapping and gamma correction to the camera rendering the materialExamples:
graphics/reflection-planaris rebuilt to use the new material properties: a lit, polished floor in the area lights room, with a Cubemap mode for comparison and controls for the resolution and roughness