1

I'm trying to use Three.js's MeshDepthMaterial, however it is not working quite how I am expecting. Maybe I misunderstand how the material is supposed to work, but I'd assume that it determines "how white" the material is at a given point using the camera's near and far settings from a given camera position. So if my camera is at (0, 0, 0) with a near of 1 and a far of 1000, and I have a cube place at (0, 0, -2), I'd assume that the cube would be very white (1 - .002 = 99.8% whiteness).

However, that has not been the case. Using a near and far of 1 and 10 respectively, with the back cube placed approximately 10 units away from the camera, this is how the material renders.

As you can see, the material for each cube is nearly all black, despite the nearest cube being 4 units closer.

As seen here, I have to get extremely close to the cube to see strong whiteness, and even then, the far corners of the cube which are not even 1 unit away are strongly gray.

These results also remain constant if I change the far to 1000 instead of 10.

Am I misunderstanding how MeshDepthMaterial works? Here's my code:

renderer: new THREE.WebGLRenderer({antailias:true, logarithmicDepthBuffer: true}),
scene: new THREE.Scene(),
camera: new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10)

....

this.renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer.setClearColor(new THREE.Color(0x00000, 1.0));
this.renderer.shadowMap.enabled = true;
this.scene.overrideMaterial = new THREE.MeshDepthMaterial();

this.camera.position.z = 4;

....

this.createCube(-3, 0, -4, "#FF1215");
this.createCube(0, 0, -2);
this.createCube(2, 0, 0, "#FF7232");

Where the parameters for createCube are the positions

josephoneill
  • 853
  • 2
  • 10
  • 33
  • 1
    At perspective projection the depth is not linear. See [this](https://stackoverflow.com/questions/7777913/how-to-render-depth-linearly-in-modern-opengl-with-gl-fragcoord-z-in-fragment-sh/45710371#45710371). You've to push the near plane as close to the geometry as possible, to get a "white" object. – Rabbid76 Aug 20 '19 at 17:09

1 Answers1

3

You're using logarithmicDepthBuffer: true, which changes the depth function to look more like this:

enter image description here

As you can see with a log function, you need to go really far down the x-axis (or bring the camera really close to the geometry) for the brightness to approach 1, since it's not a linear function. From your description, it sounds like you're expecting a linear depth buffer, which you can tell the renderer to use by setting:

logarithmicDepthBuffer: false

Or you can simply omit this option from the constructor, since linear depth is the default.

M -
  • 26,908
  • 11
  • 49
  • 81
  • That makes sense, but unfortunately even with it disabled, I still have the same issues as seen in this image: https://i.imgur.com/GK83OcM.png, with the same settings as above (1 as near, 1000 as far). The back cube is nearly completely black despite being set just a few units from the near setting of the frustum. Unless I have to explicitly set a parameter to use linear depth, I'm not sure what else to try – josephoneill Aug 20 '19 at 21:07
  • Any chance you can show a live example, maybe via https://codepen.io/ ? I don't know what's going on inside `createCube()`. It could be some odd scaling inside that method, or it could be something else entirely. – M - Aug 20 '19 at 22:19
  • Of course, for whatever reason the results are even more extreme in the codepen (both using r107). https://codepen.io/josephoneill/pen/yLBVKqq. I'm actually using Vue in the application I'm testing right now, all the rendering code being found here: https://pastebin.com/Abj8Lr2W – josephoneill Aug 21 '19 at 16:52
  • 1
    You might get slightly better results if you use `near: 1` and `far: 1000` [as you can see here](https://imgur.com/a/LzDSnfZ). However, you can only get a linear depth shading with an `OrthographicCamera`, as Rabbid76 explained in [his link above](https://stackoverflow.com/questions/7777913/how-to-render-depth-linearly-in-modern-opengl-with-gl-fragcoord-z-in-fragment-sh/45710371#45710371). If you want linear shading with a `PerspectiveCamera`, you'll need to write your own material with custom shaders. – M - Aug 21 '19 at 18:41