【风宇冲】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" { -
Properties{ -
"Tessellation",_Tess ( Range(1,32)) = 4 -
"Base_MainTex ( (RGB)", 2D) = "white"{} -
"Disp_DispTex ( Texture", 2D) = "gray"{} -
"Normalmap",_NormalMap ( 2D) = "bump"{} -
"Displacement",_Displacement ( Range(0, 1.0)) = 0.3 -
"Color",_Color ( color) = 1,1,1,0)( -
"Spec_SpecColor ( color", color) = 0.5,0.5,0.5,0.5)( -
} -
SubShader{ -
Tags{ "RenderType"="Opaque"} -
300LOD -
CGPROGRAM -
#pragmasurface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessFixed nolightmap -
structappdata { -
float4vertex : POSITION; -
float4tangent : TANGENT; -
float3normal : NORMAL; -
float2texcoord : TEXCOORD0; -
}; -
float_Tess; -
float4tessFixed() -
{ -
return_Tess; -
} -
sampler2D_DispTex; -
float_Displacement; -
voiddisp inout( appdata v) -
{ -
floatd tex2Dlod(_DispTex,= float4(v.texcoord.xy,0,0)).r * _Displacement; -
vertex.xyzv. += normalv. * d; -
} -
structInput { -
float2uv_MainTex; -
}; -
sampler2D_MainTex; -
sampler2D_NormalMap; -
fixed4_Color; -
voidsurf inout(Input IN, SurfaceOutput o) { -
half4c tex2D= (_MainTex, IN.uv_MainTex) * _Color; -
rgb;o.Albedo = c. -
Specularo. = 0.2; -
1.0;o.Gloss = -
Normalo. = tex2D(_NormalMap,UnpackNormal( IN.uv_MainTex)); -
} -
ENDCG -
} -
FallBack"Diffuse" - }
[例二:基于距离细分曲面]
http://s11/mw690/001iGO8Ggy6YTuHXwZI4a&690
基于相机距离进行细分,离相机越近细分面数越多。
- Shader
"Tessellation/2Distance" { -
Properties{ -
"Tessellation",_Tess ( Range(1,32)) = 4 -
"Base_MainTex ( (RGB)", 2D) = "white"{} -
"Disp_DispTex ( Texture", 2D) = "gray"{} -
"Normalmap",_NormalMap ( 2D) = "bump"{} -
"Displacement",_Displacement ( Range(0, 1.0)) = 0.3 -
"Color",_Color ( color) = 1,1,1,0)( -
"Spec_SpecColor ( color", color) = 0.5,0.5,0.5,0.5)( -
} -
SubShader{ -
Tags{ "RenderType"="Opaque"} -
300LOD -
CGPROGRAM -
#pragmasurface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessDistance nolightmap -
"Tessellation.cginc"#include -
structappdata { -
float4vertex : POSITION; -
float4tangent : TANGENT; -
float3normal : NORMAL; -
float2texcoord : TEXCOORD0; -
}; -
float_Tess; -
float4tessDistance (appdata v0, appdata v1, appdata v2) { -
floatminDist 10.0;= -
floatmaxDist 25.0;= -
returnUnityDistanceBasedTess(v0. vertex,v1. vertex,v2. vertex,minDist, maxDist, _Tess); -
} -
sampler2D_DispTex; -
float_Displacement; -
voiddisp inout( appdata v) -
{ -
floatd tex2Dlod(_DispTex,= float4(v.texcoord.xy,0,0)).r * _Displacement; -
vertex.xyzv. += normalv. * d; -
} -
structInput { -
float2uv_MainTex; -
}; -
sampler2D_MainTex; -
sampler2D_NormalMap; -
fixed4_Color; -
voidsurf inout(Input IN, SurfaceOutput o) { -
half4c tex2D= (_MainTex, IN.uv_MainTex) * _Color; -
rgb;o.Albedo = c. -
Specularo. = 0.2; -
1.0;o.Gloss = -
Normalo. = tex2D(_NormalMap,UnpackNormal( IN.uv_MainTex)); -
} -
ENDCG -
} -
FallBack"Diffuse" - }
[例三:边缘长度曲面]
http://s6/mw690/001iGO8Ggy6YTuI0Dzvf5&690
根据三角面的边缘长度进行细分,也就是越大的三角细分越多
- Shader
"Tessellation/3EdgeLength" { -
Properties{ -
"Edge_EdgeLength ( length", Range(2,50)) = 15 -
"Base_MainTex ( (RGB)", 2D) = "white"{} -
"Disp_DispTex ( Texture", 2D) = "gray"{} -
"Normalmap",_NormalMap ( 2D) = "bump"{} -
"Displacement",_Displacement ( Range(0, 1.0)) = 0.3 -
"Color",_Color ( color) = 1,1,1,0)( -
"Spec_SpecColor ( color", color) = 0.5,0.5,0.5,0.5)( -
} -
SubShader{ -
Tags{ "RenderType"="Opaque"} -
300LOD -
CGPROGRAM -
#pragmasurface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessEdge nolightmap -
"Tessellation.cginc"#include -
structappdata { -
float4vertex : POSITION; -
float4tangent : TANGENT; -
float3normal : NORMAL; -
float2texcoord : TEXCOORD0; -
}; -
float_EdgeLength; -
float4tessEdge (appdata v0, appdata v1, appdata v2) -
{ -
returnUnityEdgeLengthBasedTess vertex,(v0. v1. vertex,v2. vertex,_EdgeLength); -
} -
sampler2D_DispTex; -
float_Displacement; -
voiddisp inout( appdata v) -
{ -
floatd tex2Dlod(_DispTex,= float4(v.texcoord.xy,0,0)).r * _Displacement; -
vertex.xyzv. += normalv. * d; -
} -
structInput { -
float2uv_MainTex; -
}; -
sampler2D_MainTex; -
sampler2D_NormalMap; -
fixed4_Color; -
voidsurf inout(Input IN, SurfaceOutput o) { -
half4c tex2D= (_MainTex, IN.uv_MainTex) * _Color; -
rgb;o.Albedo = c. -
Specularo. = 0.2; -
1.0;o.Gloss = -
Normalo. = tex2D(_NormalMap,UnpackNormal( IN.uv_MainTex)); -
} -
ENDCG -
} -
FallBack"Diffuse" - }
http://s1/mw690/001iGO8Ggy6YTuI35HW60&690
如果是low poly的模型的话,沿着法线方向去细分效果并不好。
http://s5/bmiddle/001iGO8Ggy6YTAaVuqE04&690
而我们可以用Phong Tesselation去细分,该方法尤其适用于low poly模型。
tessphong:_Phong
- Shader
"Tessellation/4Phong" { -
Properties{ -
"Edge_EdgeLength ( length", Range(2,50)) = 5 -
"Phong_Phong ( Strengh", Range(0,1)) = 0.5 -
"Base_MainTex ( (RGB)", 2D) = "white"{} -
"Color",_Color ( color) = 1,1,1,0)( -
} -
SubShader{ -
Tags{ "RenderType"="Opaque"} -
300LOD -
CGPROGRAM -
#pragmasurface surf Lambert vertex:dispNone tessellate:tessEdge tessphong:_Phong nolightmap -
"Tessellation.cginc"#include -
structappdata { -
float4vertex : POSITION; -
float3normal : NORMAL; -
float2texcoord : TEXCOORD0; -
}; -
voiddispNone inout( appdata v) { } -
float_Phong; -
float_EdgeLength; -
float4tessEdge (appdata v0, appdata v1, appdata v2) -
{ -
returnUnityEdgeLengthBasedTess vertex,(v0. v1. vertex,v2. vertex,_EdgeLength); -
} -
structInput { -
float2uv_MainTex; -
}; -
fixed4_Color; -
sampler2D_MainTex; -
voidsurf inout(Input IN, SurfaceOutput o) { -
half4c tex2D= (_MainTex, IN.uv_MainTex) * _Color; -
rgb;o.Albedo = c. -
a;o.Alpha = c. -
} -
ENDCG -
} -
FallBack"Diffuse" - }
http://s13/mw690/001iGO8Ggy6YTBlelnmfc&690
参考资料:
Surface Shaders with DX11 Tessellation
Phong Tessellation
《Introduction_to_3D_Game_Programming_with_Directx_11》

加载中…