2011-12-13 21 views
1

我想讓我的片段着色器遍歷序列化的四叉樹。 當找到內部節點時,rg vales被解釋爲相同紋理的索引。 藍色值爲0表示內部節點。第二次紋理訪問後的偏移錯誤

在第一步中,使用提供的uv座標從位置0x0處的2x2子圖像中讀取指針。 然後,該指針用於訪問同一紋理的另一個2x2部分。 但是,對於根節點的每個孩子來說,存在增加的偏移錯誤,導致錯誤的顏色。

這是我的着色器(對於調試功能,循環固定爲一次迭代,因此只能訪問四級樹的兩個級別)。

同樣爲了調試,我確實在左上角的孩子的位置放置了一個紅色的2x2圖片,右上方是綠色圖片,左下角是藍色,右下角孩子是黃色。

產生的圖像是這樣的: enter image description here

我完全地毫無頭緒。你們中的一個人能否想到這種情況發生的原因? 我檢查了所有座標轉換和計算3次都是正確的。

這裏是着色器:

// virtual_image.fs 
precision highp float; 

uniform sampler2D t_atlas; 
uniform sampler2D t_tree; 

uniform vec2 gridpoolSize; 
uniform vec2 atlasTileSize; 
uniform vec2 atlasSize; 

varying vec2 v_texcoord; 

const float LEAF_MARKER = 1.0; 
const float NODE_MARKER = 0.0; 

const float CHANNEL_PERECISION = 255.0; 

vec2 decode(const vec2 vec){ 
    return vec * CHANNEL_PERECISION; 
} 

void main() 
{ 
    vec4 oc = vec4(1); // output color 
    vec4 tColor = texture2D(t_tree, v_texcoord); // only for debuging 
    vec4 aColor = texture2D(t_atlas, v_texcoord); // only for debuging 
    // oc = mix(tColor, aColor, 0.5); 

    highp vec2 localCoord = v_texcoord; 

    // by convention the root node starts at [0,0] 
    // so we read the first pointer relative to that point 
    // we use the invertedGridpoolSize to convert the local coords in local coords of the first grid at [0,0] 
    highp vec3 pointer = texture2D(t_tree, localCoord/gridpoolSize).rgb;// pointer is correct at this point! 

    for(int i = 0 ; i < 1; i++) { 

     // divides the local coords into 4 quadrants 
     localCoord = fract(localCoord * 2.0); // localCoord is correct! 


     // branch 
     if(pointer.b <= NODE_MARKER + 0.1){ 
      highp vec2 index = decode(pointer.rg);// index is correct! 
      highp vec2 absoluteCoord = (localCoord + index)/gridpoolSize;// absoluteCoord is correct! 
      // we have a inner node get next pointer and continue 
      pointer = texture2D(t_tree, absoluteCoord).rgb; 
      oc.rgb = pointer.rgb; // this point in the code introduces a growing offset, I don't know where this comes from. BUG LOCATION 
      //gl_FragColor = vec4(1,0,0,1); 
     } else { 
      if(pointer.b >= LEAF_MARKER - 0.1){ 
       // we have a leaf 
       vec2 atlasCoord = ((decode(pointer.rg) * atlasTileSize)/atlasSize) + (localCoord * (atlasTileSize/atlasSize)); 
       vec4 atlasColor = texture2D(t_atlas, atlasCoord); 
       //vec4 atlasCoordColor = vec4(atlasCoord,0,1); 
       //gl_FragColor = mix(atlasColor, vec4(localCoord, 0, 1), 1.0); 
       //gl_FragColor = vec4(localCoord, 0, 1); 
       oc = vec4(1,0,1,1); 
      } else { 
       // we have an empty cell 
       oc = vec4(1,0,1,1); 
      } 
     } 
    } 
    //oc.rgb = pointer; 
    //oc.rgb = oc.rgb * (255.0/20.0); 
    gl_FragColor = oc; 
} 

有關如何序列四叉樹作爲紋理來看看本文的詳細信息:Octree Textures on the GPU

回答

1

事實證明,它是一個舍入的問題。

在解碼功能HAST的代碼更改爲:

vec2 decode(const vec2 vec){ 
    return floor(0.5 + (vec * CHANNEL_PERECISION)) 
} 

值的回報應該是爲int的指標,但這裏稍微小的,如5.99,而不是6