david.stack
david.stack

Reputation: 13

THREE.ShaderMaterial depth information lost

In my scene I have two overlapping / crossing plane meshes. The first one uses a MeshBasicMaterial and the second one a custom ShaderMaterial (simple cut-out fragment shader). It seems as if the mesh with the ShaderMaterial doesn't have any depth information as the other plane is always rendered on top of it.

How can I add the plane mesh with the ShaderMaterial to the scene so the collisions and overlapping with other meshes is shown correctly? Do I have to do this in the fragment shader or is it something I have to set up in the material?

Edit: I've made two different variants: A and B. A: works as it should, both Plane Meshes have depth information and use the MeshBasicMaterial:

var movieMaterial = new THREE.MeshBasicMaterial( { map: videoTexture, overdraw: true, side:THREE.DoubleSide } );

Screenshot of Variant A, two crossing Plane Meshes using MeshBasicMaterial
Screenshot of Variant A, two crossing Plane Meshes using MeshBasicMaterial

Variant B uses a custom ShaderMaterial on one Plane Mesh:

    var movieMaterial = new THREE.ShaderMaterial({
    uniforms: {
      texture: { type: "t", value: videoTexture }
    },
    vertexShader: [
        "varying vec2 vUv;",
        "void main() {",
            "vUv = uv;",
            "gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);",
        "}",
    ].join("\n"),
    fragmentShader: [
        "varying vec2 vUv;",
        "uniform sampler2D texture;",
        "void main() {",
            "gl_FragColor = texture2D(texture, vUv);",
            "if (gl_FragColor.r + gl_FragColor.b + gl_FragColor.g > 1.5) discard;",
        "}",
    ].join("\n"),
    side:THREE.DoubleSide
});  

Screenshot of Variant B, now one Plane Mesh is using a custom ShaderMaterial Screenshot of Variant B, now one Plane Mesh is using a custom ShaderMaterial

And now the depth information is lost. The code I posted is the only difference here.

Thanks in advance

Upvotes: 1

Views: 913

Answers (1)

Longi
Longi

Reputation: 3973

This is an old question but I've recently come across this problem. The issue was with the usage of the logarithmic depth buffer. The shaders passed to the ShaderMaterial do not work with it out of the box. Option one is to disable the logarithmic depth buffer. Option two is to append a few pieces of glsl code to your shaders provided by three, something like this:

import { ShaderChunk } from 'three';

const VertexShader = ShaderChunk.common + '\n' + ShaderChunk.logdepthbuf_pars_vertex + `
  ...
  void main() {
    ...
    ` + ShaderChunk.logdepthbuf_vertex + `
  }
`;

const FragmentShader = ShaderChunk.logdepthbuf_pars_fragment + `
  ...
  void main() {
    ...
    ` + ShaderChunk.logdepthbuf_fragment + `
  }
`;

Upvotes: 6

Related Questions