Shader第二十六講 Tessellation

Unity 5.1之前的版本天吓,OpenGL ES2.0 较沪、3.0、desktop OpenGL的渲染都是分別的版本失仁。而5.1尸曼,unity使用統(tǒng)一的OpenGL Core,所以一些渲染的新功能DX和OpenGL都可以使用:

Tessellation Shader:細分曲面萄焦。GeometryShader:幾何Shader控轿。

Compute Shader:計算Shader。

(1)使用要求:

【Tessellation Shader/GeometryShader】

PC/Console:Shader Model 4.6+DX11/OpenGL Core

安卓平臺:OpenGLES 3.1 +AEP(Android Extension Pack)

【Compute Shader】

PC/Console:DX11/OpenGLdesktop 4.3+

安卓平臺:OpenGL ES 3.1+

(2)開啟:

最好是在Player Settings里關(guān)掉Auto Graphics API.

做PC/Console的話

直接選擇例如DX11即可

移動端的話

Computer Shader建議用Vulkan

Tessellation/Geometry建議用 OpenGLES3 + Require ES3.1 + AEP

簡而言之拂封,Instancing/Compute Shader/Tessellation Shader/GeometryShader

在電腦/家用機/移動端都可以運行(只要顯卡支持)

下面用一張圖說明這些Shader的關(guān)系茬射。

本講就來介紹Tessellation細分曲面。

當(dāng)我們顯示普通的模型時冒签,效果一般在抛,于是有了法線貼圖。但是法線貼圖有局限性萧恕,例如入視角刚梭。而DX11的

Tessellation是真正的生成更細致的mesh。一句話就是把模型的三角面細分成一組更小的面票唆,再配合Displace貼圖等信息進行處理朴读。

Unity的Surface Shader支持Tessellation,例子如下

[例一:基本細分曲面]

步驟

1:準(zhǔn)備Displacement和Normal 兩張貼圖走趋。Displacement根據(jù)亮度決定細分曲面的高度或者說凸起程度衅金。2:代碼中添加

tessellate:tessFixed

float_Tess;

float4tessFixed()

{

return_Tess;

}

這個表示每個三角面細分的量級

3:對

Displacement進行紋理采樣,并沿法線方向作相應(yīng)偏移簿煌。voiddisp(inoutappdatav)

{

floatd=tex2Dlod(_DispTex,float4(v.texcoord.xy,0,0)).r*_Displacement;

v.vertex.xyz+=v.normal*d;

}

Shader"Tessellation/1FixedAmount"{

Properties{

_Tess("Tessellation",Range(1,32))=4

_MainTex("Base(RGB)",2D)="white"{}

_DispTex("DispTexture",2D)="gray"{}

_NormalMap("Normalmap",2D)="bump"{}

_Displacement("Displacement",Range(0,1.0))=0.3

_Color("Color",color)=(1,1,1,0)

_SpecColor("Speccolor",color)=(0.5,0.5,0.5,0.5)

}

SubShader{

Tags{"RenderType"="Opaque"}

LOD300

CGPROGRAM

#pragmasurfacesurfBlinnPhongaddshadowfullforwardshadowsvertex:disptessellate:tessFixednolightmap

structappdata{

float4vertex:POSITION;

float4tangent:TANGENT;

float3normal:NORMAL;

float2texcoord:TEXCOORD0;

};

float_Tess;

float4tessFixed()

{

return_Tess;

}

sampler2D_DispTex;

float_Displacement;

voiddisp(inoutappdatav)

{

floatd=tex2Dlod(_DispTex,float4(v.texcoord.xy,0,0)).r*_Displacement;

v.vertex.xyz+=v.normal*d;

}

structInput{

float2uv_MainTex;

};

sampler2D_MainTex;

sampler2D_NormalMap;

fixed4_Color;

voidsurf(InputIN,inoutSurfaceOutputo){

half4c=tex2D(_MainTex,IN.uv_MainTex)*_Color;

o.Albedo=c.rgb;

o.Specular=0.2;

o.Gloss=1.0;

o.Normal=UnpackNormal(tex2D(_NormalMap,IN.uv_MainTex));

}

ENDCG

}

FallBack"Diffuse"

}

[例二:基于距離細分曲面]

基于相機距離進行細分氮唯,離相機越近細分面數(shù)越多。

float4tessDistance(appdatav0,appdatav1,appdatav2){

floatminDist=10.0;

floatmaxDist=25.0;

returnUnityDistanceBasedTess(v0.vertex,v1.vertex,v2.vertex,minDist,maxDist,_Tess);

}

Shader"Tessellation/2Distance"{

Properties{

_Tess("Tessellation",Range(1,32))=4

_MainTex("Base(RGB)",2D)="white"{}

_DispTex("DispTexture",2D)="gray"{}

_NormalMap("Normalmap",2D)="bump"{}

_Displacement("Displacement",Range(0,1.0))=0.3

_Color("Color",color)=(1,1,1,0)

_SpecColor("Speccolor",color)=(0.5,0.5,0.5,0.5)

}

SubShader{

Tags{"RenderType"="Opaque"}

LOD300

CGPROGRAM

#pragmasurfacesurfBlinnPhongaddshadowfullforwardshadowsvertex:disptessellate:tessDistancenolightmap

#include"Tessellation.cginc"

structappdata{

float4vertex:POSITION;

float4tangent:TANGENT;

float3normal:NORMAL;

float2texcoord:TEXCOORD0;

};

float_Tess;

float4tessDistance(appdatav0,appdatav1,appdatav2){

floatminDist=10.0;

floatmaxDist=25.0;

returnUnityDistanceBasedTess(v0.vertex,v1.vertex,v2.vertex,minDist,maxDist,_Tess);

}

sampler2D_DispTex;

float_Displacement;

voiddisp(inoutappdatav)

{

floatd=tex2Dlod(_DispTex,float4(v.texcoord.xy,0,0)).r*_Displacement;

v.vertex.xyz+=v.normal*d;

}

structInput{

float2uv_MainTex;

};

sampler2D_MainTex;

sampler2D_NormalMap;

fixed4_Color;

voidsurf(InputIN,inoutSurfaceOutputo){

half4c=tex2D(_MainTex,IN.uv_MainTex)*_Color;

o.Albedo=c.rgb;

o.Specular=0.2;

o.Gloss=1.0;

o.Normal=UnpackNormal(tex2D(_NormalMap,IN.uv_MainTex));

}

ENDCG

}

FallBack"Diffuse"

}

[例三:邊緣長度曲面]

根據(jù)三角面的邊緣長度進行細分姨伟,也就是越大的三角細分越多

float4tessEdge(appdatav0,appdatav1,appdatav2)

{

returnUnityEdgeLengthBasedTess(v0.vertex,v1.vertex,v2.vertex,_EdgeLength);

}

Shader"Tessellation/3EdgeLength"{

Properties{

_EdgeLength("Edgelength",Range(2,50))=15

_MainTex("Base(RGB)",2D)="white"{}

_DispTex("DispTexture",2D)="gray"{}

_NormalMap("Normalmap",2D)="bump"{}

_Displacement("Displacement",Range(0,1.0))=0.3

_Color("Color",color)=(1,1,1,0)

_SpecColor("Speccolor",color)=(0.5,0.5,0.5,0.5)

}

SubShader{

Tags{"RenderType"="Opaque"}

LOD300

CGPROGRAM

#pragmasurfacesurfBlinnPhongaddshadowfullforwardshadowsvertex:disptessellate:tessEdgenolightmap

#include"Tessellation.cginc"

structappdata{

float4vertex:POSITION;

float4tangent:TANGENT;

float3normal:NORMAL;

float2texcoord:TEXCOORD0;

};

float_EdgeLength;

float4tessEdge(appdatav0,appdatav1,appdatav2)

{

returnUnityEdgeLengthBasedTess(v0.vertex,v1.vertex,v2.vertex,_EdgeLength);

}

sampler2D_DispTex;

float_Displacement;

voiddisp(inoutappdatav)

{

floatd=tex2Dlod(_DispTex,float4(v.texcoord.xy,0,0)).r*_Displacement;

v.vertex.xyz+=v.normal*d;

}

structInput{

float2uv_MainTex;

};

sampler2D_MainTex;

sampler2D_NormalMap;

fixed4_Color;

voidsurf(InputIN,inoutSurfaceOutputo){

half4c=tex2D(_MainTex,IN.uv_MainTex)*_Color;

o.Albedo=c.rgb;

o.Specular=0.2;

o.Gloss=1.0;

o.Normal=UnpackNormal(tex2D(_NormalMap,IN.uv_MainTex));

}

ENDCG

}

FallBack"Diffuse"

}

[例四:Phong細分曲面]

如果是low poly的模型的話惩琉,沿著法線方向去細分效果并不好。

而我們可以用Phong Tesselation去細分授滓,該方法尤其適用于low poly模型琳水。

tessphong:_Phong

#pragmasurfacesurfLambertvertex:dispNonetessellate:tessEdgetessphong:_Phongnolightmap

Shader"Tessellation/4Phong"{

Properties{

_EdgeLength("Edgelength",Range(2,50))=5

_Phong("PhongStrengh",Range(0,1))=0.5

_MainTex("Base(RGB)",2D)="white"{}

_Color("Color",color)=(1,1,1,0)

}

SubShader{

Tags{"RenderType"="Opaque"}

LOD300

CGPROGRAM

#pragmasurfacesurfLambertvertex:dispNonetessellate:tessEdgetessphong:_Phongnolightmap

#include"Tessellation.cginc"

structappdata{

float4vertex:POSITION;

float3normal:NORMAL;

float2texcoord:TEXCOORD0;

};

voiddispNone(inoutappdatav){}

float_Phong;

float_EdgeLength;

float4tessEdge(appdatav0,appdatav1,appdatav2)

{

returnUnityEdgeLengthBasedTess(v0.vertex,v1.vertex,v2.vertex,_EdgeLength);

}

structInput{

float2uv_MainTex;

};

fixed4_Color;

sampler2D_MainTex;

voidsurf(InputIN,inoutSurfaceOutputo){

half4c=tex2D(_MainTex,IN.uv_MainTex)*_Color;

o.Albedo=c.rgb;

o.Alpha=c.a;

}

ENDCG

}

FallBack"Diffuse"

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市般堆,隨后出現(xiàn)的幾起案子在孝,更是在濱河造成了極大的恐慌,老刑警劉巖淮摔,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件私沮,死亡現(xiàn)場離奇詭異,居然都是意外死亡和橙,警方通過查閱死者的電腦和手機仔燕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來魔招,“玉大人晰搀,你說我怎么就攤上這事“彀撸” “怎么了外恕?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長乡翅。 經(jīng)常有香客問我鳞疲,道長,這世上最難降的妖魔是什么蠕蚜? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任尚洽,我火速辦了婚禮,結(jié)果婚禮上靶累,老公的妹妹穿的比我還像新娘腺毫。我一直安慰自己,他們只是感情好挣柬,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布拴曲。 她就那樣靜靜地躺著,像睡著了一般凛忿。 火紅的嫁衣襯著肌膚如雪澈灼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天店溢,我揣著相機與錄音叁熔,去河邊找鬼。 笑死床牧,一個胖子當(dāng)著我的面吹牛荣回,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播戈咳,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼心软,長吁一口氣:“原來是場噩夢啊……” “哼壕吹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起删铃,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤耳贬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后猎唁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咒劲,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年诫隅,在試婚紗的時候發(fā)現(xiàn)自己被綠了腐魂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出茫叭,到底是詐尸還是另有隱情台谍,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏眼刃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一摇肌、第九天 我趴在偏房一處隱蔽的房頂上張望擂红。 院中可真熱鬧,春花似錦围小、人聲如沸昵骤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽变秦。三九已至,卻和暖如春框舔,著一層夾襖步出監(jiān)牢的瞬間蹦玫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工刘绣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留樱溉,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓纬凤,卻偏偏與公主長得像福贞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子停士,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容