shaderMaterial: render-order with logarithmicDepthBuffer is wrong

Hi, In my renderer there is a logarithmicDepthBuffer and also I want to use shaderMaterial on my meshesh. However, when I add shaderMaterial, its renderOrder gets stuck. Could you help ?

White sphere is without shader while red has a shader.


The usage of a logarithmic depth buffer requires the enhancement of your custom shader with internal shader chunks. Have you already done this in your app?

Actually, I am not sure but on my renderer, there is logDepthBuffer. Also, I am creating a customShaderMaterial like that


const uniforms = {
	time: { value: 0.0 },
	speed: { value: 18.0 },
	charSize: { value: { x: 2.0, y: 1.5 } },
	charResolution: { value: 0.0 },
	color: { value: new THREE.Color('green') },
	resolution: { value: { x: 1.0, y: 1.0 } },
};
const _VS = `

// Set the precision for data types used in this shader
precision highp float;
precision highp int;

varying vec2 vUv;

void main() {

    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

}`;
const _FS = `
// Based on https://www.shadertoy.com/view/MlfXzN
precision highp float;
precision highp int;

uniform float time;
uniform float speed;

uniform vec2 charSize;
uniform float charResolution;
uniform vec3 color;
uniform vec4 backgroundColor;
uniform vec2 resolution;

varying vec2 vUv;

float seed = 2.0;

float random( float x ) {
    return fract( sin( x ) * 43758.5453 );
}

float random( vec2 st ) {
    return fract( sin( dot( st.xy, vec2( 12.9898, 78.233 ) ) ) * 43758.5453 );
}

float randomChar( vec2 outer, vec2 inner ) {
    vec2 margin = 1.0 - charSize;
    vec2 borders = step( margin, inner ) * step( margin, 1.0 - inner );
    return step(
        0.5,
        random( outer * seed + floor( inner * charResolution ) )
    ) * borders.x * borders.y;
}

vec4 matrix( vec2 st ) {
    float rows = 50.0;
    vec2 ipos = floor( st * rows ) + vec2( 1.0, 0.0 );

    ipos += vec2( 0.0, floor( time * speed * random( ipos.x ) ) );

    vec2 fpos = fract( st * rows );
    vec2 center = 0.5 - fpos;

    float pct = random( ipos );
    float glow = ( 1.0 - dot(center,center) * 3.0 ) * 2.0;

    float result = randomChar( ipos, fpos ) * pct * glow;
    return vec4( color * result, result );
}

void main() {
    
	vec2 st = vUv * resolution;
	gl_FragColor = vec4(0.0,0.0,0.0,1.0)+ matrix( st );
	
}
`;
export const customShader = new THREE.ShaderMaterial({
	uniforms: uniforms,
	vertexShader: _VS,
	fragmentShader: _FS,
});

Try it with:

const _VS = `

// Set the precision for data types used in this shader
precision highp float;
precision highp int;

#include <common>
#include <logdepthbuf_pars_vertex>

varying vec2 vUv;

void main() {

    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
    #include <logdepthbuf_vertex>

}`;
const _FS = `
// Based on https://www.shadertoy.com/view/MlfXzN
precision highp float;
precision highp int;

uniform float time;
uniform float speed;

uniform vec2 charSize;
uniform float charResolution;
uniform vec3 color;
uniform vec4 backgroundColor;
uniform vec2 resolution;

#include <common>
#include <logdepthbuf_pars_fragment>

varying vec2 vUv;

float seed = 2.0;

float random( float x ) {
    return fract( sin( x ) * 43758.5453 );
}

float random( vec2 st ) {
    return fract( sin( dot( st.xy, vec2( 12.9898, 78.233 ) ) ) * 43758.5453 );
}

float randomChar( vec2 outer, vec2 inner ) {
    vec2 margin = 1.0 - charSize;
    vec2 borders = step( margin, inner ) * step( margin, 1.0 - inner );
    return step(
        0.5,
        random( outer * seed + floor( inner * charResolution ) )
    ) * borders.x * borders.y;
}

vec4 matrix( vec2 st ) {
    float rows = 50.0;
    vec2 ipos = floor( st * rows ) + vec2( 1.0, 0.0 );

    ipos += vec2( 0.0, floor( time * speed * random( ipos.x ) ) );

    vec2 fpos = fract( st * rows );
    vec2 center = 0.5 - fpos;

    float pct = random( ipos );
    float glow = ( 1.0 - dot(center,center) * 3.0 ) * 2.0;

    float result = randomChar( ipos, fpos ) * pct * glow;
    return vec4( color * result, result );
}

void main() {

	#include <logdepthbuf_fragment>
	vec2 st = vUv * resolution;
	gl_FragColor = vec4(0.0,0.0,0.0,1.0)+ matrix( st );
	
}
`;

There are four logdepthbuf* chunks as well as the common chunk added to your code.

5 Likes

So much thanks @Mugen87 , it has worked :smile: What was the reason of that issue?

Do you mean why is it necessary to include the mentioned shader chunks?

1 Like
#include <common>
#include <logdepthbuf_pars_vertex>
#include <logdepthbuf_vertex>

@Chaser_Code Iā€™m afraid your code snippet is misleading. It only shows the vertex shaders chunks and it is not clear how they should be integrated in the program. E.g. logdepthbuf_vertex must be in the main() method at a specific place.

For the logarithmic depth buffer all materials need to alter the depth writing the logarithmic depth to gl_FragDepth for correct depth testing, you need to do it yourself in ShaderMaterial but since the shader chunks for it are very universal you can just use them.

1 Like