首页 > 解决方案 > 为什么位置向量的最后一个元素会导致颜色为纯色

问题描述

在附加的代码中,我尝试使用其纹理坐标绘制一个三角形。我希望结果是渐变色。但结果却是纯色。

原因是这一行:

gl_Position = vec4(a_position.x, a_position.y, 0.0, 0.0);

位置的最后一个数字是 0.0。如果我将其更改为 1.0,颜色将是渐变。为什么?

var vertexShaderSource = `#version 300 es
// an attribute is an input (in) to a vertex shader.
// It will receive data from a buffer
in vec2 a_position;
in vec2 a_texcoord;
out vec2 v_texcoord;

// all shaders have a main function
void main() {
  // Multiply the position by the matrix.
  gl_Position = vec4(a_position.x, a_position.y, 0.0, 0.0);

  // Pass the texcoord to the fragment shader.
  v_texcoord = a_texcoord;
}
`;

var fragmentShaderSource = `#version 300 es

precision highp float;

// Passed in from the vertex shader.
 in vec2 v_texcoord;

// The texture.
// uniform sampler2D u_texture;

// we need to declare an output for the fragment shader
out vec4 outColor;

void main() {
  //outColor = texture(u_texture, v_texcoord);
  outColor = vec4(v_texcoord.x, v_texcoord.y, 0.0, 1.0);
}
`;


    const canvas = document.querySelector('#imageA');

    const gl = canvas.getContext('webgl2');

    gl.viewportWidth = canvas.width;
    gl.viewportHeight = canvas.height;

    gl.clearColor(0.0,0.0,0.0,1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    var program = webglUtils.createProgramFromSources(gl,[vertexShaderSource, fragmentShaderSource]);

    // look up where the vertex data needs to go.
    var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
    var texcoordAttributeLocation = gl.getAttribLocation(program, "a_texcoord");

    // Create a vertex array object (attribute state)
    //var vao = gl.createVertexArray();

    // and make it the one we're currently working with
   // gl.bindVertexArray(vao);

    // look up uniform locations
    //  var textureLocation = gl.getUniformLocation(program, "u_texture");

    var positions = new Float32Array(
    [
     -1.0,  1.0,
     1.0,  1.0, 
     -1.0,   -1.0, 
     1.0,   -1.0, 
    ]);

    var texCoords = new Float32Array(
    [
     0.0,  0.0,
     1.0,  0.0, 
     1.0,   1.0, 
     0.0,   1.0, 
    ]);
    // Tell it to use our program (pair of shaders)
    gl.useProgram(program);
    // Create a buffer
    var positionBuffer = gl.createBuffer();

    // Turn on the attribute

    // Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    // Set Geometry.
    gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);

    gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(positionAttributeLocation);


    var texcoordBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);

    // Set Geometry.
    gl.bufferData(gl.ARRAY_BUFFER, texCoords, gl.STATIC_DRAW);

    gl.vertexAttribPointer(texcoordAttributeLocation, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(texcoordAttributeLocation);



    // Tell WebGL how to convert from clip space to pixels
   // gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    // turn on depth testing
   // gl.disable(gl.DEPTH_TEST);

    // tell webgl to cull faces
   // gl.disable(gl.CULL_FACE);



    // Bind the attribute/buffer set we want.
    //gl.bindVertexArray(vao);

    gl.drawArrays(gl.TRIANGLES, 0, 3);
<html>
<head>
    <title>
        test
    </title>
</head>

<canvas id="imageA" width="640" height="480"></canvas>
<script src="https://webgl2fundamentals.org/webgl/resources/webgl-utils.js"></script>

</html>

标签: opengl-esshaderwebgl2

解决方案


正如其他人间接指出的那样,变量的计算如下

result = (1 - t) * a / aW + t * b / bW
         -----------------------------
            (1 - t) / aW + t / bW

当变量设置为 时设置的aWW 是哪里,而变量设置为时设置的 W 是哪里。gl_Position.wabWgl_Position.wb

所以设置gl_Position.w= 0 会有一些问题

https://webgl2fundamentals.org/webgl/lessons/webgl-3d-perspective-correct-texturemapping.html


推荐阅读