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"
}