2017-04-25 39 views
2

你好我是GLSL的新手,在嘗試寫下面的遞歸調用時遇到了這個錯誤。我已經看到了GLSL中遞歸光線追蹤實現的很多演示,所以我假定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; 
} 
+2

如果你知道你的遞歸的最大深度可以用一個循環替換它和陣列充當堆疊 –

+0

@MrD沒錯的在這裏小例子[反射和折射不可能沒有遞歸光線追蹤?](https://stackoverflow.com/a/45140313/2521214) – Spektre

回答

4

我認爲GLSL支持遞歸

號GLSL沒有支持或更好的表示允許遞歸函數調用。

GLSL沒有。 GLSL內存模型不允許遞歸函數調用。這允許GLSL在簡單地不允許遞歸的硬件上執行。它允許GLSL的時候沒有隨意寫入內存,這是大多數着色器硬件的真實(儘管它正變得越來越真實與時間的能力發揮作用。

所以,GLSL沒有遞歸。任何類型的。

OpenGL Wiki – Core Language (GLSL)

遞歸是不允許的,甚至不是靜態的。靜態遞歸是否存在如果程序的靜態函數調用圖包含循環。這包括通過聲明爲 子程序統一變量(下面描述)的變量的所有潛在函數調用。如果單個編譯單元 (着色器)包含靜態遞歸或通過子例程變量遞歸的可能性,則這是編譯時或鏈接時錯誤。

GLSL 4.5 Specification, Page 115

+1

感謝您的信息。 –