统一数组中的某些元素被错误地优化了?

问题描述

我开始创建基本的漫射光照着色器,我使用统一数组存储灯光的信息。

循环的大小可变,由“ 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不支持没有构造的原始统一数组,但这是我发现的唯一方法。无论如何,我最终都会将我的所有制服重构为结构,所以我想这很好。

感谢大家的帮助,而我也很想回答一个草率的问题!