WebGL 着色器不尊重形状方向

问题描述

我对 WebGL 非常陌生,我正在修改我在网上找到的一个现有项目以满足我的需求。

我的相机是等距的,我正在渲染两个立方体。我想在“地面”上有一个无限网格,就像在许多 3d 编辑器中一样。

您可以在下面看到网格不是无限的(我知道这是因为顶点仅从 -1 到 1),并且它的方向不正确。它直接在屏幕上呈现,而不考虑发送到 GPU 的变换矩阵。

enter image description here

由于涉及三个相互关联的程序(2个着色器,加上JS),我不知道错误在哪里。这是最相关的代码;该项目很大,所以如果您需要查看其他内容,请告诉我:

let vertices = [
    1.0,1.0,0.0,-1.0,0.0
];

let bufferObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,bufferObject);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW);

let attribute = shader.position; // getAttribLocation(...,'position')
gl.bindBuffer(gl.ARRAY_BUFFER,vertices);
gl.enabLevertexAttribArray(attribute);
gl.vertexAttribPointer(attribute,3,gl.FLOAT,false,0); // size of 3 is the only one that renders the quad

// this rotates the plane to be along the 'ground' - even without this,it stands up,and the grid still doesn't respect the orientation
(new Matrix()).rotateX(90).sendToGpu(gl,shader.model); // getUniformlocation(...,'model')
gl.drawArrays(gl.TRIANGLE_STRIP,4); // 4 vertices

顶点着色器:

attribute vec4 position;
attribute vec2 uv;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
varying vec2 vUv;

void main()
{
        vUv = uv;
        gl_Position = projection * view * model * position;
}

片段着色器:

precision mediump float;

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

vec2 offset = vec2(0,0);
vec2 pitch = vec2(32,32);

void main()
{
        float lX = gl_FragCoord.x / resolution.x;
        float lY = gl_FragCoord.y / resolution.y;

        float scaleFactor = 10000.0;

        float offX = (scaleFactor * offset[0]) + gl_FragCoord.x;
        float offY = (scaleFactor * offset[1]) + (1.0 - gl_FragCoord.y);

        if (int(mod(offX,pitch[0])) == 0 || int(mod(offY,pitch[1])) == 0)
        {
                gl_FragColor = vec4(0.0,0.2);
        }
        else
        {
                gl_FragColor = vec4(1.0,0.1);
        }
}

有人能指出我正确的方向吗?

解决方法

根据纹理坐标 (vUv) 而不是 gl_FragCoord.xy 生成网格。

添加纹理坐标属性:

let vertices = [
//   x     y    z     u    v
     1.0,1.0,0.0,-1.0,0.0   0.0,];

let bufferObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,bufferObject);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW);

gl.bindBuffer(gl.ARRAY_BUFFER,vertices);

let attribute = shader.position; // getAttribLocation(...,'position')
gl.enableVertexAttribArray(attribute);
gl.vertexAttribPointer(attribute,3,gl.FLOAT,false,5*4,0);

let attribute_uv = gl.getAttribLocation(...,'uv')
gl.enableVertexAttribArray(attribute_uv);
gl.vertexAttribPointer(attribute_uv,2,3*4);

在片段着色器中通过 offX 而不是 offY 设置 vUVgl_FragCoord.xy

// [...]

varying vec2 vUv;

void main()
{
    // float offX = (scaleFactor * offset[0]) + gl_FragCoord.x;
    // float offY = (scaleFactor * offset[1]) + (1.0 - gl_FragCoord.y);

    float scaleFactor = 32.0*8.0;
    float offX = scaleFactor * vUv.x;
    float offY = scaleFactor * vUv.y;

    // [...]
}