【问题标题】:How to apply a mask to a texture with transparency to achieve see-trough effect如何将蒙版应用于具有透明度的纹理以实现透视效果
【发布时间】:2015-08-11 21:39:52
【问题描述】:

我正在尝试将蒙版应用于具有透明度的纹理。我想要达到的效果是一个有裂缝的物体,你应该能够从裂缝中看到。我尝试使用混合和帧缓冲区但没有成功。

这是我正在使用的精灵:
球:http://i.stack.imgur.com/4gImO.png
(注意球周围是透明的)
面具:http://i.stack.imgur.com/ij4Uw.png
(面具为白色,中间有透明裂缝)

这是我得到的当前结果:

这是我正在寻找的结果:
(这是使用像素图通过检查掩码中的每个像素来完成的,并且只绘制那些 alpha > 0 的像素,但它太慢了,它在 android 上冻结了一两秒钟,我无法预加载它,因为我没有在我需要应用蒙版之前不知道我要应用蒙版的对象)

这是我的渲染函数:

@Override
public void render() {
  Gdx.gl.glClearColor(1, 0, 0, 1);
  Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
  batch.begin();

  mBackground.draw(batch);

  batch.setBlendFunction(GL20.GL_ZERO, GL20.GL_SRC_COLOR);
  mMask.draw(batch);

  batch.setBlendFunction(GL20.GL_DST_ALPHA, GL20.GL_ONE_MINUS_DST_ALPHA);
  mObject.draw(batch);

  batch.end();
}

【问题讨论】:

  • 能否在 libgdx 中提供自定义着色器?如果是这样,请创建一个从蒙版纹理和球体 tex 采样的着色器,以便将蒙版应用于片段着色器...这意味着蒙版纹理的采样必须与球体的 UV 很好地对齐网格...如果这是一个非首发,另一种方法可能是做一个预先通过,标记裂缝所在的模板缓冲区(这里的着色器需要丢弃白色片段),然后使用模板缓冲区来掩盖随后的可渲染...只是一些想法-我不熟悉 libgdx。
  • 另一种可能无法针对您的问题进行扩展的选项是每个需要破解的纹理有两个版本...一个有破解,一个没有破解。
  • 这是纹理组合器的工作,真的。但除非绝对必要,否则我尽量不去解释那些讨厌的旧事。着色器是理想的,但这看起来像 ES 1.x 级别的东西。
  • 感谢您的帮助。我设法使用着色器让它工作。然而,一个问题是,我如何定位和旋转面具?我希望蒙版与球处于相同的位置和角度,但这是不可能的,因为我无法旋转蒙版纹理,我需要绘制它才能旋转它。我现在这样做的方式是:绑定球纹理,绑定蒙版纹理,在选定的位置和选定的角度绘制球,然后着色器片段将接收这两个纹理,并且如果两种纹理的像素都不透明。
  • 好的,所以蒙版似乎会自动移动和旋转,问题是我使用的是纹理图集,我的猜测是蒙版与图集对齐,而不是与图集中的纹理区域对齐阿特拉斯。任何想法如何解决这个问题?

标签: opengl opengl-es libgdx


【解决方案1】:

我设法通过使用着色器来完成这项工作。这是我的解决方案:
渲染函数:

@Override
public void render() {
    Gdx.gl20.glClearColor(0, 0, 0, 1);
    Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);

    batch.begin();
    mBackground.draw(batch);

    batch.setShader(mShaderProgram);

    Gdx.graphics.getGL20().glActiveTexture(GL20.GL_TEXTURE0);
    mObjectTexture.bind(0);
    mShaderProgram.setUniformi("u_texture", 0);

    Gdx.graphics.getGL20().glActiveTexture(GL20.GL_TEXTURE1);
    mMaskTexture.bind(1);
    mShaderProgram.setUniformi("u_mask", 1);

    Gdx.graphics.getGL20().glActiveTexture(GL20.GL_TEXTURE0);
    batch.draw(mObjectTexture, 0, 0, 500, 500);

    batch.end();
    batch.setShader(null);
}  

顶点着色器:

attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;

uniform mat4 u_projTrans;

varying vec2 v_texCoords;

void main() {
    v_texCoords = a_texCoord0;
    gl_Position = u_projTrans * a_position;
}  

片段着色器:

varying vec2 v_texCoords;
uniform sampler2D u_texture;
uniform sampler2D u_mask;
uniform mat4 u_projTrans;

void main() {
    vec4 texColor = texture2D(u_texture, v_texCoords);
    vec4 maskColor = texture2D(u_mask, v_texCoords);

    gl_FragColor = texColor * maskColor.a;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 2021-07-03
    相关资源
    最近更新 更多