Apple's Best Practices for OpenGL ES建议不要对片段着色器中计算的结果进行分支。但Phong shading通常涉及在光源位于曲面的“错误”一侧时跳过镜面反射项,其中直接的方法是将单位法线方向N
和光线方向{{1检查结果是否正确。
我试图在我的着色器中没有分支的情况下执行此操作:我不是使用L
语句,而是对镜面术语进行所有计算,然后给它一个系数if
如果{ {1}}大于零,否则为1.0
。 (我使用内置dot(N, L)
函数实现此目的。组合0.0
和step()
会产生相同的结果,但据说速度稍慢。)
然而,这似乎导致奇怪的,设备和/或iOS版本特定的结果:
显然,问题不在于分支或缺乏分支。 (顺便说一句,右手图像是“正确的”渲染。)
这是我的片段着色器:
max()
我欢迎进一步提出改进此着色器在iOS硬件上的性能的建议!
答案 0 :(得分:1)
正如@ BradLarson的评论中所述,lowp
上的materialShininess
限定符证明是问题所在;相反,它设置为mediump
,无论是分支还是无分支(step
)版本使用着色器。
(使用lowp
与mediump
对于计算R
的输入V
和cos_alpha
不会产生任何明显的差异,这是有道理的:那些是归一化的向量,因此它们的分量的大小在0.0到1.0之间。这与颜色分量的范围相同,lowp
似乎是预期的。)