게임 프로그래밍
[Unity-Shader] NPR 렌더링 2pass 외각선 본문
앞서 포스팅 했던 Lambert, Blinn-Phong 방식은 현실과 비슷하게 만드는 방식으로 PR(Photo Realistic) 렌더링 이라고 합니다.
반대로 NPR 렌더링이란, Non-Photo Realistic으로 현실적이지 않은 렌더링을 뜻 합니다. 흔히 말하는 카툰 렌더링 같은 그래픽을 생각하면 될 것 입니다.
그렇다면 2pass 를 이용해 외각선을 만들어 보겠습니다.
2pass 란 물체를 두번 그리는 것 입니다.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
Shader "Custom/Pass2Shader"
{
Properties
{
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_OutLine("Outline",Range(0.01,1)) = 1
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
cull front
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf NoLight vertex:vert noshadow noambient
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
float _OutLine;
void vert(inout appdata_full v)
{
v.vertex.xyz = v.vertex.xyz + v.vertex.xyz * _OutLine;
}
struct Input
{
float4 color:COLOR;
};
void surf (Input IN, inout SurfaceOutput o)
{
}
float4 LightingNoLight(SurfaceOutput s,float3 lightDir,float atten)
{
return float4(s.Albedo,1);
}
ENDCG
cull back
//2pass
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Toon noambient
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
float4 LightingToon(SurfaceOutput s, float3 lightDir,float viewDir, float atten)
{
float ndotl = dot(s.Normal,lightDir) * 0.5 + 0.5;
if(ndotl >= 0.5)
{
ndotl = 1;
}
else
{
ndotl = 0.3;
}
return ndotl;
}
ENDCG
}
FallBack "Diffuse"
}
|
cs |
외각선을 그리는 코드 입니다. 2pass 는 간단하게 CGPROGRAM ~ ENDCG을 두번 써주면 됩니다.
cull back 을 이용해 면을 뒤집습니다.
#pragma surface surf NoLight vertex:vert noshadow noambient
void vert(inout appdata_full v)
{
v.vertex.xyz = v.vertex.xyz + v.vertex.xyz * _OutLine;
}
버텍스 쉐이더를 이용해 오브젝트를 확장한 것입니다. appdata_full은 SurfaceOutput처럼, UnityCG.cginc 파일 안에 미리 선언되어 있는 특수한 구조체 입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
float4 LightingToon(SurfaceOutput s, float3 lightDir,float viewDir, float atten)
{
float ndotl = dot(s.Normal,lightDir) * 0.5 + 0.5;
if(ndotl >= 0.5)
{
ndotl = 1;
}
else
{
ndotl = 0.3;
}
return ndotl;
}
|
cs |
이 부분은 끊어지는 음영을 만드는 부분입니다. 만화같은 연출이 됩니다.
완성되면 이러한 결과가 나오게 될 것입니다.
Comments