在顶点和片段着色器中访问同名统一失败

Posted

技术标签:

【中文标题】在顶点和片段着色器中访问同名统一失败【英文标题】:Accessing same-named uniform in vertex and fragment shaders fails 【发布时间】:2014-03-23 16:39:02 【问题描述】:

我仍然对着色器非常缺乏经验,但我正在很好地攀登学习曲线。

今天早上我偶然发现了在片段着色器和顶点着色器中使用同名制服的努力。

uniform 可以在两个着色器中定义,但只能在一个或另一个着色器中以独占方式访问,但不能同时在两者中访问。如果我尝试在两者中访问着色器,程序将无法编译。

我最后的想法是它们被编译为单独的符号,但我不知道如何访问它们,除非通过 glGetUniformLocation。使用相同的字符串调用两次会返回相同的统一位置...帮助不大。

着色器非常简单,除了对渲染没有影响的单行工作与否测试之外,一切都运行良好。

有没有一种特殊的方法可以在两个着色器之间使用具有相同值的同名制服?

【问题讨论】:

也许我应该在 gamedev.stackexchange.com 上发布这个? 【参考方案1】:

已解决!根据我的经验,精度限定符 通常不是要求。我没有使用它……因为我的制服是一个整数。

我在这里读到了关于制服可以在顶点和片段着色器之间同名的确认:

http://www.gamedev.net/topic/535321-glsl-the-same-named-uniform-in-vertex-and-fragment-shaders/

所以我认为这是我自己的错误。

最后,我尝试添加 highp 精度限定符,这解决了崩溃的问题。

技术上:

设置 1崩溃

Vertex shader:
uniform int frameNum;

Fragment shader:
uniform int frameNum;

设置 2崩溃

Vertex shader:
uniform highp int frameNum;

Fragment shader:
uniform int frameNum;

设置 3成功

Vertex shader:
uniform highp int frameNum;

Fragment shader:
uniform highp int frameNum;

设置 4成功

Vertex shader:
uniform int frameNum;

Fragment shader:
uniform highp int frameNum;

【讨论】:

说到精度限定符...您可能会受益于知道在 GLES 2.0 中,highp 是片段着色器中的可选精度。它保证可以在顶点着色器中工作,但在片段着色器中允许实现不支持它(与顶点纹理查找是可选的方式相同)。 ES 3.0 强制要求,但在 ES 2.0 中,您应该在片段着色器中使用 highp 之前检查是否存在 GL_FRAGMENT_PRECISION_HIGH 的预处理器定义。至于您不使用精度限定符的理由,整数也支持它们。 因此在片段着色器中您必须明确指定float 精度 - 它不像片段着色器中那样具有默认的highp 精度。参考:khronos.org/files/opengles_shading_language.pdf,第 4.5.3 段。在某些硬件上,片段着色器在没有指定精度的情况下是有效的,但为了 100% 符合标准,您必须在片段着色器中指定 float 精度。 precision mediump float; 适用于任何 GPU。 @keaukraine 这真是一个惊喜......如果未指定,float 似乎是一个自然预定义的精度。我注意到您在第一句话中使用了两次“片段着色器”。你的意思是片段着色器必须指定浮点数,顶点着色器有highp吗?我在学习/练习时参考了 OpenGL ES Shading Language 1.0 快速参考卡。 @AndonM.Coleman 我在 GLSL 1.0 的快速参考卡中看到关于 highp 是可选的注释。但是,在我的同名制服用例中,需要精确限定符才能支持的整数令人惊讶且违反直觉。谢谢你的建议!我会调查 GL_FRAGMENT_PRECISION_HIGH 帮助我解决了一个奇怪的问题,即在均匀乘法计算 gl_PointSize 后没有绘制点。就我而言,将mediump 添加到制服中是有效的。谢谢!

以上是关于在顶点和片段着色器中访问同名统一失败的主要内容,如果未能解决你的问题,请参考以下文章

在片段着色器中使用 textureCube 访问环境贴图失败

在片段着色器中,为啥我不能使用平面输入整数来索引 sampler2D 的统一数组?

如何在片段着色器中找到 4 个顶点之间的插值位置?

此顶点着色器中的统一浮动不起作用

片段着色器中的OpenGL点精灵旋转

将统一值传递给顶点和片段着色器