본문 바로가기

유니티/쉐이더

[Unity Shader] Custom PostProcessing(포스트 프로세싱) 직접 만들기 (노이즈 필터)

Post Processing(포스트 프로세싱)이란? 

  • 기존에 렌더링된 씬에 렌더링 효과를 더하는 작업

유니티에서 포스트프로세싱 기능을 제공하긴 하지만 직접 만들어서 적용하는 법을 알아보겠습니다.


C# 스크립트 생성

c# 스크립트를 생성해준뒤 다음과 같이 작성해줍니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PostProcessing : MonoBehaviour
{
    public Material material;

    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
		Graphics.Blit(source, material);
	}

}

OnRenderImage는 모든 렌더링이 완료된 후 이미지를 불러오기 위해 호출됩니다.

marerial에 제작한 쉐이더를 기반으로 material을 만들어준 뒤 넣어주면 적용됩니다.


스크립트 추가

카메라가 붙은 스크립트에 스크립트를 추가해줍니다.

카메라 컴포넌트를 필수적으로 요구하기때문에 스크립트에 

[RequireComponent(typeof(Camera))]를 추가해준다면 에러 발생 확률을 줄일 수 있습니다.

[RequireComponent(typeof(Camera))]
public class PostProcessing : MonoBehaviour
{
    public Material material;

    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
		Graphics.Blit(source, material);
    }
}

쉐이더 제작    

지글지글(?)거리는 느낌의 노이즈 쉐이더를 만들겠습니다.

프로젝트 창에서 우클릭 - Create - Shader - Image Effect shader

(Unlit Shader로 해도 되긴 합니다.)

Shader "Hidden/Noise"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _NoisePower("Noise Power", Range(0, 0.1)) = 0.01
    }
    SubShader
    {
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            float2 nrand(float x, float y)
            {
                return frac(sin(dot(float2(x, y), float2(12.9898, 78.233))) * 43758.5453);
            }

            sampler2D _MainTex;
            float _NoisePower;

            fixed4 frag(v2f i) : SV_Target
            {
                float2 add = _NoisePower * nrand(i.vertex.x, _Time.x);
                fixed4 col = tex2D(_MainTex, i.uv + add);
                

                return col;
            }
            ENDCG
        }
    }
}

쉐이더 생성 후 _NoisePower 변수 추가와 frag 함수, nrand함수 부문만 수정하였습니다.

nrand는 랜덤 함수로 시드값은 원하는대로 넣어주면 됩니다.

랜덤하게 UV 값을 더해줘서 노이즈를 주는 방식입니다.


Marerial 적용

만든 Shader를 가지고 Marerial을 생성한 뒤 앞서 생성한 스크립트의 Material 에 넣어줍니다.


결과 확인

원본

 

포스트 프로세싱 적용