一、閑話不多扯,先摘幾條官方手冊關于深度測試的說明:
1、ZWrite(On/Off)
Controls whether pixels from this object are written to the depth buffer (default is On). If you’re drawng solid objects, leave this on. If you’re drawing semitransparent effects, switch to ZWrite Off.
譯:深度緩存控制指令,控制這個物體上的像素是否寫到深度緩存區内(預設為On,開啟)。如果你在繪制實心物體,就保持其預設的開啟值即可。如果你想繪制的是半透明的效果,那麼就将Zwrite的值設為Off,即關閉深度緩存寫。
2、Ztest(ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always)
How should depth testing be performed. Default is LEqual (draw objects in from or at the distance as existing objects; hide objects behind them).
譯:決定了深度測試如何進行,預設值為LEqual(即繪制距離相機更近的物體,即如果正在繪制的物體離錄影機更近,那麼已經存在的後面的物體将會被遮擋住)
3、Offset(Offset Factor, Units)
Allows you specify a depth offset with two parameters. factor and units. Factor scales the maximum Z slope, with respect to X or Y of the polygon, and units scale the minimum resolvable depth buffer value. This allows you to force one polygon to be drawn on top of another although they are actually in the same position. For example Offset 0, –1 pulls the polygon closer to the camera ignoring the polygon’s slope, whereas Offset –1, –1 will pull the polygon even closer when looking at a grazing angle.
二、上例子(以做一個水池子為例)
1、搭建場景,用5個cube搭建如下水池子基本結構(不包含水面),5個cube的材質是自己建立的材質球,shader用的是unity的standard标準材質,換了張貼圖。
2、制作水面貼圖。在PS cs3中随便畫了張如下圖所示的帶有透明通道的圖檔。
3、将水面貼圖導入unity,在場景中建立一個plane作為水面,建立一個材質球,然後建立一個unlit shader,将其賦給建立的材質球,看到如下效果:
4、打開建立的shader,進行改寫。考慮到要渲染的是水面這種有透明效果的物體(因為要透明效果,是以要帶有alpha通道的貼圖),是以在subshader的tags裡面應該設定其渲染隊列為半透明,渲染類型為半透明即Tags{"Queue"="Transparent" "RenderType"="Transparent" },根據上面的說明,渲染半透明的物體要關閉寫緩存,故設定 ZWrite Off。這時候傳回unity中會發現其實并沒有什麼變化,那是因為前面的設定并沒有利用到透明通道,即其實還是把他們當做實心物體渲染的,故會有遮擋。此時再在subshader裡加上 Blend SrcAlpha OneMinusSrcAlpha,即可發現水面神奇的就變成透明的,可以看到水池底了!如下圖:
5、擴充之一:讓水面動起來
再在建立的shader中繼續修改,将頂點着色器中的下面這句:o.uv = TRANSFORM_TEX(v.uv, _MainTex);
改成o.uv = TRANSFORM_TEX(v.uv, _MainTex)+float2(sin(6.28*_Time.x),0);儲存并傳回unity運作會發現水面有周期的左右移動了。
6、擴充之二:改變某些設定指令
(1)将上面修改過後的Tags裡的兩個設定項去掉,會發現對結果并沒有什麼影響太大的影響,但是在某些角度下會出現一些怪異的缺少面等的結果。查閱官網手冊看到渲染隊列中的Queue的預設值為geometry,即為一般的不透明物體的渲染隊列(原文:
Geometry
(default) - this is used for most objects. Opaque geometry uses this queue.)由于按照不透明物體進行渲染,混合方式不變,故影響不是很大。
(2)開啟ZWrite。開啟後若不設定ZTest,預設為LEqual,此時是沒有太大的影響的,但是如果将ZTest設定為Greater,就會發現有很大的變化,如下圖
出現上圖所示的效果的原因如下:由于開啟了ZWrite,且設定的是同一像素點上遠離相機的物體會被渲染,是以會出現上圖的效果,那麼問題是,為什麼上圖還會有水呢?中間區域沒有水好了解,周邊的水就難了解了。周邊的水和池子共三層,即兩層池子實體中間夾雜一層水,那為什麼隻渲染出中間的水呢?我的猜想是:因為先渲染的水池的實體,深度緩存中儲存的是最上面的一層的水池實體的深度值,水池實體渲染完成後,再渲染水,水的位置是在兩層水池實體中間的,其深度值大于緩沖區的值,是以會通過深度測試,進而被渲染出來。
本文完,有不足及謬誤之處,懇請指出,不勝感激!