如何在glsl中实现任意大小的向量



目前我正试图实现一个数学库的glsl,这将是有用的着色器程序,我要创建以后。我试着从简单的开始,创建一个大小为N的向量结构,在整个程序中大小不会改变。例如,一个向量可以是kr_vec a = kr_vec(4, float(4)(1.0,2.0,3.0,4.0))或者它甚至可以有两个分量或者更多的kr_vec b = kr_vec(2, float(2)(1.0,2.0))。我试着为它写一个结构体

struct kr_vec {
const int size;
float elements[size];
};

但是它不起作用,我希望有一个模板结构,我可以使用,这意味着我不必为我想使用的每个数据类型数组创建一个不同的结构。

template <typename in_type, const int in_length>
struct kr_vec {
in_type elements[in_length];
};

我已经做了一些阅读,我看到这是可能的内存缓冲区,然而,我不知道如何做到这一点,当你可以调用函数不止一次。如果有人能帮助我找到一个工作的代码块,解决我的问题,那将是伟大的,谢谢!

你想做的在GLSL中是不可能的。


首先,让我们看看你问题中的结构:

struct kr_vec {
const int size;
float elements[size];
};

由于以下几个原因,这是不可能的:

在GLSL中,可以创建任意大小的数组。但是请参见Shading Language 4.60 Specification (HTML) - 4.1.9 Arrays:

在声明中指定数组大小时,必须是整型常量表达式[…]

struct的元素不能是constconst是变量的存储限定符(或参数限定符),不能用于结构的元素。当然常量也需要初始化

你可以用常量来指定数组的大小,但这显然不是你想要的:

const int size = 4;
struct kr_vec {
float elements[size];
};

我希望可能有一个模板结构,我可以使用[…]

没有。参见最新的OpenGL着色语言4.60规范(HTML)。
在GLSL中没有模板或泛型的概念。


我已经做了一些阅读,我看到这是可能的内存缓冲区,[…]

不,它不是。可变大小数组的唯一可能性是Shader Storage Buffer Object块定义中最底部的变量。然而,SSBO是为着色器程序提供数据的接口。它不是函数参数类型。


您可以在GLSL中获得的最接近的解决方案是预处理器。使用#define,#ifdef,else等编写C类宏。
或者您可以动态生成着色器代码。只需在编译代码片段(字符串)之前连接它们。


另一个可能的解决方案是函数重载。您可以使用相同的名称但不同的参数声明多个函数(参见6.1)。函数定义):

void foo(float[3] v) { }
void foo(float[4] v) { }
void main(void)
{
float[3] a;
foo(a);
float[4] b;
foo(b);
// [...]
}

最新更新