1. 程式人生 > >Unity—Camera&Culling Mask's OP

Unity—Camera&Culling Mask's OP

天空 inspector 好的 ever object 標記 如何 需要 href

Reprinted from Tanmengmeng in CSDN,AR4DS in Sina等.

1.簡述兩個屬性

1.1 Clear Flags 清除標記

每個相機在渲染時會存儲顏色和深度信息。屏幕的未繪制部分是空的,默認情況下會顯示天空盒。當你使用多個相機時,每一個都將自己的顏色和深度信息存儲在緩沖區中,還將積累大量的每個相機的渲染數據。當場景中的任何特定相機進行渲染時,你可以設定清除標記以清除緩沖區信息的不同集合。可以通過下面四個選項之一來完成:

1.Skybox 天空盒

這是默認設置。在屏幕上空的部分將顯示當前相機的天空盒。如果當前相機沒有設置天空盒,它會默認使用渲染設置(在Edit->Render Settings裏)中選擇的天空盒。然後它將退回使用背景顏色。另外天空盒組件可以添加到相機上。如果你想創建一個新的天空盒,您可以使用本指南。

2.Solid Color 純色

屏幕上的任何空的部分將顯示當前相機的背景顏色。

3.Depth Only 僅深度

如果你想繪制一個玩家的槍而不讓它在環境內部得到裁剪,你要設置一個深度為0的相機來繪制環境,還要另一個深度為1的相機單獨繪制武器。該武器相機的清除標記應設置為僅深度。這將保持環境的圖形顯示在屏幕上,但會丟棄所有關於每個對象在三維空間中的位置的信息。當槍被繪制出來,不透明的部分將完全覆蓋任何已繪制的事物,而不管槍到墻之間如何接近。(這部分看起來很費勁)

4.Don‘t Clear 不清除

該模式不清除任何顏色或深度緩存。其結果是,每幀繪制在下一幀之上,造成塗片效果。這不是用於遊戲的典型方式,最好是與自定義著色器一起使用。

1.2 Culling Mask 剔除遮罩

剔除遮罩使用層有選擇地渲染一組對象。有關使用層的信息可以在這裏找到。

通常好的做法,是把用戶界面放到不同的層,然後用一個獨立相機單獨渲染UI層。

為了使UI顯示在其他相機視角的頂部,你還需要設置清除標記為Depth only,並確保UI相機的深度比其他相機高。

2.下面將通過幾步演示來展示攝像機該兩個屬性

一:

首先在Unity場景中創建兩個攝像機,分別命名為camera1和camera2;

再在場景中創建一個cube和Sphere作為攝像機的拍攝物體;並讓兩攝像機都能夠拍攝到兩個物體。

技術分享圖片

接著設置camera1的Depth為0,camera2的Depth為1;

你會發現Game窗口將只顯示camera2拍攝到的畫面;

可見攝像機Depth屬性設置相機繪圖順序,具有較大值的相機將被繪制在具有較小值的相機的上面,換言之,一個深度為1的相機將繪制在一個深度為0的相機之上。

二:

Clear Falgs默認Skybox;

將camera2的Clear Falgs設置為Depth Only;

技術分享圖片

此時你可以看到Game窗口將顯示camera1和camera2同時拍攝到的畫面

技術分享圖片

由此可見,要想將多個相機拍攝的畫面渲染到同一個畫面是很簡單的事情,只需要將它們的Clear Falgs設置為Depth Only;但是有一個條件是,它們的Depth都需要比Clear Falgs為Skybox或Solid Color的攝像機的Depth高,這樣才可以將多個相機單獨拍攝的畫面疊加於同一個畫面上。

三:

現在的問題是,兩個攝像機拍攝的物體是一樣的,我該如何讓camera1只拍攝場景背景,而camera2只拍攝制定的物體;

在場景中創建一個plane,並設置材質,充滿camera1畫面,當做場景背景。

技術分享圖片

接下來,我們要為物體設置層關系。Unity的Layer的概念可以類比PS裏面的圖層。

首先,添加一個層(Layer),如下圖所示,並命名為object;

技術分享圖片

其次,給物體設置層;如圖將sphere物體的層設為object層;同樣cube的層也設置為object層。

技術分享圖片

最後你將設置兩個攝像機的culling mask 屬性,以使攝像機渲染指定層物體。

攝像機的cullingmask默認為Everything,表明渲染所有層的物體。

技術分享圖片

Camera1:將culling mask裏面的object層勾去掉,culling mask將顯示為Mixed… ;你將發現Camera1的窗口將只顯示背景圖片,物體沒有被渲染。

技術分享圖片

Camera2:在culling mask選項裏面先勾選Nothing,再勾選object層,表明該攝像機只渲染屬於object的東西,將不會拍攝到別的圖層。

技術分享圖片

最後,在Game窗口看到兩個攝像機疊加的畫面;

技術分享圖片

四:

至此,我們明白了攝像機的Depth、Clear Falgs和Culling Mask的強大作用。

同樣的,如果是制作遊戲,你可以創建一個界面攝像機,單獨渲染界面,而別的攝像機將渲染場景。你只需要添加UI圖層,將所有的界面物體的Layer設置為UI,UI攝像機的Culling Mask也只勾選UI層。

技術分享圖片

技術分享圖片

CullingMask OP:

1.首先引入‘|‘、‘&‘、‘~‘的概念
與(交集)& :10000001 & 10000100 == 10000000
或(並集)| :10000001 | 10000100 == 10000101
非(反轉)~ :10000001 == ~01111110
左移<< 右移 >>
2.int myLayerMask = 1 << curLayer;
等式右側 curLayer 代表Inspector/Layer中的某一層

等號左側是通過一個數來保存多個層的信息
他是怎麽做到的呢?
其實是用 myLayerMask = 00000000 方式來保存的
myLayerMask = 1 << 3 ---> myLayerMask == 00001000
這時層級中的第3層被開啟,其余層處於關閉狀態
另外,需註意的是,層的序號是從0開始計算的
因此,上面的操作相當於使用二進制方法進行一對多表現方式的轉化過程

3.實例講解

有了上面鋪墊,我們就可以輕松的對多個Layer進行開關了
1)開啟1、2層
camera.cullingMask = (1 << 1) | (1 << 2);
2)開啟除2層外的所有層
camera.cullingMask = ~(1 << 2);
3)開啟除1、2、4層外的所有層
camera.cullingMask = ~((1 << 1) | (1 << 2) | (1 << 4));

RefCamera.cullingMask = ~(1 << LayerMask.NameToLayer("Water"));

this.camera.cullingMask = (1 << 0)+(1 << 8);這樣你就可以看到0層和8層了,記得一定要加括號哦。

當然你還可以通過層名去打開相應層:this.camera.cullingMask = (1 << 0) + (1 << LayerMask.NameToLayer("Ground"));

Unity—Camera&Culling Mask's OP