glsl函数指针(或等效物)

glsl函数指针(或等效物),glsl,function-pointers,raytracing,Glsl,Function Pointers,Raytracing,我试图根据变量的值调用许多函数中的一个。该变量是在运行时设置的,因此CPU上的代码将无法工作。由于可能性很大,使用if/switch语句会很慢。[可能不正确] 我正在寻找一种将函数存储在数组中的方法,可以使用函数指针,也可以将实际方程(例如texcoord.x*2)存储在数组中 psuedo代码示例: in vec2 texcoord; out vec4 color; int number; //Assigned a number between 0 and 300 d

我试图根据变量的值调用许多函数中的一个。该变量是在运行时设置的,因此CPU上的代码将无法工作。由于可能性很大,使用if/switch语句会很慢。[可能不正确]

我正在寻找一种将函数存储在数组中的方法,可以使用函数指针,也可以将实际方程(例如texcoord.x*2)存储在数组中

psuedo代码示例:

    in vec2 texcoord;
    out vec4 color;

    int number; //Assigned a number between 0 and 300 during runtime

    float func1(void) {
      return texcoord.x + texcoord.y;
    }

    float func2(void) {
      return texcoord.x*2;
    }

    ...

    float func299(void) {
      return texcoord.y - 7;
    }

    void main(void) {
      number = <something calculated during runtime>;
      float output = func<number>(); //              <--------------
      color = vec4(output, output, output, 1);
    }
vec2 texcoord中的
;
输出vec4颜色;
整数//在运行时分配了一个介于0和300之间的数字
浮动功能1(无效){
返回texcoord.x+texcoord.y;
}
浮动功能2(无效){
返回texcoord.x*2;
}
...
浮动func299(无效){
返回texcoord.y-7;
}
真空总管(真空){
数字=;

float output=func();//GLSL没有函数指针。即使SPIR-V也没有函数指针。着色器表示有限的执行环境。其中一个限制是缺少堆栈要求。如果没有这些指针,就无法真正拥有任意函数指针

GLSL 4.00可怕的il-advised1功能可能也不会有帮助。只有当您的
是CPU生成的值时,它才会有帮助,而这在您的情况下似乎不太可能

唯一的通用解决方案是switch语句。坦率地说,这没什么错

我的意思是,不管怎样,你做这种情况都会彻底破坏你的性能。不管它是如何实现的,如果同一个波前中的不同实例正在执行不同的代码,那么你的性能就有点糟糕了

更不用说,switch语句不一定会因为存在多少条件而变慢。它的实现方式完全取决于硬件。如果有跳转表,则可以合理高效地完成(当然,忽略上述性能问题)

另外,32上校的想法是,将每个函数的操作编码为具有恒定向量的点积。显然,这限制了各种函数的实际执行。但如果它在您的情况下起作用,它就起作用了


< P > 1。如果你想对此进行讨论,请考虑SpIL-V为GLSL的每一个特性提供了一个模拟,不管冗余、愚蠢或不必要……除了着色器子程序。

< P> GLSL中没有函数指针,但可以定义一个具有函数名列表的结构:

struct functions_list {
    int sin;
    int cos;
    int tan;
    int fract;
};
const functions_list functions = functions_list(1,2,3,4);
使用此函数名列表,可以模拟回调:

float callback(int func,float arg){
    if(func == functions.sin)
        return sin(arg);
    else if(func == functions.cos)
        return cos(arg);
    else if(func == functions.tan)
        return tan(arg);
    else if (func == functions.fract)
        return fract(arg);
    else
        return 0.0;
}

这些“函数指针”可用于模拟。

“使用if/switch语句由于可能性很大,速度会很慢。”这是一个相当大胆的假设。如果所有函数都是线性方程组,则可以创建向量数组,并获得tex坐标和向量的点积。(例如
func1(texcoord)=点(vec3(texcoord,1),vec3(1,1,0))
func299(texcoord)=点(vec3(texcoord,1),vec3(0,1,-7))
@jjxtra:它将作为