jk自慰喷水,无码精品一区二区三区在线播放,亚洲精品无码AV中文永久在线,四虎影院国产精品

完美教室IT教育

[游戲動漫]
獵學網(wǎng)訂閱號
獵學網(wǎng)官方企業(yè)微信
位置: 獵學網(wǎng) > 學校機構 > 完美教室IT教育 > 學習資訊> unity3d游戲引擎立體渲染教程

unity3d游戲引擎立體渲染教程

547 2017-05-26

完美教室教程之立體渲染(VolumetricRendering)。這些技術能突破現(xiàn)代3D引擎只能渲染物體外殼的最大限制。立體渲染可以實現(xiàn)逼真的材質與燈光進行復雜的交互,例如霧、煙、水和玻璃。查看NMZ的PlasmaGlobe效果了解立體渲染的基本概念,如下圖:

unity3d游戲引擎立體渲染教程

誠然,這些技術本身并不復雜,但實現(xiàn)上圖效果需要非常多的步驟。本教程將為大家全面介紹以下概念:

第一篇:立體渲染。介紹立體渲染的概念以及在Unity中如何實現(xiàn)立體渲染。

第二篇:光線追蹤。文章著重說明如何實現(xiàn)距離輔助的光線追蹤,這是是渲染立體的事實性標準技術。

第三篇:表面著色。全面指引如何逼真地進行立體著色。

第四篇:有向距離常一篇對于數(shù)學工具更深入的討論,讓我們能制作和組合任意幾何體。

本文將介紹立體渲染的基本概念,并以一個簡單的著色器收尾,后續(xù)的文章將以此為基礎進行迭代:

介紹

第一部分立體渲染

第二部分立體射線投射

第三部分固定步長的立體光線追蹤

結論

介紹

在3D游戲引擎中,球體、立方體以及所有其它復雜的集合體都是由三角面片組成的。Unity采用的實時光照系統(tǒng)只能渲染平面。例如渲染球體,Unity僅繪制球體表面的三角形。盡管一些材質是半透明的,也只繪制表面并將其顏色與后面的物體進行混合。光照系統(tǒng)無法探測到材質的幾何體的內部。對于GPU來說,整個世界就是由各種空殼構成的。

為了突破這種強大的限制,大量技術順勢而出。盡管傳統(tǒng)著色器最終都會止于物體表面,但這并不意味著無法更深入。立體渲染技術可以在材質內部模擬光線的傳送,從而實現(xiàn)更震撼也更真實的視覺效果。

立體渲染

無光照紋理的片段著色器如下:

fixed4frag(v2fi):SV_Target

{

fixed4col=tex2D(_MainTex,i.texcoord);

returncol;

}

不嚴格地說,上述代碼會為最終渲染圖像每一個可能的像素(片段)調用。GPU會在有三角形與相機視錐體相交時,調用該片段著色器。換句話說,就是相機“看見了”該對象。Unity需要知道該對象的實際顏色,以便將其分配到渲染圖像的各個像素。

unity3d游戲引擎立體渲染教程

片段著色器最后返回的對象,是從特定角度看過去特定位置的顏色。這種方式計算的顏色是完全隨意的,因此返回的內容可以不必匹配幾何體的真實渲染情況。下圖展示了一個3D立方體的例子。當片段著色器檢測到立方體表面的顏色時,我們獲得的顏色如同我們在一個球體上所看到的。這個幾何體是個立方體,但是從相機的角度來看,它的外觀和感覺其實“酷似”一個球體。

unity3d游戲引擎立體渲染教程

這就是立體渲染(VolumetricRendering)的基本概念:模擬光線在物體內部的傳送。

如果想模擬前面的效果,就要更精確地進行描述。假設主物體是一個立方體,要在其內部立體渲染一個球體,實際上并不存在這個球體,因為我們將完全通過著色器代碼來渲染。球體中心點位于_Centre,半徑是_Radius,均為世界坐標。移動立方體不會影響球體位置,因為它是完全以世界坐標系來表述的。外部的幾何體也不會對該球體造成任何影響。立方體表面的三角形就是通向幾何體內部的窗口。雖然可以使用四邊形(Quad)減少三角形數(shù)量,但要能從立方體的任意角度觀看該球體。

立體射線投射

第一種立體渲染的方式完全適用于實現(xiàn)前文所述的效果。片段著色器接收要渲染的點(wolrdPosition)以及視線方向(viewDirection),然后使用raycastHit函數(shù)檢測是否投射到紅色球體。這種技術叫做立體射線投射(VolumetricRaycasting),它將射線從相機投射到幾何體內部。

在片段著色器函數(shù)中添加剩下的代碼:

float3_Centre;

float_Radius;

fixed4frag(v2fi):SV_Target

{

float3worldPosition=...

float3viewDirection=...

if(raycastHit(worldPosition,viewDirection))

returnfixed4(1,0,0,1);//Redifhittheball

else

returnfixed4(1,1,1,1);//Whiteotherwise

}

下面來解釋代碼中的其它變量。

世界坐標

首先,片段的世界坐標就是從相機生成的射線投射到幾何體上的點。在片段著色器中獲取世界坐標的代碼如下:

structv2f{

float4pos:SV_POSITION;//Clipspace

float3wPos:TEXCOORD1;//Worldposition

};

v2fvert(appdata_fullv)

{

v2fo;

o.pos=mul(UNITY_MATRIX_MVP,v.vertex);

o.wPos=mul(_Object2World,v.vertex).xyz;

returno;

}

視線方向

其次,視線方向就是射線從相機投射到幾何體上被渲染的點的方向。這里需要知道相機坐標,Unity已內置了該變量_WorldSpaceCameraPos。計算通過兩點的射線方向可使用如下代碼:

float3viewDirection=normalize(i.wPos-_WorldSpaceCameraPos);

RaycastHit函數(shù)

當我們知道了渲染點的坐標和方向后,現(xiàn)在需要使用raycastHit函數(shù)來決定射線是否投射到了虛擬的紅色球體上。這就是球體與線段相交的問題,這種問題已有慣用解決方案,但通常效率不高。如果需要更具分析性的方法,就需要自行解決線段與自定義幾何體相交的問題。這種方案極大限制了可以創(chuàng)建的模型,所以很少被應用。

固定步長的立體光線追蹤

上面提到純分析式的立體射線投射,其實不適合解決這里的問題。如果希望模擬任意幾何體,就要找到不依賴于相交方程的更為靈活的技術。常見的解決方案叫做立體光線追蹤(VolumetricRaymarching),是基于迭代的解決方案。

立體光線追蹤會緩慢地將射線投射到立方體內,每一步都會檢測當前是否已投射到紅色球體。

unity3d游戲引擎立體渲染教程

每條射線均從片段坐標worldPosition開始,然后迭代沿著viewDirection的方向投射STEP_SIZE單位長度。這可以通過每次迭代為worldPosition加上STEP_SIZE*viewDirection來實現(xiàn)。

用下面的raymarchHit函數(shù)代替之前的raycastHit:

#defineSTEPS64

#defineSTEP_SIZE0.01

boolraymarchHit(float3position,float3direction)

{

for(inti=0;i

{

if(sphereHit(position))

returntrue;

position+=direction*STEP_SIZE;

}

returnfalse;

}

下面的函數(shù)用于檢測點p是否位于球體內:

boolsphereHit(float3p)

{

returndistance(p,_Centre)<_Radius;

}

線段與球體相交很難,但迭代檢測點是否位于球體內就很簡單了。結果見下圖,別看它看起來就是個圓形,實際上這就是個無光照的球體:

unity3d游戲引擎立體渲染教程

結論

本文介紹了基本的立體渲染概念。盡管傳統(tǒng)著色器只能渲染材質的外殼,但還是有辦法讓光線穿透到材質內部的幾何體,創(chuàng)造畫面的深度。光線追蹤就是最常用的技術,本文用該技術在立方體內繪制了一個紅色球體。后面的教程將分享如何逼真地著色(第三篇表面著色)以及如何做出一些有趣的形狀(第四篇有向距離場)。最終將能夠使用簡單幾行代碼和一個立體渲染著色器實現(xiàn)如下效果:

unity3d游戲引擎立體渲染教程

請聯(lián)系網(wǎng)站客服,了解詳細的優(yōu)惠課程信息~

優(yōu)質、權威、便捷、省心

溫馨提示: 專業(yè)老師1對1為您解答    馬上填寫,¥1000 元豪禮免費領!

掃一掃
獲取更多福利

×
獵學網(wǎng)