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

GLSL顶点着色器复用方案:适配不同片段着色器的技术问询

顶点着色器复用与着色器配对问题

现有着色器情况

Vector Shader(顶点着色器)

#version 330 core

layout (location = 0) in vec4 values;
layout (location = 1) in vec4 rect;
layout (location = 2) in int depth;
layout (location = 3) in float radians;
layout (location = 4) in float effect;

layout (std140) uniform Matrices
{
    mat4 projection;
    mat4 view;
};


out vec2 texCoord;

void main()
{
    vec2 transformed = vec2(values.xy * rect.zw*.5); //scale
    transformed = vec2(cos(radians)*transformed.x - sin(radians)*transformed.y,sin(radians)*transformed.x + cos(radians)*transformed.y); //rotate
    transformed += rect.xy + rect.zw*.5; //move
    gl_Position = projection*view*vec4(transformed,depth,1);
    texCoord = vec2(values.z,values.a);
}

原Fragment Shader(片段着色器)

#version 330 core

out vec4 fragColor;
in vec2 texCoord;
uniform sampler2D sprite;

void main()
{
    vec4 text = texture(sprite,texCoord);
    fragColor = text;
}

Paint Shader(新增片段着色器)

#version 330 core

//renders a sprite in a specific color

out vec4 fragColor;
in vec2 texCoord;
in vec4 tint;
uniform sampler2D sprite;

void main()
{
    vec4 text = texture(sprite,texCoord);
    if (text.w ==0)
    {
        fragColor = vec4(0);
    }
    else
    {
        fragColor = tint;
    }

}

当前为适配Paint Shader,需维护一份几乎完全相同的顶点着色器(仅新增tint输入输出逻辑),后续修改成本高。需求为:找到无需维护两份顶点着色器的方案,并确认是否可用带tint输出的顶点着色器配合原Fragment Shader。


解决方案

1. 直接复用带tint输出的顶点着色器配合原Fragment Shader

完全可行。GLSL允许顶点着色器输出的变量在片段着色器中不被引用,驱动会自动忽略未使用的输出变量,不会引发编译错误或性能问题。你可以直接用这款带tint输出的顶点着色器同时搭配原Fragment Shader和Paint Shader,无需修改原片段着色器代码。

2. 使用预处理器宏实现单份顶点着色器适配两种场景

为彻底避免维护两份代码,可在顶点着色器中加入预处理器宏,控制tint相关逻辑的启用。修改后的顶点着色器代码如下:

#version 330 core

layout (location = 0) in vec4 values;
layout (location = 1) in vec4 rect;
layout (location = 2) in int depth;
layout (location = 3) in float radians;
layout (location = 4) in float effect;
#ifdef ENABLE_TINT
layout (location = 5) in vec4 tint_;
#endif

layout (std140) uniform Matrices
{
    mat4 projection;
    mat4 view;
};


out vec2 texCoord;
#ifdef ENABLE_TINT
out vec4 tint;
#endif

void main()
{
    vec2 transformed = vec2(values.xy * rect.zw*.5); //scale
    transformed = vec2(cos(radians)*transformed.x - sin(radians)*transformed.y,sin(radians)*transformed.x + cos(radians)*transformed.y); //rotate
    transformed += rect.xy + rect.zw*.5; //move
    gl_Position = projection*view*vec4(transformed,depth,1);
    texCoord = vec2(values.z,values.a);
#ifdef ENABLE_TINT
    tint = tint_;
#endif
}

使用方式:

  • 搭配原Fragment Shader时,编译顶点着色器不定义ENABLE_TINT宏,此时着色器会自动剔除tint相关代码,功能与原Vector Shader完全一致。
  • 搭配Paint Shader时,编译顶点着色器时定义ENABLE_TINT宏(例如在OpenGL中通过编译参数添加#define ENABLE_TINT),此时着色器会包含tint的输入输出逻辑,适配Paint Shader需求。

这样只需维护一份顶点着色器代码,后续修改仅需在一处操作即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 07:43:15