본문 바로가기

유니티/쉐이더

[Unity Shader] 커스텀 라이트 : Lambert, Half - Lambert

Lambert (램버트)

Specular 공식이 없고 빛에 의한 밝고 어두움이 구현된 가벼운 라이트 구조

내장된 Lambert를 이용한 코드

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

        CGPROGRAM
        #pragma surface surf Lambert
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

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

 


커스텀 라이트 함수

좀 더 확실한 결과를 보기 위해 noambient(주변광, 환경광 제거)를 추가했습니다.

- #pragma 부분자신이 원하는 이름으로 작성합니다.

- 아래 함수 부분Lighting + Custom(자신이 작성한 이름)으로 함수를 작성합니다.

- 함수의 인자SurfaceOutput, float3, float으로 정해져있습니다.


SurfaceOutput S

- SurfaceOutputsurf함수거쳐서 들어옵니다.

- SurfaceOutput 구조체 

  • fixed3 Albedo;
  • fixed3 Normal;
  • fixed3 Emission;
  • half Specular;
  • fixed Gloss;
  • fixed Alpha;

float3 lightDir

- 파란색 화살표뒤집은 VectorlightDir 입니다. 

- 계산하기 쉽게 뒤집힌 상태입니다. (사진의 파란색 화살표와 반대로)


float atten

- attenattenuation(감쇠)준말입니다.

- 그림자를 받거나, 라이트의 거리별 감쇠 현상을 나타냅니다.

- '빛을 받는 것'을 줄일 때 사용합니다.

- 포인트 라이트에서 멀어질수록 빛이 약해지는 게 아니라 '감쇠'가 일어나는 것입니다.


라이트 연산

라이트 연산을 하기 전에 NormalMap을 추가했습니다.


Lambert 라이트 연산

 

- dot(내적) 함수를 통해 값이 -1~1으로 나옵니다.

- saturate함수로 값을 0~1로 가둬줍니다. (음수로 인한 문제가 발생 방지)

-  -1~0값이 모두 0이 되기 때문에 부드럽지 않은 문제점이 있습니다.


Half - Lambert 라이트 연산

 

- saturate함수 대신 내적값에 0.5를 곱하고 0.5를 더해줍니다.

-  -1~1값을 -0.5~0.5로 만들어주고 0.5를 더해 0~1값으로 만들어집니다.

- 물리적으로 옳지 않지만, Lambert보다 비교적 보기 좋게 만들어집니다.


Lambert 라이트 완성하기

위에까지는 빛 방향에 따른 밝기만 구현됐습니다.

조명의 색상, 빛 감쇠 등을 넣어서 완성시켜줍니다.

 

- s.Albedo에서 들어온 값라이트 연산이 되어서 Diffuse가 됩니다.

- _LightColo0내장된 변수라이트 색상을 가져옵니다.

- atten은 빛의 감쇠계산합니다. Point Light나 그림자에 영향을 미칩니다.