在webgl中绘制简单的正方形

在webgl中绘制简单的正方形,webgl,Webgl,我有一个非常基本的问题。我是webgl新手,正在尝试画一个简单的正方形。我正在使用gl矩阵库进行矩阵操作 Javascript代码: squareVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); vertices = [ 0.9, 0.9, 0.0,1.0, -0.9, 0.9, 0.0

我有一个非常基本的问题。我是webgl新手,正在尝试画一个简单的正方形。我正在使用gl矩阵库进行矩阵操作

Javascript代码:

squareVertexPositionBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
    vertices = [
         0.9,  0.9,  0.0,1.0,
        -0.9,  0.9,  0.0,1.0,
         0.9, -0.9,  0.0,1.0,
        -0.9, -0.9,  0.0,1.0

    ];


    squareVertexPositionBuffer.itemSize = 4;
    squareVertexPositionBuffer.numItems = 4;

    mat4.identity(pMatrix);
    mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);
    mat4.identity(mvMatrix);
    mat4.translate(mvMatrix, [-1.5, 0.0, -7.0]);

    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,         squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
    setMatrixUniforms();
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems);
着色器:

attribute vec3 aVertexPosition;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;

varying vec3 debug;


void main(void) {
    gl_Position =  uPMatrix * uMVMatrix * vec4(aVertexPosition.xyz, 1.0);
    debug = aVertexPosition;
}
这似乎很好。在这里,我将模型视图和透视矩阵作为统一体传递给着色器程序,并将它们与那里的顶点坐标相乘。但是如果将javascript中的模型视图和透视矩阵相乘,然后将修改后的顶点传递给着色器,那么它似乎不起作用


我看不出这个错误。非常感谢您的帮助

我立刻注意到几个问题:

1) 顶点着色器输入属性与传递给VertexAttribute指针的参数不匹配:

指定属性为4浮动宽度,但顶点着色器将其指定为vec3。这些应该是一致的

2) 我没有看到对EnableVertexAttributeArray的调用,类似于:

gl.enableVertexAttributeArray(shaderProgramm.vertexPositionAttribute)

必须启用顶点着色器使用的顶点属性数组

3) 从显示的代码中,您只指定了一个模型矩阵(标识、转换)。您需要创建一个视图矩阵。一个简单的方法是调用mat4.lookAt。其定义如下:

mat4.lookAt=功能(眼睛、中心、向上、目标)

眼睛是相机的位置 “中心”是相机正在查看的位置 up应始终为(0,1,0)

例如:

眼睛=(0,0,1) 中心=(0,0,0)

这将使相机1装置沿正Z轴向下,并使其注视原点

将其与模型矩阵相乘将得到模型视图矩阵


代码缺失太多,因此很难确定您的错误是否存在于其他地方。例如,片段着色器的作用是什么


当尝试在屏幕上显示第一个基本体时,我建议禁用剔除和深度测试。如果片段输出与清晰颜色匹配,还可以随时间改变清晰颜色


约翰

我立刻注意到几个问题:

1) 顶点着色器输入属性与传递给VertexAttribute指针的参数不匹配:

指定属性为4浮动宽度,但顶点着色器将其指定为vec3。这些应该是一致的

2) 我没有看到对EnableVertexAttributeArray的调用,类似于:

gl.enableVertexAttributeArray(shaderProgramm.vertexPositionAttribute)

必须启用顶点着色器使用的顶点属性数组

3) 从显示的代码中,您只指定了一个模型矩阵(标识、转换)。您需要创建一个视图矩阵。一个简单的方法是调用mat4.lookAt。其定义如下:

mat4.lookAt=功能(眼睛、中心、向上、目标)

眼睛是相机的位置 “中心”是相机正在查看的位置 up应始终为(0,1,0)

例如:

眼睛=(0,0,1) 中心=(0,0,0)

这将使相机1装置沿正Z轴向下,并使其注视原点

将其与模型矩阵相乘将得到模型视图矩阵


代码缺失太多,因此很难确定您的错误是否存在于其他地方。例如,片段着色器的作用是什么


当尝试在屏幕上显示第一个基本体时,我建议禁用剔除和深度测试。如果片段输出与清晰颜色匹配,还可以随时间改变清晰颜色


John

John回答中概述的问题值得研究,但如果您现在正在正确渲染原语,那么我认为它们不是这个问题的根本原因

我将答案分为两部分,因为我不确定哪种情况适用于您:

  • 您没有展示如何构建MVP的JavaScript版本,但请仔细检查乘法语法是否正确。其形式应为:

    mat4.multiply(p, mv, mvp);
    
    其中,
    p
    是投影矩阵,
    mv
    是模型视图矩阵,
    mvp
    是接收模型视图投影矩阵(结果将存储在其中)

  • 同样,如果要对顶点位置本身进行预乘,则正确的语法为:

    mat4.multiplyVec4(mvp, vertex, transformedVertex);
    
    其中,
    mvp
    是modelview投影矩阵,
    vertex
    是未修改的顶点(a
    vec4
    ),而
    transformedVertex
    是将存储值的接收
    vec4
    。如果使用这种方法,在将顶点数组发送到GPU之前,必须将它们展平为单个连续的浮点数组

    小心不要将
    mat4.multiplyVec3
    mat4.multiplyVec4
    混淆。在乘法之前,
    顶点
    的第四个分量应设置为
    1
    ;这样,GPU可以使用
    transformedVertex
    的第四个组件执行透视分割(这会自动发生,但需要发送正确的值)

    还请注意,如果错误地将
    vec3
    属性发送到GPU,并且该属性实际上是
    vec4
    类型,则第四个组件默认为1.0。这通常很方便,但如果在JavaScript中预乘这些值,也可能导致棘手的错误。正如John所说,尽量使着色器定义与JavaScript端保持一致;从长远来看,这将减少混乱


    • John回答中概述的问题值得研究,但如果您现在正在正确渲染原语,那么我认为它们不是这个问题的根本原因

      我将答案分为两部分,因为我不确定哪种情况适用于您:

      • 您没有展示如何构建JavaScrip