有没有办法在 GLSL 中使用联合?

use*_*798 7 union shader glsl

我想知道是否有办法在 GLSL 中使用联合。我还没有看到任何关于此的文档。如果没有,是否有使用联合的干净解决方法。

我基本上想要一系列的东西。并且某物可能是两件事中的任何一个,因此我想使用联合来定义它。

谢谢!

PS 可能有一些我不知道的奇怪的铸造技巧来做到这一点,请随时提出更好的方法。

编辑:

代码示例(无法编译,因为联合不可用):

struct A{
    bool isA;
    float value;
};
struct B{
    bool isA;
    int value;
};

/* union */
union AandB {
    A a;
    B b;
}

void main()
{
    AandB foo;
    if(foo.a.isA)
        /* process on A */

    else
        /* process on B */
}
Run Code Online (Sandbox Code Playgroud)

另外,假设 A 和 B 很大,您不会想复制它们。

编辑2:

以下是更多信息,希望对您有所帮助:

该数据将来自“外部”并且是特定于顶点的。根据类型(A 或 B),必须对其进行不同的处理。它们可能可以从 VBO 访问。

Nic*_*las 5

由于我们正在讨论顶点属性,因此您可以这样做:

layout(location = 0) vec4 floatVal;
layout(location = 0) ivec4 intVal;
Run Code Online (Sandbox Code Playgroud)

OpenGL 将此称为属性别名,并且明确允许这样做,但有以下警告。要么仅访问别名属性之一,要么通过着色器的每个代码路径仅访问属性之一。因此,如果您使用布尔条件来保护访问和值计算,那就没问题:

//Don't use either variable yet

if(isFloat)
{
  //Do something with `floatVal`
}
else
{
  //Do something with `intVal`
}

//Don't use either variable again.
Run Code Online (Sandbox Code Playgroud)

嗯,理论上你会没事的。属性别名是一种非常奇怪的极端情况,任何使用 OpenGL 的主要程序实际上都不太可能这样做。这意味着实现支持可能会有错误(未使用的代码是尚未经过测试的代码)。因此,如果您想确保您的代码实际上可以跨平台运行,我建议您切换程序。