threejs gl.readPixels 阿尔法总是 return 255

threejs gl.readPixels alpha always return 255

我想从 threejs 应用程序中读取像素值。

const gl = renderer.context;
const currentFrame = new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4);
// read image data from gl
gl.readPixels(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RGBA, gl.UNSIGNED_BYTE, currentFrame);

Threejs 代码

const renderer = new THREE.WebGLRenderer({preserveDrawingBuffer: true});

renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight );

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 6;

const geometry = new THREE.BoxGeometry(10, 10, 10);
const cube = new THREE.Mesh(geometry);
scene.add(cube);

RBG 值 return 正确,但 alpha 值始终 return 255。

有两种可能。
内部缓冲区包含所有纹素的 alpha 通道的 1.0 (255)。
或者您读取的缓冲区在其内部格式中根本没有 alpha 通道。这意味着内部缓冲区格式是例如RGB.

WebGL 1.0 Specifications - 5.13.12 Reading back pixels指的是OpenGL ES 2.0规范。

OpenGL ES 2.0 Specification - 3.6.2 Transfer of Pixel Rectangles:

Final Expansion to RGBA

Each group is converted to a group of 4 elements as follows: if a group does not contain an A element, then A is added and set to 1.0. If any of R, G, or B is missing from the group, each missing element is added and assigned a value of 0.0.


请注意,如果您没有设置写入片段颜色的顶点属性的 alpha 通道,则 alpha 通道将为 1.0(RGBA8 缓冲区中为 255),因为所有顶点属性都使用 (0, 0, 0, 1):

WebGL 1.0 Specifications - 5.13.10 Uniforms and attributes指的是OpenGL ES 2.0规范。

OpenGL ES 2.0 Specification - See 2.7 Current Vertex State:

The state required to support vertex specification consists of MAX_VERTEX_ATTRIBS four-component floating-point vectors to store generic vertex attributes. The initial values for all generic vertex attributes are (0, 0, 0, 1).


如果要在 THREE.mesh 的几何体上设置 alpha 通道,则必须将 transparent material 附加到 opacity 小于 1.0 的网格。参见 THREE.material

var geometry = new THREE.BoxGeometry( 10, 10, 10 );  
var material = new THREE.MeshBasicMaterial( {
    color: 0xff0000,
    transparent: true, 
    opacity: 0.5,
} );
const cube = new THREE.Mesh(geometry, material);


为了能够读取 alpha 通道,您必须确保 canvas 包含 alpha(透明度)缓冲区。这可以通过设置 THREE.WebGLRenderer:

alpha 属性来实现
renderer = new THREE.WebGLRenderer( {
    alpha: true
});