分享

【风宇冲】Unity3D教程宝典之Shader篇:第二十六讲Tessellation

 雪柳花明 2016-06-03

原创文章如需转载请注明:转载自风宇冲Unity3D教程学院


                            Shader第二十六讲 Tessellation

Unity 5.1之前的版本,OpenGL ES2.0 、3.0 desktop OpenGL的渲染都是分别的版本。而5.1,unity使用统一的open GL渲染器,所以一些渲染的新功能DX和OpenGL都可以使用:
Tessellation Shader:细分曲面。安卓平台需要支持 Android Extension Pack
Geometry Shader:几何Shader。
Compute Shader:
计算Shader。OpenGL  desktop 4.3+  ,OpenGL ES 3.1+

下面用一张图说明这些Shader的关系。
【风宇冲】Unity3D教程宝典之Shader篇:第二十六讲Tessellation


本讲就来介绍Tessellation细分曲面。
  当我们显示普通的模型时,效果一般,于是有了法线贴图。但是法线贴图有局限性,例如入视角。而DX11的

Tessellation是真正的生成更细致的mesh。一句话就是把模型的三角面细分成一组更小的面,再配合Displace贴图等信息进行处理。
Unity的Surface Shader支持
Tessellation,例子如下

【风宇冲】Unity3D教程宝典之Shader篇:第二十六讲Tessellation


[例一:基本细分曲面]
【风宇冲】Unity3D教程宝典之Shader篇:第二十六讲Tessellation
步骤

1:准备
Displacement和Normal 两张贴图。Displacement根据亮度决定细分曲面的高度或者说凸起程度。
2:代码中添加
tessellate:tessFixed

    float _Tess;

            float4 tessFixed()
            {
                return _Tess;
            }

这个表示每个三角面细分的量级
3:对

Displacement进行纹理采样,并沿法线方向作相应偏移。

    void disp (inout appdata v)
            {
                float tex2Dlod(_DispTex, float4(v.texcoord.xy,0,0)).r _Displacement;
                v.vertex.xyz += v.normal d;
            }
 
  1. Shader "Tessellation/1FixedAmount" {
  2.         Properties {
  3.             _Tess ("Tessellation"Range(1,32)) 4
  4.             _MainTex ("Base (RGB)"2D"white" {}
  5.             _DispTex ("Disp Texture"2D"gray" {}
  6.             _NormalMap ("Normalmap"2D"bump" {}
  7.             _Displacement ("Displacement"Range(01.0)) 0.3
  8.             _Color ("Color"color(1,1,1,0)
  9.             _SpecColor ("Spec color"color(0.5,0.5,0.5,0.5)
  10.         }
  11.         SubShader {
  12.             Tags "RenderType"="Opaque" }
  13.             LOD 300
  14.             CGPROGRAM
  15.             #pragma surface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessFixed nolightmap
  16.             struct appdata {
  17.                 float4 vertex POSITION;
  18.                 float4 tangent TANGENT;
  19.                 float3 normal NORMAL;
  20.                 float2 texcoord TEXCOORD0;
  21.             };
  22.             float _Tess;
  23.             float4 tessFixed()
  24.             {
  25.                 return _Tess;
  26.             }
  27.             sampler2D _DispTex;
  28.             float _Displacement;
  29.             void disp (inout appdata v)
  30.             {
  31.                 float tex2Dlod(_DispTex, float4(v.texcoord.xy,0,0)).r _Displacement;
  32.                 v.vertex.xyz += v.normal d;
  33.             }
  34.             struct Input {
  35.                 float2 uv_MainTex;
  36.             };
  37.             sampler2D _MainTex;
  38.             sampler2D _NormalMap;
  39.             fixed4 _Color;
  40.             void surf (Input IN, inout SurfaceOutput o) {
  41.                 half4 tex2D (_MainTex, IN.uv_MainTex) _Color;
  42.                 o.Albedo c.rgb;
  43.                 o.Specular 0.2;
  44.                 o.Gloss 1.0;
  45.                 o.Normal UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));
  46.             }
  47.             ENDCG
  48.         }
  49.         FallBack "Diffuse"
  50. }
【风宇冲】Unity3D教程宝典之Shader篇:第二十六讲Tessellation【风宇冲】Unity3D教程宝典之Shader篇:第二十六讲Tessellation【风宇冲】Unity3D教程宝典之Shader篇:第二十六讲Tessellation


[例基于距离细分曲面]

【风宇冲】Unity3D教程宝典之Shader篇:第二十六讲Tessellation

基于相机距离进行细分,离相机越近细分面数越多。

       float4 tessDistance (appdata v0, appdata v1, appdata v2) {
                float minDist 10.0;
                float maxDist 25.0;
                return UnityDistanceBasedTess(v0.vertexv1.vertexv2.vertexminDist, maxDist, _Tess);
            }



  1. Shader "Tessellation/2Distance" {
  2.         Properties {
  3.             _Tess ("Tessellation"Range(1,32)) 4
  4.             _MainTex ("Base (RGB)"2D"white" {}
  5.             _DispTex ("Disp Texture"2D"gray" {}
  6.             _NormalMap ("Normalmap"2D"bump" {}
  7.             _Displacement ("Displacement"Range(01.0)) 0.3
  8.             _Color ("Color"color(1,1,1,0)
  9.             _SpecColor ("Spec color"color(0.5,0.5,0.5,0.5)
  10.         }
  11.         SubShader {
  12.             Tags "RenderType"="Opaque" }
  13.             LOD 300
  14.             CGPROGRAM
  15.             #pragma surface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessDistance nolightmap
  16.             #include "Tessellation.cginc"
  17.             struct appdata {
  18.                 float4 vertex POSITION;
  19.                 float4 tangent TANGENT;
  20.                 float3 normal NORMAL;
  21.                 float2 texcoord TEXCOORD0;
  22.             };
  23.             float _Tess;
  24.             float4 tessDistance (appdata v0, appdata v1, appdata v2) {
  25.                 float minDist 10.0;
  26.                 float maxDist 25.0;
  27.                 return UnityDistanceBasedTess(v0.vertexv1.vertexv2.vertexminDist, maxDist, _Tess);
  28.             }
  29.             sampler2D _DispTex;
  30.             float _Displacement;
  31.             void disp (inout appdata v)
  32.             {
  33.                 float tex2Dlod(_DispTex, float4(v.texcoord.xy,0,0)).r _Displacement;
  34.                 v.vertex.xyz += v.normal d;
  35.             }
  36.             struct Input {
  37.                 float2 uv_MainTex;
  38.             };
  39.             sampler2D _MainTex;
  40.             sampler2D _NormalMap;
  41.             fixed4 _Color;
  42.             void surf (Input IN, inout SurfaceOutput o) {
  43.                 half4 tex2D (_MainTex, IN.uv_MainTex) _Color;
  44.                 o.Albedo c.rgb;
  45.                 o.Specular 0.2;
  46.                 o.Gloss 1.0;
  47.                 o.Normal UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));
  48.             }
  49.             ENDCG
  50.         }
  51.         FallBack "Diffuse"
  52. }
【风宇冲】Unity3D教程宝典之Shader篇:第二十六讲Tessellation


[例边缘长度曲面]
【风宇冲】Unity3D教程宝典之Shader篇:第二十六讲Tessellation
根据三角面的边缘长度进行细分,也就是越大的三角细分越多


    float4 tessEdge (appdata v0, appdata v1, appdata v2)
            {
                return UnityEdgeLengthBasedTess (v0.vertexv1.vertexv2.vertex_EdgeLength);
            }




  1. Shader "Tessellation/3EdgeLength" {
  2.         Properties {
  3.             _EdgeLength ("Edge length"Range(2,50)) 15
  4.             _MainTex ("Base (RGB)"2D"white" {}
  5.             _DispTex ("Disp Texture"2D"gray" {}
  6.             _NormalMap ("Normalmap"2D"bump" {}
  7.             _Displacement ("Displacement"Range(01.0)) 0.3
  8.             _Color ("Color"color(1,1,1,0)
  9.             _SpecColor ("Spec color"color(0.5,0.5,0.5,0.5)
  10.         }
  11.         SubShader {
  12.             Tags "RenderType"="Opaque" }
  13.             LOD 300
  14.             CGPROGRAM
  15.             #pragma surface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessEdge nolightmap
  16.             #include "Tessellation.cginc"
  17.             struct appdata {
  18.                 float4 vertex POSITION;
  19.                 float4 tangent TANGENT;
  20.                 float3 normal NORMAL;
  21.                 float2 texcoord TEXCOORD0;
  22.             };
  23.             float _EdgeLength;
  24.             float4 tessEdge (appdata v0, appdata v1, appdata v2)
  25.             {
  26.                 return UnityEdgeLengthBasedTess (v0.vertexv1.vertexv2.vertex_EdgeLength);
  27.             }
  28.             sampler2D _DispTex;
  29.             float _Displacement;
  30.             void disp (inout appdata v)
  31.             {
  32.                 float tex2Dlod(_DispTex, float4(v.texcoord.xy,0,0)).r _Displacement;
  33.                 v.vertex.xyz += v.normal d;
  34.             }
  35.             struct Input {
  36.                 float2 uv_MainTex;
  37.             };
  38.             sampler2D _MainTex;
  39.             sampler2D _NormalMap;
  40.             fixed4 _Color;
  41.             void surf (Input IN, inout SurfaceOutput o) {
  42.                 half4 tex2D (_MainTex, IN.uv_MainTex) _Color;
  43.                 o.Albedo c.rgb;
  44.                 o.Specular 0.2;
  45.                 o.Gloss 1.0;
  46.                 o.Normal UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));
  47.             }
  48.             ENDCG
  49.         }
  50.         FallBack "Diffuse"
  51. }
[例 Phong细分曲面]

【风宇冲】Unity3D教程宝典之Shader篇:第二十六讲Tessellation

如果是low poly的模型的话,沿着法线方向去细分效果并不好。
【风宇冲】Unity3D教程宝典之Shader篇:第二十六讲Tessellation【风宇冲】Unity3D教程宝典之Shader篇:第二十六讲Tessellation

而我们可以用Phong Tesselation去细分,该方法尤其适用于low poly模型。

tessphong
:_Phong

 #pragma surface surf Lambert vertex:dispNone tessellate:tessEdge tessphong:_Phong nolightmap



  1. Shader "Tessellation/4Phong" {
  2.         Properties {
  3.             _EdgeLength ("Edge length"Range(2,50)) 5
  4.             _Phong ("Phong Strengh"Range(0,1)) 0.5
  5.             _MainTex ("Base (RGB)"2D"white" {}
  6.             _Color ("Color"color(1,1,1,0)
  7.         }
  8.         SubShader {
  9.             Tags "RenderType"="Opaque" }
  10.             LOD 300
  11.             CGPROGRAM
  12.             #pragma surface surf Lambert vertex:dispNone tessellate:tessEdge tessphong:_Phong nolightmap
  13.             #include "Tessellation.cginc"
  14.             struct appdata {
  15.                 float4 vertex POSITION;
  16.                 float3 normal NORMAL;
  17.                 float2 texcoord TEXCOORD0;
  18.             };
  19.             void dispNone (inout appdata v) }
  20.             float _Phong;
  21.             float _EdgeLength;
  22.             float4 tessEdge (appdata v0, appdata v1, appdata v2)
  23.             {
  24.                 return UnityEdgeLengthBasedTess (v0.vertexv1.vertexv2.vertex_EdgeLength);
  25.             }
  26.             struct Input {
  27.                 float2 uv_MainTex;
  28.             };
  29.             fixed4 _Color;
  30.             sampler2D _MainTex;
  31.             void surf (Input IN, inout SurfaceOutput o) {
  32.                 half4 tex2D (_MainTex, IN.uv_MainTex) _Color;
  33.                 o.Albedo c.rgb;
  34.                 o.Alpha c.a;
  35.             }
  36.             ENDCG
  37.         }
  38.         FallBack "Diffuse"
  39. }


【风宇冲】Unity3D教程宝典之Shader篇:第二十六讲Tessellation

参考资料:
Surface Shaders with DX11 Tessellation
Phong Tessellation

《Introduction_to_3D_Game_Programming_with_Directx_11》

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多