Dissolve SKShader 在模拟器上按预期工作,在实际设备上有奇怪的行为

Dissolve SKShader works as expected on simulator, strange behaviour on actual device

我在尝试为 iOS spritekit 创建溶解着色器时遇到了奇怪的行为。我有这个基本着色器,现在只根据噪声纹理的黑色值更改纹理的 alpha:

let shader = SKShader(source: """
        void main() {\
            vec4 colour = texture2D(u_texture, v_tex_coord);\
            float noise = texture2D(noise_tex, v_tex_coord).r;\
            gl_FragColor = colour * noise;\
        }
        """, uniforms: [
            SKUniform(name: "noise_tex", texture: spriteSheet.textureNamed("dissolve_noise"))
        ])

请注意,此代码在 spriteSheet 预加载回调中调用。

在模拟器上,这始终给出预期的结果,即。到处都有不同 alpha 值的纹理。在实际的 14.5.1 设备上它有所不同:

  1. 直接应用于 SKSpriteNode - 它使整个纹理具有单值半透明
  2. 应用于以 SKSpriteNode 作为子节点的 SKEffectNode - 我看到了整个 spritesheet 的小型化部分
  3. 与 2 相同,但纹理是从 spritesheet 外部的图像创建的 - 它在模拟器上工作(如预期)

为什么会这样?考虑到这需要在 iOS 9 台设备上运行,我担心 3 台设备无法在任何地方运行。所以我想了解为什么会发生这种情况,并且理想情况下,我想确定强制 1 个或至少 2 个在所有设备上工作的方法。

经过更多测试后,我终于弄清楚发生了什么。着色器中的纹理是整个 spritesheet,而不是设备上的单独纹理,因此坐标到处都是。 (现在我想到它实际上比模拟器行为更有意义)

因此,根据我想要 1 还是 2,我需要应用不同的数学。 2 更容易,因为显示纹理首先渲染到缓冲区,所以 v_text_coord 将占用完整的 [0.0, 1.0],所以我只需要噪声纹理矩形来进行适当的变换。对于 1,我需要另外提供纹理矩形,首先自己将其更改为 [0.0, 1.0],然后将其应用于噪声坐标。

这将适用于加载到着色器中的 spritesheet 或单独的图像,只是在以后的情况下它会做一些不必要的计算。