GLSL 中禁止递归?

问题描述 投票:0回答:2

我在尝试编写以下递归调用时遇到了此错误。我看过很多 GLSL 中递归光线追踪实现的演示,所以我假设 GLSL 支持递归。

难道不是这样吗?

OpenGL 返回编译时错误消息:

Error: Function trace(vec3, vec3, vec3, int) has static recursion

这是我的函数定义:

vec3 trace(vec3 origin, vec3 direction, vec3 illum, int order) 
{       
   float dist;  
   int s_index = getSphereIntersect(origin, direction, dist);   
   //if light hit
   float light_dist = 200;
   for(int k = 0; k < L_COUNT;k++)      
       if(s_intersects(l_center[k], l_radius[k], 
             origin, direction, 
             light_dist)) 
             if(light_dist < dist )             
                 return l_color[k]; //light is pure color  

   if (s_index != -1)
   {
       illum = s_color[s_index];
       for(int j = 0; j < L_COUNT; j++)
       {
           float ambient = 0.68;
           float diffuse = 0.5;
           vec3 poi = view + (direction * dist); 
           vec3 li_disp = normalize( poi - l_center[j]); 
           vec3 poi_norm = s_normal(s_center[s_index], s_radius[s_index], poi); 
            float shade=  dot(li_disp, normalize(poi_norm)); 
            if(shade < 0) shade = 0;
            illum = illum*l_color[j]*ambient + diffuse * shade; 
            //test shadow ray onto objects, if shadow then 0    
            if(order > 0)
                  illum = trace(poi+.0001*poi_norm, poi_norm, illum, order-1); 
        }   
    }   
    else
        illum = vec3(0,0,0);
    return illum; 
}
c++ opengl glsl raytracing
2个回答
17
投票

我假设 GLSL 支持递归

不。 GLSL 不支持或者更好的说法是允许递归函数调用。

GLSL 没有。 GLSL 内存模型不允许递归函数调用。这允许 GLSL 在根本不允许递归的硬件上执行。它允许 GLSL 在无法任意写入内存时发挥作用,这对于大多数着色器硬件来说都是如此(尽管随着时间的推移,情况变得越来越不真实)。

所以,GLSL 中没有递归。任何类型。

OpenGL Wiki – 核心语言 (GLSL)

不允许递归,即使是静态的也是如此。如果静态函数调用图为 程序包含循环。这包括通过声明为的变量进行的所有潜在函数调用 子程序统一(如下所述)。如果单个编译单元是编译时或链接时错误 (着色器)包含静态递归或通过子例程变量进行递归的可能性。

GLSL 4.5 规范,第 115 页


0
投票

虽然GLSL不直接支持递归,但可以使用宏来模拟。这是 GLSL 中递归斐波那契函数的实现:

int fib0(int n) //base case
{
    if (n <= 1)
        return n;
    else return -1; //return -1 if the maximum recursion depth is exceeded
}

//recursive cases: here, the maximum recursion depth is 5
fib(fib1,fib0)
fib(fib2,fib1)
fib(fib3,fib2)
fib(fib4,fib3)
fib(fib5,fib4)

#undef fib
#define fib fib5

宏扩展为以下函数:

int fib0(int n)
{
    if (n <= 1)
        return n;
    else return -1;
}

int fib1(int n){ if (n <= 1) return n; return fib0(n - 1) + fib0(n - 2); }
int fib2(int n){ if (n <= 1) return n; return fib1(n - 1) + fib1(n - 2); }
int fib3(int n){ if (n <= 1) return n; return fib2(n - 1) + fib2(n - 2); }
int fib4(int n){ if (n <= 1) return n; return fib3(n - 1) + fib3(n - 2); }
int fib5(int n){ if (n <= 1) return n; return fib4(n - 1) + fib4(n - 2); }
© www.soinside.com 2019 - 2024. All rights reserved.