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程序错误执行的主要内容,如果未能解决你的问题,请参考以下文章

GLSL 错误:2001 - 此错误代码是啥意思?

GLSL 错误:无法预处理源。我该如何解决这个问题?

GLEW 链接错误 [重复]

GLSL语法以及如何与程序链接

如何在 Windows 中运行基本的“Hello World”GLSL 程序? [关闭]

我的 GLSL 着色器程序链接正常,但是当我尝试使用它时出错——我该如何调试它?