Calmer的文章

  • 首页
  • 文章归档
  • 关于页面

  • 搜索
体验游戏 笔记 推荐 工具链 工具使用 小游戏 插件 UI 软件 教程

基础高光Shader(带阴影+光照衰减)

发表于 2020-07-26 | 分类于 游戏开发 | 0 | 阅读次数 805

前言

记录学习玩基础篇,书写的Shader


代码

Shader "MyShader/TheShader"
{
    Properties
    {
        _Color("Color Tint",Color)=(1,1,1,1) 
        _MainTex ("Texture", 2D) = "white" {}
        _Specular("Specular",Color)=(1,1,1,1)
        _Gloss("Gloss",Range(8.0,256))=20
        _BumpedTex("Normal Tex",2D)="bump"{}
        _BumpedScale("BumpedScale",float)=1

    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "Queue"= "Geometry" }

        Pass
        {
            Name "ShadowCaster"
            Tags {"LightMode" = "ShadowCaster"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #pragma multi_compile_shadowcaster

            #include "UnityCG.cginc"

            struct v2f{
                V2F_SHADOW_CASTER;
            };

            v2f vert(appdata_base v)
            {
                v2f o;
                TRANSFER_SHADOW_CASTER_NORMALOFFSET(o);
                return o;
            }

            float4 frag(v2f i) : SV_Target
            {
                SHADOW_CASTER_FRAGMENT(i)
            }

            ENDCG
        }

        Pass
        {
            Tags{"LightMode"="ForwardBase" }
            CGPROGRAM
            #pragma multi_compile_fwdbase
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            fixed4 _Color;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _Specular;
            float _Gloss;
            sampler2D _BumpedTex;
            float4 _BumpedTex_ST;
            float _BumpedScale;

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 tangent : TANGENT;
                float4 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 uv : TEXCOORD0;
                float4 TtoW0: TEXCOORD1;
                float4 TtoW1: TEXCOORD2;
                float4 TtoW2: TEXCOORD3;
                SHADOW_COORDS(4)
                
            };


            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv.xy = v.uv.xy * _MainTex_ST.xy +_MainTex_ST.zw;
                o.uv.zw = TRANSFORM_TEX(v.uv,_BumpedTex).xy;
                float3 worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
                fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
                fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
                fixed3 worldBinormal = cross(worldNormal,worldTangent) * v.tangent.w;
                o.TtoW0 = float4(worldTangent.x,worldBinormal.x,worldNormal.x,worldPos.x);
                o.TtoW1 = float4(worldTangent.y,worldBinormal.y,worldNormal.y,worldPos.y);
                o.TtoW2 = float4(worldTangent.z,worldBinormal.z,worldNormal.z,worldPos.z);

                TRANSFER_SHADOW(o);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {

                float3 worldPos = float3(i.TtoW0.w,i.TtoW1.w,i.TtoW2.w);

                fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
                fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));
                fixed3 adelbo = tex2D(_MainTex, i.uv.xy).rgb * _Color.rgb;

                fixed3 bump = UnpackNormal(tex2D(_BumpedTex,i.uv.zw));
                bump.xy *= _BumpedScale;
                bump.z = sqrt(1-saturate(dot(bump.xy,bump.xy)));

                bump = normalize(half3(dot(i.TtoW0.xyz,bump),dot(i.TtoW1.xyz,bump),dot(i.TtoW2.xyz,bump)));

                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb * adelbo.rgb ;

                fixed3 diffuse = _LightColor0.rgb * adelbo.rgb * saturate(dot(bump,lightDir));
                
                fixed3 halfDir = normalize(lightDir+viewDir);

                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(bump,halfDir)),_Gloss);

                UNITY_LIGHT_ATTENUATION(atten,i,worldPos);

                return fixed4(ambient+(diffuse+specular)*atten , 1.0);
            }
            ENDCG
        }

        Pass
        {
            Tags{"LightMode"="ForwardAdd" }

            Blend One One
            CGPROGRAM
            //#pragma multi_compile_fwdadd
            #pragma multi_compile_fwdadd_fullshadows
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            fixed4 _Color;
            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _Specular;
            float _Gloss;
            sampler2D _BumpedTex;
            float4 _BumpedTex_ST;
            float _BumpedScale;

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 tangent : TANGENT;
                float4 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float4 uv : TEXCOORD0;
                float4 TtoW0: TEXCOORD1;
                float4 TtoW1: TEXCOORD2;
                float4 TtoW2: TEXCOORD3;
                SHADOW_COORDS(4)
                
            };


            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv.xy = v.uv.xy * _MainTex_ST.xy +_MainTex_ST.zw;
                o.uv.zw = TRANSFORM_TEX(v.uv,_BumpedTex).xy;
                float3 worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
                fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
                fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
                fixed3 worldBinormal = cross(worldNormal,worldTangent) * v.tangent.w;
                o.TtoW0 = float4(worldTangent.x,worldBinormal.x,worldNormal.x,worldPos.x);
                o.TtoW1 = float4(worldTangent.y,worldBinormal.y,worldNormal.y,worldPos.y);
                o.TtoW2 = float4(worldTangent.z,worldBinormal.z,worldNormal.z,worldPos.z);

                TRANSFER_SHADOW(o);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {

                float3 worldPos = float3(i.TtoW0.w,i.TtoW1.w,i.TtoW2.w);

                fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
                fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));
                fixed3 adelbo = tex2D(_MainTex, i.uv.xy).rgb * _Color.rgb;

                fixed3 bump = UnpackNormal(tex2D(_BumpedTex,i.uv.zw));
                bump.xy *= _BumpedScale;
                bump.z = sqrt(1-saturate(dot(bump.xy,bump.xy)));

                bump = normalize(half3(dot(i.TtoW0.xyz,bump),dot(i.TtoW1.xyz,bump),dot(i.TtoW2.xyz,bump)));

                fixed3 diffuse = _LightColor0.rgb * adelbo.rgb * saturate(dot(bump,lightDir));
                
                fixed3 halfDir = normalize(lightDir+viewDir);

                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(bump,halfDir)),_Gloss);

                UNITY_LIGHT_ATTENUATION(atten,i,worldPos);

                return fixed4((diffuse+specular)*atten , 1.0);
            }
            ENDCG
        }
    }

    FallBack "Specular"
}

  • 本文作者: Calmer
  • 本文链接: https://mytechplayer.com/archives/基础高光shader带阴影光照衰减
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
Unity3D Shader入门
LRU算法
  • 文章目录
  • 站点概览
Calmer

Calmer

88 日志
7 分类
10 标签
RSS
Creative Commons
0%
© 2020 — 2025 Calmer
由 Halo 强力驱动
蜀ICP备20010026号-1川公网安备51019002006543
Copyright © 2020-2025 Calmer的文章