WebGL:移动设备上的Z缓冲区工件

WebGL:移动设备上的Z缓冲区工件,webgl,shader,Webgl,Shader,我有WebGL上下文,我正在渲染房间和家具的3d模型。它在个人电脑上工作正常,但当我在房间里,我的近飞机靠近相机时,它会在移动设备上给我奇怪的z形格斗效果 当我的剪裁平面远离相机时,即使在移动设备上,一切都正常: 近距离:4267.639824060027,远距离:11183.900282644734 projectionMatrix=[1.9196896450555059,0,0,0,0,1.732050807568774,0,0,0,0,0,0,-2.234082350944259,-1,

我有WebGL上下文,我正在渲染房间和家具的3d模型。它在个人电脑上工作正常,但当我在房间里,我的近飞机靠近相机时,它会在移动设备上给我奇怪的z形格斗效果

当我的剪裁平面远离相机时,即使在移动设备上,一切都正常:

近距离:4267.639824060027,远距离:11183.900282644734

projectionMatrix=[1.9196896450555059,0,0,0,0,1.732050807568774,0,0,0,0,0,0,-2.234082350944259,-1,0,0,-13801.866294355888,0]

但是什么时候

zLimits={near:30,far:5960.493230110447}

projectionMatrix=[1.9196896450555059,0,0,0,0,1.732050807568774,0,0,0,0,0,0,-1.010117203425247,-1,0,0,-60.30351607027574,0]

图片因第一个物体的z形格斗和三角形损坏,距离第二个物体1000个单位,在第二个物体三角形后面不断闪烁

PS:我尝试在我的着色器中使用

precision highp float
precision highp int
和gl.getShaderPrecisionFormat(gl.VERTEX_着色器,gl.HIGH_FLOAT);导致 WebGLShaderPrecisionFormat{rangeMin:127,rangeMax:127,精度:23} 但这对我没有任何影响

gl.getParameter(gl.DEPTH_位)返回24

我有两个渲染路径(使用深度分量32f向前和延迟),它们都提供相同的artfifacts

PPS:我通过使用ThreeJS render的应用程序在同一台设备上打开类似的场景,它渲染的场景大小相似,没有任何瑕疵

PPPS:用于正向渲染的我的顶点和片段着色器

export const geometry = new ShaderProgram(
    // vertex shader
    `
    precision highp float;
    uniform mat4 u_transformMatrix;
    uniform mat4 u_modelViewMatrix;
    uniform mat4 u_meshMatrix;
    uniform vec3 u_viewDir;

    attribute vec4 a_position;
    attribute vec3 a_normal;
    attribute vec2 a_texcoord;

    varying float v_lighting;
    varying vec3 v_normal;
    varying vec3 v_position;
    varying vec2 v_texcoord;

    void main(void)
    {
        vec4 vertex4 = u_meshMatrix * a_position;
        vec3 normal = (u_meshMatrix * vec4(a_normal, 0.0)).xyz;
        v_normal = (u_modelViewMatrix * vec4(normal, 0.0)).xyz;;
        v_position = (u_modelViewMatrix * vertex4).xyz;
        gl_Position = u_transformMatrix * vertex4;
        v_lighting = min(abs(dot(normal, u_viewDir)) + 0.4, 1.0);
        v_texcoord = a_texcoord;
    }
    `
    ,
    // fragment shader
    `
    precision highp float;
    uniform lowp vec4 color;
    uniform lowp float u_selection;
    uniform sampler2D u_texture;
    uniform lowp float u_opacity;
    uniform lowp vec2 u_textureOffset;
    uniform lowp vec2 u_textureScale;

    varying float v_lighting;
    varying vec2 v_texcoord;
    varying vec3 v_normal;
    varying vec3 v_position;

    void main(void)
    {
        vec3 cur_color = vec3(0.0, 1.0, 1.0);
        float ligtMapVal = v_lighting;
        vec2 texCoord = (v_texcoord + u_textureOffset) * u_textureScale;
        vec3 texColor = texture2D(u_texture, texCoord).xyz;
        //vec3 texColor = vec3(0.4, 0.4, 0.6);
        vec3 selectionColor = vec3(0.0, 0.0, 1.0);
        vec3 color = mix(texColor, selectionColor, u_selection);

        vec3 lightDirection = normalize(vec3(1.0, 1.0, 1.0));
        float diffuseWeight = max(dot(v_normal, vec3(0, 0, 1)) + 0.2, 0.5);

        vec3 eyeDirection = normalize(-v_position);
        vec3 halfVector = normalize(lightDirection + eyeDirection);
        float uShininess = 25.1;
        float specularWeight = pow(max(dot(v_normal, halfVector), 0.0), uShininess);

        vec3 lightSpecular = vec3(1.0, 1.0, 1.0);
        gl_FragColor = vec4(color * diffuseWeight + specularWeight * lightSpecular, u_opacity);
    }
`
);

问题的主要根源是我编译了一些具有mediump精度的着色器。它们甚至不会被渲染路径使用,而是首先加载。 删除这些着色器可以修复该问题


感谢伟大的文档进一步优化它

问题的主要来源是我编译了一些具有mediump精度的着色器。它们甚至不会被渲染路径使用,而是首先加载。 删除这些着色器可以修复该问题


感谢伟大的文档进一步优化它

您是否尝试过使用不同的深度函数享受阅读:您是否尝试过使用不同的深度函数享受阅读: