Closed fire67 closed 1 year ago
+1 Why haven't we fixed this? What is the final solution? @mrdoob let's get something merged we have plenty of PRs and Gists in this thread but nothing someone can just import and use right now.
Also what is up with the breaking changes from 127 to 128? Codepen: https://codepen.io/johnnyshankman/pen/MWGMqYZ I can't seem to figure out how to upgrade to 128 successfully.
This remains open because no working, stable fix has been found. You might try https://github.com/pmndrs/postprocessing/, it may support bloom + canvas transparency.
I'd recommend using the forums (https://discourse.threejs.org/) for help with the upgrade to r128.
Voting again for closing this issue since I don't think it can be fixed, see https://github.com/mrdoob/three.js/issues/14104#issuecomment-1180499097.
//fragmentShader
void main() {
vec2 invSize = 1.0 / texSize;
float fSigma = float(SIGMA);
float alphaNum = 0.0;
float weightSum = gaussianPdf(0.0, fSigma);
vec3 diffuseSum = texture2D( colorTexture, vUv).rgb * weightSum;
for( int i = 1; i < KERNEL_RADIUS; i ++ ) {
float x = float(i);
float w = gaussianPdf(x, fSigma);
vec2 uvOffset = direction * invSize * x;
vec3 sample1 = texture2D( colorTexture, vUv + uvOffset).rgb;
vec3 sample2 = texture2D( colorTexture, vUv - uvOffset).rgb;
diffuseSum += (sample1 + sample2) * w;
weightSum += 2.0 * w;
alphaNum += (texture2D( colorTexture, vUv + uvOffset).a + texture2D( colorTexture, vUv - uvOffset).a) * w;
}
gl_FragColor = vec4(diffuseSum/weightSum, alphaNum/weightSum);
}
//212 line
render( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
renderer.getClearColor( this._oldClearColor );
this.oldClearAlpha = renderer.getClearAlpha();
const oldAutoClear = renderer.autoClear;
renderer.autoClear = false;
renderer.setClearColor( this.clearColor, 0 );
if ( maskActive ) renderer.state.buffers.stencil.setTest( false );
if ( this.renderToScreen ) {
this.fsQuad.material = this.basic;
this.basic.map = readBuffer.texture;
renderer.setRenderTarget( null );
//Todo
renderer.clear(false,true,true);
//this.fsQuad.render( renderer );
}
The three version is 0.146.0 This is the effect before I changed UnrealBloomPass.js. The background is opaque. To make the background transparent, I modified the code of the slice source shader in UnrealBloomPass.js, but it cannot make my scene transparent. So I changed renderer. clear() to renderer clear(false,true,true); And commented out this.fsQuad render( renderer ); The display is as follows. The background is transparent, but the display is very false. I need official help
@Mugen87 Recently I tried to implement UnrealBloom in my app but encountered the same transparency problem. I came across this thread, seeing all attempts to modify the blur pass in the middle but none seemed to yield favorable results. After trying some experiments by myself, I suggest a new approach which basically doesn't need to modify UnrealBloom.js.
I use the selective bloom example as a base. In the fragment shader of the final pass where the bloom texture and the screen texture is merged,
gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) );
which is practically a simple additive operation, I replace it with the following.
vec4 base_color = texture2D(baseTexture, vUv);
vec4 bloom_color = texture2D(bloomTexture, vUv);
float lum = 0.21 * bloom_color.r + 0.71 * bloom_color.g + 0.07 * bloom_color.b;
gl_FragColor = vec4(base_color.rgb + bloom_color.rgb, max(base_color.a, lum));
The concept is fairly simple. I generate an alpha value for the final bloom texture by using its luminosity as a base (it can be something else other than luminosity, which is open for discussion). The final result is the original base_color + bloom_color
as color, plus the max of base_color.a
and the new bloom alpha as the final alpha. For fully opaque parts, the result is completely the same as the default approach.
The actual result is fairly decent, at least according to my testings. Below are some screenshots using the same bloom parameters. As you can see, the default one with no transparency (i.e. black background) looks almost identical with the new approach using a HTML black background.
The new approach also looks fairly decent on a pure white background, as well as a complex background.
Of course, this is not a perfect solution. There is no perfect solution when there is no way to actually mix WebGL with HTML background with additive blending. At least, this is a fairly reasonable solution for those who really needs a transparent background.
Wow, the result is amazing, congratz!
Description of the problem
I am currently using the Unreal Bloom post with a transparent renderer.
Unfortunately, the Unreal Bloom pass doesn't seem to take in account the alpha channel of the coming texture when doing the blur and it apparently comes from
getSeperableBlurMaterial
in js\postprocessing\UnrealBloomPass.js.The fragment's alpha channel is always set to 1.0 which results in a complete removal of the previous alpha values when doing the additive blending at the end.
This is happening in the latest version of Three.js r92 and you can experiment about this issue using the Unreal Bloom example