GLSL ES Phong着色器结果中的设备/操作系统不一致

时间:2012-10-04 06:54:13

标签: ios opengl-es opengl-es-2.0 glsl fragment-shader

Apple's Best Practices for OpenGL ES建议不要对片段着色器中计算的结果进行分支。但Phong shading通常涉及在光源位于曲面的“错误”一侧时跳过镜面反射项,其中直接的方法是将单位法线方向N和光线方向{{1检查结果是否正确。

我试图在我的着色器中没有分支的情况下执行此操作:我不是使用L语句,而是对镜面术语进行所有计算,然后给它一个系数if如果{ {1}}大于零,否则为1.0。 (我使用内置dot(N, L)函数实现此目的。组合0.0step()会产生相同的结果,但据说速度稍慢。)

然而,这似乎导致奇怪的,设备和/或iOS版本特定的结果:

with branch without branch

  • 在运行iOS 6.0的iPhone 4上,带分支的版本有一个宽镜面反射高光(左图);没有分支我看到一个狭窄的镜面高光(右图),尽管“光泽”指数保持不变。
  • 在iOS 6.0模拟器上,我看到了两个版本的着色器的第二个图像。
  • 在我的iPad(原版2010型号,坚持iOS 5.1)上,我看到第一个带有两个版本着色器的图像。

显然,问题不在于分支或缺乏分支。 (顺便说一句,右手图像是“正确的”渲染。)

这是我的片段着色器:

max()

我欢迎进一步提出改进此着色器在iOS硬件上的性能的建议!

1 个答案:

答案 0 :(得分:1)

正如@ BradLarson的评论中所述,lowp上的materialShininess限定符证明是问题所在;相反,它设置为mediump,无论是分支还是无分支(step)版本使用着色器。

(使用lowpmediump对于计算R的输入Vcos_alpha不会产生任何明显的差异,这是有道理的:那些是归一化的向量,因此它们的分量的大小在0.0到1.0之间。这与颜色分量的范围相同,lowp似乎是预期的。)