GLSL程序错误执行
Posted
技术标签:
【中文标题】GLSL程序错误执行【英文标题】:GLSL program wrong execution 【发布时间】:2017-03-03 11:55:15 【问题描述】:在三星 Galaxy Note 4 设备上运行我们的 GLSL(300 es) 着色器程序时,我遇到了一些非常奇怪的视觉错误。它有一个 Quallcom Adreno(TM) 420 gpu,支持 GLES2.0 和 GLES3.0。我们有相当复杂的着色器程序,用于渲染 BRDF、阴影贴图等效果。
上面提到的设备根本不显示阴影(直到我们在代码中找到导致它的位置,请参阅更多内容)。灯光着色行为也是错误的。 相同的程序在以下硬件上运行良好: PC (PowerVR GLES 模拟器),ios(6-7),Samsung Galaxy A7,Samsung Galaxy S6,魅族 M5,小米 4A,摩托罗拉 Nexus 6
如果是阴影,我们有这段代码:
bool InRange(float val)
return val >= 0.0 && val <= 1.0;
float shadowFunc (sampler2D shadowMap, vec4 lightClipPosition, float bias)
vec3 shadowMapCoords = lightClipPosition.xyz / lightClipPosition.w;
shadowMapCoords = (shadowMapCoords + 1.0) / 2.0;
//...some more code
if (!InRange (shadowMapCoords.z)
|| !InRange (shadowMapCoords.x)
|| !InRange (shadowMapCoords.y))
return 1.0;
//...some more code
if() 语句在哪里调用了 3 次
InRange()
方法导致阴影根本不显示。更改为
if ((shadowMapCoords.x < 0.0 || shadowMapCoords.x > 1.0 || shadowMapCoords.y < 0.0 || shadowMapCoords.y > 1.0 || shadowMapCoords.z < 0.0 || shadowMapCoords.z > 1.0))
return 1.0;
修复它。
需要注意的是,在着色器编译或运行时没有错误。
现在我想知道,这是一种由 GLSL 编译器或驱动程序规定的规则吗?着色器主体中的函数执行量是否有任何限制?我完全知道我的着色器使用了很多函数调用。 (尚未进入优化阶段)。但是所有这些着色器在我测试的所有其他手机上都运行良好。这就是为什么我不确定真正的问题出在我的代码中。
我是否必须将着色器中的所有方法内联到着色器的“主”函数中才能让我们所有的东西在这个设备上正常工作?
或者可能只是驱动程序错误?
【问题讨论】:
【参考方案1】:是的,这看起来像是一个直接的驱动程序错误;它应该可以正常工作。
也就是说,请不要编写这样的代码……它会使着色器核心随着分支的数量而哭泣。
理想情况下,只需将您的值限制在 0 和 1 之间并运行着色器;如果你正确地设计你的算法边界条件,它可能看起来还不错,而且通常只运行阴影代码会比早期运行便宜。
如果你真的必须使用条件代码,请尝试使用向量内置函数,它们通常有硬件辅助支持:
if (any(greaterThan(shadowMapCoords, 1.0)) || any(lessThan(shadowMapCoords, 0.0))) ...
【讨论】:
以上是关于GLSL程序错误执行的主要内容,如果未能解决你的问题,请参考以下文章