如何将自定义结构从顶点着色器传递到片段着色器
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;
}
在片段着色器中,我定义了两个结构如下
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;
}