0506 쉐이더 블린퐁

2021. 5. 6. 17:57unity/쉐이더

N=normal Vector, L=Light Vect0r, V=View Vector

하프벡터 : normalize (Light V+View V)
N과 1 사이의 각을 구하는 공식 > 블린퐁 공식

Shader "Custom/BlinnPhong"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Bump("Normal Map", 2D) = "bump" {}
    }
        SubShader
    {
        Tags { "RenderType" = "Opaque" }
        LOD 200

        CGPROGRAM

        #pragma surface surf _MyLambert

        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _Bump;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_Bump;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Normal = UnpackNormal(tex2D(_Bump, IN.uv_Bump));
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
     
        float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float3 viewDir, float atten)
        {
            float ndotl = dot(s.Normal, lightDir);
            float4 final;

            float3 H = normalize(viewDir + lightDir);
            float spec = saturate(dot(H, s.Normal));

            final.rgb = s.Albedo * ndotl;
            final.a = s.Alpha;
            return spec;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

좌 : 일반 램버트 라이팅, 우: 블린퐁 공식 입힌 스페큘러 + 텍스쳐

 

Shader "Custom/BlinnPhong"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Bump("Normal Map", 2D) = "bump" {}
        _SpecPow("Specular Power",Range(0,100)) = 0
        _SpecCol("Specular Color", Color) = (1,1,1,1)
    }
        SubShader
    {
        Tags { "RenderType" = "Opaque" }
        LOD 200

        CGPROGRAM

        #pragma surface surf _MyLambert

        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _Bump;
        float _SpecPow;
        float4 _SpecCol;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_Bump;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Normal = UnpackNormal(tex2D(_Bump, IN.uv_Bump));
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
     
        float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float3 viewDir, float atten)
        {
            float ndotl = dot(s.Normal, lightDir);
            float4 final;

            float3 H = normalize(viewDir + lightDir);
            float spec = pow(dot(H, s.Normal), _SpecPow);
            s.Specular = 0.5;

            final.rgb = s.Albedo * ndotl;
            final.a = s.Alpha;
            return spec;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 

 

스페큘러에 색상 더하기

Shader "Custom/BlinnPhong"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _BumpMap ("Normal Map",2D) = "bump" {}
        _SpecPow("Specualr Power",Range(1,100)) = 1
        _SpecCol ("Specular Color",Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
       
        #pragma surface surf _MyLambert
        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _BumpMap;
        float _SpecPow;
        float4 _SpecCol;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_BumpMap;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }

        float4 Lighting_MyLambert (SurfaceOutput s, float3 lightDir, float3 viewDir, float atten)
        {
            //커스텀 램버트 라이트 공식
            float ndotl = dot(s.Normal, lightDir);
            
            //하프벡터 구하기
            float3 H = normalize(viewDir + lightDir);
            //dot : 하프 벡터와 노말 벡터 사이의 내적 세타 값 구하기
            float spec = dot(H, s.Normal);
            //스페큘러 값에 제곱해주기
            spec = pow(spec, _SpecPow);

            //스페큘러 색상 적용
            float3 specColor;
            specColor = spec * _SpecCol.rgb;

            //알베도 적용
            float4 final;
            final.rgb = (s.Albedo * ndotl) +specColor.rgb;
            final.a = s.Alpha;
            
            return final;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 

 

Rim 적용하기

Shader "Custom/BlinnPhong"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _BumpMap ("Normal Map",2D) = "bump" {}
        _SpecPow("Specualr Power",Range(1,100)) = 1
        _SpecCol ("Specular Color",Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
       
        #pragma surface surf _MyLambert noambient
        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _BumpMap;
        float _SpecPow;
        float4 _SpecCol;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_BumpMap;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }

        float4 Lighting_MyLambert (SurfaceOutput s, float3 lightDir, float3 viewDir, float atten)
        {
            float4 final;

            //Lambert 및 알베도 적용
            float3 DiffColor;
            float ndotl = saturate(dot(s.Normal, lightDir));
            DiffColor = ndotl * s.Albedo;

            //스페큘러 적용
            float3 specColor;
            float3 H = normalize(viewDir + lightDir);
            float spec = dot(H, s.Normal);
            specColor = spec * _SpecCol.rgb;
            
            //Rim 적용
            float rimColor;
            float rim = dot(viewDir, s.Normal);
            float invertRim = 1 - rim;
            rimColor = invertRim;

            final.rgb = DiffColor + specColor + rimColor;
            final.a = s.Alpha;
            
            return final;
        }
        ENDCG
    }
    FallBack "Diffuse"
}