Notice
Recent Posts
Recent Comments
Link
«   2026/02   »
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
Tags
more
Archives
Today
Total
관리 메뉴

MOONSUN

[그래픽스] Toon Shading (툰 셰이딩) : Lambert 단계화 & Ramp Texture 방식 본문

D3D

[그래픽스] Toon Shading (툰 셰이딩) : Lambert 단계화 & Ramp Texture 방식

MoonSun_v 2025. 11. 10. 22:26

 

 

 

0. Toon Shading (툰 셰이딩) 이란?

현실적인 조명 표현 대신,

단계적인 명암 구분을 사용하는 비사실적 셰이딩 (NPR, Non-Photorealistic Rendering) 기법

 

  • 일반적인 Phong / Lambert 조명처럼 부드러운 명암을 사용하지 않고,
  • 단계적인 색 구분(밝음–중간–어두움) 으로 음영을 표현한다. 
  • 만화, 애니메이션 같은 느낌을 내는 렌더링 기법

 

 

 

1. Toon Shading 구현 방식

Toon Shading은 2가지 방식이 있다. 

1. Lambert 조명 단계화

2. Ramp Texture 방식 

 

1-1. Lambert 조명 단계화 ( Lambert Quantization ) 방식 

기본적인 Lambert 조명 모델은 다음과 같다.

Diffuse = (MaterialDiffuse ⊗ LightColor) * max(dot(N, L), 0)

 

여기서 dot(N, L)은 법선 벡터(N)와 광선 방향(L)의 내적 값으로, 빛의 세기를 의미한다.


이 값은 0~1 사이의 실수값을 가지며,

보통 이 값을 그대로 사용해서 부드러운 명암을 만들어 낸다.

 

 

 

1-1-1. Toon Shading을 위한 단계화 (Quantization)

Toon Shading에서는 이 값을 인위적으로 단계화(Quantize) 해서 사용한다.

dot(N, L) → floor(saturate(dot(N, L)) * levels) * scaleFactor
  • levels : 밝기 단계 수 (4단계, 6단계 등)
  • scaleFactor  =  1.0 / levels

 

즉, dot(N, L)의 값을 몇 개의 구간으로 나누고, 각 구간마다 고정된 밝기를 부여한다.

int levels = 6;  // 밝기 단계 수 
float scaleFactor = 1.0 / (float)levels;
float DiffuseIntensity = floor(saturate(dot(N, L)) * levels) * scaleFactor;

float3 diffuseRGB = DiffuseIntensity * (MaterialDiffuseColor.xyz * LightColor.xyz);

 

이렇게 처리하면, 기존의 부드러운 음영 대신 뚜렷한 단계별 음영이 만들어진다.

 

 

 

 

1-2. Ramp Texture ( Texture Lookup 기반 ) 방식 

 

Ramp Texture란?

Ramp는 "점진적 변화"를 의미한다. 


Ramp Texture는 이런 변화를 이미지 형태로 표현한 텍스처로,
dot(N, L) 값을 Ramp Texture의 X 좌표(U) 로 삼아 색을 샘플링한다.

 

즉, dot(N, L) 값에 따라 Ramp Texture에서 색상을 읽어오는 방식

 

 

DiffuseIntensity 대신 RampColor 사용

  • RampColor = tex2D(RampTexture, float2(NdotL, 0.5))
float NdotL = saturate(dot(N, L));
float2 rampUV = float2(NdotL, 0.5);
float4 RampColor = tex2D(RampTexture, rampUV);
float4 MaterialDiffuseColor = tex2D(BaseTexture, Input.TexCoord);

float3 diffuseRGB = RampColor.rgb * (MaterialDiffuseColor.rgb * LightColor.rgb);

 

 

Ramp Texture 방식은 다음과 같은 장점을 가진다.

  • 수학적 계산(floor) 대신 이미지 기반 제어 가능
  • Ramp Texture만 바꿔도 다양한 스타일 연출 가능
    • 예: Classic / Warm / Cool / Soft 등

즉, 아티스트가 직접 톤 맵을 그려서 원하는 명암 스타일을 시각적으로 조정할 수 있다.

 

 

 

 

2. Toon Shading + 단계화된 Specular (Quantized Specular Highlight)

 

2-1. 일반적인 Specular 계산 

기본 Phong 하이라이트는 다음과 같이 계산한다.

float3 R = normalize(2.0 * dot(N, L) * N - L);
float SpecularIntensity = pow(saturate(dot(R, V)), Shininess);
float3 specularRGB = SpecularIntensity * (MaterialSpecularColor * LightColor);

 

하지만 이 방식은 부드럽게 번지는 하이라이트를 만들어내며,
만화풍 스타일인 Toon Shading 에서는 딱딱 끊기는 반사광이 더 자주 사용된다.

 

 

2-2. Toon Specular (단계화 Floor 방식)

Specular 값에 floor() 를 적용해 단계화할 수 있다. (밝은 영역만 또렷하게 남도록) 

// Toon Shading 단계 수 설정 
int specularLevels = 3;  // 하이라이트 단계 수

float speculatScaleFactor = 1.0 / (float)specularLevels;

// Toon Specular (단계화 floor 방식) 
// Specular Reflection Vector R = 2(N·L)N - L
float3 R = normalize(2.0 * dot(N, L) * N - L);
float SpecularIntensity = pow(saturate(dot(R, V)), Shininess);

SpecularIntensity = floor(SpecularIntensity * specularLevels) * speculatScaleFactor;

float3 specularRGB = SpecularIntensity * (MaterialSpecularColor * LightColor);

 

이렇게 하면 반사광이 ‘계단식으로’ 표현되어, 만화적이고 선명한 빛 반사 효과를 구현할 수 있다. 

 

 

 

 

3. Toon Shading + Specular Ramp Texture

 

단계화된 Specular을 Ramp Texture 기반으로 제어할 수도 있다.

float3 R = normalize(2.0 * dot(N, L) * N - L);
float SpecularIntensity = pow(saturate(dot(R, V)), Shininess);

// Specular RampTexture를 통해 하이라이트 단계 제어
float2 specRampUV = float2(SpecularIntensity, 0.5);
float4 specRampColor = tex2D(SpecularRampTexture, specRampUV);

float3 specularRGB = specRampColor.rgb * (MaterialSpecularColor.rgb * LightColor.rgb);

 

이 방식은 Diffuse와 동일한 원리로,
SpecularRampTexture 이미지를 통해 반사광의 단계나 톤을 자유롭게 조절할 수 있다.

 

 

 

 

 

4. 정리

구분 방식 특징 
Lambert 단계화 dot(N,L) → floor() 방식 수학적 계산으로 계단화된 밝기
Ramp Texture 방식 dot(N,L) → RampTexture lookup 이미지 기반 색상 단계 제어
Quantized Specular pow(dot(R,V)) → floor() 적용 하이라이트 단계화 (딱딱한 빛 표현)
Specular Ramp 방식 RampTexture로 Specular 제어 반사광의 톤과 형태를 시각적으로 조절 가능