【问题标题】:glslLangValidator multiple preprocessor substitutionsglslLangValidator 多个预处理器替换
【发布时间】:2020-11-10 01:45:59
【问题描述】:

我想使用如下着色器中的宏访问统一块实例成员:

#version 450 core

layout(std140, set=0, binding=0) uniform UBlock {
    float value;
} uInstance;
#define value uInstance.value

#define saturate(X) clamp( X, 0, 1 )

layout(location = 0) out float Out;

void main ()
{
    Out = value;
    Out = saturate(value);
}

但每当我将重新定义的符号传递给另一个宏时,glsllangValidator 都会返回以下错误:

ERROR: D:/shader_translation/glsl_preprocessor.frag:15: 'uInstance' : no such field in structure
ERROR: D:/shader_translation/glsl_preprocessor.frag:15: '' : compilation terminated
ERROR: 2 compilation errors.  No code generated.

有没有办法让它工作? 它适用于 cpp: (https://onlinegdb.com/SJ-B3A8tP)

【问题讨论】:

    标签: opengl glsl shader preprocessor vulkan


    【解决方案1】:

    value 变量可以从uInstance 结构外部访问,而无需指定uInstance.*。也就是说 - 你不必#define,你只需使用value。它似乎也干扰了#define,就好像你重命名它一样——它工作正常(至少对我来说)。

    【讨论】:

    • 不幸的是,我需要该实例用于反射目的...
    • 正如我所说,将#define 重命名为与变量名称不同的工作正常
    • 您可以使用哪个编译器访问值成员而无需任何定义?我使用最新的 vulkan sdk 并直接使用 value 会导致未声明的标识符错误。我无法更改#define 名称
    • 我正在使用 glslc
    【解决方案2】:

    这里的问题是宏在 glsl 中是如何工作的。通过将value 定义为uInstance.value,GLSL 预处理器还将替换uInstance.value 中的值,从而生成uInstance.uinstance.value。这也是错误消息所指的内容。

    如果你例如将着色器更改为

    #version 450 core
    
    layout(std140, set=0, binding=0) uniform UBlock {
        float value;
    } uInstance;
    
    #define val uInstance.value
    
    #define saturate(X) clamp( X, 0, 1 )
    
    layout(location = 0) out float Out;
    
    void main ()
    {
        Out = val;
        Out = saturate(val);
    }
    

    它可以在 Vulkan 目标环境中正常编译。

    【讨论】:

    • thx,似乎没有办法完成我所需要的。错误发生在第二行,其中宏被赋予另一个宏,第一行运行良好。我虽然可能有一种方法可以绕过论点的第二次扩展。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-21
    • 2010-09-25
    • 2014-07-30
    • 2014-09-07
    • 2017-08-08
    • 1970-01-01
    相关资源
    最近更新 更多