【问题标题】:GLSL program wrong executionGLSL程序错误执行
【发布时间】: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 编译器或驱动程序规定的规则吗?着色器主体中的函数执行量是否有任何限制?我完全知道我的着色器使用了很多函数调用。 (尚未进入优化阶段)。但是所有这些着色器在我测试的所有其他手机上都运行良好。这就是为什么我不确定真正的问题出在我的代码中。

我是否必须将着色器中的所有方法内联到着色器的“主”函数中才能让我们所有的东西在这个设备上正常工作?

或者可能只是驱动程序错误?

【问题讨论】:

    标签: android opengl-es glsl


    【解决方案1】:

    是的,这看起来像是一个直接的驱动程序错误;它应该可以正常工作。

    也就是说,请不要编写这样的代码……它会使着色器核心随着分支的数量而哭泣。

    理想情况下,只需将您的值限制在 0 和 1 之间并运行着色器;如果你正确地设计你的算法边界条件,它可能看起来还不错,而且通常只运行阴影代码会比早期运行便宜。

    如果你真的必须使用条件代码,请尝试使用向量内置函数,它们通常有硬件辅助支持:

    if (any(greaterThan(shadowMapCoords, 1.0)) || any(lessThan(shadowMapCoords, 0.0))) { ... }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-02
      • 1970-01-01
      • 1970-01-01
      • 2015-01-16
      相关资源
      最近更新 更多