오다기리 박의 알고리즘 노트

[셰이더 프로그래밍 입문] 6. 툰셰이더 본문

컴퓨터 그래픽스/쉐이더

[셰이더 프로그래밍 입문] 6. 툰셰이더

오다기리 박 2018. 7. 1. 23:33

6. 툰셰이더

  • ceil() : 올림함수

  • 행렬 합치기 : 여러 개의 행렬을 미리 곱해 놓은 뒤, 그 결과를 정점변환에사용해도 결과는 동일하고 속도는 더 빠름

  • 역행렬 : 반대방향으로 공간변환시 사용


난반사광의 양

툰셰이더 값

0

0

0~0.2

0.2

0.2~0.4

0.4

0.4~0.6

0.6

0.6~0.8

0.8

0.8~1

1



▶렌더몽키 코드 

- 버텍스 셰이더
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
30
31
float4x4 gWorldViewProjectionMatrix;
float4x4 gInvWorldMatrix;
 
float4 gWorldLightPosition;
 
struct VS_INPUT 
{
   float4 mPosition : POSITION;
   float3 mNormal: NORMAL;   
};
 
struct VS_OUTPUT 
{
   float4 mPosition : POSITION;
   float3 mDiffuse : TEXCOORD1;   
};
 
VS_OUTPUT vs_main( VS_INPUT Input )
{
   VS_OUTPUT Output;
 
   Output.mPosition = mul( Input.mPosition, gWorldViewProjectionMatrix );
   
   float3 objectLightPosition = mul( gWorldLightPosition, gInvWorldMatrix);
   float3 lightDir = normalize(Input.mPosition.xyz - objectLightPosition);
   
   Output.mDiffuse = dot(-lightDir, normalize(Input.mNormal));
   
   return( Output );
   
}
cs

- 픽셀 셰이더
1
2
3
4
5
6
7
8
9
10
11
12
13
14
float3 gSurfaceColor;
 
struct PS_INPUT
{
   float3 mDiffuse : TEXCOORD1;   
};
 
float4 ps_main(PS_INPUT Input):COLOR
{
   float3 diffuse=saturate(Input.mDiffuse);
   diffuse=ceil(diffuse*5)/5.0f;
 
   return float4(diffuse.xyz*gSurfaceColor,1);;
}
cs

- 결과

만화같은 명암을 입히는 툰셰이더입니다. 명암처리를 부드럽게 하는대신 2~3단계로 딱딱 끊어서 표현하였습니다.

img