使用 AppleTV 遥控器时,SceneKit 顶点着色器制服无法正确更新
SceneKit vertex shader uniforms not updating properly when AppleTV remote is used
这可能是现存最疯狂的技术问题,我对获得解决方案的希望不大,但无论如何我都会尝试。也许有人可能会建议我尝试一下,虽然可能没有解释问题背后的原因,但无论如何都可以解决它。
我有一个正在为电视开发的 SpriteKit 游戏OS(Xcode 8.0,Mac OS 10.12),我有一个 SK3DNode,它有一个三角形网格,它使用顶点着色器来移动顶点。
顶点着色器有几个 mat4 制服(尽管这没有太大区别;即使我使用例如 vec4 制服也会出现问题),我用它来传递代码中的数据到着色器,从当前 SKScene 的更新方法。为此,我正在使用三角形网格 material 的 [SCNMaterial setValue:forKeyPath:]。
这运行良好且流畅,除非发生一件事:当我使用 AppleTV 遥控器的触摸板时,更新这些制服非常滞后(就像更新之间可能有半秒的延迟)。
请注意,我并不是说游戏滞后。或者甚至渲染三角形网格、顶点着色器或 SKScene 更新方法也会滞后。从字面上和明确的角度来看,这是对那些滞后的特定制服的新价值观的更新,没有别的。并且仅在我使用 AppleTV 遥控器的触摸板时明确显示。
是的,这个问题绝对是疯了。要理解为什么它绝对疯狂,请注意:
我已经特别确定滞后的只是更新了我的制服的值,没有别的。例如,如果除了使用它们之外,我还使用系统提供的 u_time 制服向顶点着色器中的顶点添加了一些移动,那效果很好。 (换句话说,u_time 制服更新得很好,每秒 60 次,但我的 mat4 制服不是,导致从 u_time 计算的运动完全平滑,而我的额外运动最重要的制服真的很滞后。)同样,屏幕上的其他任何东西都不滞后。
是的,我设置这些制服值的更新方法每秒被调用 60 次。我已经使用系统时钟检查过这个。这里没有延迟。这不像系统正在跳过调用我的更新功能,这导致了问题。它每秒被调用 60 次,我每次都在更新制服(使用 [SCNMaterial setValue:forKeyPath:])。我已经彻底检查过了。
而且它也不仅仅是到处跳帧。如前所述,我们谈论的延迟最多可达半秒,最坏情况下甚至更多;并且经常重复这一点。 (当更新值最终到达着色器本身时,更新后的值会向前跳等量。)
是的,它仅在我使用 AppleTV 遥控器的触控板时发生。 (我不确定在使用它的按钮时是否会发生这种情况。它可能是,但实际上不可能以足够快的速度按下它们以使其产生效果。在触控板上滑动会导致系统连续输入流,这就是当它发生时。)如果我不使用触控板,制服每秒更新 60 次,顶点移动平滑。
游戏手柄不会出现此问题。即使游戏手柄的模拟摇杆产生类似的输入流,它似乎也不会产生相同的效果。
我怀疑,当遥控器的触控板出现问题时,SCNMaterial 并没有使用从其 setValue:forKeyPath: 方法中获得的值更新制服。我一点也不知道是什么或为什么,这是一个完全疯狂的问题。
当然这里的问题是,由于游戏是用遥控器控制的,所以基本不能用。顶点着色器无法正常工作。使用触控板改变方向,网格变形开始像疯了一样滞后。这是无法使用的。我不知道为什么会这样,也不知道如何解决。
我怀疑你的问题出现时SpriteKit渲染线程的runloop是运行 "slowly"。为确保您的 SceneKit 更改已提交 'asap' 到渲染树,您可以将更改包装在显式事务中:
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:0];
// your changes
[SCNTransaction commit];
请注意,当您编写 'SceneKit' 应用程序并直接处理 SceneKit 的回调时,没有必要这样做。因为 SceneKit 将确保在 SceneKit 回调结束时提交您的更改。但是在这里你是从 SpriteKit 的游戏循环中修改 SceneKit 的模型。
尽管提交错误还是值得的。
这可能是现存最疯狂的技术问题,我对获得解决方案的希望不大,但无论如何我都会尝试。也许有人可能会建议我尝试一下,虽然可能没有解释问题背后的原因,但无论如何都可以解决它。
我有一个正在为电视开发的 SpriteKit 游戏OS(Xcode 8.0,Mac OS 10.12),我有一个 SK3DNode,它有一个三角形网格,它使用顶点着色器来移动顶点。
顶点着色器有几个 mat4 制服(尽管这没有太大区别;即使我使用例如 vec4 制服也会出现问题),我用它来传递代码中的数据到着色器,从当前 SKScene 的更新方法。为此,我正在使用三角形网格 material 的 [SCNMaterial setValue:forKeyPath:]。
这运行良好且流畅,除非发生一件事:当我使用 AppleTV 遥控器的触摸板时,更新这些制服非常滞后(就像更新之间可能有半秒的延迟)。
请注意,我并不是说游戏滞后。或者甚至渲染三角形网格、顶点着色器或 SKScene 更新方法也会滞后。从字面上和明确的角度来看,这是对那些滞后的特定制服的新价值观的更新,没有别的。并且仅在我使用 AppleTV 遥控器的触摸板时明确显示。
是的,这个问题绝对是疯了。要理解为什么它绝对疯狂,请注意:
我已经特别确定滞后的只是更新了我的制服的值,没有别的。例如,如果除了使用它们之外,我还使用系统提供的 u_time 制服向顶点着色器中的顶点添加了一些移动,那效果很好。 (换句话说,u_time 制服更新得很好,每秒 60 次,但我的 mat4 制服不是,导致从 u_time 计算的运动完全平滑,而我的额外运动最重要的制服真的很滞后。)同样,屏幕上的其他任何东西都不滞后。
是的,我设置这些制服值的更新方法每秒被调用 60 次。我已经使用系统时钟检查过这个。这里没有延迟。这不像系统正在跳过调用我的更新功能,这导致了问题。它每秒被调用 60 次,我每次都在更新制服(使用 [SCNMaterial setValue:forKeyPath:])。我已经彻底检查过了。
而且它也不仅仅是到处跳帧。如前所述,我们谈论的延迟最多可达半秒,最坏情况下甚至更多;并且经常重复这一点。 (当更新值最终到达着色器本身时,更新后的值会向前跳等量。)
是的,它仅在我使用 AppleTV 遥控器的触控板时发生。 (我不确定在使用它的按钮时是否会发生这种情况。它可能是,但实际上不可能以足够快的速度按下它们以使其产生效果。在触控板上滑动会导致系统连续输入流,这就是当它发生时。)如果我不使用触控板,制服每秒更新 60 次,顶点移动平滑。
游戏手柄不会出现此问题。即使游戏手柄的模拟摇杆产生类似的输入流,它似乎也不会产生相同的效果。
我怀疑,当遥控器的触控板出现问题时,SCNMaterial 并没有使用从其 setValue:forKeyPath: 方法中获得的值更新制服。我一点也不知道是什么或为什么,这是一个完全疯狂的问题。
当然这里的问题是,由于游戏是用遥控器控制的,所以基本不能用。顶点着色器无法正常工作。使用触控板改变方向,网格变形开始像疯了一样滞后。这是无法使用的。我不知道为什么会这样,也不知道如何解决。
我怀疑你的问题出现时SpriteKit渲染线程的runloop是运行 "slowly"。为确保您的 SceneKit 更改已提交 'asap' 到渲染树,您可以将更改包装在显式事务中:
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:0];
// your changes
[SCNTransaction commit];
请注意,当您编写 'SceneKit' 应用程序并直接处理 SceneKit 的回调时,没有必要这样做。因为 SceneKit 将确保在 SceneKit 回调结束时提交您的更改。但是在这里你是从 SpriteKit 的游戏循环中修改 SceneKit 的模型。
尽管提交错误还是值得的。