webgl2 渲染不透明和半透明三角形的问题

问题描述 投票:0回答:1

我正在使用 https://interactivecomputergraphics.com/ 上的示例进行工作。我的目标是有一个简单的示例来显示 alpha 与不透明和半透明三角形的混合。我有 6 个正方形(2 个三角形),每个都有不同的深度和不同的颜色。最近的(黄色)和最远的(蓝色)方块是不透明的(alpha = 1),中间的 4 个方块是半透明的(alpha = 0.5)。我启用 DEPTH_TEST,将 heightMask 设置为 true,并禁用 BLEND 来单独渲染不透明方块。然后我将深度掩码设置为 false 并启用混合来单独渲染半透明方块,从最远的开始到最近的结束。

我希望看到黄色方块始终位于顶部并且完全可见,但事实并非如此。我附上了所有 6 个方块都不透明时的输出屏幕截图。我已将我的代码作为片段包含在内。有什么想法吗?

/* eslint-disable require-jsdoc */
'use strict';

let gl;
let program;

let modelViewMatrix;
let projectionMatrix;
let modelViewMatrixLoc;
let projectionMatrixLoc;

const vertices = [
  vec4(-0.5, -0.5, 6.0, 1.0),
  vec4(-0.5, 0.5, 6.0, 1.0),
  vec4(0.5, 0.5, 6.0, 1.0),
  vec4(0.5, -0.5, 6.0, 1.0),
  vec4(-0.5, -0.5, 5.0, 1.0),
  vec4(-0.5, 0.5, 5.0, 1.0),
  vec4(0.5, 0.5, 5.0, 1.0),
  vec4(0.5, -0.5, 5.0, 1.0),
  vec4(-0.5, -0.5, 4.0, 1.0),
  vec4(-0.5, 0.5, 4.0, 1.0),
  vec4(0.5, 0.5, 4.0, 1.0),
  vec4(0.5, -0.5, 4.0, 1.0),
  vec4(-0.5, -0.5, 3.0, 1.0),
  vec4(-0.5, 0.5, 3.0, 1.0),
  vec4(0.5, 0.5, 3.0, 1.0),
  vec4(0.5, -0.5, 3.0, 1.0),
  vec4(-0.5, -0.5, 2.0, 1.0),
  vec4(-0.5, 0.5, 2.0, 1.0),
  vec4(0.5, 0.5, 2.0, 1.0),
  vec4(0.5, -0.5, 2.0, 1.0),
  vec4(-0.5, -0.5, 1.0, 1.0),
  vec4(-0.5, 0.5, 1.0, 1.0),
  vec4(0.5, 0.5, 1.0, 1.0),
  vec4(0.5, -0.5, 1.0, 1.0)];

const faceColors = [
  vec4(0.0, 0.0, 1.0, 1.0), // blue opaque
  vec4(0.0, 1.0, 0.0, 0.5), // green
  vec4(0.0, 1.0, 1.0, 0.5), // cyan
  vec4(1.0, 0.0, 0.0, 0.5), // red
  vec4(1.0, 0.0, 1.0, 0.5), // magenta
  vec4(1.0, 1.0, 0.0, 1.0)]; // yellow opaque

const positions = [];
const colors = [];

const near = 0;
const far = 10;
const left = -1.0;
const right = 1.0;
const bottom = -1.0;
const topp = 1.0;

const eye = vec3(0.0, 0.0, -1.0);
const at = vec3(0.0, 0.0, 0.0);
const up = vec3(0.0, 1.0, 0.0);

window.onload = function() {
  const canvas = document.getElementById('gl-canvas');

  gl = canvas.getContext('webgl2');
  if (!gl) {
    alert('WebGL 2.0 is not available');
  }

  // get the data ready for rendering
  colourSquares();

  gl.viewport(0, 0, canvas.width, canvas.height);
  gl.clearColor(0.5, 0.5, 0.5, 1.0);
  gl.enable(gl.DEPTH_TEST);

  //
  //  Load shaders and initialize attribute buffers
  //
  program = initShaders(gl, 'vertex-shader', 'fragment-shader');
  gl.useProgram(program);

  const cBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW);
  const colorLoc = gl.getAttribLocation(program, 'aColor');
  gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(colorLoc);

  const vBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, flatten(positions), gl.STATIC_DRAW);
  const positionLoc = gl.getAttribLocation(program, 'aPosition');
  gl.vertexAttribPointer(positionLoc, 4, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(positionLoc);

  modelViewMatrixLoc = gl.getUniformLocation(program, 'uModelViewMatrix');
  projectionMatrixLoc = gl.getUniformLocation(program, 'uProjectionMatrix');

  render();
};

function render() {
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  projectionMatrix = ortho(left, right, bottom, topp, near, far);
  gl.uniformMatrix4fv(projectionMatrixLoc, false, flatten(projectionMatrix));
  // draw opaque squares, writing into depth buffer
  gl.depthMask(gl.TRUE);
  gl.disable(gl.BLEND);
  for (let i = 0; i < 6; i += 5) {
    modelViewMatrix = mult(lookAt(eye, at, up),
        mult(translate(0.5 * Math.random() - 0.25, 0.5 * Math.random() - 0.25, 0.0),
            rotateZ(360.0 * Math.random())));
    gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(modelViewMatrix));
    gl.drawArrays(gl.TRIANGLES, 6 * i, 6);
  }

  // draw translucent squares, not writing into depth buffer
  gl.depthMask(gl.FALSE);
  gl.enable(gl.BLEND);
  gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
  for (let i = 1; i < 5; i++) {
    modelViewMatrix = mult(lookAt(eye, at, up),
        mult(translate(0.5 * Math.random() - 0.25, 0.5 * Math.random() - 0.25, 0.0),
            rotateZ(360.0 * Math.random())));
    gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(modelViewMatrix));
    gl.drawArrays(gl.TRIANGLES, 6 * i, 6);
  }
  setTimeout(
      function() {
        requestAnimationFrame(render);
      },
      5000);
}

function colourSquares() {
  square(1, 0, 3, 2, 0); // opaque
  square(5, 4, 7, 6, 1);
  square(9, 8, 11, 10, 2);
  square(13, 12, 15, 14, 3);
  square(17, 16, 19, 18, 4);
  square(21, 20, 23, 22, 5); // opaque
}

function square(a, b, c, d, clr) {
  // store data for the square as 2 triangles (6 vertices)
  const indices = [a, b, c, a, c, d];

  for (let i = 0; i < indices.length; ++i) {
    positions.push(vertices[indices[i]]);
    colors.push(faceColors[clr]);
  }
}
<!DOCTYPE html>
<html>
<script id="vertex-shader" type="x-shader/x-vertex">
    #version 300 es

    in  vec4 aPosition;
    in  vec4 aColor;
    out vec4 vColor;

    uniform mat4 uModelViewMatrix;
    uniform mat4 uProjectionMatrix;

    void main()
    {
        gl_Position = uProjectionMatrix * uModelViewMatrix * aPosition;
        vColor = aColor;
    }
</script>

<script id="fragment-shader" type="x-shader/x-fragment">
#version 300 es

precision mediump float;

in vec4 vColor;
out vec4 fColor;

void
main()
{
    fColor = vColor;
}
</script>

<script type="text/javascript" src="https://interactivecomputergraphics.com/8E/Code/Common/initShaders.js"></script>
<script type="text/javascript" src="https://interactivecomputergraphics.com/8E/Code/Common/MVnew.js"></script>

    <body>
        <canvas id="gl-canvas" width="512"" height="512">
            Your browser does not support the HTML5 canvas element
        </canvas>
    </body>
</html>

alphablending depth-buffer webgl2
1个回答
0
投票

看起来

gl.true
未定义。尝试简单地使用
true
,因为它在这种情况下对我有用。 (与
gl.false
同样的问题)

© www.soinside.com 2019 - 2024. All rights reserved.