问题
Material shines through when zooming out (three.js r78)
When zooming out to a certain extend the material of objects behind other objects starts to shine through. It looks very similar to the effect when faces are overlapping (faces are in the same plane).
To demonstrate this I made a fiddle.
In this example I draw two thin boxes (thickness 1 and there is a empty space between the boxes of also 1) so the boxes are not touching eachother but the material shines through anyway.
// geometry with thickness 1
var geometry = new THREE.BoxGeometry(20000, 20000, 1);
This screenshot demonstrates the effect:

This screenshot shows there is a space between the two geometries.

When zooming the effect sometimes appears and sometimes disappears (it is also depending on zoom distance and the size of the screen).
I tried to play around with different material properties, but I seem to be unable to find any material setting that prevents this from happening.
Is this a bug? Or a WebGL limitation? Or a general limitation in 3D graphics? Or am I missing something and is this actually a material or renderer configuration mistake?
In my models this effect is really disturbing and ugly. Can I somehow prevent this from happening?
回答1:
This problem is caused by a faulty configuration that severely limits the depth buffer precision.
On OpenGL.org it is described as follows:
You may have configured your
zNear
andzFar
clipping planes in a way that severely limits your depth buffer precision. Generally, this is caused by azNear
clipping plane value that's too close to0.0
. As thezNear
clipping plane is set increasingly closer to0.0
, the effective precision of the depth buffer decreases dramatically. Moving thezFar
clipping plane further away from the eye always has a negative impact on depth buffer precision, but it's not one as dramatic as moving thezNear
clipping plane.
True, since in the example the near clipping plane value was set to 1
.
So far I know two solutions to this problem.
1) Simply increase the camera near
value:
// camera
camera = new THREE.PerspectiveCamera(
45, window.innerWidth / window.innerHeight,
500, // <-- Increased near from 1 to 500
150000
);
This solution is demonstrated in this fiddle
- The solution was suggested by @WestLangley here on GitHub
- Refer to that OpenGL.org page for more background information
- Here a nice question about deciding on your near clipping plane values
2) Configure the WebGL renderer to use a logarithmic depth buffer:
// renderer
renderer = new THREE.WebGLRenderer({
antialias: true,
logarithmicDepthBuffer: true // <-- Set render to use logarithmic depth buffer
});
This solution is demonstrated in this fiddle
- This solution was suggested by @FastSnail in his comment and comes from this answer on StackOverflow
- See also an OpenGL demo on logarithmic VS normal depth buffer in this YouTube movie
- And another demo specifically for three.js / WebGL in this YouTube movie
- Refer also to this StackOverflow question for more background on logarithmic depth buffer
Please post another answer in case you know any other solutions.
来源:https://stackoverflow.com/questions/37858464/material-shines-through-when-zooming-out-three-js-r78