shader积雪

作者: 树上的cat_ee3c | 来源:发表于2018-01-09 18:13 被阅读70次

    效果如图:

    原理在代码注释中。

    Shader代码:

    Shader"Custom/RealisticSnow"{

    Properties{

    _MainTex("Base(RGB)",2D)="white"{}

    _Bump("Bump",2D)="bump"{}

    _Snow("SnowLevel",Range(0,1))=0

    _SnowColor("SnowColor",Color)=(1.0,1.0,1.0,1.0)

    _SnowDirection("SnowDirection",Vector)=(0,1,0)

    _SnowDepth("SnowDepth",Range(0,0.2))=0.1

    _Wetness("Wetness",Range(0,0.5))=0.3

    }

    SubShader{

    Tags{"RenderType"="Opaque"}

    LOD200

    CGPROGRAM

    #pragmasurfacesurfLambertvertex:vert

    sampler2D_MainTex;

    sampler2D_Bump;

    float_Snow;

    float4_SnowColor;

    float4_SnowDirection;

    float_SnowDepth;

    float_Wetness;

    structInput{

    float2uv_MainTex;

    float2uv_Bump;

    float3worldNormal;

    INTERNAL_DATA

    };

    voidvert(inoutappdata_fullv){

    //通过【模型到视角的逆转置矩阵】将【积雪方向】转换到【模型坐标系】中

    float4sn=mul(UNITY_MATRIX_IT_MV,_SnowDirection);

    //计算当前【点的法线方向】和【下雪反方向】的点乘[-1,1]

    //如果顶点点乘大于设置的_Snow值,那么该点就往【点的法线方向】和【下雪反方向】之和的方向挤出

    //如果雪量_Snow为0.5,那么模型法线为up的点挤出最多

    if(dot(v.normal,sn.xyz)>=lerp(1,-1,_Snow))

    {

    v.vertex.xyz+=(sn.xyz+v.normal)*_SnowDepth*_Snow;

    }

    }

    voidsurf(InputIN,inoutSurfaceOutputo){

    half4c=tex2D(_MainTex,IN.uv_MainTex);

    o.Normal=UnpackNormal(tex2D(_Bump,IN.uv_Bump));

    //_Snow为0.5时,diff值域【-1,1】

    halfdifference=dot(WorldNormalVector(IN,o.Normal),_SnowDirection.xyz)-lerp(1,-1,_Snow);

    //当_Wetness为0.3时,要控制diff的最终值域为【0,1】,那么就有0

    //可以得出【法线方向】和【积雪方向】夹角为73-90度之间时,就会有【雪】与【地面】材质叠加的效果

    //而小于73度的,都是积雪;大于90度的没有积雪

    difference=saturate(difference/_Wetness);

    o.Albedo=difference*_SnowColor.rgb+(1-difference)*c;

    o.Alpha=c.a;

    }

    ENDCG

    }

    FallBack"Diffuse"

    }

    来源:http://www.lxway.com/40250226.htm

    相关文章

      网友评论

        本文标题:shader积雪

        本文链接:https://www.haomeiwen.com/subject/uiegnxtx.html