曲面细分着色器

曲面细分:Hull Shader, Tessellation, Domian Shader
         tessellation学习迈克老狼2012 (cnblogs.com)

Shader "may/my Tess"
{
    Properties
    {
        _BaseColor ("Base Color",   2D) = "white" {}
        _Tessellation( "tesselation " , Range(1, 64)) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        Pass
        {
            Tags { "LightMode" = "ForwardBase" }
            CGPROGRAM
            #pragma vertex vert
            #pragma hull hull
            #pragma domain domain 
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Tessellation.cginc"   //包含一些曲面细分的函数

            sampler2D _BaseColor;
            float4 _BaseColor_ST;
            half _Tessellation;

            struct VSInput
            {
                float4 vertex:      POSITION;
                float3 normal:      NORMAL;
                float4 tangent:     TANGENT;
                float2 uv:          TEXCOORD;
            };
            struct HullInput// also VSOutput
            {
                float4 pos          :POSITION;
                float3 normalMS     :NORMAL;
                float4 tangentMS    :TANGENT;
                float2 uv           :TEXCOORD;
            };
            HullInput vert(VSInput v)
            {
                HullInput o;
                o.pos = v.vertex;
                o.normalMS = v.normal;
                o.tangentMS = v.tangent;
                o.uv = TRANSFORM_TEX(v.uv, _BaseColor);
                return o;
            }
            struct DomainInput
                {
                    float4 pos          :SV_POSITION;
                    float3 normalMS     :NORMAL;
                    float4 tangentMS    :TANGENT;
                    float2 uv           :TEXCOORD;
                };
            //#ifdef UNITY_CAN_COMPILE_TESSELLATION       //检查平台是否支持曲面细分
                //Hull**********************
                [domain("tri")]                         //三角形            tri, quad, isoline
                [partitioning("fractional_odd")]        //切分方式          integer, fractional_even, fractional_odd, pow2.
                [outputtopology("triangle_cw")]         //三角形顺时针      point, line, triangle_cw, triangle_ccw
                [outputcontrolpoints(3)]                //三个控制点        
                [patchconstantfunc("ConstFunction")]    //计算常量数据的函数名
                
                DomainInput hull(InputPatch<HullInput,3> patch, uint pointId : SV_OutputControlPointID)
                {
                    DomainInput o;
                    o.pos = patch [pointId].pos;
                    o.normalMS = patch [pointId].normalMS;
                    o.tangentMS = patch [pointId].tangentMS;
                    o.uv = patch [pointId].uv;
                    return o;
                }
                //Const Function***************************
                struct ConstFuncType
                {
                    float edges[3] : SV_TessFactor;
                    float inside : SV_InsideTessFactor;
                };
                ConstFuncType ConstFunction(InputPatch<HullInput, 3> inputPatch)
                {
                    ConstFuncType o;
                    o.edges[0] = _Tessellation;
                    o.edges[1] = _Tessellation;
                    o.edges[2] = _Tessellation;
                    o.inside = _Tessellation;
                    return o;
                }

                //Domain *************************
                
                struct PSInput
                {
                    float4 pos          :SV_POSITION;
                    float3 normalMS     :NORMAL;
                    float4 tangentMS    :TANGENT;
                    float2 uv           :TEXCOORD;
                };
                [domain("tri")]
                PSInput domain(ConstFuncType i, float3 bary:SV_DOMAINLOCATION, OutputPatch<DomainInput,3> patch)
                {
                    PSInput o;
                    o.pos = patch[0].pos * bary.x + patch[1].pos * bary.y + patch[2].pos * bary.z;                          
                    o.tangentMS = patch[0].tangentMS * bary.x + patch[1].tangentMS * bary.y + patch[2].tangentMS * bary.z;
                    o.normalMS = patch[0].normalMS * bary.x + patch[1].normalMS * bary.y + patch[2].normalMS * bary.z;
                    o.uv = patch[0].uv * bary.x + patch[1].uv * bary.y + patch[2].uv * bary.z;

                    o.pos = UnityObjectToClipPos(o.pos);
                    return o;
                }
            //#endif
            fixed4 frag( PSInput i ):SV_TARGET
            {
                return fixed4(i.uv, 0, 1);
            }
            ENDCG
        }
    }
}

Shader "may/Displacement map"
{
    Properties
    {
        _BaseColor ("Base Color Map",           2D) = "white" {}
        _DisplacementMap("Displacement Map",    2D) = "black"{}
        _Hight("Hight",                         Range(0,0.01)) = 0.01
        _Tessellation("Tessellation",           Range(1, 100)) = 10
        _NormalMap("Normal Map",                2D) = "bump"{}

        [Toggle]_use_tess("use Tess", Int) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            Tags{"LightMode" = "ForwardBase"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma shader_feature _USE_TESS_ON
   
            #pragma hull hull 
            #pragma domain domain 

            #pragma multi_compile_fwdbase
            #include "UnityCG.cginc"
            #include "Tessellation.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"
            

            sampler2D _BaseColor;
            float4 _BaseColor_ST;
            sampler2D _DisplacementMap;
            float4 _DisplacementMap_ST;
            float _Hight;
            float _Tessellation;
            sampler2D _NormalMap;
            float4 _NormalMap_ST;

            struct toPS
            {
                float4 vertex       :POSITION;
                float4 tangentMS    :TANGENT;
                float3 normalMS     :NORMAL;
                float2 uv           :TEXCOORD;
            };
            struct VStoHS
            {
                float4 pos              :POSITION;
                float3 lightDirTS       :TEXCOORD;
                float3 viewDirTS        :TEXCOORD1;
                float2 uv_BaseColorMap  :TEXCOORD2;
                float2 uv_DisplaceMap   :TEXCOORD3;
                float2 uv_NormalMap     :TEXCOORD4;
                float3 normalMS         :TEXCOORD5;
                //LIGHTING_COORDS(6,7)
            };
            struct HStoDS
            {
                float4 pos              :POSITION;
                float3 lightDirTS       :TEXCOORD;
                float3 viewDirTS        :TEXCOORD1;
                float2 uv_BaseColorMap  :TEXCOORD2;
                float2 uv_DisplaceMap   :TEXCOORD3;
                float2 uv_NormalMap     :TEXCOORD4;
                float3 normalMS         :TEXCOORD5;
                //SHADOW_COORDS(5)
            };
            
            struct DStoPS
            {
                float4 pos              :POSITION;
                float3 lightDirTS       :TEXCOORD;
                float3 viewDirTS        :TEXCOORD1;
                float2 uv_BaseColorMap  :TEXCOORD2;
                float2 uv_DisplaceMap   :TEXCOORD3;
                float2 uv_NormalMap     :TEXCOORD4;
                float3 normalMS         :TEXCOORD5;
                //LIGHTING_COORDS(5,6)
            };
            
            VStoHS vert(toPS v)
            {
                VStoHS o;
                o.uv_BaseColorMap = TRANSFORM_TEX(v.uv, _BaseColor);
                o.uv_DisplaceMap = TRANSFORM_TEX(v.uv, _DisplacementMap);
                o.uv_NormalMap = TRANSFORM_TEX(v.uv, _NormalMap);

                //v.vertex.xyz += v.normalMS * tex2Dlod(_DisplacementMap, float4(o.uv_DisplaceMap, 0, 1)).xyz * _Hight;
                o.pos = /*UnityObjectToClipPos(*/v.vertex;
                o.normalMS = v.normalMS;
                float3 binormal = cross(v.tangentMS.xyz, v.normalMS) * v.tangentMS.w;
                float3x3 MStoTS = {
                    v.tangentMS.xyz,
                    binormal,
                    v.normalMS
                };
                float3 lightDirMS = ObjSpaceLightDir(v.vertex);
                float3 viewDirMS = ObjSpaceViewDir(v.vertex);
                o.lightDirTS = mul(MStoTS, lightDirMS);
                o.viewDirTS = mul(MStoTS, viewDirMS);

                //TRANSFER_VERTEX_TO_FRAGMENT(o)

                return o;
            }

                [domain("tri")]                         //三角形
                [partitioning("fractional_odd")]        //切分方式
                [outputtopology("triangle_cw")]         //三角形顺时针
                [outputcontrolpoints(3)]                //三个控制点
                [patchconstantfunc("ConstFunction")]    //计算常量数据的函数名
                
                HStoDS hull(InputPatch<VStoHS,3> patch, uint pointId : SV_OutputControlPointID)
                {
                    HStoDS o;
                    o.pos = patch [pointId].pos;
                    o.lightDirTS = patch [pointId].lightDirTS;
                    o.viewDirTS = patch [pointId].viewDirTS;
                    o.uv_BaseColorMap = patch [pointId].uv_BaseColorMap;
                    o.uv_DisplaceMap = patch [pointId].uv_DisplaceMap;
                    o.uv_NormalMap = patch [pointId].uv_NormalMap;
                    o.normalMS      = patch [pointId].normalMS;
                    
                    return o;
                }
                //Const Function***************************
                struct ConstFuncType
                {
                    float edges[3] : SV_TessFactor;
                    float inside : SV_InsideTessFactor;
                };
                ConstFuncType ConstFunction(InputPatch<VStoHS, 3> inputPatch)
                {
                    ConstFuncType o;
                    o.edges[0] = _Tessellation;
                    o.edges[1] = _Tessellation;
                    o.edges[2] = _Tessellation;
                    o.inside = _Tessellation;
                    return o;
                }

                [domain("tri")]
                DStoPS domain(ConstFuncType i, float3 bary:SV_DOMAINLOCATION, OutputPatch<HStoDS,3> patch)
                {
                    DStoPS o;                         
                    o.lightDirTS = patch[0].lightDirTS * bary.x + patch[1].lightDirTS * bary.y + patch[2].lightDirTS * bary.z;
                    o.viewDirTS = patch[0].viewDirTS * bary.x + patch[1].viewDirTS * bary.y + patch[2].viewDirTS * bary.z;
                    o.uv_BaseColorMap = patch[0].uv_BaseColorMap * bary.x + patch[1].uv_BaseColorMap * bary.y + patch[2].uv_BaseColorMap * bary.z;
                    o.uv_DisplaceMap = patch[0].uv_DisplaceMap * bary.x + patch[1].uv_DisplaceMap * bary.y + patch[2].uv_DisplaceMap * bary.z;
                    o.uv_NormalMap = patch[0].uv_NormalMap * bary.x + patch[1].uv_NormalMap * bary.y + patch[2].uv_NormalMap * bary.z;
                    o.normalMS = patch[0].normalMS * bary.x + patch[1].normalMS * bary.y + patch[2].normalMS * bary.z;
                    o.pos = patch[0].pos * bary.x + patch[1].pos * bary.y + patch[2].pos * bary.z;
                    o.pos += tex2Dlod(_DisplacementMap, float4(o.uv_DisplaceMap, 0, 1)) * _Hight * float4(o.normalMS, 1);
                    o.pos = UnityObjectToClipPos(o.pos);
                    return o;
                }

            fixed4 frag(DStoPS i):SV_TARGET
            {
                fixed3 lightDirTS = normalize(i.lightDirTS);
                fixed3 viewDirTS = normalize(i.viewDirTS);
                fixed3 normalTS = UnpackNormal(tex2D(_NormalMap,i.uv_NormalMap));

                //diffuse 
                fixed3 albedo = tex2D(_BaseColor, i.uv_BaseColorMap);
                fixed3 diffuseColor = albedo * _LightColor0 * max(0, dot(lightDirTS, normalTS));

                return fixed4(diffuseColor,1);
            }
            ENDCG
        }
    }
    Fallback "Diffuse"
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值