Second order functions in GLSL?

巧了我就是萌 提交于 2020-02-21 12:35:28

问题


I'm looking for a way to use a function as an argument to another function in GLSL. In regular C, it can be simulated by passing a function pointer as a function argument. It also seems that other languages (like HLSL) now provide ways to deal with high-level constructs like higher-order functions, or can simulate them with clever use of HLSL structures. unfortunately I'm stuck with GLSL for now, and I can't find any way to simulate higher-order functions. Is it really impossible in current (4.2) GLSL ? Or am I missing some clever trick ?

common example of what I'm trying to achieve :

int f(someType f2, int i) {
    return f2(i);
}

回答1:


I'm looking for a way to use a function as an argument to another function in GLSL.

Short answer: you can't.

The closest thing to this kind of functionality you'll get in GLSL is shader subroutines. And that only allows the external OpenGL API to select which subroutine to use, not the shader itself.

So just do the switch/case statement and get it over with.




回答2:


There are no higher-order functions in GLSL, but it's possible to simulate them:

#define second_order 1
#define second_order1 2
#define another_function 3
//there are no function pointers in GLSL, so I use integers instead

int call(int f2,int param1){
    //instead of a function, an integer is passed as a parameter
    switch(f2){
        case second_order:
            return param1*2;
        case second_order1:
            return param1*3;
    }
}

int call(int f2,int param1,int param2){
    //this function can be overloaded to accept more parameters
    switch(f2){
        case another_function:
            return param1 + param2;
    }
}

int f(int f2, int i) {
    return call(f2,i);
}

Alternatively, this can be done using structs:

struct function{
    int x;
};
function Sin(){
    return function(1);
}
function Cos(){
    return function(2);
}
float call(function func,float x){
    if(func == Sin()){
        return sin(x);
    }
    else if(func == Cos()){
        return cos(x);
    }
}

vec4 map(function func,vec4 a1){
    //this function can be overloaded for different array sizes
    vec4 a2;
    for(int i = 0; i < 4; i++){
        a2[i] = call(func,a1[i]);
    }
    return a2;
}


来源:https://stackoverflow.com/questions/9500494/second-order-functions-in-glsl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!