8 – 01 ~ 02 Standard Shader / Metallic, Smoothness (Unity Shader)

08 – 01 Standard Shader

https://docs.unity3d.com/kr/2020.3/Manual/UpgradeGuide5.html

유니티 5.0이 되면서 다른 많은 그래픽 툴이나 엔진처럼 최신의 쉐이더 시스템인

‘물리 기반 쉐이더’ 시스템을 도입하게 되었습니다.

기존의 쉐이더 시스템과는 다르게, 주변 환경에 따른 재질 변화를 물리 법칙에 기반하여

실시간으로 재질을 구현해주는 사실적인 쉐이더 표현 기법입니다.

유니티에 있는 기본 Standard Shader 가 대표적인 물리 기반 쉐이더입니다.

https://docs.unity3d.com/kr/2021.3/Manual/SL-SurfaceShaders.html

우리가 사용한  o.Emission과 o.Albedo 같은 변수들은 바로 이 구조체 안에 정의되어 있는 것을 사용한 것이고

우리는 여기에 알맞은 값을 넣어 주면 알아서 결과가 나오게 되는 것입니다. 

이제 다른 구조체들을 사용해 보겠습니다.


08 – 02 Metallic, Smoothness

새로운 쉐이더와 메테리얼을 만들어서 Sphere에 적용 시켜줍니다.

Shader "Custom/Metallic"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

기존 쉐이더에 이미 Metallic, Smoothness 가 생성되어 있습니다.

공부를 위해서 만들어 봅시다.

이제 Properties에 Metallic, Smoothness를

Shader "Custom/Metallic"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Metallic ("Metallic", Range(0, 1)) = 0 
        _Smoothness("Smoothness", Range(0, 1)) = 0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard
        #pragma target 3.0

        sampler2D _MainTex;
        float _Smoothness;
        float _Metallic;

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
            o.Metallic = _Metallic;
            o.Smoothness = _Smoothness;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

이제 적당한 텍스쳐를 넣고 결과를 확인합니다.

Smoothness는 이 재질이 매끄러운지 거친 지를 결정하는 부분입니다.

0이면 완벽히 거칠어서 난반사(Diffise)만 일어나고 1이면 완벽히 매끄러워서 정반사(Specular)만 일어나게 됩니다.

유니티에서 Standard Shader라는 물리기반렌더링의 기본 개념은

나가는 빛의 양은 들오는 빛의 양을 넘길 수 없다라는 에너지 보존법칙 개념입니다.

재질의 거칠기에 따라서 난반사와 정반사의 비율이 결정되므로 정반사가 높아지면 그만큼 난반사의 비율이 적어집니다.

물리 기반 쉐이더에서 Metallic 이 0이면 스페큘러 컬러가 흑백이 되며 1이면 Albedo에 넣은 색이 됩니다.

금속은 고유의 스펙큘러 컬러를 가지고 있기 때문입니다.

가급적 0과 1외의 값은 쓰지 않는 것이 정확한 물리 기반 쉐이더를 다루는 방법입니다. 

https://docs.unity3d.com/Manual/StandardShaderMaterialCharts.html

유니티에서는 이러한 재질의 올바른 사용법을 위해서 아래와 같은 차트를 제공합니다.

노멀맵 추가 후 확인해보면 진짜 금속같이 보이네요

Shader "Custom/Metallic"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Metallic ("Metallic", Range(0, 1)) = 0 
        _Smoothness("Smoothness", Range(0, 1)) = 0
        _BumpMap("NormalMAp", 2D) = "bump" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard
        #pragma target 3.0

        sampler2D _MainTex;
        float _Smoothness;
        float _Metallic;
        sampler2D _BumpMap;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_BumpMap;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            float3 d = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
            o.Normal = d;
            o.Albedo = c.rgb;
            o.Alpha = c.a;
            o.Metallic = _Metallic;
            o.Smoothness = _Smoothness;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다