유니티/게임그래픽

Lambert & Blinn Phong

DOlpa_GB 2024. 2. 21. 16:06

유니티에 내장되어 있는 라이팅은 총 3가지가 있다

1. Lambert

빛에 의한 밝고 어두움이 구현된 가벼운 라이팅 구조. SurfaceOutput 구조체 사용 (Specular 공식 x)

2. Blinn Phong

램버트 공식에 블린 퐁 공식이 더해진 라이트 구조 (Specular 공식 o)

3. Standard

주변 환경을 반사해서 Specular을 구현

 

*Specular 공식 : 보는 각도와 조명각도에 따라 계산된 특정 색의 하이라이트 동그라미로 표현 

 

주로 이런건 이론으로 보는것보다는 바로 적용시켜 차이점을 확인하는것이 훨씬 빠를것같다

<Lambert 라이팅 만들기>

Shader "Custom/NewSurfaceShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" }

        CGPROGRAM
        #pragma surface surf Lambert // 1. Standard 지우고 Lambert 쓰기
        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutput o) // 2. output 뒤에 붙는것들 다 지우기
        {
           fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
           o.Albedo = c.rgb;
           o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

바꿔야하는건 딱 2가지이다. 스크립트에 주석으로 기입해두었다

전후차이

차이는 거의 없어보인다. 그러나 이 Lambert 라이팅 구조는 Specular를 전혀 구현할 수 없고

내장된 기본 라이팅 구조중 가장 가볍고 저사양기기에 적합하다는것 정도만 알고 있자

 

<Blinn-Phong 라이팅 만들기>

Shader "Custom/NewSurfaceShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _SpecColor("_Specular Color", color) = (1,1,1,1) // 추가
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" }

        CGPROGRAM
        #pragma surface surf BlinnPhong  // 변경
        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.specular = 0.5; // 추가
           o.Gloss = 1;      // 추가
           o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

o.Glass = 0~1 사이 값을 넣어야하며 Specular의 강도를 의미 (0이면 둔탁, 1이면 매끈)

o.Specular = 0~1 사이값을 넣어야하며 Specular의 크기를 의미 (0은 커지고, 1이면 작아진다)

 

분명 _SpecColor 는 (1,1,1,1)이 초기값임에도 불구하고 float4라는 변수선언이 되어있지 않다

 

여기서 주의해야할건 _SpecColor는 절대 코드에서 받으면 안되고 단지 Properties에서만 만들어야한다

그리고 _SpecColor 외에 다른 이름을 써서도 안된다

 

이걸 다 이해하기엔 머리가 너무 아프니 일종의 약속쯤으로 생각하고 알아두자

 

반응형