编写片段着色器:无法理解制服的定义方式

时间:2015-05-11 11:00:56

标签: javascript glsl webgl phaser-framework pixi.js

我尝试使用Phaser制作自定义过滤器,但我不知道制服的方式,特别是vTextureCoordHere's a JSFiddle(编辑:忽略图像,最小的情况放在方形渐变中):

  • 为什么右上角没有白色?我已将滤镜分辨率和精灵尺寸都设置为256,但vTextureCoord仅从[0,0]变为[.5,.5](或者似乎如此)
  • 尝试拖动精灵:它似乎被顶部和左边框的墙挡住了。它只与着色器相关,因为游戏对象本身被正确拖动。怎么样?

我在最后一个Ludum Dare中拉了我的头发,试图找出精灵中的像素位置(即左下角的[0,0]和[sprite.w,sprite.h])右上角...)但是无论精灵的位置和大小是什么,我都找不到任何可靠的计算方法。

感谢您的帮助!

编辑:正如 emackey 指出的那样,Phaser或Pixi(不知道它处理的是哪个级别?)似乎使用了中间纹理。因此,我得到的uSampler不是原始纹理,而是修改后的纹理,例如,如果精灵超出屏幕的左上角,则移位/裁剪。 uSamplervTextureCoord可以很好地协同工作,所以只要我做出像颜色调整这样简单的事情看起来都很好,但是对于使用纹理坐标进行玩弄它根本就不可靠。

Phaser / Pixi大师可以解释为什么它会以这种方式工作,以及我应该做些什么来获得清晰的坐标并使用我的实际源纹理? I managed to hack a shader通过"修复vTextureCoord"并在iChannel0中插入我的纹理,但这感觉有些笨拙。

感谢。

1 个答案:

答案 0 :(得分:2)

我对Phaser并不太熟悉,但我们可以对片段着色器的实际作用有所了解。加载你的jsFiddle并用这个替换GLSL主体:

void main() {
    gl_FragColor = vec4(vTextureCoord.x * 2., vTextureCoord.y * 2., 1., 1.);
    gl_FragColor *= texture2D(uSampler, vTextureCoord) * 0.6 + 0.4;
}

上面的滤镜着色器是原始纹理(添加了一些灰色)和颜色的组合,因此您可以同时看到纹理和UV。

你是正确的vTextureCoord仅转到0.5,因此上面是* 2.,但这不是全部故事:尝试从左上角拖动精灵。纹理滑动但纹理坐标不移动!

怎么可能呢?我的猜测是原始的精灵纹理被渲染到一个中间纹理,使用一些精灵的变换位置信息。当您的自定义过滤器运行时,您的过滤器GLSL代码在现在已经变换的中间纹理上运行,并且纹理坐标不再与原始精灵纹理具有已知关系。

如果你运行Chrome Canvas Inspector,你可以看到确实存在多次传递,包括渲染到纹理传递。您还可以看到过滤器传递使用的坐标看起来是过滤器区域大小与游戏区域大小的比率,在这种情况下,两个维度上都是0.5

我不太了解Phaser,知道是否可以快速解决这个问题。也许你可以在过滤器中添加一些制服,这样可以为着色器提供所需的额外变换,如果你能弄清楚它来自哪里。或者也许有一种方法可以直接在sprite上附加一个着色器(有一个同名的空字段),所以你可以在那里而不是在过滤器中运行你的GLSL代码。我希望这个答案至少解释了上述两个问题的“原因”。