【问题标题】:webgl 2d blending two transparent textures on top of each otherwebgl 2d 将两个透明纹理相互叠加
【发布时间】:2017-08-17 10:37:30
【问题描述】:

我正在尝试将两个带有 Alpha 通道的纹理相互混合。

通过网络查看后,似乎没有简单的方法可以解决这个问题。我在片段着色器中尝试了这个技巧:

if(gl_FragColor.a < 0.5){
    discard;
}

这适用于没有太多 alpha 变化的简单纹理,例如背景中的人类精灵。但我希望能够处理更复杂的图像,比如根本不起作用的渐变精灵。

这是我的片段着色器:

precision mediump float;
varying vec3 fragColor;
varying highp vec2 vTextureCoord;
uniform sampler2D uSampler;
void main()
{
    vec4 tex = texture2D(uSampler, vTextureCoord);
    gl_FragColor = tex * vec4(fragColor, 1.0);
    if(gl_FragColor.a < 0.5){
    discard;
}
}'

这是我的顶点着色器:

precision mediump float;

attribute vec3 vertPosition;
attribute vec3 vertColor;
attribute vec2 aTextureCoord;
varying vec3 fragColor;
varying highp vec2 vTextureCoord;
uniform mat4 uPMatrix;
uniform mat4 uMVMatrix;

uniform vec2 uvOffset;
uniform vec2 uvScale;

void main()
{
  fragColor = vertColor;
  gl_Position = uPMatrix * uMVMatrix * vec4(vertPosition.x, vertPosition.y, vertPosition.z, 1.0);
  vTextureCoord = aTextureCoord * uvScale + uvOffset;
}

这是我使用的 gl 设置的一部分:

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

目前所有精灵都在同一个 z 轴 0 上绘制。但是我不知道这是否是问题的根源,因为我测试给每个对象一个随机 z 值并且问题仍然存在。

编辑: 回应 Rabbid76 的评论。

这很好用! alpha 是混合的,但唯一的问题是精灵看起来“烧焦了”:

我尝试将片段着色器更改为:

<strike>gl_FragColor = tex * vec4(tex.rgb, tex.a);</strike>

但它看起来仍然被烧毁了。

编辑 2

我解决了。 gl_FragColor 应该是:

gl_FragColor = vec4(tex.rgb, tex.a);

而不是

gl_FragColor = vec4(fragColor* tex.rgb, tex.a);

否则会产生燃烧混合效果

【问题讨论】:

    标签: javascript textures webgl blending


    【解决方案1】:

    目前所有精灵都在同一个 z 轴 0 上绘制。

    由于启用了深度测试(gl.enable(gl.DEPTH_TEST)),并且默认的深度函数(depthFunc)是gl.LESS,所以第二个绘制的精灵不会通过深度测试。
    你必须禁用深度测试:

    gl.disable(gl.DEPTH_TEST);
    


    此外,我建议调整混合功能(blendFunc):

    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    

    或者你使用Alpha premultiplication。因此,您必须调整片段着色器:

    gl_FragColor = tex * vec4(fragColor * tex.rgb, tex.a);
    

    而且你必须使用下面的混合函数(blendFunc):

    gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
    

    注意,您不再需要if(gl_FragColor.a &lt; 0.5) discard;

    【讨论】:

      猜你喜欢
      • 2022-08-17
      • 2017-09-09
      • 2018-05-30
      • 2010-11-26
      • 2020-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-29
      相关资源
      最近更新 更多