내일배움캠프/TIL

TIL260616 - Ch3 - 2 - 카툰 렌더링

옆집히드라 2026. 6. 16. 18:32

1. 핵심 개념


  • 하프 램버트 & 램버트
  • MPC
  • 블린-퐁 스페큘러
  •  

2. 상세 내용


관련 문서에 참고한 이득우의 카룬 렌더링 강의 내용을 정리함

2.1. 카툰 렌더링

2.1.1. 카툰 렌더링의 기본 원리

렌더링, 메터리얼, Diffuse, Specular, BRDF 기본 개념(램버트 디퓨즈, 램버트 BRDF가 원론적)

반사량에 따라 정해지는 표면에 들어오는 빛의 양 > Illuminance
디퓨즈 계산 식은 $cos \theta$ (세타는 점 p에서 노말 벡터 N과 빛의 방향 라이트 벡터 L 사이의 각)

이때 벡터의 크기가 1이라면 $\vec{a} \cdot \vec{b} = a_x b_x + a_y b_y = \Vert{}\vec{a}\Vert{} \Vert{}\vec{b}\Vert{} \cos\theta$ 에 의해서 컴퓨터에 유리한 덧셈, 곱셈 연산만으로 사잇각을 구할 수 있음

램버트 연산은 직접광 연산을 위한 것으로 간접광 연산을 위해서는 또 다른 모델이 필요하다. 과거에는 이 간접광 연산이 매우 무거웠기 때문에 하프 램버트 같은 경량 모델을 사용했다.

하프 램버트

 

Half Lambert lighting is a technique designed to prevent the rear of an object losing its shape and looking too flat.

Half Lambert is a completely non-physical technique and gives a purely percieved visual enhancement and is an example of a forgiving lighting model.

// 라이트 값 계산
float difLight = dot(s.Normal, lightDir);
// 라이트 값을 하프 램버트 값으로
float hLambert = difLight * 0.5 + 0.5;

하프 램버트 = cos에(normalized 된 두 벡터의 dot)에 0.5를 곱하고 0.5를 더해서 모든 영역에 그림자가 지게 함

밴드(Band) 셰이딩

하프 램버트에서 ceil 함수를 사용하면 그림자 영역을 띠로 나누어 그리는 밴드 셰이딩을 할 수 있다. 이는 카툰 렌더링의 기초가 된다.

 

 

올림 함수(치역 0

1)에 나눌 영역의 수인 N을 곱한 뒤에 floor(또는 ceil, round) 함수를 취한 뒤에 나온 값을 다시 N으로 나누면(치역 0

1 맞춤) 밴딩 효과를 구현할 수 있다.

2.1.2. 카툰 명암을 조절하고 색을 입히는 방법

가산 모델(RGB)

색에 흑백 그레이디언트를 곱하면 밝은 곳에서 점차 어두워지는 음영 표현이 가능(색 * 무채색(어둡기))

 

 

그레이디언트에 색을 곱하는 것만으로 모델에 음영 표현이 가능하다.

 

lerp

이때 선형 보간 $lerp(A, B, \alpha) = A + \alpha (B - A)$ 를 사용해서 어두운 영역과 밝은 영역의 컬러를 각각 A, B로 두어서 보간할 수 있다.

 

 

2.1.1에서 언급한 밴드 쉐이딩을 사용하여 암부와 명부에 컬러를 지정해서 lerp로 보간한 메테리얼의 모습이다.

step

 

step(y, x) y를 기준으로 반올림(round) 한다. 위와 같이 구성하면 매초 0->1, 1->0으로 왕복하는 모습을 볼 수 있다.

Smooth step

TIL260518 - VFX

SmoothStep graph

입력값 $x$를 $min$과 $max$ 사이의 $0$ ~ $1$ 범위로 정규화($t$)한 뒤, 부드러운 곡선을 만드는 3차 다항식에 대입합니다.

[1단계: 클램핑 및 정규화]

정규화는 Min-Max 정규화 사용

$$t = max(0, {min}(1, \frac{x - min}{max - min}))$$
[2단계: 3차 에르미트 보간(Hermite Interpolation)]

$${SmoothStep}(x) = 3t^2 - 2t^3$$

상황 max−min (거리) 보간 구간 시각적 효과
max 증가 ↑ 멀어짐 넓어짐 더 부드럽고 완만한 전환
max 감소 ↓ 가까워짐 좁아짐 더 급격하고 뚜렷한 전환
min 증가 ↑ 가까워짐 좁아짐 더 늦게 시작해서 급하게 변함
min 감소 ↓ 멀어짐 넓어짐 더 일찍 시작해서 천천히 변함

 

 

step보다 보간 영역이 더 넓고 부드러운 것을 알 수 있다.

Ramp 텍스처 셰이딩

 

Ramp는 경사로를 의미하나 그래픽스에서는 한 색에서 다른 색으로 서서히 이동하는 디자인 기법을 의미한다.

 

 

앞서 배운 공식들과 같이 수치적으로 계산할 수 있지만 램프 텍스처를 준비해서 각 영역(0~1)에 램프 텍스처를 매핑하는 식으로 그림자를 표현할 수도 있다.

(번외) MPC와 메테리얼

 

MPC(Material Parameter Collection)은 모든 메테리얼에서 참조 가능한 글로벌 변수 구조체이다. 만약 MPC가 없다면 메테리얼마다 Dynamic Material instance를 생성해서 일일히 값을 변경해줘야 한다.

따라서 다음과 같은 경우에서 MPC를 사용하는 것이 유리하다.

  • 글로벌 날씨 시스템: 맵 전체에 비가 와서 오브젝트가 젖음
  • 바람 시스템: 맵 전체의 나무, 풀, 깃발이 흔들리는 방향과 강도를 한 번에 제어할 때
  • 플레이어 상호작용: 플레이어의 현재 위치를 실시간으로 MPC에 업데이트해서, 플레이어가 지나갈 때마 주변 풀들이 알아서 구부러지는 효과 등

 

 

이렇게 등록한 MPC는 Directional light 블루프린트에서 수치를 변경한다. 변경된 수치는 앞서 사용한 메테리얼 그래프에서 사용하고 있다.

 

 

위 이미지는 밴드 쉐이딩이 적용되고 있는 예시이다.

2.1.3. 빛의 반사 영역은 어떻게 만들어지는가?

 

 

스페큘러 로브의 BRDF(램버트 BRDF, 퐁 BRDF)

퐁 BRDF에서 반사 벡터 R을 구하는 식($R = 2 ( N \cdot L) N - L$) 유도는 How to calculate the reflection vector에서 스크랩한 글 참고

 

 

반사 벡터 R과 카메라 벡터 V와의 사잇각으로 스페큘러를 구현한다.

 

 

내적으로 만든 그레이디언트를 쨍하게(집중되게) 변형할 때는 거듭 제곱 연산(pow)을 사용하자

 

 

20번부터 스페큘러와 비슷하게 상이 맺히는 것을 볼 수 있다.

표면이 매우 거친 경우 스페큘러 로브의 크기가 90도를 넘어갈 수 있는데(2.1.3. 상단 그림의 3번째 예시) 퐁 스페큘러 모델에서는 이런 90도가 넘어가는 영역을 모두 검정(0)으로 처리하는 문제가 있다.

 

 

퐁 모델이 가진 문제를 보완하기 위해 나온 것이 블린-퐁 스페큘러 모델이다. 블린-퐁 스페큘러 모델은 노말 벡터를 사용하여 명암을 계산하기 때문에 하프 벡터 H와 N 벡터 사이가 90도를 넘을 일이 없다.

하프 벡터 H는 빛 벡터 L과 카메라 벡터 V를 더해줘서 normalize 하면 구할 수 있다. 이렇게 구한 하프 벡터 H와 노말 벡터 N의 사잇각을 사용해서 명암을 표현한다.

현재는 퐁, 블린-퐁이 아닌 GGX 모델을 사용한다고 한다.

 

 

위부터 하프 램버트, 램버트, 하프 램버트와 Smooth step을 사용한 diffuse, lerp를 사용한 ColorDiffuse를 구현한 예제

 

 

블린-퐁 구현 예제

 

 

앞서 구한 diffuse, specular를 lerp로 보간하여 최종적으로 완성된 셰이더 예제

두 RGB 색의 혼합

 

 

색을 곱할 때 multiply로 표현한다면 색이 점점 어두워지는 문제가 있다. 이때 multiply로 구한 색과 add로 구한 두 색을 lerp로 보간하면 원래의 색을 살리면서 어두워지지 않게 색을 혼합해서 사용할 수 있다.

3. 질문 및 해결 (Q&A)


  • GGX 모델은?
  • Hermit 보간은?

4. 관련 문서 (Links)


'내일배움캠프 > TIL' 카테고리의 다른 글

TIL260615 - Ch3 - 1 - 표정, 메테리얼 슬롯, 양면 렌더  (0) 2026.06.15
TIL260612 - Unreal  (0) 2026.06.12
TIL260611 - Unreal - GAS4  (0) 2026.06.11
TIL260610 - Unreal - GAS3  (0) 2026.06.10
TIL260609 - Unreal - GAS2  (0) 2026.06.09