Shader "Custom/phong2"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _SpecColor ("Specular Color", Color) = (1,1,1,1)
        _NormalMap ("Normal Map", 2D) = "bump" {}
        _GlossTex ("Gloss Map", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf _Phong noambient
        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _NormalMap;
        sampler2D _GlossTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            float4 c = tex2D(_MainTex, IN.uv_MainTex);
            float3 n = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));
            float4 g = tex2D(_GlossTex, IN.uv_MainTex);
            o.Normal = n;
            o.Albedo = c.rgb;
            o.Gloss = g.a;
            o.Alpha = c.a;
        }

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

            //diffuse
            //lambert : N · L
            float3 diffuseColor;
            float ndotl = saturate(dot(s.Normal, lightDir));
            //벡터 * 색상 * 감쇠 * 광원컬러
            diffuseColor = ndotl * s.Albedo * atten * _LightColor0.rgb;

            //spec
            float3 specularColor;
            //1. 하프 단위 벡터 구하기 lightDir + viewDir 
            float3 h = normalize(lightDir + viewDir);
            //2. 노멀벡터와 내적 
            float spec = saturate(dot(s.Normal, h));
            //벡터 * 색상 * 글로스 * 색상
            specularColor = pow(spec, 100) * s.Gloss * _SpecColor.rgb;


            //rim 
            float3 rimColor;
            float rim = abs(dot(s.Normal, viewDir));
            float inverseRim = 1-rim;
            rimColor = pow(inverseRim, 3);
            //fake specular 
            float3 fakeSpec = rimColor * s.Gloss * float3(0.1, 0.1, 0.1);
            
            final.rgb = specularColor + diffuseColor + fakeSpec;
            final.a = s.Alpha;

            return final;
        }

        ENDCG
    }
    FallBack "Diffuse"
}

'산대특 > 게임 UIUX 프로그래밍' 카테고리의 다른 글

Shader - Cubemap Reflection  (0) 2024.02.22
Shader - Diffuse Warping  (0) 2024.02.22
Shader - Lambert  (0) 2024.02.20
Shader - Vertex  (0) 2024.02.19
Shader 기초  (0) 2024.02.18

차례대로 Standard, CustomLambert, HalfLambert

 

1. Standard

 

Shader "Custom/lambert"
{
    Properties
    {
        _MainTex("Main Texture", 2D) = "white"{}
        _NormalMap("NormalMap", 2D) = "bump" {}
        _Color("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf Standard
        #pragma target 3.0
        sampler2D _MainTex;
        sampler2D _NormalMap;     
        float4 _Color;
        struct Input
        {
            float4 color : COLOR;
            float2 uv_MainTex;
            float2 uv_NormalMap;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            
            float4 c = tex2D(_MainTex, IN.uv_MainTex);
            float4 d = tex2D(_NormalMap, IN.uv_NormalMap);
            o.Normal = UnpackNormal (d);
            o.Albedo = c.rgb * _Color;
            o.Alpha = c.a;
        }
        // 빛을 만든다
       
        ENDCG
    }
    FallBack "Diffuse"
}

 

2. CustomLambert

Shader "Custom/customLambert"
{
    Properties
    {
        _MainTex("Main Texture", 2D) = "white"{}
        _NormalMap("NormalMap", 2D) = "bump" {}
        _Color("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf _MyLambert
        #pragma target 3.0
        sampler2D _MainTex;
        sampler2D _NormalMap;     
        float4 _Color;
        struct Input
        {
            float4 color : COLOR;
            float2 uv_MainTex;
            float2 uv_NormalMap;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            float4 c = tex2D(_MainTex, IN.uv_MainTex);
            float4 d = tex2D(_NormalMap, IN.uv_NormalMap);
            o.Normal = UnpackNormal (d);
            o.Albedo = c.rgb * _Color;
            o.Alpha = c.a;
        }
        // 빛을 만든다
        float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
        {
            float4 final;
            float ndot1 = dot(s.Normal, lightDir);
            final.rgb = ndot1 * s.Albedo.rgb;
            final.a = s.Alpha;
            return final;
            }
        ENDCG
    }
    FallBack "Diffuse"
}

 

2-2. CustomLambert

Shader "Custom/customLambert"
{
    Properties
    {
        _NormalMap("Normal Map",2D) = "bump"{}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf _MyLambert noambient;
        #pragma target 3.0
        sampler2D _NormalMap;     
        struct Input
        {
            float4 color : COLOR;
            float2 uv_NormalMap;
        };
        void surf (Input IN, inout SurfaceOutput o)
        {
            float4 c = tex2D(_NormalMap, IN.uv_NormalMap);
            o.Normal = UnpackNormal (c);
            o.Albedo = 1;
            
        }

        float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
        {
            float4 final;
            //return float4(1,0,0,1);
            //노멀벡터와 조명벡터를 내적해라
            float ndot1 = dot(s.Normal, lightDir);
            final = saturate(ndot1);
            return final;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 

3. HalfLambert

Shader "Custom/customLambert2"
{
    Properties
    {
        _MainTex("Main Texture", 2D) = "white"{}
        _NormalMap("NormalMap", 2D) = "bump" {}
        _Color("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf _MyLambert
        #pragma target 3.0
        sampler2D _MainTex;
        sampler2D _NormalMap;     
        float4 _Color;
        struct Input
        {
            float4 color : COLOR;
            float2 uv_MainTex;
            float2 uv_NormalMap;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            float4 c = tex2D(_MainTex, IN.uv_MainTex);
            float4 d = tex2D(_NormalMap, IN.uv_NormalMap);
            o.Normal = UnpackNormal (d);
            o.Albedo = c.rgb * _Color;
            o.Alpha = c.a;
        }
        // 빛을 만든다
        float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
        {
            float4 final;
            float ndot1 = dot(s.Normal, lightDir)* 0.5 + 0.5;
            final = pow(ndot1, 3);
            final.rgb = ndot1 * s.Albedo.rgb * _LightColor0.rgb * atten;
            final.a = s.Alpha;
            return final;
            }
        ENDCG
    }
    FallBack "Diffuse"
}

 


 

CustomLambert의 기본형

 

1. #pragma surface surf _MyLambert

2. void surf (Input IN, inout SurfaceOutput o)

3. float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
 {
  ;
     return float4(1, 0, 0 , 1);

 }

 

우선 이 3가지로 스탠다드를 바꿔주고 메서드를 만들어준다.

이때 매개변수는 변경하거나 수정할 수 없으며 주어진 대로 사용해야 한다.

 

 

float3 lightDir
조명 방향의 벡터
단, 조명을 편하게 사용하기 위해 뒤집혀지고 길이가 1인 단위 벡터 상태

 

float atten(uation) - 감쇠
그림자를 받거나 거리가 멀어지면 점점 조명이 흐려지는 라이트의 거리별 현상

 

dot : 노멀 벡터와 라이트 벡터를 내적 연산해주는 함수

우리는 o.Normal에 값을 넣지 않았지만 s.Normal의 값을 가져올 수 있다.

 

lightDir

lightDir은 vertex에서 바라보는 조명의 방향을 뒤집은 조명 벡터이므로 두 벡터를 단순히 내적하면 cos값이 나온다.

 

나중에 ambient light 또는 추가라이트를 비출 때 이 음수는 문제를 일으킬수 있는데

이(0아래는 전부 0으로 잘라주는)를 해결해주는 함수 saturate, max가 있다.

saturate
max

이 함수들을 사용하면 빨간선처럼 0보다 작은수는 0으로 지정해준다.

 


 

HalfLambert

 

* 0.5 + 0.5는 마법의 숫자이다.

이 공식은 -1 ~ 1까지의 숫자를 0에서 1까지의 범위로 만들어준다.

그 결과 cos라인을 끌어 올려주어 부드러운 결과 값이 나온다.

 

조명의 색상 or 감쇠를 이용할 수 있다.

ex) final.rgb = ndotl * s.Albedo * _LightColor0.rgb * atten;

 

https://docs.unity3d.com/kr/2021.3/Manual/SL-UnityShaderVariables.html

 

빌트인 셰이더 변수 - Unity 매뉴얼

Unity의 빌트인 포함 파일에는 셰이더에 대한 전역 변수(예: 현재 오브젝트의 변환 매트릭스, 광원 파라미터, 현재 시간 등)가 포함되어 있습니다. 이러한 셰이더 프로그램에서 이러한 전역 변수

docs.unity3d.com

 

이에 따라 조명의 색깔을 변경하고 거리에 따른 그림자를 조절할 수 있다.

+ Recent posts