You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AMD锐龙7000核显GLSL宏##运算符编译错误求助

GLSL宏中##运算符在AMD显卡上编译失败的解决办法

我使用AMD Radeon Graphics(锐龙7000系列)核显开发OpenGL程序,采用GLSL 330版本并启用GL_ARB_shading_language_420pack扩展,但在宏函数里使用##运算符时出现编译错误:

'##' : not supported for these tokens
即便切换到GLSL 420等更高版本,问题依然存在(选用330是为了兼容性)。相同代码在Nvidia、Intel显卡上可正常运行。

最初报错的宏代码

#define calc_channel( n )                                                                                                                    \
{                                                                                                                                            \
    vec3 enable_light_rgb = vec3( chan_ctrl##n##_color_light_enable, chan_ctrl##n##_color_light_enable, chan_ctrl##n##_color_light_enable ); \
    vec3 light_color_rgb = clamp( diffuse_light.rgb + amb_color##n.rgb * cAmbColor[##n].rgb, 0.0, 1.0 );                                     \
    float light_color_a  = clamp( diffuse_light.a   + amb_color##n.a,                        0.0, 1.0 );                                     \
    color##n##a##n.rgb = chan_ctrl##n##_color.rgb * max( enable_light_rgb, light_color_rgb );                                                \
    color##n##a##n.a   = chan_ctrl##n##_alpha.a   * max( 1.0 - chan_ctrl##0##_alpha_light_enable, light_color_a );                           \
}

调用方式:

calc_channel( 0 );

修正部分代码后仍报错的情况

把宏中错误的chan_ctrl##0##_alpha_light_enable改为chan_ctrl0_alpha_light_enable后,报错依旧。移除该段代码后,另一个使用##的宏也出现编译问题:

#define calc_tex_coord( n )                                        \
{                                                                  \
    expand_tex_func( n );                                          \
    tex_coord##n##.x = dot( expand_tex_mtx( n )[ 0 ], tex_coord ); \
    tex_coord##n##.y = dot( expand_tex_mtx( n )[ 1 ], tex_coord ); \
    float tw         = dot( expand_tex_mtx( n )[ 2 ], tex_coord ); \
}

调用方式:

calc_tex_coord( 0 );

报错信息:

ERROR: 0:355: 'tex_coord0nx' : undeclared identifier
ERROR: 0:355: 'tex_coord0ny' : undeclared identifier
ERROR: 0:355: '' : missing #endif
ERROR: 0:355: '' : compilation terminated
ERROR: 4 compilation errors. No code generated.

预处理器错误地将tex_coord##n##.x和tex_coord##n##.y扩展为tex_coord0nx和tex_coord0ny,而非预期的tex_coord0.x和tex_coord0.y。

补充的详细错误信息(来自AMD Radeon RX 5500 XT)

第一个宏的错误:

Pasting "[" and "0" does not give a valid preprocessing token.
(注:##0##无报错)

第二个宏的错误:

Pasting "tex_coord0" and "." does not give a valid preprocessing token.


问题原因与解决办法

问题根源是AMD的GLSL预处理器对##运算符的实现更严格——GLSL预处理器基于C标准,要求##必须连接合法的预处理记号,而.、[这类标点不属于可拼接的记号元素。

针对第一个宏的修正

  1. cAmbColor[##n]中的##是多余的,直接写成cAmbColor[n]即可,宏参数n会被直接替换为数字,无需拼接:
    vec3 light_color_rgb = clamp( diffuse_light.rgb + amb_color##n.rgb * cAmbColor[n].rgb, 0.0, 1.0 );
    
  2. 像chan_ctrl##n##_color_light_enable、color##n##a##n这类标识符之间的##拼接是合法的,可以保留。

针对第二个宏的修正

tex_coord##n##.x的错误是用##连接了拼接后的标识符和.,这违反了预处理器规则。正确写法是去掉.前的##,直接写成tex_coord##n.x:

#define calc_tex_coord( n )                                        \
{                                                                  \
    expand_tex_func( n );                                          \
    tex_coord##n.x = dot( expand_tex_mtx( n )[ 0 ], tex_coord ); \
    tex_coord##n.y = dot( expand_tex_mtx( n )[ 1 ], tex_coord ); \
    float tw         = dot( expand_tex_mtx( n )[ 2 ], tex_coord ); \
}

通用注意事项

AMD预处理器对##的语法检查比Nvidia/Intel严格,需遵守:

  • 仅在标识符片段之间使用##拼接(比如把chan_ctrl、n、_color_light_enable拼成一个变量名)
  • 标识符与标点符号(.、[、]等)之间不能用##,直接书写即可,宏替换后会自动形成合法语法。

内容的提问来源于stack exchange,提问作者AboodXD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 19:45:01