尝试使用带有一些后期效果的透明背景,例如示例中提供的Unreal Bloom,SMAA和Tonemapping,但它似乎打破了渲染的透明度。
renderer = new THREE.WebGLRenderer({ canvas, alpha: true });
renderer.setClearColor(0xFF0000, 0);
composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));
// Bloom pass
canvasSize = new THREE.Vector2(canvas.width, canvas.height);
pass = new UnrealBloomPass(canvasSize, strength, radius, threshhold);
composer.addPass(pass);
// SMAA pass
size = canvasSize.multiplyScalar(this.renderer.getPixelRatio());
pass = new SMAAPass(size.x, size.y);
pass.renderToScreen = true
composer.addPass(pass);
// Tonemapping
renderer.toneMappingExposure = exposure;
renderer.toneMappingWhitePoint = whitePoint;
renderer.toneMapping = type;
composer.render();
如果我停用了布鲁斯传球,我会得到正确的透明背景,但在激活时,我会获得黑色背景。我查看了源代码,看起来它应该正确处理alpha纹理通道,因为格式设置正确THREE.RGBAFormat
。
编辑:经过一番研究,我发现了它的来源。它来自 js \ postprocessing \ UnrealBloomPass.js中的getSeperableBlurMaterial
。
片段的alpha通道始终设置为1.0,这样可以在最后进行添加混合时完全删除先前的alpha值。
很酷的是找到一种在高斯模糊中应用alpha的正确方法。知道怎么样?
答案 0 :(得分:0)
我找到了一个解决方案,可以这样排序: https://github.com/mrdoob/three.js/issues/14104
void main()
{
vec2 invSize = 1.0 / texSize;
float fSigma = float(SIGMA);
float weightSum = gaussianPdf(0.0, fSigma);
float alphaSum = 0.0;
vec3 diffuseSum = texture2D(colorTexture, vUv).rgb * weightSum;
for( int i = 1; i < KERNEL_RADIUS; i ++ )
{
float x = float(i);
float weight = gaussianPdf(x, fSigma);
vec2 uvOffset = direction * invSize * x;
vec4 sample1 = texture2D( colorTexture, vUv + uvOffset);
float weightAlpha = sample1.a * weight;
diffuseSum += sample1.rgb * weightAlpha;
alphaSum += weightAlpha;
weightSum += weight;
vec4 sample2 = texture2D( colorTexture, vUv - uvOffset);
weightAlpha = sample2.a * weight;
diffuseSum += sample2.rgb * weightAlpha;
alphaSum += weightAlpha;
weightSum += weight;
}
alphaSum /= weightSum;
diffuseSum /= alphaSum; // Should apply discard here if alphaSum is 0
gl_FragColor = vec4(diffuseSum.rgb, alphaSum);
}