UnityShader案例(一)——漫反射

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_25614787/article/details/73197984

一、漫反射原理

1、兰伯特模型

(1)定义:反射光线的强度与表面法线和光源的方向之间夹角的余弦值成正比。
(2)计算公式:这里写图片描述

这里写图片描述:最终的漫反射颜色
这里写图片描述:入射光的颜色和强度
这里写图片描述:材质的漫反射系数
这里写图片描述:表面法线
这里写图片描述:指向光源单位矢量

2、半兰伯特模型

(1)定义:与原兰伯特相比,半兰伯特光照模型没有使用max函数操作来防止向量n向量l的点积为负值,而是对结果进行了一个0.5倍的缩放再加上0.5大小的偏移
(2)计算公式:这里写图片描述
这里写图片描述:最终的漫反射颜色
这里写图片描述:入射光的颜色和强度
这里写图片描述:材质的漫反射系数
这里写图片描述:表面法线
这里写图片描述:指向光源单位矢量

二、漫反射案例

1、表面着色器实现兰伯特光照模型

Shader "Custom/Unlit/Diffuse" {
    Properties {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Lamb

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        inline fixed4 LightingLamb (SurfaceOutput s, fixed3 lightDir,  fixed atten){
            float diff=dot(s.Normal,lightDir);
            fixed4 c;
            c.rgb = (s.Albedo * _LightColor0.rgb * diff) ;
            c.a=1.0;
            return c;
        }

        struct Input {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o) {
            half4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

这里写图片描述

2、逐顶点光照实现兰伯特光照模型

Shader "Custom/Unlit/VertexDiffuse"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color("Diffuse",Color)=(1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal:NORMAL;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                fixed3 color:COLOR;
            };

            sampler2D _MainTex;
            fixed4 _Color;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);

                o.uv = TRANSFORM_TEX(v.uv,_MainTex);

                fixed3 ambient1=UNITY_LIGHTMODEL_AMBIENT.xyz;

                fixed3 worldNormal=normalize(mul(v.normal,(float3x3)unity_WorldToObject));

                fixed3 worlfLight=normalize(_WorldSpaceLightPos0.xyz);

                fixed halfLanbern=dot(worldNormal,worlfLight)*0.5+0.5;

                fixed3 diffuse1=_LightColor0.rgb * _Color.rgb * halfLanbern;

                o.color= ambient1+ diffuse1;

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                return fixed4(col.rgb*i.color,1.0);
            }
            ENDCG
        }
    }
}

这里写图片描述

3、逐像素光照实现兰伯特光照模型

Shader "Custom/Unlit/FlagmentDiffuse"
{
    Properties
    {
        _Diffuse("diffuse",Color)=(1,1,1,1)
        _MainTex("Texture",2D)="white"{}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

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

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            struct appdata
            {
                float4 pos : POSITION;
                float3 normal:NORMAL;
                float2 uv:TEXCOORD0;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float3 worldNormal:NORMAL;
                float2 uv:TEXCOORD0;
            };

            fixed4 _Diffuse;
            sampler2D _MainTex;

            v2f vert (appdata v)
            {
                v2f o;
                o.pos=mul(UNITY_MATRIX_MVP,v.pos);
                o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);
                o.uv=v.uv;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {


                fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;

                fixed3 worldNormal=normalize(i.worldNormal);

                fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);

                fixed a=dot(worldNormal,worldLightDir)*0.5+0.5;

                fixed4 col = tex2D(_MainTex, i.uv);

                fixed3 diffuse=_LightColor0.rgb * _Diffuse.rgb * a;

                fixed3 color = diffuse + ambient;

                return fixed4(color*col.rgb,1.0);
            }
            ENDCG
        }
    }
}

这里写图片描述

4、表面着色器实现半兰伯特光照模型

Shader "Custom/HalfLambert" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf HalfLambert
        #pragma target 3.0
        #include "UnityCG.cginc"

        sampler2D _MainTex;
        float4 _Color;

        struct Input {
            float2 uv_MainTex;
        };

        inline float4 LightingHalfLambert(SurfaceOutput s,fixed3 lightDir,fixed atten ){
            float difLight=dot(s.Normal,lightDir);
            float hLambert=difLight*0.5+0.5;
            float4 col;
            col.rgb=s.Albedo *_LightColor0.rgb *(hLambert*atten*2);
            col.a=s.Alpha;
            return col;
        }

        void surf (Input IN, inout SurfaceOutput o) {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

这里写图片描述

展开阅读全文

没有更多推荐了,返回首页