如何正确检查webgl输出
你可以在下面找到关于亮度α的原始问题,但我意识到我的问题是错的。 真正的问题应该是: 如何有效地检查使用webgl绘制的画布上的输出值? 使用webgl画布作为图像在2D画布中绘制并使用getImageData获取值是一个好主意吗如何正确检查webgl输出,webgl,Webgl,你可以在下面找到关于亮度α的原始问题,但我意识到我的问题是错的。 真正的问题应该是: 如何有效地检查使用webgl绘制的画布上的输出值? 使用webgl画布作为图像在2D画布中绘制并使用getImageData获取值是一个好主意吗 const webglCanvas = ...; const offCanvas = document.createElement('canvas'); offCanvas.style.background = 'black'; offCanvas.width =
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
我从以下方面得到了这个定义:
每个元素都是亮度/阿尔法双精度。GL将每个组件转换为浮点,钳制到范围[0,1],并通过将亮度值放置在红色、绿色和蓝色通道中,将它们组合为RGBA元素
不确定这如何应用于webgl,因为没有双精度。也许我缺少了将每个组件转换为浮点的方法,或者缺少了一些打包/解包配置
下面是一个复制问题的片段:
常量vertShaderStr=`
属性向量2 a_位置;
真空总管{
gl_位置=vec4a_位置,0,1;
}
`;
常数fragShaderStr=`
精密中泵浮子;
均匀的二维u_纹理;
真空总管{
gl_FragColor=纹理2 du_纹理,向量20,0;
}
`
var canvas=document.getElementById'canvas';
宽度=1;
高度=1;
const gl=canvas.getContext'webgl';
const program=gl.createProgram;
const vertexShader=gl.createShadergl.VERTEX_着色器;
gl.shaderSourcevertexShader,vertShaderStr;
gl.compileShadervertexShader;
如果gl.getShaderParametervertexShader,gl.COMPILE\U状态
抛出新错误“顶点着色器错误”,gl.getShaderInfoLogvertexShader;
gl.attachShaderprogram,vertexShader;
const fragmentShader=gl.createShadergl.FRAGMENT\u着色器;
gl.shaderSourcefragmentShader,fragShaderStr;
gl.compileShaderfragmentShader;
如果gl.getShaderParameterfragmentShader,gl.COMPILE\u状态
抛出新错误'Fragment shader Error',gl.getShaderInfoLogfragmentShader;
gl.attachShaderprogram,fragmentShader;
gl.linkProgramprogram;
如果gl.getProgramParameterprogram,gl.LINK\U状态
抛出新的Errorgl.getProgramInfoLogprogram;
gl.useprogrammProgram;
const positionBuffer=gl.createBuffer;
gl.bindbuffer gl.ARRAY_BUFFER,positionBuffer;
gl.bufferDatagl.ARRAY\U缓冲区,新浮点数组[
1, 1,
-1, 1,
1, -1,
-1, -1
],gl.静态图;
const positionLocation=gl.getAttriblLocationProgram“a_position”;
gl.EnableVertexAttributeArrayPositionLocation;
gl.bindbuffer gl.ARRAY_BUFFER,positionBuffer;
gl.VertexAttributePointerPositionLocation,2,gl.FLOAT,false,0,0;
常量纹理=gl.createTexture;
gl.bindTexturegl.TEXTURE_2D,纹理;
/***这里是相互关联的部分***/
gl.pixelStoreigl.UNPACK_校准,2;
gl.pixelStoreigl.PACK_校准,2;
gl.texImage2Dgl.TEXTURE\u 2D,0,gl.LUMINANCE\u ALPHA,1,1,0,gl.LUMINANCE\u ALPHA,gl.UNSIGNED\u字节,
新的UINT8阵列[1,30];
gl.activeTexturegl.TEXTURE0;
gl.drawArraysgl.TRIANGLE_带,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.drawImagecanvas,0,0;
console.log context.getImageData0,0,canvas.width,canvas.height.data;
将webgl画布绘制到另一个2d画布转换时,将应用过滤和混合操作,这可能会导致结果扭曲。虽然您可以通过将2d上下文上的globalCompositeOperation设置为copy来禁用混合,但您仍在运行转换和筛选过程,该过程未标准化,也不能保证提供精确的结果 使用返回正确的结果,这是从当前颜色帧缓冲区获得保证准确读数的唯一方法。如果需要该数据可用于二维上下文,则可以与结合使用 常量vertShaderStr=` 属性向量2 a_位置; 真空总管{ gl_位置=vec4a_位置,0,1; } `; 常数fragShaderStr=` 精密中泵浮子; 均匀的二维u_纹理; 真空总管{ gl_FragColor=纹理2 du_纹理,向量20,0; } ` var canvas=document.getElementById'canvas'; 宽度=1; 高度=1; const gl=canvas.getContext'webgl'; const program=gl.createProgram; const vertexShader=gl.createShadergl.VERTEX_着色器; gl.shaderSourcevertexShader,vertShaderStr; gl.compileShadervertexShader; 如果gl.getShaderParametervertexShader,gl.COMPILE\U状态 抛出新错误“顶点着色器错误”,gl.getShaderInfoLogvertexShader; gl.attachShaderprogram,vertexShader; const fragmentShader=gl.createShadergl.FRAGMENT\u着色器; gl.shaderSourcefragmentShader,fragShaderStr; gl.compileShaderfragmentShader; 如果gl.getShaderParameterfragmentShader,gl.COMPILE\u STAT 我们 抛出新错误'Fragment shader Error',gl.getShaderInfoLogfragmentShader; gl.attachShaderprogram,fragmentShader; gl.linkProgramprogram; 如果gl.getProgramParameterprogram,gl.LINK\U状态 抛出新的Errorgl.getProgramInfoLogprogram; gl.useprogrammProgram; const positionBuffer=gl.createBuffer; gl.bindbuffer gl.ARRAY_BUFFER,positionBuffer; gl.bufferDatagl.ARRAY\U缓冲区,新浮点数组[ 1, 1, -1, 1, 1, -1, -1, -1 ],gl.静态图; const positionLocation=gl.getAttriblLocationProgram“a_position”; gl.EnableVertexAttributeArrayPositionLocation; gl.bindbuffer gl.ARRAY_BUFFER,positionBuffer; gl.VertexAttributePointerPositionLocation,2,gl.FLOAT,false,0,0; 常量纹理=gl.createTexture; gl.bindTexturegl.TEXTURE_2D,纹理; /***这里是相互关联的部分***/ gl.pixelStoreigl.UNPACK_校准,2; gl.pixelStoreigl.PACK_校准,2; gl.texImage2Dgl.TEXTURE\u 2D,0,gl.LUMINANCE\u ALPHA,1,1,0,gl.LUMINANCE\u ALPHA,gl.UNSIGNED\u字节, 新的UINT8阵列[1,30]; gl.activeTexturegl.TEXTURE0; gl.drawArraysgl.TRIANGLE_带,0,4; var readback=新的Uint8Array4; gl.readPixels0,0,1,1,gl.RGBA,gl.UNSIGNED_字节,readback; const offCanvas=document.createElement'canvas'; offCanvas.style.background='black'; offCanvas.width=canvas.width; offCanvas.height=canvas.height; const context=offCanvas.getContext'2d'; context.globalCompositeOperation='copy'; context.drawImagecanvas,0,0,1,1; console.logCanvas,context.getImageData0,0,canvas.width,canvas.height.data; console.logreadPixels,readback;
不鼓励将外部服务用于代码小提琴,以使问题随着时间的推移保持完整,请在将来使用SOs内置代码小提琴选项。转换是可预测的。回读时,像素只是不相乘。1/30/256 ~= 8. 另外,无论您做什么,使用一些alpha绘制像素都是有损操作。@请注意,当webgl上下文属性premultipledalpha设置为false时,画布结果如何更改为[0,0,0,30]?也许我遗漏了一些东西,但这不应该影响回读,因为据说该参数只影响合成,所以我的结论是,它不是真正可预测/可靠的,在任何情况下都不能保证。如果gl画布被认为不是预乘的,那么在2D画布SRC_ALPHA上合成时,颜色会成倍增加,一减去SRCα。1*30/256四舍五入为零>有损操作。倍增/取消倍增天花板或地板值时,四舍五入可能存在平台不一致,这就是你的意思?对。。。但是,是否应该将2d上下文的globalCompositeOperation设置为“复制”来禁用该操作?复制忽略dest值,但合成器始终确保源是预乘绘制的。如