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

Writing fragment shaders: cannot make sense of how the uniforms are defined

我正在尝试使用 Phaser 制作自定义滤镜,但我不知道制服是如何指定的,尤其是 vTextureCoordHere's a JSFiddle(编辑:忽略图像,最小情况位于方形渐变中):

我在上次 Ludum Dare 期间在这个上拉扯了我的头发,试图找出精灵中的像素位置(即左下角的 [0,0] 和 [sprite.w,sprite.h] 在右上角)...但是我找不到任何可靠的方法来计算精灵的位置和大小。

感谢您的帮助!


EDIT:正如 emackey 所指出的,似乎 Phaser 或 Pixi(不确定它在哪个级别处理?)使用中间纹理。因此,我得到的 uSampler 不是原始纹理,而是经过修改的纹理,例如 shifted/cropped 如果精灵超出屏幕的左上角。 uSamplervTextureCoord 可以很好地协同工作,所以只要我做一些简单的事情,比如颜色调整,一切看起来都很好,但是对于玩弄纹理坐标来说,它根本不可靠。

Phaser/Pixi 大师能否解释一下为什么它会这样工作,以及我应该怎么做才能获得清晰的坐标并使用我的实际源纹理? I managed to hack a shader by "fixing vTextureCoord" 并将我的纹理插入 iChannel0,但这感觉有点 hacky。

谢谢。

我不太熟悉 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.,但这不是全部:尝试将你的 sprite 拖离左上角。纹理滑动但纹理坐标没有移动!

这怎么可能?我的猜测是原始精灵纹理被渲染为中间纹理,使用一些精灵的位置信息进行转换。当您的自定义滤镜 运行 时,您的滤镜 GLSL 代码 运行 正在处理现在转换后的中间纹理,并且纹理坐标与原始精灵纹理不再具有已知关系。

如果你 运行 Chrome Canvas Inspector 你可以看到确实有多个通道,包括渲染到纹理通道。您还可以看到过滤器通道使用的坐标似乎是过滤器区域大小与游戏区域大小的比率,在本例中,两个维度上都是 0.5

我对 Phaser 的了解还不够深,不知道是否有快速修复方法。也许您可以向过滤器添加一些制服,从而为着色器提供所需的额外变换,前提是您能弄清楚它的确切来源。或者也许有一种方法可以将着色器直接附加到精灵本身(有一个同名的空字段),这样你就可以 运行 你的 GLSL 代码在那里而不是在过滤器中。我希望这个答案至少已经解释了你上面两个问题的"why"。