2013-05-03 45 views
3

我在嘗試在opengl着色器中編寫光線跟蹤器時遇到了很多奇怪的問題。我試圖確定錯誤的來源是否是我自己,並且通常情況是這樣,但我得出的結論是,這些問題中的一些可能只是我的圖形驅動程序中的錯誤(我在ATI上)。在這些情況下,我剛剛實施瞭解決方法。GLSL:刪除死代碼會導致視覺錯誤

但我只是遇到了一些問題,我不知道如何解決(至少沒有真正奇怪的代碼),我無法將一些數據從統一數組切換到紋理緩衝區這一事實,因爲那一刻我刪除的均勻陣列引用(這並不做任何事情了,我已經刪除了數據的任何實際使用),我的那張着色器從這樣看:

https://dl.dropboxusercontent.com/u/39921754/bug_pic_0.png

這樣:

https://dl.dropboxusercontent.com/u/39921754/bug_pic_1.png

請注意,移動相機會導致您看到的不正常變化。

這是我改變了獲得這些結果的方法:(有問題的行註釋掉,他們訪問均勻陣列quad_vertex_indices)

bool Collide_KDTree(Ray ray, out Surface surface) 
{ 
float t_entry, t_exit; 

if(!RayBox(ray.tail, ray.head, scene_bounds.position, scene_bounds.extent, t_entry, t_exit)) 
    return false; 

uint node_indices[TREE_DEPTH]; 
float node_exits[TREE_DEPTH]; 

uint top= 0; 

node_indices[top]= kd_nodes.length()- 1; 
node_exits[top++]= t_exit; 

while(top> 0) 
{ 
    uint node_index_foo= node_indices[top- 1]; 
    KDNode node= kd_nodes[node_indices[top- 1]]; 
    t_exit= node_exits[top- 1]; 
    top--; 

    if(node.node_type== NodeType_Parent) 
    { 
     uint near_index, far_index; 

     if(ray.tail[node.split_axis] < node.split) 
     { 
      near_index= node.left_index_or_offset+ 1; 
      far_index= node.right_index_or_count+ 1; 
     } 
     else 
     { 
      near_index= node.right_index_or_count+ 1; 
      far_index= node.left_index_or_offset+ 1; 
     } 

     float t_intersection; 

     RayAxisAlignedPlane(ray.tail, ray.head, node.split_axis, node.split, t_intersection); 

     if(t_intersection> t_exit) 
     { 
      node_indices[top]= near_index; 
      node_exits[top++]= t_exit; 
     } 
     else if(t_intersection< t_entry) 
     { 
      if(t_intersection< 0) 
      { 
       node_indices[top]= near_index; 
       node_exits[top++]= t_exit; 
      } 
      else 
      { 
       node_indices[top]= far_index; 
       node_exits[top++]= t_exit; 
      } 
     } 
     else if(t_intersection> t_entry && t_intersection< t_exit) 
     { 
      if(t_intersection< 0) 
      { 
       node_indices[top]= near_index; 
       node_exits[top++]= t_exit; 
      } 
      else 
      { 
       node_indices[top]= far_index; 
       node_exits[top++]= t_exit; 

       node_indices[top]= near_index; 
       node_exits[top++]= t_intersection; 
      } 
     } 
    } 
    else 
    { 
     float shortest_distance= INFINITY; 
     bool collision_detected= false; 

     uint primitive_offset= node.left_index_or_offset; 
     uint primitive_count= node.right_index_or_count; 

     for(uint i= primitive_offset; i< (primitive_offset+ primitive_count); i++) 
     { 
      uint primitive_index= primitive_indices[i]; 

      if(primitive_index< QUAD_COUNT) 
      { 
       uint quad_index= primitive_index; 

       vec3 intersection; 

       //uint foo0= quad_vertex_indices[quad_index* 4+ 0]; 
       //uint foo1= quad_vertex_indices[quad_index* 4+ 1]; 
       //uint foo2= quad_vertex_indices[quad_index* 4+ 2]; 
       //uint foo3= quad_vertex_indices[quad_index* 4+ 3]; 

       vec3 vertex0= vertices[texelFetch(test_texture_buffer, int(quad_index* 4+ 0)).r]; 
       vec3 vertex1= vertices[texelFetch(test_texture_buffer, int(quad_index* 4+ 1)).r]; 
       vec3 vertex2= vertices[texelFetch(test_texture_buffer, int(quad_index* 4+ 2)).r]; 
       vec3 vertex3= vertices[texelFetch(test_texture_buffer, int(quad_index* 4+ 3)).r]; 

       if(RayQuad(ray.tail, ray.head, vertex0, vertex1, vertex2, vertex3, quad_normals[quad_index], intersection)) 
       { 
        float this_distance= distance(ray.tail, intersection); 

        if(this_distance< shortest_distance) 
        { 
         surface.position= intersection; 
         surface.normal= quad_normals[quad_index]; 
         surface.material= materials[quad_material_indices[quad_index]]; 

         shortest_distance= this_distance; 
         collision_detected= true; 
        } 
       } 
      } 
      else 
      { 
       uint sphere_index= primitive_index- QUAD_COUNT; 

       vec3 intersection; 

       if(RaySphere(ray.tail, ray.head, spheres[sphere_index].position, spheres[sphere_index].radius, intersection)) 
       { 
        float this_distance= distance(ray.tail, intersection); 

        if(this_distance< shortest_distance) 
        { 
         surface.position= intersection; 
         surface.normal= normalize(intersection- spheres[sphere_index].position); 
         surface.material= materials[sphere_material_indices[sphere_index]]; 

         shortest_distance= this_distance; 
         collision_detected= true; 
        } 
       } 
      } 
     } 

     if(collision_detected && (shortest_distance/ length(ray.head))< t_exit) 
      return true; 

     t_entry= t_exit; 
    } 
} 

return false; 

}

這似乎給我這只是一個編譯器問題,但如果不是,那很好,因爲這意味着我可以修復它。

有誰知道可能是什麼原因造成的,我的選擇是什麼?我有時間限制,所以我正在考慮只是做一個黑客才能得到這個工作(即只留下行,或類似的東西)

+0

確保您將變量初始化爲某些默認值。在NVidia驅動程序中,我讓着色器瘋狂地打印像素怪異的東西,因爲我有一些變量未初始化。可能您的情況遭受同樣的問題。 – 2013-05-03 18:10:08

回答

2

恐怕它看起來非常像着色器編譯器錯誤。統一數組應該在着色器程序之外進行優化(除非在其他地方引用),而不管這些行是否被註釋掉。

這可能是值得檢查的制服(使用glGetActiveUniform)的程序對象有和沒有這些行評論。

另外 - 嘗試在不同的硬件上運行它。

+1

我不知道glGetActiveUniform,謝謝。我有其他人運行它,似乎我的統一陣列大小太大了。 (雖然這就是爲什麼我試圖切換到不同的內存)。這很容易確定,因爲這些其他編譯器正在吐出有用的信息,包括行號和實際的單詞「數組太大」,更不用說拒絕編譯着色器(它出現的nvidia卡)。我現在很確定我的問題與擁有巨大的統一數組和接受它的編譯器有關,然後在執行期間將會執行beserk。 – user2345397 2013-05-07 03:13:36

+0

@ user2345397你應該爲你自己的問題創建一個答案,因爲你找到了解決問題的方案 – Julius 2013-08-05 18:15:32

+0

不幸的是,我不能有意義地解釋我的錯誤和觀察到的問題之間的聯繫,所以我不認爲我可以打電話給我做什麼修復(或者更確切地說,我所做的修復),觀察到的問題可以被稱爲合法的答案。 – user2345397 2013-08-11 00:43:11