본문 바로가기

Unity3D C#/유니티 쉐이더 공부

Blinn-Phong(블린-퐁) 라이팅 만들기

1975년 유타 대학의 부이 통 퐁의 박사 논문에서 발표된 퐁(Phong) 공식은 1977년 제임스 F 블린에 의해 Blinn-Phong 공식으로 개량되었음. 이 공식은 Specular를 가볍게 표현할 수 있는 공식이었고, 유니티에서는 이 Blinn-Phong 공식이 들어 있음


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Shader "Custom/Blinn-Phong" {
    Properties{
        _MainTex("Albedo (RGB)", 2D) = "white" {}
        _SpecColor("Specular Color", color) = (1,1,1,1)
    }
        SubShader{
        Tags{ "RenderType" = "Opaque" }
 
        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"
}
 
cs

BlinnPhong 라이팅 공식이 가동되어도, Specular가 잘 보이지 않음

_MainTex가 없기 때문에 흰 텍스쳐가 들어간 것처럼 계산되어서 하이라이트가 눈에 띄지 않는 것

어두운 텍스쳐를 넣거나 o.Albedo에 색이 어둡게 들어가도록 강제로 만들어 주면 하이라이트가 보이게 됨

Blinn Phong을 적용시킨 모습


Blinn-Phong과 Lambert 라이팅 비교 (좌:Blinn-Phong, 우:Lambert)


        _SpecColor("Specular Color", color) = (1,1,1,1)

평범한 Properties 인데 float4 _SpecColor와 같은 구문을 받지 않음

저 값을 코드 내에서 평범하게 받으면 오히려 에러가 발생

_SpecColor는 절대로 코드에서 받으면 안 되고, Properties에서만 만들어야 하며, _SpecColor라는 이름 외에 다른 이름을 써도 안됨. BlinnPhong 공식이 구현된 코드를 열어보면 _SpecColor라는 값을 받고 있기 때문에 다른 이름을 써서는 Specular가 구현되지 않음

_SpecColor라는 이름은 예약어이며 절대로 코드 내부에서 받아서 안 된다는 특이한 예외사항이 존재함


o.Gloss는 0~1 사이의 값을 넣어야 하고 Specular의 강도를 의미함 0(둔탁한 재질) ~ 1(매끄러운 재질)

o.Specular는 0~1 사이의 값을 넣어야 하고 Specular의 크기를 의미함. 0(큼) ~ 1(작음)


Specular 0.1 / Gloss 1                                   Specular 1 / Gloss 1

Specular 0 / Gloss 1                                   Specular 0 / Gloss 0