【发布时间】:2017-12-14 08:29:44
【问题描述】:
您可以在下面找到有关 LUMINANCE_ALPHA 的原始问题,但我意识到我的问题是错误的。 真正的问题应该是:
我们如何有效地检查使用 webgl 绘制的画布上的输出值?
使用 webgl 画布作为图像在 2D 画布中绘制它并使用 getImageData() 获取值是个好主意吗?
const webglCanvas = ...;
const offCanvas = document.createElement('canvas');
offCanvas.style.background = 'black';
offCanvas.width = canvas.width;
offCanvas.height = canvas.height;
const context = offCanvas.getContext('2d');
context.drawImage(webglCanvas, 0, 0);
console.log( context.getImageData(0, 0, canvas.width, canvas.height).data );
原问题:
我不明白 gl.LUMINANCE_ALPHA 是如何工作的,据我了解,它应该获取 2 乘 2 字节并将第一个值分配给 rgb,将第二个值分配给 alpha。 但是,当我使用 webgl 执行此操作时:
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE_ALPHA, 1, 1, 0, gl.LUMINANCE_ALPHA, gl.UNSIGNED_BYTE, new Uint8Array([1, 30]));
我得到(8, 8, 8, 30) 的颜色,而我期待(1, 1, 1, 30)。
我从those specs 得到这个定义:
每个元素都是亮度/alpha 双精度值。 GL 将每个分量转换为浮点数,钳制在 [0,1] 范围内,并通过将亮度值放置在红色、绿色和蓝色通道中,将它们组合成一个 RGBA 元素。
不确定这如何应用于 webgl,因为没有双精度。也许我错过了converts each component to floating point 的含义或缺少一些打包/解包配置。
这是一个复制问题的 sn-p:
const vertShaderStr = `
attribute vec2 a_position;
void main() {
gl_Position = vec4(a_position, 0, 1);
}
`;
const fragShaderStr = `
precision mediump float;
uniform sampler2D u_texture;
void main() {
gl_FragColor = texture2D(u_texture, vec2(0, 0));
}
`
var canvas = document.getElementById('canvas');
canvas.width = 1;
canvas.height = 1;
const gl = canvas.getContext('webgl');
const program = gl.createProgram();
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertShaderStr);
gl.compileShader(vertexShader);
if ( !gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS) )
throw new Error('Vertex shader error', gl.getShaderInfoLog(vertexShader));
gl.attachShader(program, vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragShaderStr);
gl.compileShader(fragmentShader);
if ( !gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS) )
throw new Error('Fragment shader error', gl.getShaderInfoLog(fragmentShader));
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if ( !gl.getProgramParameter(program, gl.LINK_STATUS) )
throw new Error(gl.getProgramInfoLog(program));
gl.useProgram(program);
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
1, 1,
-1, 1,
1, -1,
-1, -1
]), gl.STATIC_DRAW);
const positionLocation = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
/*** Interresting part here ***/
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 2);
gl.pixelStorei(gl.PACK_ALIGNMENT, 2);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE_ALPHA, 1, 1, 0, gl.LUMINANCE_ALPHA, gl.UNSIGNED_BYTE,
new Uint8Array([1, 30]));
gl.activeTexture(gl.TEXTURE0);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
const offCanvas = document.createElement('canvas');
offCanvas.style.background = 'black';
offCanvas.width = canvas.width;
offCanvas.height = canvas.height;
const context = offCanvas.getContext('2d');
context.drawImage(canvas, 0, 0);
console.log( context.getImageData(0, 0, canvas.width, canvas.height).data );
<canvas id="canvas"></canvas>
更新
刚刚发现alpha值(30)会影响生成的rgb。但是我不知道到底在做什么,是使用 alpha 来计算 rgb 还是从缓冲区中读取了错误的字节。
【问题讨论】:
-
不鼓励使用外部服务进行代码提琴,以便随着时间的推移保持问题的完整性,请在未来使用 SO 内置的代码提琴选项。
标签: webgl