使用着色器

时间:2015-06-04 04:09:41

标签: opengl-es opengl-es-2.0 mask

在使用OpenGL ES 2.0的2D池游戏中,我需要在围绕球的边缘旋转时屏蔽“白色”和“数字”纹理。我目前正在使用模板,但有两个问题:

  1. 在模板测试中没有抗锯齿,产生锯齿状边缘。
  2. 每个球都被单独遮挡(相邻的球可能会相互渗透),而且每帧多次清除并重新创建模板缓冲区的速度太慢。
  3. 我很确定最好的解决方案会涉及着色器代码,但我是shader编程的新手(对OpenGL本身来说还是新手),而且我在研究中发现的结果量让我不确定如何最好继续。

    这个似乎接近我的需要: https://gamedev.stackexchange.com/questions/98573/how-do-i-draw-a-circular-portion-of-a-texture-within-libgdx-using-an-opengl-es-s

    特别是第一个回答“Alpha蒙版纹理”的方法,使用灰度图像作为最终gl_FragColor的alpha值。但是我找不到任何关于如何设置这样的着色器程序的例子。 (常见示例有3个带背景,前景和蒙版的图像,并使用mix()来混合它们。)

    例如,蒙版将是整个球的大小和形状,但是像球一样的纹理被绘制在球的一部分上(并且具有不同的透视变换矩阵),因此纹理坐标将是完全不同的图像和面具。我找不到类似的东西。

    第二种替代方案可能更容易,只是对距中心一定距离^ 2的像素使用'丢弃'。甚至可以羽化阿尔法。我找到了这种方法: https://gist.github.com/tgfrerer/6009069

    ...但它使用ES 2.0中没有的功能。如果有人可以提供功能类似但适合ES的示例,那也是受欢迎的。与任何一种方法的优点形成鲜明对比。

2 个答案:

答案 0 :(得分:0)

也许这篇论文可以提供帮助:https://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf 我认为这正是你所需要的 - 并且应该在ES2中正常工作。

答案 1 :(得分:0)

我现在使用第二个距离'方法。既然它也做得很光滑,我应该很高兴。请注意,center和inner / outerEdge的制服都需要在"窗口坐标"中。距离()中的每像素sqrt让我感到困扰,但是我尝试将它展开到距离^ 2测试中,并且描述的速度更慢。

precision mediump float;
varying vec2 v_texCoord;
uniform vec2 center;
uniform float innerEdge;
uniform float outerEdge;
uniform float alpha;
uniform sampler2D s_texture;
void main() {
  float dist = distance(gl_FragCoord.xy, center);
  if (dist >= innerEdge)
    gl_FragColor = alpha * (1. - smoothstep(innerEdge, outerEdge, dist)) * texture2D(s_texture, v_texCoord);
  else
    gl_FragColor = alpha * texture2D(s_texture, v_texCoord);
}