如何在 glsl 中实现任意大小的向量
Posted
技术标签:
【中文标题】如何在 glsl 中实现任意大小的向量【英文标题】:How to implement a vector of any size in glsl 【发布时间】:2021-06-02 02:21:44 【问题描述】:目前我正在尝试为 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];
;
我做了一些阅读,发现内存缓冲区可以实现,但是,当您可以多次调用该函数时,我不知道该怎么做。 如果有人可以帮助我找到可以解决我的问题的有效代码,那就太好了,谢谢!
【问题讨论】:
@Rabbid76 有什么方法可以实现我想要的功能吗? @Rabbid76 为什么不呢?可以创建任意大小的数组,为什么我不能在结构中这样做? @Rabbid76 使用我使用的结构,它是恒定的,但它仍然返回错误 【参考方案1】:GLSL 无法实现您想要做的事情。
首先,让我们看看您问题中的构造:
struct kr_vec const int size; float elements[size]; ;
这不可能有几个原因:
在 GLSL 中,您可以创建任意大小的数组。不过见Shading Language 4.60 Specification (html) - 4.1.9 Arrays:
在声明中指定数组大小时,它必须是整数常量表达式 [...]
struct
的元素不能是const
。 const
是变量的Storage Qualifiers(或Parameter Qualifier),不能用于结构的元素。当然常量也需要初始化。
你可以用一个常数来指定数组大小,但这显然不是你想要的:
const int size = 4;
struct kr_vec
float elements[size];
;
我希望可能有一个模板结构可以使用 [...]
不,没有。查看最新的OpenGL Shading Language 4.60 Specification (HTML)。 在 GLSL 中没有模板或泛型的概念。
我做了一些阅读,发现内存缓冲区是可能的,[...]
不,不是。可变大小数组的唯一可能性是Shader Storage Buffer Object 的块定义中最底部的变量。然而,SSBO 是一个Interface,用于为着色器程序提供数据。它不是函数参数类型。
您可以在 GLSL 中获得的最接近的解决方案是 Preprocessor。使用#define
、#ifdef
、else
等编写类似 C 的宏。
或者,您可以动态生成着色器代码。只需在编译它们之前连接代码(字符串)的 sn-ps。
另一个可能的解决方案是函数重载。您可以声明多个具有相同名称但不同参数的函数(请参阅6.1. Function Definitions):
void foo(float[3] v)
void foo(float[4] v)
void main(void)
float[3] a;
foo(a);
float[4] b;
foo(b);
// [...]
【讨论】:
以上是关于如何在 glsl 中实现任意大小的向量的主要内容,如果未能解决你的问题,请参考以下文章
当我尝试增加矩阵大小时,在 AMD openCL/C 中实现矩阵向量乘法会导致系统死机
如何在python中实现适用于N维特征向量的GMM聚类EM算法(期望最大化算法)