如何解决WebGL:为什么将透明源颜色与不透明目标颜色混合永远不会变成原始源颜色?
在下面的示例中,我将 WebGL 画布背景颜色设置为 #444,使用 2 个不透明度为 1 的三角形绘制一个纯白色正方形,然后尝试通过多次绘制 2 个三角形来覆盖它以完全填充画布颜色为#444,不透明度为0.1。
我的期望是一段时间后画布颜色会变成#444,不透明度为1.0,即画布中间的白色方块会消失。但是当每个组件(r,g,b)中的背景颜色和与白色混合的叠加颜色之间的差异为5时,混合停止,因此您仍然可以看到正方形,尽管它被许多透明层完全覆盖与背景颜色相同。我测试了许多不同的颜色,但由于某种原因,每个组件的颜色差异始终为 5。
你能解释一下这个现象吗?
function createShader(gl,type,source) {
const shader = gl.createShader(type);
gl.shaderSource(shader,source);
gl.compileShader(shader);
const success = gl.getShaderParameter(shader,gl.COMPILE_STATUS);
if (success) {
return shader;
}
console.log(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
}
function createProgram(gl,vertexShader,fragmentShader) {
const program = gl.createProgram();
gl.attachShader(program,vertexShader);
gl.attachShader(program,fragmentShader);
gl.linkProgram(program);
const success = gl.getProgramParameter(program,gl.LINK_STATUS);
if (success) {
return program;
}
console.log(gl.getProgramInfoLog(program));
gl.deleteProgram(program);
}
let gl,colorLocation,opacityLocation,positionAttributeLocation;
function setupGL() {
const canvas = document.getElementById('canvas');
gl = canvas.getContext('webgl2',{
preserveDrawingBuffer: true
});
const vertex = `#version 300 es
in vec4 a_position;
void main() {
gl_Position = a_position;
}`;
const fragment = `#version 300 es
precision highp float;
out vec4 outColor;
uniform vec3 u_color;
uniform float u_opacity;
void main() {
outColor = vec4(u_color.xyz,u_opacity);
}`;
const triangleVertexShader = createShader(gl,gl.VERTEX_SHADER,vertex);
const triangleFragmentShader = createShader(gl,gl.FRAGMENT_SHADER,fragment);
const triangleProgram = createProgram(gl,triangleVertexShader,triangleFragmentShader);
gl.useProgram(triangleProgram);
colorLocation = gl.getUniformLocation(triangleProgram,"u_color");
opacityLocation = gl.getUniformLocation(triangleProgram,"u_opacity");
positionAttributeLocation = gl.getAttribLocation(triangleProgram,"a_position");
gl.enableVertexAttribArray(positionAttributeLocation);
gl.clearColor(0.2,0.2,1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
gl.useProgram(triangleProgram);
gl.vertexAttribPointer(
positionAttributeLocation,2,gl.FLOAT,false,0);
gl.blendFuncSeparate(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA,gl.ONE,gl.ONE_MINUS_SRC_ALPHA);
gl.enable(gl.BLEND);
gl.viewport(0,gl.canvas.width,gl.canvas.height);
}
function main() {
setupGL();
let triangles = new Float32Array(
[
-0.5,-0.5,0.5,-0.5
]
);
gl.uniform1f(opacityLocation,1.0);
gl.uniform3f(colorLocation,1,1);
gl.bufferData(gl.ARRAY_BUFFER,triangles,gl.STATIC_DRAW);
gl.drawArrays(gl.TRIANGLES,6);
gl.uniform1f(opacityLocation,0.1);
gl.uniform3f(colorLocation,0.2);
let transparentTriangles = new Float32Array(
[
-1,-1,-1
]
);
requestAnimationFrame(drawTriangles);
function drawTriangles() {
gl.bufferData(gl.ARRAY_BUFFER,transparentTriangles,gl.STATIC_DRAW);
gl.drawArrays(gl.TRIANGLES,6);
requestAnimationFrame(drawTriangles);
}
}
main();
html,body {
height: 100%;
}
#canvas {
width: 100%;
height: 100%;
}
<canvas id="canvas"></canvas>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。