如何将自定义结构从顶点着色器传递到片段着色器

How to pass a custom struct from vertex shader to fragment shader

在片段着色器中,我定义了两个结构如下

struct DirLight{
    vec3 direction;
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

struct PointLight {
    vec3 position;
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    float constant;
    float linear; 
    float quadratic;
};

并且在顶点着色器中,我定义了以下变量,因为我首先想在顶点着色器中对这些统一变量进行一些变换(例如片段着色器中不推荐的矩阵乘法) .

uniform DirLight dirLight; // only one directional light
uniform int pointLightCnt; // number of point light sources
uniform PointLight pointLight[MAX]; // point lights

如何将顶点着色器中的结构转移到片段着色器中?

我可以使用类似于 c++ 的方法吗? 在头文件中定义结构,vertex shader和[=22]中包含它们 =]fragment shader,然后在vertex shader中定义对应的out变量,在[=22]中定义对应的in变量=]fragment shader实现了吗?

我打算详细解释如何实现您的光照结构,以便它对任何光照类型都是通用的,但这是一个单独的问题。

您当前的问题是顶点函数根本不需要使用光照均匀;它们之间没有数据可传递。顶点着色器唯一应该做的就是将局部 space 转换为剪辑 space 并将中间世界 space 保存为片段着色器输入的单独部分,以便它可以计算光照正确。

所有光照计算都可以在 pixel/fragment 着色器上完成,任何动态光照(位置、半影计算、方向变化等)都应该在 CPU 上完成,然后传递给光照中的 GPU buffer/uniform 一次。

这是在 hlsl 中,但很容易转换为 glsl:

//Uniform
cbuffer matrix_cb : register(b0) {
    float4x4 g_MODEL;
    float4x4 g_VIEW;
    float4x4 g_PROJECTION;
};

struct vs_in_t {
    float3 position : POSITION;
    float4 color : COLOR;
    float2 uv : UV;
    float4 normal : NORMAL;
};

struct ps_in_t {
    float4 position : SV_POSITION;
    float4 color : COLOR;
    float2 uv : UV;
    float4 normal : NORMAL;
    float3 world_position : WORLD;
};

ps_in_t VertexFunction(vs_in_t input_vertex) {
    ps_in_t output;

    float4 local = float4(input_vertex.position, 1.0f);
    float4 normal = input_vertex.normal;
    float4 world = mul(local, g_MODEL);
    float4 view = mul(world, g_VIEW);
    float4 clip = mul(view, g_PROJECTION);

    output.position = clip;
    output.color = input_vertex.color;
    output.uv = input_vertex.uv;
    output.normal = normal;
    output.world_position = world.xyz;

    return output;
}