OpenGL shader 中關於頂點坐標值的思考


今天工作中需要做一個事情:

在shader內部做一些空間距離上的計算,而且需要對所有的點進行計算,符合條件的顯示,不符合條件的點不顯示。

思路很簡單,在vertex shader內知道頂點坐標,進行計算,算好以后判斷是否需要顯示,例如設置alpha值,那么再將alpha值傳給fragment shader,在里面設置alpha的值就好了。

基本代碼如下

// vertex shader
#version 300 es
in vec4 vPosition;
in vec2 vTexCoord;
out float alpha;
void main() {
    alpha = 1.0f;
    if (vPosition...) {
        alpha = 0.0f;
    }
}

// fragment shader
#version 300 es
in float alpha;
void main() {
    // set the color..
}

看起來天衣無縫,邏輯合理,實際運行出現問題。由於我繪制的是一個球形,然后希望部分球面不顯示,僅顯示部分球面,基本功能確實實現了,但是顯示與隱藏的邊緣特別的粗糙,有特別大的鋸齒。仔細思考一下,繪制球形是從上到下繪制三角形帶得到的,出現的鋸齒很有可能就是三角形的邊。也就是說在計算的時候,很有可能是取了上傳的頂點數據來進行計算,而沒有對每一個點進行計算,所以只能判斷若干頂點,而不是每一個點。

回顧一下 OpenGL 渲染管線的知識,在光柵化階段,如何根據三個點畫出三角形?如何獲得每個點的紋理坐標?

通過光柵化將頂點按照拓撲結構渲染到屏幕上。例如,如果我們要繪制一個三角形那就意味着要找出位於三角形內部的所有點。對於這樣每一個點,在光柵化過程中都會調用片元處理器對其進行處理。在片元處理器中我們可以通過對紋理進行取樣或者使用其他技術來確定像素的顏色。
光柵器在三角形的三個頂點之間執行插值(比如說掃描線算法或者其他技術),並且通過執行片元着色器來“訪問”三角形內的每一個像素點。片元着色器會返回此片元的顏色值,光柵器會將這個顏色值更新到顏色緩沖區內並最終顯示出來(在通過一些其他測試例如深度測試之后),而從頂點着色器中傳出的其他任何變量都不會經歷上述步驟。如果片元着色器沒有明確的表示要使用那個變量(對於同一個頂點着色器,我們可以有多個片元着色器與之對應),那么一個驅動優化程序將對 VS 進行優化,並丟棄 VS 中的任何只影響該變量的指令(這個特定的程序指的是由一個 VS 和 FS 組合成的 Shader 程序)。然而如果 FS 確實用到這個變量,那么光柵器在光柵化過程會對這個變量進行插值。這通常意味着緊挨着的兩個像素之間的值會有一點差異(盡管三角形離相機越遠,這種現象會越來越不明顯)。

來源

結論:在vertex shader內對頂點做計算是錯誤的,一定要在fragment shader內,利用OpenGL插值的功能,拿到每一個點的坐標值,再進行計算。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM