【风宇冲】Shader:二十六Tessellation

分类: Unity3d之Shader篇 |
原创文章如需转载请注明:转载自风宇冲博客
Tessellation Shader:细分曲面。Geometry Shader:几何Shader。
Compute Shader: 计算Shader。
(1)使用要求:
【Tessellation Shader/Geometry Shader】
PC/Console:
安卓平台:
【Compute Shader】
PC/Console:
安卓平台:
(2)开启:
最好是在Player Settings里关掉Auto Graphics API.
做PC/Console的话
移动端的话
简而言之,Instancing/Compute Shader/Tessellation Shader/Geometry Shader
下面用一张图说明这些Shader的关系。
http://s3/mw690/001iGO8Ggy6YVumJNke22&690
本讲就来介绍Tessellation细分曲面。
Tessellation是真正的生成更细致的mesh。一句话就是把模型的三角面细分成一组更小的面,再配合Displace贴图等信息进行处理。
Unity的Surface Shader支持Tessellation,例子如下
http://s2/mw690/001iGO8Ggy6YTuHU5zj91&690
步骤
1:准备Displacement和Normal 两张贴图。Displacement根据亮度决定细分曲面的高度或者说凸起程度。
2:代码中添加
tessellate:tessFixed
这个表示每个三角面细分的量级
3:对
Displacement进行纹理采样,并沿法线方向作相应偏移。
- Shader
"Tessellation/1FixedAmount" { -
{ -
_Tess ( Range(1,32)) = 4 -
_MainTex ( (RGB)", 2D) = "white"{} -
_DispTex ( Texture", 2D) = "gray"{} -
_NormalMap ( 2D) = "bump"{} -
_Displacement ( Range(0, 1.0)) = 0.3 -
_Color ( color) = 1,1,1,0)( -
_SpecColor ( color", color) = 0.5,0.5,0.5,0.5)( -
} -
{ -
{ "RenderType"="Opaque"} -
LOD -
-
surface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessFixed nolightmap -
appdata { -
vertex : POSITION; -
tangent : TANGENT; -
normal : NORMAL; -
texcoord : TEXCOORD0; -
}; -
_Tess; -
tessFixed() -
{ -
_Tess; -
} -
_DispTex; -
_Displacement; -
disp inout( appdata v) -
{ -
d tex2Dlod(_DispTex,= float4(v.texcoord.xy,0,0)).r * _Displacement; -
v. += normalv. * d; -
} -
Input { -
uv_MainTex; -
}; -
_MainTex; -
_NormalMap; -
_Color; -
surf inout(Input IN, SurfaceOutput o) { -
c tex2D= (_MainTex, IN.uv_MainTex) * _Color; -
o.Albedo = c. -
o. = 0.2; -
o.Gloss = -
o. = tex2D(_NormalMap,UnpackNormal( IN.uv_MainTex)); -
} -
-
} -
"Diffuse" - }
[例二:基于距离细分曲面]
http://s11/mw690/001iGO8Ggy6YTuHXwZI4a&690
基于相机距离进行细分,离相机越近细分面数越多。
- Shader
"Tessellation/2Distance" { -
{ -
_Tess ( Range(1,32)) = 4 -
_MainTex ( (RGB)", 2D) = "white"{} -
_DispTex ( Texture", 2D) = "gray"{} -
_NormalMap ( 2D) = "bump"{} -
_Displacement ( Range(0, 1.0)) = 0.3 -
_Color ( color) = 1,1,1,0)( -
_SpecColor ( color", color) = 0.5,0.5,0.5,0.5)( -
} -
{ -
{ "RenderType"="Opaque"} -
LOD -
-
surface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessDistance nolightmap -
#include -
appdata { -
vertex : POSITION; -
tangent : TANGENT; -
normal : NORMAL; -
texcoord : TEXCOORD0; -
}; -
_Tess; -
tessDistance (appdata v0, appdata v1, appdata v2) { -
minDist 10.0;= -
maxDist 25.0;= -
UnityDistanceBasedTess(v0. vertex,v1. vertex,v2. vertex,minDist, maxDist, _Tess); -
} -
_DispTex; -
_Displacement; -
disp inout( appdata v) -
{ -
d tex2Dlod(_DispTex,= float4(v.texcoord.xy,0,0)).r * _Displacement; -
v. += normalv. * d; -
} -
Input { -
uv_MainTex; -
}; -
_MainTex; -
_NormalMap; -
_Color; -
surf inout(Input IN, SurfaceOutput o) { -
c tex2D= (_MainTex, IN.uv_MainTex) * _Color; -
o.Albedo = c. -
o. = 0.2; -
o.Gloss = -
o. = tex2D(_NormalMap,UnpackNormal( IN.uv_MainTex)); -
} -
-
} -
"Diffuse" - }
[例三:边缘长度曲面]
http://s6/mw690/001iGO8Ggy6YTuI0Dzvf5&690
根据三角面的边缘长度进行细分,也就是越大的三角细分越多
- Shader
"Tessellation/3EdgeLength" { -
{ -
_EdgeLength ( length", Range(2,50)) = 15 -
_MainTex ( (RGB)", 2D) = "white"{} -
_DispTex ( Texture", 2D) = "gray"{} -
_NormalMap ( 2D) = "bump"{} -
_Displacement ( Range(0, 1.0)) = 0.3 -
_Color ( color) = 1,1,1,0)( -
_SpecColor ( color", color) = 0.5,0.5,0.5,0.5)( -
} -
{ -
{ "RenderType"="Opaque"} -
LOD -
-
surface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessEdge nolightmap -
#include -
appdata { -
vertex : POSITION; -
tangent : TANGENT; -
normal : NORMAL; -
texcoord : TEXCOORD0; -
}; -
_EdgeLength; -
tessEdge (appdata v0, appdata v1, appdata v2) -
{ -
UnityEdgeLengthBasedTess vertex,(v0. v1. vertex,v2. vertex,_EdgeLength); -
} -
_DispTex; -
_Displacement; -
disp inout( appdata v) -
{ -
d tex2Dlod(_DispTex,= float4(v.texcoord.xy,0,0)).r * _Displacement; -
v. += normalv. * d; -
} -
Input { -
uv_MainTex; -
}; -
_MainTex; -
_NormalMap; -
_Color; -
surf inout(Input IN, SurfaceOutput o) { -
c tex2D= (_MainTex, IN.uv_MainTex) * _Color; -
o.Albedo = c. -
o. = 0.2; -
o.Gloss = -
o. = tex2D(_NormalMap,UnpackNormal( IN.uv_MainTex)); -
} -
-
} -
"Diffuse" - }
http://s1/mw690/001iGO8Ggy6YTuI35HW60&690
如果是low poly的模型的话,沿着法线方向去细分效果并不好。
http://s5/bmiddle/001iGO8Ggy6YTAaVuqE04&690
而我们可以用Phong Tesselation去细分,该方法尤其适用于low poly模型。
tessphong:_Phong
- Shader
"Tessellation/4Phong" { -
{ -
_EdgeLength ( length", Range(2,50)) = 5 -
_Phong ( Strengh", Range(0,1)) = 0.5 -
_MainTex ( (RGB)", 2D) = "white"{} -
_Color ( color) = 1,1,1,0)( -
} -
{ -
{ "RenderType"="Opaque"} -
LOD -
-
surface surf Lambert vertex:dispNone tessellate:tessEdge tessphong:_Phong nolightmap -
#include -
appdata { -
vertex : POSITION; -
normal : NORMAL; -
texcoord : TEXCOORD0; -
}; -
dispNone inout( appdata v) { } -
_Phong; -
_EdgeLength; -
tessEdge (appdata v0, appdata v1, appdata v2) -
{ -
UnityEdgeLengthBasedTess vertex,(v0. v1. vertex,v2. vertex,_EdgeLength); -
} -
Input { -
uv_MainTex; -
}; -
_Color; -
_MainTex; -
surf inout(Input IN, SurfaceOutput o) { -
c tex2D= (_MainTex, IN.uv_MainTex) * _Color; -
o.Albedo = c. -
o.Alpha = c. -
} -
-
} -
"Diffuse" - }
http://s13/mw690/001iGO8Ggy6YTBlelnmfc&690
参考资料:
Surface Shaders with DX11 Tessellation
Phong Tessellation
《Introduction_to_3D_Game_Programming_with_Directx_11》