OpenGL核心技術之面剔除

2021-07-26 18:01:23 字數 2856 閱讀 7422

筆者介紹:

姜雪偉,

it公司技術合夥人,

it高階講師,

csdn

社群專家,特邀編輯,暢銷書作者,國家專利發明人

;已出版書籍:《手把手教你

架構

3d遊戲引擎》電子工業出版社

和《unity3d

實戰核心技術詳解》電子工業出版社等。

面剔除技術在遊戲開發中主要目的是提高效率,在現實生活中也會經常遇到這種情況,比如我們**一幢大廈,我們在大廈的某個位置看,只能看到大廈的一到兩個面,其他的面我們是看不到的,因為被擋住了,但是這不妨礙我們看這幢大廈,在虛擬城市建模時,也會使用面剔除,城市漫遊如果只是沿著道路行走,背對道路那一側的建築面是永遠看不到的,美術可以使用一張麵片代替,不需要再建複雜的麵片,但是在遊戲中模型的面我們不知道那個面是背對玩家的,因為在場景中模型是可以隨意移動和旋轉的。這就要用到遊戲中的面剔除技術。

下面開始講遊戲中的面剔除技術處理,遊戲一般會採用dx或者opengl去做渲染,以opengl為例,它會檢查所有正面朝向(front facing)觀察者的面,並渲染它們,而丟棄所有背面朝向(back facing)的面,這樣就節約了我們很多片段著色器的命令(它們很昂貴!)。我們必須告訴opengl我們使用的哪個面是正面,哪個面是反面。opengl使用一種聰明的手段解決這個問題——分析頂點資料的連線順序(winding order)。

當我們定義一系列的三角頂點時,我們會把它們定義為乙個特定的連線順序

(winding order)

,它們可能是順時針的或逆時針的。每個三角形由

3個頂點組成,我們從三角形的中間去看,從而把這三個頂點指定乙個連線順序。

正如你所看到的那樣,我們先定義了頂點1,接著我們定義頂點2或3,這個不同的選擇決定了這個三角形的連線順序。下面的**展示出這點:

glfloat vertices = ;
每三個頂點都形成了乙個包含著連線順序的基本三角形。

opengl

使用這個資訊在渲染你的基本圖形的時候決定這個三角形是三角形的正面還是三角形的背面。預設情況下,逆時針的頂點連線順序被定義為三角形的正面。

當定義你的頂點順序時,你如果定義能夠看到的乙個三角形,那它一定是正面朝向的,所以你定義的三角形應該是逆時針的,就像你直接面向這個三角形。把所有的頂點指定成這樣是件炫酷的事,實際的頂點連線順序是在光柵化階段(

rasterization stage

)計算的,所以當頂點著色器已經執行後。頂點就能夠在觀察者的觀察點被看到。

我們指定了它們以後,觀察者面對的所有的三角形的頂點的連線順序都是正確的,但是現在渲染的立方體另一面的三角形的頂點的連線順序被反轉。最終,我們所面對的三角形被視為正面朝向的三角形,後部的三角形被視為背面朝向的三角形。下圖展示了這個效果:

在頂點資料中,我們定義的是兩個逆時針順序的三角形。然而,從觀察者的方面看,後面的三角形是順時針的,如果我們仍以1、

2、3的順序以觀察者當面的視野看的話。即使我們以逆時針順序定義後面的三角形,它現在還是變為順時針。它正是我們打算剔除(丟棄)的不可見的面!

下面進入

opengl

實際**操作,開啟

opengl

的gl_cull_face

選項就能開啟面剔除功能函式:

glenable(gl_cull_face);
從這兒以後,所有的不是正面朝向的面都會被丟棄。目前,在渲染片段上我們節約了超過50%的效能,但記住這只對像立方體或者是模型這樣的封閉形狀有效。當我們繪製上個教程中那個草的時候,我們必須關閉面剔除,這是因為它的前、後面都必須是可見的。

opengl允許我們改變剔除面的型別,要是我們剔除正面而不是背面會怎樣?我們可以呼叫glcullface來做這件事:

glcullface(gl_back);
glcullface函式有三個可用的選項:

glcullface的初始值是gl_back。另外,我們還可以告訴opengl使用順時針而不是逆時針來表示正面,這通過glfrontface來設定:

glfrontface(gl_ccw);
預設值是gl_ccw,它代表逆時針,gl_cw代表順時針順序。

我們可以做個小實驗,告訴opengl現在順時針代表正面:

glenable(gl_cull_face);

glcullface(gl_back);

glfrontface(gl_cw);

最後的結果只有背面被渲染了:

要注意,你可以使用預設逆時針順序剔除正面,來建立相同的效果:

glenable(gl_cull_face);

glcullface(gl_front);

總結:關於面剔除操作,現在都是在

shader

中加入一行命令列即可,面剔除操作是

opengl

優化的乙個方面,其實現在市面上各種引擎功能都很成熟了,引擎已經為我們做了面剔除操作的事情,但是作為開發者,自己本身還是要明白其原理,這樣更有助於提公升自己的技能。

Canvas 核心技術

最近專案需求中要寫較多h5小遊戲,遊戲本身體量不是很複雜,主要是承載較多業務邏輯,所以決定用canvas來完成遊戲部分。之前只是知道h5中有canvas這個東西,也知道它大概是畫圖的,但具體怎麼用,還是一無所知的。在mdn在看了一些相關資料,一口氣也看了html 5 canvas 核心技術和html...

Canvas 核心技術

最近專案需求中要寫較多h5小遊戲,遊戲本身體量不是很複雜,主要是承載較多業務邏輯,所以決定用canvas來完成遊戲部分。之前只是知道h5中有canvas這個東西,也知道它大概是畫圖的,但具體怎麼用,還是一無所知的。在mdn在看了一些相關資料,一口氣也看了html 5 canvas 核心技術和html...

Docker核心技術

執行在同樣的主機上,docker容器共用乙個container,而虛擬機器則使用自己的作業系統上的container,虛擬機器之間擁有比docker更好的隔離性,但docker相對於虛擬機器來說有更多的優勢,比如虛擬機器作業系統的存在額外占用了更多的計算資源,其次,從空間占用上,虛擬機器基本都是gb...