WebGL: strange behavior when rendering spritebatch to render texture

Technology: WebGL / GL

  • When I process 10k sprites (using spritebatch) directly into the back buffer, everything is fine.

10k

good

  1. When I render it into the rendering texture, I get some kind of strange problem with alpha blending (I think ..). In places where the texture has transparent pixels, alpha is not calculated correctly (IMO, it must be cumulative).

10k

bad1

1k

bad2

200 with black background

bad3

Blend Configuration:

gl.enable(gl.BLEND); gl.blendEquation(gl.FUNC_ADD); gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); 

This is how I create a render buffer:

 this._texture = this.gl.createTexture(); this.gl.bindTexture(this.gl.TEXTURE_2D, this._texture); this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.width, this.height, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, null); this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE); this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE); this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR); this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR); this.renderBuffer = this.gl.createFramebuffer(); this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.renderBuffer); this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, this._texture, 0); 
+7
javascript webgl
source share
1 answer

I changed the blending mode:

 gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD); gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); 

This is the result:

good

Explanation:

When rendering immediately in the back buffer, the alpha channel is always set to 1.0 (unless you use a transparent canvas). Therefore, it does not matter how alpha is calculated.

When rendering first to the render buffer (texture), and then this prepared texture is used to render to the back buffer - you need to use different blending modes for alpha and rgb.

SRC_ALPHA and ONE_MINUS_SRC_ALPHA are used to mix RGB (multiply) depending on SRC and DESC alpha.

If the alpha channel is also multiplied, it will overlap the opaque pixels in places where the texture has transparent pixels. We need to sum the alpha of each pixel, not multiply.

So, for the alpha function, you need to set: ONE and ONE_MINUS_SRC_ALPHA so that ALPHA accumulates, not multiplies.

Luk: I don't speak English (sorry). If someone was so good as to β€œtranslate” this explanation, I would be grateful.

+3
source share

All Articles