three.js
three.js copied to clipboard
WebGLRenderer: Add support for rotating env maps.
Fixed #16328.
Description
This PR adds a frequent requested feature to WebGLRenderer
: The ability to rotate environment maps.
Instead of adding a new property to Texture
level, I've realized a more clean approach by adding:
-
Scene.backgroundRotation
which controls the rotation of the scene's background as suggested in https://github.com/mrdoob/three.js/issues/16328#issuecomment-486926253. -
envMapRotation
for all materials which supportenvMap
.
Both new properties are of type Euler
. Environment maps in the equirectangular, cube map and cuveUV (PMREM) format can be rotated now.
I'll add documentation when the PR is accepted and merged.
📦 Bundle size
Full ESM build, minified and gzipped.
Filesize dev |
Filesize PR | Diff |
---|---|---|
676.4 kB (168.2 kB) | 678 kB (168.6 kB) | +1.65 kB |
🌳 Bundle size after tree-shaking
Minimal build including a renderer, camera, empty scene, and dependencies.
Filesize dev |
Filesize PR | Diff |
---|---|---|
457.2 kB (111 kB) | 458.4 kB (111.3 kB) | +1.2 kB |
In what coordinate frame is the background Euler rotation applied? I assume you intend it to be the three.js right-hand coordinate frame. In the shader, the coordinate frame is left-handed.
In this PR, the background rotation around the x-axis is backwards from the expected convention. A sign flip may fix that.
Do you intend to add support for rotating scene.environment
?
I assume you intend it to be the three.js right-hand coordinate frame.
Yes. I was a bit unsure about the point of reference when judging the direction of rotations for env maps. I hope the last commit fixes the x-axis issue.
Do you intend to add support for rotating scene.environment?
Users can already achieve that by modifying the new envMapRotation
property of their PBR materials. This makes it also consistent with envMapIntensity
which is a per-material property only as well.
I would only add an additional option if users struggle with the existing solution.
Hmmm... I think scene.environmentRotation
is more likely to be used than material.envMapRotation
.
I think it would be better to add support for scene.environmentRotation
first, and after that we can see if people really need material.envMapRotation
.
The problem with this approach is that Scene.environment
only applies to MeshStandardMaterial
. Hence, basic, lambert and phong materials which do support environment maps can't align their reflections to the rotated background.
How about we add Scene.environmentRotation
additionally?
I also think it's in general more flexible to have the ability to rotate environment maps directly in the material (if we don't provide a per texture setting).
How about we add
Scene.environmentRotation
additionally? When set, it overshadowsMeshStandardMateraial.envMapRotation
like withenvMap
.
That sounds good to me.
I guess scene.environmentRotation
would be new Euler()
by default so the renderer will actually have to check if scene.environment === null
to then use material.envMap
and material.envMapRotation
, right?
Yes, I think we can nicely put this check in getProgram()
and save the result in the material properties.
Okay, Scene.environmentRotation
has been added. It only affects physical materials and only if Scene.environment
is used.
The reflections and rotations are not correct. I'll file a PR in an attempted fix.
Unfortunately, getting these calculations correct has taken considerable effort...