如何有效和动态地将多个制服传递给GLSL

时间:2017-03-30 10:08:06

标签: c++ opengl glsl

我想在程序中传递一个struct数组,我知道有一些方法可以做到这一点,但我想有效地做到这一点,这就是我知道我能做到的:

  • 我可以使用简单地创建一个包含我想要传递给着色器的结构的结构,并创建一个可以传递多少数组的数组:

    struct Light
    {
        vec3 Position;
        vec3 diffuse;
        float Intensity;
    };
    
    #define NUM_OF_LIGHTS 5
    uniform Light lights[NUM_OF_LIGHTS];
    

    优点:非常容易。

    缺点:这不是动态的,我需要选择最大量的灯光,我想避免这样做。

  • 我可以使用我在opengl.org上读到的统一块对象(UBO),我可以从OpenGL 4.0中使用数组(顺便说一句,这是我的目标,(考虑4.1))。< / p>

    优点:清洁工(?)要做。可能更快(?) 1

    缺点:仍然不是动态的。

  • 着色器存储块对象(SSBO)是另一种选择,但我无法使用它们,因为它们是4.3版本的核心。对我不好,因为据我所知,它们是动态的,这就是我想要的。

我无法找到关于如何按照我想要的方式传递任何东西。

如果我不能这样做,游戏引擎如何在不知道用户将输入多少灯光的情况下创建多个灯光(考虑到他们使用OpenGL并且他们的目标是3.X到4.0,这对我来说似乎是合理的) ?

提前致谢。

脚注:

  1. 我可能在这里错了,所以如果我告诉我,我会删除它们。

2 个答案:

答案 0 :(得分:1)

一个选项是渲染,例如前16个灯光,然后为接下来的16个灯光做另一个灯光并继续直到所有灯光都渲染完毕。这将允许任意和动态数量的灯。

类似的东西:

for (int i = 0; i < lights.size(); i += 16) {
    setUniformData(lights, i, i+15);
    render();
}

请注意,这需要添加剂混合

glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);

答案 1 :(得分:0)

稍微修改一下你的第一个解决方案:

struct Light
{
    vec3 Position;
    vec3 diffuse;
    float Intensity;
};

#define MAX_NUM_OF_LIGHTS 50            //define max number of lights
uniform Light lights[MAX_NUM_OF_LIGHTS];
uniform int number_of_lights            //the actual number of lights, for loops 

仍然不完全是你想要的,但效果很好。