如何在 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 的元素不能是constconst 是变量的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#ifdefelse 等编写类似 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 中实现任意大小的向量的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中实现向量自回归?

当我尝试增加矩阵大小时,在 AMD openCL/C 中实现矩阵向量乘法会导致系统死机

如何在python中实现适用于N维特征向量的GMM聚类EM算法(期望最大化算法)

如何在 jQuery 中实现任意文本节点选择

OpenGL ES - 如何在 Blender Cycles Render 中实现光泽着色器?

我应该如何在 Delphi 中实现一个巨大但简单的索引字符串列表?