【Unity Shader】2020-04-21-崩三卡通渲染

参考博客:https://blog.csdn.net/u010333737/article/details/82287853

// 崩坏3 光照公式
// tex * Ce * Pe * Weight + (tex * Csky * Pdif + Csky * Cspec * Pspec) * (1 - Weight)
// 即 自发光 * Weight + (漫反射光 + 镜面高光)* (1 - Weight)
Shader "MyShader/mihoyo/bh3"
{
    Properties
    {
        // 基础贴图
        _MainTex ("Main Texture", 2D) = "white" {}
        // 光照贴图
        _LightTex ("Light Map Texture", 2D) = "white" {}
        //_LightShadowRange("Shadow Range", Range(0, 1)) = 0.5
        // 权重
        _Weight("Weight", Range(0, 1)) = 0.5
        // 自发光参数
        _Emission("Emission", Range(0, 1)) = 1
        _EmissionColor("Emission Color", Color) = (1,1,1,1)
        //_EmissionBloomFactor("Emission Bloom Factor", Range(0, 1)) = 0.9
        // 漫反射参数,分三层过渡
        _DiffuseColor("Diffuse Color", Color) = (1,1,1,1)
        _FirstShadowColor("1st Shadow Color", Color) = (0.8,0.8,0.8,1)
        _FirstShadowLine("1st Shadow Line", Range(0, 1)) = 0.5
        _SecondShadowColor("2nd Shadow Color", Color) = (0.5,0.5,0.5,1)
        _SecondShadowLine("2nd Shadow Line", Range(0, 1)) = 0.2
        //_ThirdShadowColor("3rd Shadow Color", Color) = (0.2,0.2,0.2,1)
        // 高光参数
        _SpecularColor("Specular Color", Color) = (1,1,1,1)
        _SpecularLine("Specular Line", Range(0, 1)) = 0.5
        _Gloss("_Gloss", Range(1, 255)) = 8
        // 描边
        _OutLineColor("Outline Color", Color) = (0,0,0,0)
        _OutLineWidth("Outline Width", Range(0, 100)) = 50
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
           
            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _LightTex;
            float4 _LightTex_ST;
            float _LightShadowRange;
            float _Weight;
            float _Emission;
            fixed4 _EmissionColor;
            float _EmissionBloomFactor;
            fixed4 _DiffuseColor;
            fixed4 _FirstShadowColor;
            float _FirstShadowLine;
            fixed4 _SecondShadowColor;
            float _SecondShadowLine;
            //fixed4 _ThirdShadowColor;
            fixed4 _SpecularColor;
            float _SpecularLine;
            float _Gloss;
            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal: NORMAL;
                float4 texcoord : TEXCOORD0;
                fixed4 color : COLOR;
            };
            struct v2f
            {
                float4 vertex : SV_POSITION;
                fixed3 worldNormal: TEXCOORD0;
                fixed3 worldPos: TEXCOORD1;
                fixed4 uv: TEXCOORD2;
                          fixed4 vertColor : TEXCOORD3;
            };
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex); 
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                o.worldPos = normalize(mul(unity_ObjectToWorld, v.vertex).xyz);
                o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
                o.uv.zw = TRANSFORM_TEX(v.texcoord, _LightTex);
                o.vertColor = v.color;
                return o;
            }
            fixed4 frag (v2f i) : SV_Target
            {
                // 法线
                fixed3 worldNormal = normalize(i.worldNormal);
                // 光照
                fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
                // 相机
                fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
                //
                fixed3 worldHalfDir = normalize(worldLightDir+worldViewDir);
               
                // 半兰伯特模型
                float halfLambert = dot(worldNormal, worldLightDir) * 0.5 + 0.5;
                fixed4 mainTex = tex2D(_MainTex, i.uv.xy);  // 基本色
                fixed4 lightTex = tex2D(_LightTex, i.uv.zw); // 光照贴图
                // 环境光
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * mainTex.rgb;
                // 计算自发光
                fixed3 emission;
                emission.rgb = mainTex.rgb * _Emission * _EmissionColor.rgb;
                // 计算漫反射
                fixed3 diffuse = fixed3(0,0,0);
                float diffuseMask = lightTex.g;
                if(diffuseMask > 0.1) {
                    float firstMask = diffuseMask > 0.5 ? diffuseMask * 1.2 - 0.1 : diffuseMask * 1.25 - 0.125;
                    bool isLight = (firstMask + halfLambert) * 0.5 > _FirstShadowLine;
                    diffuse = isLight ? mainTex.rgb : mainTex.rgb * _FirstShadowColor.rgb;
                             } else {
                    bool isFirst = (diffuseMask + halfLambert) * 0.5 > _SecondShadowLine;
                    diffuse = isFirst ? mainTex.rgb * _FirstShadowColor.rgb : mainTex.rgb * _SecondShadowColor.rgb;
                             }
                diffuse *= _DiffuseColor.rgb * _LightColor0.rgb;
               
                // 计算高光
                float specularLight = pow(max(0, dot(worldNormal, worldHalfDir)), _Gloss);
                float3 specular = float3(0,0,0);
                if(lightTex.g != 1 && lightTex.r !=1){
                    if((specularLight + lightTex.b)  > 1.0 ) {
                        if(halfLambert > _SpecularLine) {
                            specular = lightTex.b * _SpecularColor.rgb;   
                                           }
                    }
                }
                specular *= _LightColor0.rgb;
               
                // 最终颜色
                fixed4 color = fixed4(_Weight * emission + ( 1 - _Weight) * (diffuse + specular), 1);
                // _Weight * emission + ( 1 - _Weight) * color
                return  color;
            }
            ENDCG
        }
        Pass { // outline 外轮廓线
            Name "Outline"
            Cull Front
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma fragmentoption ARB_precision_hint_fastest       // 最快速精度
            fixed _OutLineWidth;
            fixed4 _OutLineColor;
            float4 vert (float4 vertex : POSITION, float3 normal : NORMAL) : SV_POSITION {
                return UnityObjectToClipPos(vertex + normal * _OutLineWidth * 0.0000001);
            }
            fixed4 frag () : SV_Target { return _OutLineColor; }
            ENDCG
        }
    }
    Fallback "VertexLit"
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路易斯·李

点个赞再走呗 :)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值