Toon shading(또는 Cel shading)은 Cell Rendering 이라고도 하는 NPR(Non-Photorealistic Rendering; 비실사 렌더링) 분야의 한 종류이다.
비실사 렌더링 중 만화적 기법을 표현하기 위해서는,
- 적은 수의 색상
- 적은 수의 음영
- 명확한 외곽선 등 세 가지 조건이 충족되어야 할 것 같다.
아래는 외곽선을 제외한 Toon Shading 기법의 예제이다.
Shading 효과를 결정하는 부분은 FragmentShader
에 있다.
FragmentShader를 이용한 효과는 게임 등에서 fade-in, fade-out, blurring 과 같은 기본적인 효과 뿐만 아니라 SSAO와 같은 특수 효과를 가능하게 한다.
1
2
3
4
5
6
7
public void init(GLAutoDrawable drawable){
....
....
int loc= gl.glGetUniformLocation(glsl.getProgID(), "lightDir");
// Shading Effect를 위해 광원의 방향을 결정한다.
gl.glUniform3f(loc, 0.1f, -0.4f, 0.5f);
}
1
2
3
4
5
6
7
8
uniform vec3 lightDir;
varying float intensity;
void main(){
// 광원과 법선의 내적을 intensity(밝기)로 한다.
intensity = dot(lightDir, normalize(gl_Normal));
gl_Position = ftransform();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
varying float intensity;
void main(){
vec4 color;
// intensity(밝기)를 4단계로 변환한다.
if( intensity > 0.95 ) color = vec4(0.5, 1.0, 0.5, 1.0);
else if( intensity > 0.5) color = vec4(0.3, 0.8, 0.3, 1.0);
else if( intensity > 0.25) color = vec4(0.2, 0.6, 0.2, 1.0);
else color = vec4(0.1, 0.3, 0.1, 1.0);
gl_FragColor = color;
}