2011-05-27 57 views
1

情況:生成具有不同變換和旋轉的形狀和相應邊的N個樣本(使用Sobel濾波器或我自己的),而視口(大小= 600 * 600)和相機保持常量。即將有N個樣本+ N個相應的邊緣。使用幀緩衝對象(FBO)或?屏幕多屏幕渲染目標?

我想做到這個樣子,

使用一個帶2個renderbuffers FBO [即每個緩衝區的大小將是=(N * 600)* 600] - 第一對於N的形狀和第二對相應的形狀的邊緣

問題:

  1. 它是達到上述的最佳方式事情呢?
  2. 雖然視口大小是600 * 600像素,但形狀只會佔用大約50 * 50像素。那麼是否有任何有效的方法僅在第二緩衝區上對邊界框/ AABB區域應用邊緣檢測?也只能有效地讀取2N邊界框(N個樣本+ N個相應邊)?

回答

2

1:我不確定你稱之爲「最佳方式」。使用多重渲染目標:創建兩個600 * N的紋理,將它們綁定都與調用glDrawArrays的FBO,並在片段着色器,所以這樣的事情:

layout(location = 0) out vec3 color; 
layout(location = 1) out vec3 edges; 

寫入時爲「顏色」和「邊緣」 ,你會有效地寫入你的紋理。

2:你不應該這樣做。計算CPU上的邊界框,並投影它們(即將每個角乘以ModelViewProjection矩陣)以獲得2D中的邊界框。順便說一下:首先計算邊界框,以便不需要600 * 600紋理,但50 * 50 ...

編輯:你通常限制繪製區域與glViewPort。但它只有一個視口,而且你需要幾個視口。你可以嘗試Viewport array extension,並且在流血邊緣生活,或者通過AABB的紋理,或者不要擔心,直到性能問題...

哦,你不能像這樣使用Sobel。 Sobel要求你可以讀取周圍的所有紋理元素,這是因爲你現在正在渲染所述紋理元素。要麼做一個沒有MRT(第一種顏色,然後是邊緣)的雙通道算法,或者不要使用Sobel並猜測你在着色器中的邊緣(我真的不知道它是怎麼樣的)

+0

@ Calvin-謝謝。它是'大約'50 * 50即將會有所不同,因爲有時它可能會更大或更小,這是由於透視投影的z轉換效應。所以不能這樣做。只有我們可以在這裏做的訣竅就是讀我想。 – Rudi 2011-05-27 23:25:00

+0

@Rudi編輯答案 – Calvin1602 2011-05-27 23:32:55

+0

@ Calvin-請考慮我從未使用過着色器。我不能使用: layout(location = 0)out vec3 color; (顏色[i,j-1]!=顏色[i,j + 1] ||(顏色[i-1,j]!=顏色[i + 1,j])1:0 ; layout(location = 1)out vec3 edges; – Rudi 2011-05-28 17:39:10

1

就像Calvin說的那樣,你必須先將對象渲染到第一幀緩衝區,然後將其作爲紋理(使用紋理附件而不是渲染緩衝區)綁定到第二遍以找到邊緣,因爲邊緣檢測通常需要訪問像素的周圍像素。

關於你的第二個問題,你可以使用模板緩衝區。只需在第一遍繪製您的形狀,並讓他們寫入模板緩衝區的參考值。然後進行邊緣檢測(通常是通過渲染一個屏幕大小爲四捨五入的片段着色器),並將模板測試配置爲僅通過模板緩衝區包含參考值的位置。這種方式(假設早期的z硬件,現在很常見),片段着色器只會在形狀實際繪製到的像素上執行。

+0

@ Christian-不使用一個帶有2個紋理緩衝區的FBO並應用片段着色器,我們可以實現第一個任務的最佳方式?正如加爾文所建議的,而不是改變FBO?即一個textrue將具有形狀顏色輸出,另一個將使用片段着色器具有邊緣? – Rudi 2011-05-28 17:51:34

+0

@Rudi是的,但像Calvin說的那樣,你不能繪製形狀並計算同一通道中的邊緣,因爲邊緣檢測器需要訪問相鄰像素。 – 2011-05-28 19:49:39

+0

是的。因此,我的新評論。這是有道理的,順便說一句:你不能訪問你的鄰居,你甚至不知道它是否已經被計算出來了! – Calvin1602 2011-05-29 08:28:44