유니티/게임그래픽

Lambert 커스텀 라이트

DOlpa_GB 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  (1) 2024.02.21