Why won't a MeshPhongMaterial's envMap
property work on polygonal faces when viewed through an orthographic camera?
It works on spheres but not an IcosahedronGeometry, for example. If I set the detail
parameter of the IcosahedronGeometry to 2+ (more faces), the envMap begins to show. But if I switch to perspective cam, the envMap is fully visible even with detail
of 0.
This is what it looks like with perspective cam, note the cubemap reflection of some clouds:
This is what it looks like with orthogonal cam and detail
is 0, note the lack of cubemap reflection (please ignore the warping of the image):
Orthogonal cam, detail
is 1; cubemap reflection is back:
The only difference between these two versions of the script is the camera.
Here's the code I'm using to create this object:
import uvGridImg from './img/grid.png';
import nxImg from './img/nx_50.png';
import pxImg from './img/px_50.png';
import nyImg from './img/ny_50.png';
import pyImg from './img/py_50.png';
import nzImg from './img/nz_50.png';
import pzImg from './img/pz_50.png';
const envTexture = new THREE.CubeTextureLoader().load([
pxImg, //right
nxImg, //left
pyImg, //top
nyImg, //bottom
pzImg, //back
nzImg, //front
])
envTexture.mapping = THREE.CubeReflectionMapping
const texture = new THREE.TextureLoader().load(uvGridImg)
const icosahedronGeometry = new THREE.IcosahedronGeometry(1, 0)
const material = new THREE.MeshPhongMaterial()
material.map = texture;
material.envMap = envTexture;
///An attempt to explicitly set every potentially relevant property...
material.envMapIntensity = 0.0;
material.transparent = false;
material.opacity = 1.0;
material.depthTest = true;
material.depthWrite = true;
material.alphaTest = 0.0;
material.visible = true;
material.side = THREE.FrontSide;
material.flatShading=true;
material.roughness = 0.0;
material.color.setHex(0xffffff);
material.emissive.setHex(0x0);
material.specular.setHex(0xffffff);
material.shininess = 30.0;
material.wireframe = false;
material.flatShading = false;
material.combine = THREE.MultiplyOperation;
material.reflectivity = 1.0;
material.refractionRatio = 1.0;
const icosahedron = new THREE.Mesh(icosahedronGeometry, material)
icosahedron.position.x = 0
scene.add(icosahedron);
For an MVCE, please see the example from this tutorial (you will have to add your own orthographic cam to compare with the given perspective cam). Here are image files for the textures.
UPDATE It seems like all non-spherical geometries cannot render a cubemap reflection correctly thru an orthographic cam. The plane, cylinder, box geometries all fail to render a environment map reflection beyond painting the entire face one uniform reflective color. The sphere, lathe, *hedron geometries (at high levels of detail) will render cubemap reflections.
Is there any way around this? This seems like a huge limitation while working with orthographic cameras.
This is the expected behavior.
See this demo I quickly put together to demonstrate what you're seeing:
You can see the reflections still work on your demo because the faces alternate between light and dark as you rotate them. You're just looking at a much narrower segment of the envMap: