본문 바로가기
Computer Graphics/ShaderLab, HLSL

[ShaderLab] Blinn-Phong, Gloss Map, Fake Specular

by 진현개발일기 2024. 3. 3.

■ Blinn-Phong 

여러 가지 스페큘러 표현 공식 중 가장 유명하고 전통적인 방식이다. 기본 원리는

'내가 바라보는 방향으로부터 반사되는 방향에 조명이 있으면 그 부분의 하이라이트가 가장 높다'이다.

 

보통 하이라이트를 표현하는 공식은 매우 유명한 Phong공식이 사용된다.

Phong 공식은 반사 벡터와 조명 벡터의 내적으로 스페큘러를 표현하는 방식이다. 

공식은 R(반사벡터) = 2N(L · N) - L 이다. 

 

이러한 Phong 공식을 간략화한 것이 Blinn-Phong 공식이다.

 

BlinnPhong은 '시선 벡터와 조명 벡터의 중간값인 하프 벡터(Half Vector)를 구하고 이를 노멀 벡터와 내적' 하는 것이다.

공식은 H · N 이다.

 

하프벡터를 구하는 방법은 시선벡터와 조명벡터를 더해주면 된다. 같은 길이의 두 벡터를 더하면 두 벡터 사이의 절반인 각도가 나오는 벡터의 연산 규칙을 이용한 것이다.

 

[코드]

 

HalfVector를 구하는 코드를 라이팅커스텀 함수안에서 볼 수 있다.

 

[구현한 모습 (with noambient)]

 

[without noambient]

 

■ Gloss Map 

 

라이트의 반사가 부드럽게 잘된 것을 확인할 수 있다. 하지만, 여전히 아직은 부자연스럽다. 반사가 되지 말아야할 곳으로부터 반사가 되고있다. (ex. 머리) 이럴때 사용하기 편한 것이 Gloss Map이다. 스페큘러의 강도를 조절해주는 것인데 기존에 공평하게 분배되어있는 스페큘러를 부분부분마다 조절해준 맵이다.

 

[Gloss Map 추가 코드]

 

 

GlossMap 사용 전 GlossMap 사용 후

둘의 차이가 크게 느껴질 것이다.

 

많이 부드러워졌지만 이전에 구현했던 Fresnel 효과를 나타내고싶다. 이를 위해 림라이트를 추가할 것이다.

이전에는 Input 구조체에 viewDir를 추가해 surf함수에서 설정해줬지만, 감사하게도 커스텀라이팅함수를 제작할 때 viewDir를 인자로 넘길 수 있기에 커스텀라이트구조를 제작할 때 뷰벡터를 사용할 수 있다.

 

[코드]

▼ 커스텀 라이팅 함수는 아래 두 인자리스트 중 하나를 골라 사용해야한다.

 

▼ Blinn-Phong에 림라이트 추가한 모습

 

■ Fake Specular

그리고 실제 세상에선 조명이 하나만 있는 경우는 거의 없기 때문에 디테일을 살려야한다. 이를 위해 노말맵의 디테일을 살리기 위해 사용되는 기술이 Fake Specular이다. 

 

스페큘러가 존재하는 하나의 물체를 두고 이리저리 둘러볼때 내가 보고있는 각도에 따라 또 다른 스페큘러가 생기기도 한다. 이러한 효과를 구현하는 것이고 이를 구현해본다면 아래와 같이 나타난다

 

 

Fake Specular 사용 X Fake Specular 사용 O

 

이번 포스팅은 커스텀 라이팅을 통하여 디테일한 스펙큘러를 표현해봤다.

728x90