问题描述
我开始创建基本的漫射光照着色器,我使用统一数组存储灯光的信息。
循环的大小可变,由“ DirectionLightsLength”统一规定。出于某种原因,从我的代码中优化了从zeroeth出发的所有元素(OpenGL找不到它的位置)。有什么方法可以防止这种情况,而无需手动展开我的for循环并删除其可变长度?
我正在通过设置“ shaderName [index]”的统一位置来设置着色器端的数组,
uniform vec3 DirectionLightsDirections[4];
uniform vec3 DirectionLightsColors[4];
uniform int DirectionLightsLength;
out vec2 v2f_uv;
out vec3 v2f_diffuse;
out vec3 v2f_normal_world;
uniform mat4 ModelRotation;
uniform mat4 ModelToWorld;
uniform mat4 WorldToView;
void main()
{
vec4 worldPos = vec4(in_position,1f) * ModelToWorld;
vec4 viewPos = worldPos * WorldToView;
gl_Position = viewPos;
v2f_uv = in_uv;
v2f_normal_world = (vec4(in_normal,1f) * ModelRotation).xyz;
vec3 diffuseColorSum = vec3(0,0);
for (int i = 0; i < DirectionLightsLength; i++){
float product = dot(DirectionLightsDirections[i],v2f_normal_world);
float diffuseShade = clamp(product,1);
vec3 diffuseColor = product * DirectionLightsColors[i];
diffuseColorSum += diffuseColor;
}
v2f_diffuse = clamp(diffuseColorSum,1);
}
感谢您的帮助! 我正在使用OpenTK,这是OpenGL的c#包装器。
解决方法
找到了解决方案:如果我在这样的着色器的单个结构中声明我的灯光制服
struct DirectionLight{
vec3 Color;
//... other members
};
uniform DirectionLight directionLights [4];
当我缓存材料的所有均匀位置时,它们将被计为活动制服,因此,我可以通过以下格式的字符串键(在c#字典中缓存均匀位置)访问它们的位置:
$"{light_name}[{index}]{member_name}"
我不知道这是否意味着OpenTK不支持没有构造的原始统一数组,但这是我发现的唯一方法。无论如何,我最终都会将我的所有制服重构为结构,所以我想这很好。
感谢大家的帮助,而我也很想回答一个草率的问题!