簡體   English   中英

GLSL 頂點着色器取消渲染

[英]GLSL vertex shader cancel render

可以在頂點着色器中終止像素的渲染嗎? 例如,如果一個頂點不滿足某個要求,取消該頂點的渲染?

我假設您說“終止頂點的渲染”。 不,你不能; OpenGL 對 VS 的輸入頂點與輸出的 1:1 比率非常嚴格。 此外,它並不真正意味着您想要它,因為頂點不會被渲染。 原語做的,原始的,可以由一個以上的頂點。 例如,丟棄三角形帶中間的頂點意味着什么。

這就是幾何着色器能夠“剔除”圖元的原因; 它們專門處理一個基元,而不僅僅是單個頂點。 這是通過簡單地不發出任何頂點來完成的; GS 必須顯式地發出它想要輸出的頂點。


頂點着色器現在能夠剔除圖元。 這是使用OpenGL 4.5 的“剔除距離”功能完成的 就像gl_ClipDistance一樣,它只是在頂點之一超過閾值時剔除整個圖元,而不是剪裁。

理論上,您可以使用頂點着色器生成退化(零區域)圖元。 具有零面積的圖元不應導致任何光柵化,因此不會渲染任何片段。 然而,它並不是特別直觀,尤其是當您使用共享頂點的圖元時。

但是不,取消頂點幾乎沒有意義。 它是構建基元的基本單位。 如果您只是刪除單個頂點,那么您將以未定義的方式更改光柵化輸出。

簡而言之,頂點不是在屏幕上創建像素的原因。 頂點之間的連接創建了圖元,最終導致了像素。 幾何着色器在逐個圖元的基礎上運行,因此通常可以在它們中以編程方式取消光柵化和片段着色。


更新:

我注意到您使用GL_POINTS作為原始類型。 在這種特殊情況下,為防止頂點沿着管道向下移動,您只需將其位置設置在相機視野范圍之外的某個位置即可。 頂點將被剪裁,並且不會發生光柵化或片段着色。

這是在片段着色器中測試某些條件然后丟棄的更有效的解決方案,因為您跳過光柵化並且根本不必執行片段着色器。 更不用說, discard通常會作為后着色器執行標志來工作,它告訴 GPU 丟棄結果 - 無論您在着色器中的哪個位置發出discard指令,GPU 通常都被迫執行整個着色器。 因此, discard很少會帶來性能優勢,並且在許多情況下,它可以禁用其他可能更有用的硬件優化。 不幸的是,這就是 GPU 調度其着色器工作負載的方式的本質。

最便宜的片段是您永遠不必處理的片段:)

您無法在頂點着色器中終止像素的渲染(它不處理像素),但您可以在片段着色器中使用丟棄指令。

我正在詳細說明 Andon M. Coleman 的答案,恕我直言,這應該被標記為正確的答案。

盡管 OpenGL 規范堅持認為您不能跳過片段着色器步驟(除非您實際上刪除了幾何着色器中的整個圖元,正如Nicol Bolas 正確指出的那樣,這有點矯枉過正,恕我直言),您可以做到在實踐中,通過讓 OpenGL 剔除整個幾何體,因為現代 GPU 具有早期的片段拒絕優化,這可能會產生相同的效果。

而且,對於記錄,丟棄整個幾何體真的很容易:只需將頂點寫入 (-1, -1, -1),(1,1,1) 立方體之外,

gl_Position = vec4(2.0, 2.0, 2.0, 1.0);

……你走吧!

希望這可以幫助

您可以對頂點流進行更改,包括移除頂點,但可以在幾何着色器中進行更改。 如果您研究幾何着色器,您可能會發現您正在尋找的解決方案只是未能“發射”頂點。

編輯:如果渲染三角形條帶,您可能還需要注意在移除頂點時開始新的圖元; 如果您調查 geom,您就會明白為什么。 着色器。 使用 GL_POINTS 就不是問題了。

是的,例如,如果你發送一個只有 2 個頂點的三角形帶,那么你確實無法渲染任何東西——就像你首先傳入這樣一個退化帶一樣。 然而,這並不意味着不能在 GL 方面更改頂點流。

希望有幫助>湯姆

  1. 將位置設置在 ndc 之外

    要么

  2. 設置flag並傳給fragment,根據flag在fragment中丟棄

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM