我正在开发一款大型游戏,当你在游戏世界中移动时,它会在关卡数据(包括着色器)中流动.因为着色器是编译/链接的,或者在第一次使用时,我不希望在帧速率上出现问题.
我有一个着色器编译和链接工作在一个单独的线程与自己的open-gl上下文.但是我无法使着色器的预热在单独的线程上工作(因此在首次使用着色器时没有性能损失).
在iOS或OpenGL文档中,任何地方都没有提到预热.然而,它在OpenGL ES分析器中提到(从xcode分析时可用的仪器之一).在这个工具中,每次使用之前没有用于渲染某些内容的着色器渲染某些内容时,我会收到"在预热阶段之外编译的着色器"警告."扩展细节"说:
"OpenGL ES Analyzer检测到一个着色器编译,它不是初始预热阶段的一部分.着色器编译可能是一个耗时的操作.要避免它们,请预热所有用于渲染的着色器.为此,在应用程序启动时进行预热通道使用每个着色器程序执行绘图调用,使用任何gl状态设置,着色器程序将与.一起使用.混合,颜色掩码,逻辑运算,多重采样,纹理格式和点原始状态等状态可以都会影响着色器编译."
"汇编"这个词在这里有点令人困惑.顶点和片段着色器已经编译,程序已经链接.但是第一次使用给定的OpenGL状态渲染某些东西时,它会在着色器上做更多工作,以便针对该状态对其进行优化.
我有代码通过在第一次使用之前渲染零大小的三角形来预热着色器.
如果我使用与正常渲染相同的Open GL上下文编译,链接和预热主线程上的着色器,那么它可以工作.但是,如果我在具有单独的Open GL上下文的后台线程上执行此操作,则它不起作用(它在第一次使用时仍会收到Analyzer警告).
所以...可能是在单独的上下文中预先设置着色器对其他上下文没有影响.或者可能是我没有所有相同的状态设置单独的上下文.可能需要设置很多潜在的Open GL状态.我在后台线程上使用了屏幕外渲染缓冲区,因此可以将其视为状态的一部分.
有没有人成功地在后台线程上进行预热?