본문 바로가기

Unity3D C#/유니티 쉐이더 공부

Standard Shader - Metallic과 Smoothness

유니티 5.0 업그레이드 후에 유니티도 다른 많은 그래픽 툴이나 엔진처럼 최신의 쉐이더 시스템인 '물리 기반 쉐이더' 시스템을 도입하게 됨. 물리 기반 쉐이더란 기존의 쉐이더 시스템과는 다르게 주변 환경에 따른 재질 변화를 물리 법칙에 기반하여 실시간으로 재질을 구현해주는 사실적인 쉐이더 표현 기법.

유니티에 있는 기본 Standard Shader가 대표적인 물리 기반 쉐이더. o.Albedo나 o.Emission 등이 모두 물리 기반 쉐이더의 요소임. 


1
2
3
4
5
6
7
8
9
10
11
struct SurfaceOutputStandard
{
    fixed3 Albedo;
    fixed3 Normal;
    fixed3 Emission;
    half Metallic;
    half Smoothness;
    half Occlusion;
    half Alpha;
};
 
cs

사용했던 o.Albedo, o.Emission같은 변수들이 이 SurfaceOutputStandard 구조체 안에 정의되어 있는 것을 사용하는 것이고, 여기에 알맞은 값만 넣어 주면 알아서 결과가 나오게 되는 것. 실제 연산되는 물리 기반 쉐이더의 라이팅 구조는 매우 복잡하지만 우리는 이 구조체에 알맞은 값만 넣으면 되니 매우 간편하다고 함.



Metallic(메탈릭)과 Smoothness(스무스니스)

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
Shader "Custom/MetallicSmoothness" {
    Properties {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Metallic("Metallic", Range(0,1)) = 0
        _Smoothness("Smoothness", Range(0,1)) = 0.5
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        
        CGPROGRAM
        #pragma surface surf Standard 
 
        sampler2D _MainTex;
        float _Metallic;
        float _Smoothness;
 
        struct Input {
            float2 uv_MainTex;
        };
 
        void surf (Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Metallic = _Metallic;
            o.Smoothness = _Smoothness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
 
cs

Metallic은 이 재질이 금속이냐 아니냐를 결정하는 부분이며, 0이면 비금속, 1이면 금속 재질이 됨. 물리 기반 쉐이더에서 Metallic이 0이면 스페귤러 컬러가 흑백(흰 빛을 비추었을 때)이 되며, Metallic이 1이면 스페큘러 컬러가 Albedo에 넣은 색이 됨. 금속은 고유의 스페큘러 컬러를 갖고 있기 때문. 가급적 Metallic은 0과 1 외의 값은 쓰지 않도록 하는 것이 정확한 물리 기반 쉐이더를 다루는 방법이라고 함.


Metallic = 0                                            Metallic = 1



Smoothness는 이 재질이 매끄러운지 거친지를 결정하는 부분. 0이면 완벽히 거칠어서 난반사만 일어나고, 1이면 완벽히 매끄러워서 정반사만 일어나게 됨(언리얼 엔진은 이 부분을 Roughness라고 부르며, 유니티와 정반대로 사용함.)

세상의 물건 중 완벽히 0이나 1인 물체는 없다고 해도 과언이 아니므로 완전한 0이나 1로 정의된 재질을 만들지 않는 것이 보기 좋은 효과를 볼 수 있을 것. 실제 대부분의 주변 사물들은 약간이라도 정반사를 가지고 있고, 거의 모두는 이 둘이 적절히 섞여 있음.

난반사가 일어나는 이유는 '거친 표면' 때문이며, 특히 겉으로는 부드러워 보이더라도 미세한 표면 단계에서의 거칠기 때문에 피부나 천의 경우에는 스페큘러가 적게 나타나는 것


Metallic = 0

Smoothness = 0.3                           Smoothness = 0.8


Metallic = 1

Smoothness = 0.3                           Smoothness = 0.8


재질이 매끈하면 난반사(Diffuse) 연산보다 정반사(Specular) 연산이 늘어나며, 이것을 조절할 수 있는 게 Smoothness.

유니티에서 Standard Shader라는 '물리 기반 렌더링'의 기본 개념은 '에너지 보존 법칙'으로 '나가는 빛의 양은 들어온 빛의 양을 넘을 수 없다'라고 간단하게 설명할 수 있음. 

Metallic과 Smoothness를 값으로 받아 처리했지만 Standard Shader에서는 값으로 받아서 처리할 수도 있고 텍스쳐로 받아서 처리할 수도 있게 만들어 놓았음. 텍스쳐(RGBA)로 받아서 처리하면 Metallic 수치는 R 채널을 쓰고, Smoothness 수치는 A 채널을 쓰게 됨.


유니티에서는 이러한 재질의 올바른 사용법을 위해서 Metallic Value Chart 제공