Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
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
Archives
Today
Total
관리 메뉴

게임 프로그래밍

[Unity-Shader] NPR 렌더링 2pass 외각선 본문

카테고리 없음

[Unity-Shader] NPR 렌더링 2pass 외각선

Junwe 2020. 5. 1. 22:32

앞서 포스팅 했던 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