webgl - alpha 如何在禁用混合的 webGL 中工作?
问题描述
我在点模式下渲染了几个顶点,禁用了混合,下面是相关代码:
var canvas = htmlToElement('<canvas width="100" height="100" style="margin:auto;display:block;"></canvas>');
document.body.appendChild(canvas);
gl = canvas.getContext('experimental-webgl');
var vertices = [
-0.5, 0.5, 0.0,
0.0, 0.5, 0.0,
];
var vertLen = vertices.length / 3;
var vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
var vertShader = createShader(document.getElementById('vert').textContent, gl.VERTEX_SHADER);
var fragShader = createShader(document.getElementById('frag').textContent, gl.FRAGMENT_SHADER);
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
var coord = gl.getAttribLocation(shaderProgram, "coordinates");
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(coord);
gl.clearColor(0, 0, 0, 1);
gl.enable(gl.DEPTH_TEST);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.viewport(0, 0, canvas.width, canvas.height);
gl.disable(gl.BLEND);
//gl.blendEquation(gl.FUNC_ADD);
//gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
gl.drawArrays(gl.POINTS, 0, vertLen);
这是片段着色器:
<script type='x-shader/x-fragment' id='frag'>
void main(void) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);
}
</script>
这就是我得到的:
这张图片上的红色是 [255,27,32]。
所以我的问题是,在没有混合的情况下,将半透明红色转换为 [255,27,32] 的公式是什么?
我认为它在OpenGL中是一样的吗?
解决方案
你是什么意思它是[255,27,32]?你是怎么得到那个号码的?
就像所有 HTML 元素一样,该<canvas>
元素与 HTML 页面的其余部分混合,因此“通常”如果您将 1、0、0、0.5 放入片段着色器中,那么 255、0、0、127 将写入画布中。
然后画布将与页面混合。画布后面的内容取决于您的 CSS。也许你有<canvas style="background: purple;"></canvas>
或者你的 CSS 设置为
body {
background: #123456;
}
背景可以是您设置的任何内容
默认情况下,画布将被混合,假设画布内的颜色使用“预乘 alpha”,这意味着颜色 (255, 0, 0, 127) 是无效颜色。
预乘 alpha 表示 R、G 和 B 已乘以 alpha。当 R 为 1 且 alpha 0.5 时,最高 R 可以为 0.5(因为 1.0 乘以 0.5 为 0.5)
因此,在这种情况下发生的事情在 HTML 规范中是未定义的。
premultipledAlpha: false
您可以通过在创建 WebGL 上下文时传递来告诉浏览器使用未预乘的 alpha 在画布之上绘制画布。alpha: false
您还可以在创建上下文时关闭画布中的 alpha 。(虽然 IIRC 在 Safari 中不起作用,但 Safari 是新的 IE
例子:
test('#normal', {});
test('#unpremultiplied-alpha', {premultipliedAlpha: false});
test('#no-alpha', {alpha: false});
function test(selector, options) {
const canvas = document.querySelector(selector);
const gl = canvas.getContext('webgl', options);
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.enable(gl.SCISSOR_TEST);
gl.scissor(32, 32, 64, 64);
gl.clearColor(0.5, 0.25, 0.125, 0.5);
gl.clear(gl.COLOR_BUFFER_BIT);
}
/* make the background stripes */
html, body {
height: 100%;
background: repeating-linear-gradient(
45deg,
lime,
lime 10px,
orange 10px,
orange 20px
);
}
canvas {
border: 1px solid black;
}
<canvas width="128" height="128" id="normal"></canvas>
<canvas width="128" height="128" id="unpremultiplied-alpha"></canvas>
<canvas width="128" height="128" id="no-alpha"></canvas>
推荐阅读
- python - 如何在不耗尽内存的情况下将 14,000 个图像数据集加载到变量中?
- javascript - 如何在本机反应中创建带有数据表的单选按钮部分?
- vue.js - Vue
使用 v-move 类时不触发? - java - 有人可以编码并解释合并排序的合并部分吗?
- neo4j - Neo4J 4 + Apoc:无法为程序“静态”设置注入
- docker - Ubuntu 和 Docker:来自守护进程的错误响应:创建挂载源路径时出错
- r - 将嵌套的 json 文件读入 R 并写入 csv
- matlab - 如何使用 cvpartion 将数据集拆分为训练/验证/测试?
- javascript - jQuery:上传前的多图像尺寸验证
- android - ListPopupWindow 动画在文本字段中开始,而不是在其下方