THREE.WebGLRenderTarget 中带有 alpha 通道的颜色比预期的要暗
Colors in THREE.WebGLRenderTarget with alpha channel are darker than expected
我正在尝试将一些具有透明度的图形渲染到 WebGLRenderTarget 中。然后将渲染图像用作第二个 material 的纹理。
我对 alpha 混合有疑问。我在 alpha=0.5 时获得的颜色比预期的要暗。
下图显示了问题:
- 上面的圆圈是我所期望的。这是通过 HTML DIV 圆角和不透明度 =0.5
获得的
- 底部的圆圈是我使用在纹理内渲染圆圈的着色器获得的。
我觉得我漏掉了什么!
部分代码报告如下。您可以在以下jsbin中找到完整的代码:https://jsbin.com/zukoyaziqe/1/edit?html,js,output
感谢您的帮助!!
着色器:
const texFrag = `
varying vec2 vUv;
void main() {
vec2 center = vec2(0.5, 0.2);
float d = length(vUv - center);
if (d < 0.1) {
gl_FragColor = vec4(1.0,0.0,1.0,0.5);
}
else {
discard;
}
}
`;
纹理:
const makeTexture = (renderer, width, height) => {
const target = new THREE.WebGLRenderTarget(width, height, {minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, type: THREE.FloatType});
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(90, 1, 0.1, 100000);
const geometry = new THREE.PlaneGeometry(2, 2);
const material = new THREE.ShaderMaterial({
transparent : true,
vertexShader : simpleVert,
fragmentShader : texFrag,
});
const mesh = new THREE.Mesh(geometry, material);
camera.position.set(0, 0, 1);
scene.add(camera);
scene.add(mesh);
renderer.render(scene, camera, target, true);
return target.texture;
}
主视图:
const renderer = new THREE.WebGLRenderer({canvas});
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(90, 1, 0.1, 100000);
const geometry = new THREE.PlaneGeometry( 2, 2 );
const material = new THREE.MeshBasicMaterial({
transparent : true,
map : makeTexture(renderer, canvas.width, canvas.height)
});
const mesh = new THREE.Mesh(geometry, material);
首先,在您链接的示例中,您的 main 函数被调用了两次,因此有两个 CSS 圆圈相互堆叠,导致圆圈不太透明。
然后,您在空白渲染目标上绘制一个颜色为 (1,0,1,0.5) 的圆,使用默认混合模式 (SRC_ALPHA, ONE_MINUS_SRC_ALPHA ),产生 (0.5,0,0.5,0.5) 颜色,然后将其用作纹理。如果您想要纹理中的原始颜色,您应该禁用 alpha 混合或使用不同的混合模式。只需在 makeTexture
中将 transparent
设置为 false
即可。
我正在尝试将一些具有透明度的图形渲染到 WebGLRenderTarget 中。然后将渲染图像用作第二个 material 的纹理。
我对 alpha 混合有疑问。我在 alpha=0.5 时获得的颜色比预期的要暗。
下图显示了问题:
- 上面的圆圈是我所期望的。这是通过 HTML DIV 圆角和不透明度 =0.5 获得的
- 底部的圆圈是我使用在纹理内渲染圆圈的着色器获得的。
我觉得我漏掉了什么!
部分代码报告如下。您可以在以下jsbin中找到完整的代码:https://jsbin.com/zukoyaziqe/1/edit?html,js,output
感谢您的帮助!!
着色器:
const texFrag = `
varying vec2 vUv;
void main() {
vec2 center = vec2(0.5, 0.2);
float d = length(vUv - center);
if (d < 0.1) {
gl_FragColor = vec4(1.0,0.0,1.0,0.5);
}
else {
discard;
}
}
`;
纹理:
const makeTexture = (renderer, width, height) => {
const target = new THREE.WebGLRenderTarget(width, height, {minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, type: THREE.FloatType});
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(90, 1, 0.1, 100000);
const geometry = new THREE.PlaneGeometry(2, 2);
const material = new THREE.ShaderMaterial({
transparent : true,
vertexShader : simpleVert,
fragmentShader : texFrag,
});
const mesh = new THREE.Mesh(geometry, material);
camera.position.set(0, 0, 1);
scene.add(camera);
scene.add(mesh);
renderer.render(scene, camera, target, true);
return target.texture;
}
主视图:
const renderer = new THREE.WebGLRenderer({canvas});
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(90, 1, 0.1, 100000);
const geometry = new THREE.PlaneGeometry( 2, 2 );
const material = new THREE.MeshBasicMaterial({
transparent : true,
map : makeTexture(renderer, canvas.width, canvas.height)
});
const mesh = new THREE.Mesh(geometry, material);
首先,在您链接的示例中,您的 main 函数被调用了两次,因此有两个 CSS 圆圈相互堆叠,导致圆圈不太透明。
然后,您在空白渲染目标上绘制一个颜色为 (1,0,1,0.5) 的圆,使用默认混合模式 (SRC_ALPHA, ONE_MINUS_SRC_ALPHA ),产生 (0.5,0,0.5,0.5) 颜色,然后将其用作纹理。如果您想要纹理中的原始颜色,您应该禁用 alpha 混合或使用不同的混合模式。只需在 makeTexture
中将 transparent
设置为 false
即可。