2013-05-03 67 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