0

我在尝试为 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 在所有设备上工作。

4

1 回答 1

0

经过更多的测试,我终于弄清楚发生了什么。着色器中的纹理是整个精灵表,而不是设备上的单独纹理,因此坐标遍布各处。(现在我考虑一下,这实际上比模拟器行为更有意义)

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

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

于 2021-08-13T10:17:15.690 回答