2016-02-12 73 views
0

我想在屏幕上渲染正方形平面網格,255 x 255分辨率,128個世界單位 - 讀取浮動 - 大小。使用自定義着色器的OpenGL/ES渲染=網格上的僞影

分配和在RAM填補這一目,將其上傳到V-RAM,結合屬性和索引緩衝器,主叫glDrawElements正確地在其上還沒有一個問題,因爲預期該對象被繪製。

這是一個我正在做的水面模擬,頂點高度計算並上傳每一幀。當點擊「登記」水面時,會產生干擾,然後計算水流並更新法線(考慮從下到上的從左到右的流動)。

我的問題是,在網格的某些部分,我得到了您可以在下面的圖片中看到的渲染(第三次無剔除)。

**THIS** **THIS** **THIS (sans culling)**

注意的是,在最後一張照片居多,顯示的效果某處視口的最左側開始,持續向右另一半寬。只有當相機向左搖攝時,相對於網格的某些位置,而不是其他位置,相機的向前方向或ViewMatrix似乎對該製品沒有影響時,此效果纔可見。如果我將相機從一側滑到另一側,我可以注意到工件的原點與相機一起移動。這個起源似乎處於ViewPort的中心,並且具有與ViewPort的高度相等的高度,但是其寬度有時只有它的四分之一,其他時間可能會高達一半。正如我之前所說的,相機的前進方向/觀看矢量對渲染沒有影響。即使從「鳥瞰」視圖渲染,效果仍然可以觀察到。

似乎有一個問題,相機位置干擾與gl_Position = mat4_ModelViewProjection *位置;位在我的着色器中,或者可能是在頂點顏色計算中,float dot = dot(N,V);需要某種(怪物)驗證?

下面是我的一些代碼:

頂點着色器

"attribute vec2 pos;" 
"attribute vec2 normal;" 
"attribute float height;" 

"uniform vec3 sunColor;" 
"uniform float ax;" 

"varying PRECISION_MEDIUM vec4 waterColor_;" 
"varying PRECISION_LOW vec2 tex_coord;" 

"const vec3 g_WaterBlue = vec3(0.05, 0.25, 0.3);" 
"const vec3 g_WaterGreen = vec3(0.05, 0.3, 0.2);" 

"vec3 CalculateWaterColor(vec3 V, vec3 N)" 
"{" 
    "float dot = dot(N, V);" 

    "vec3 waterColor = mix(g_WaterGreen, g_WaterBlue, dot);" 
    "waterColor = mix(sunColor, waterColor, dot);" 
    "waterColor = mix(waterColor, g_WaterBlue, dot);" 

    "return waterColor;" 
"}" 

"void main()" 
"{" 
    "vec4 position = vec4(pos.x, height, pos.y, 1.0);" 

    "vec3 V = camera_pos.xyz + camera_forward.xyz - position.xyz;" 
    "V = normalize(V);" 

    "vec3 N = vec3(normal.x, 1, normal.y);" 
    "N = normalize(N);" 

    "waterColor_.xyz = CalculateWaterColor(V, N);" 
    "waterColor_.w = 1.0;"//ax * 18/length(camera_pos.xyz - position.xyz);" 

    "gl_Position = mat4_ModelViewProjection * position;" 
"}" 

平面網格頂點生成

// set accelerators 
accel1 = Size/static_cast<float>(Resolution - 1); 
accel2 = -Size/2.0f; 

x = accel2; 
y = accel2; 
z = 1.0f; 
// .. 

// fill the vertex buffer 
p_data = reinterpret_cast<float*>(buf_vertex->DataPointer) - 1; 
for (index1 = 0; index1 < Resolution; ++index1) 
{ 
    for (index2 = 0; index2 < Resolution; ++index2) 
    { 
     *++p_data = x; 
     *++p_data = y; 

     if (buf_vertex->Dimension == 3) 
     { 
      *++p_data = z; 
     } 

     x += accel1; 
    } 

    x = accel2; // Size/2 
    y += accel1; 
} 
// .. 

平面網格指數發電機

// LEFT to RIGHT, BOTTOM to TOP 
for (index1 = 0; index1 < (Resolution - 1); ++index1) 
{ 
    for (index2 = 0; index2 < (Resolution - 1); ++index2) 
    { 
     // CLOCKWISE 
     *++p_data = index2  + index1  * Resolution; 
     *++p_data = index2  + (index1 + 1) * Resolution; 
     *++p_data = index2 + 1 + (index1 + 1) * Resolution; 

     *++p_data = index2  + index1  * Resolution; 
     *++p_data = index2 + 1 + (index1 + 1) * Resolution; 
     *++p_data = index2 + 1 + index1  * Resolution; 

     // COUNTER-CLOCKWISE 
     //*++p_data = index2 +  (index1 + 1) * Resolution; 
     //*++p_data = index2 +  index1  * Resolution; 
     //*++p_data = index2 + 1 + index1  * Resolution; 

     //*++p_data = index2 + 1 + index1  * Resolution; 
     //*++p_data = index2 + 1 + (index1 + 1) * Resolution; 
     //*++p_data = index2 +  (index1 + 1) * Resolution; 
     // .. 
    } 
} 

事情我曾嘗試:

  • 啓用/禁用深度測試
  • 一個更大的值設置爲深度緩衝器大小(試過16,32,10 - 上的所有值相同的結果)
  • 玩剔除
  • 玩alpha混合
  • 深度排序 - 無用,不做混合反正...
  • 設置巨大的世界大小以網格化(10000.0f),以避免以百萬分之一的世界單位(1.0f)舍入誤差
  • 使用不同的索引緩衝區,以不同順序渲染頂點,從頂部到底部,離開以及它們各自的反轉 - 對減少或加重工件渲染沒有任何影響。

... HEPL! :)

+0

您是否啓用了MSAA? –

+0

沒有AA任何 –

+0

當你啓用它會發生什麼? –

回答

0

問題是不是在已發佈的代碼 - 這都是正確的!

問題是這樣的:

// enable blending 
    glEnable(GL_BLEND); 
    // .. 

    glBlendFunc 
    (
     GL_SRC_ALPHA, 
     GL_ONE_MINUS_SRC_ALPHA 
    ); 

GL_ONE_MINUS_SRC_ALPHA應GL_ONE避免畫這種僞像。

下面是一些更好理解glBlendFunc如何工作的例子。

  1. http://www.quake-1.com/docs/blending.jpg
  2. http://www.andersriggelsen.dk/glblendfunc.php

而且,重要的足夠做混合時,你應該記得glDisable(GL_DEPTH_TEST)

+0

爲什麼你首先需要混合?從圖片中,它看起來像只是渲染立體幾何。 –

+0

它實際上與天空的反射相混合,它是在水面網格之前繪製的 –

相關問題