ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Lambert 커스텀 라이트
    유니티/게임그래픽 2024. 2. 21. 18:09

    우선 간단하게 텍스쳐 하나 받아 출력하게 한다

    Shader "Custom/NewSurfaceShader"
    {
        Properties
        {
            _MainTex ("Albedo (RGB)", 2D) = "white" {}
        }
        SubShader
        {
            Tags { "RenderType"="Opaque" }
    
            CGPROGRAM
            #pragma surface surf _MyLambert noambient   // 환경광 제거
            sampler2D _MainTex;
    
            struct Input
            {
                float2 uv_MainTex;
            };
    
            void surf (Input IN, inout SurfaceOutput o)  // Lambert쓸거면 output 이후로 지우자
            {
               fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
               o.Albedo = c.rgb;
            }
    
            float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
            {
                return float4(1,0,0,1);
            }
            ENDCG
        }
        FallBack "Diffuse"
    }

     

    하지만 여기서 처음 보는 부분이 있다

      //반환타입 float4는 최종 color
      //Custom Light 만들때 반드시 Lightning<라이트 모델이름> ex) Lightning_MyLambert
    
      float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
      {
          return float4(1,0,0,1);
      }

     

    = > 여기서 _MyLambert가 라이팅 이름이다

    #pragma surface surf _MyLambert noambient

     

    이게 커스텀 라이트 함수의 기본형이다. 반환타입은 float4이고 이 반환값은 최종 color를 의미한다

    float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)

    {

        return float4(1, 0, 0, 1);

    }

     

    여기서 주의할건 커스텀 라이트 이름앞에 Lighting을 붙여줘야 라이트 함수로 받아들인다

    float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)

    {

        return float4(1, 0, 0, 1);

    }

     

    변경하거나 수정할 수 없다. 주어진대로 사용해야 한다.

    매개변수 SurfaceOutput s 의 값은 surf 함수에서 계산된 후 전달된 구조체 인스턴스이다

    매개변수 float3 lightDir 는 Vertex에서 바라보는 조명의 방향을 뒤집은 조명 벡터이다. 길이가 1인 단위벡터이다

    매개변수 float atten 는 그림자를 받거나 거리가 멀어지면서 점점 조명이 흐려지는 라이트의 거리별 감쇠현상을 나타낸다

    float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)

    {

        return float4(1, 0, 0, 1);

    }

     

    위 코드는 말 그대로 (1,0,0,1) 값을 출력하도록 만드는 단순한 코드이며

    이제 dot 함수를 사용하여 노멀벡터와 라이트벡터를 내적 연산을 해주자

     

            float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
            {
                float ndot = dot(s.Normal, lightDir);
                return ndot;
            }

     

    이전 surf 함수에서 o.Normal에 아무값도 넣지 않았으나 기본값이 있는  s.Normal의 값을 가져올 수 있다

    이게 Lambert 라이트의 기본형이다

    하지만 지금은 보다시피 조명의 색상도 받지 못하며 내적연산한 값이 1 ~ -1이기에 

    후에 ambient light나 추가 라이트를 비출때 이 음수가 문제를 불러일으킬 수 있다

     

    이것을 방지하기 위해 0 밑의 값은 전부 0으로 잘라버려야 하는데

    이러한 기능을 가진 함수는 saturate, max가 있다

     

    이번엔 staturate함수를 사용하여 바꿔보겠다

     float4 Lighting_MyLambert(SurfaceOutput s, float3 lightDir, float atten)
     {
         float ndot = dot(s.Normal, lightDir);
         float4 final = saturate(ndot) + 0.5;
         return final;
     }

    솔직히 이 과정에서 쓰이는 코싸인, 벡터를 내적한다던가 하는것들은 아직 이해되지 않는다

    하지만 우선 이런 상황에서 이런 함수가 쓰인다는것, 그리고 커스텀 라이팅 만드는법만 익히고 넘어가자

    '유니티 > 게임그래픽' 카테고리의 다른 글

    Half-Lambert  (0) 2024.02.22
    Vertex Color 응용  (0) 2024.02.22
    디지털 라이트 이론 & Vector  (0) 2024.02.21
    Lambert & Blinn Phong  (0) 2024.02.21
    NormalMap  (0) 2024.02.21
Designed by Tistory.