본문 바로가기
Shader

Post Effect 만들기 기본 : 흑백 후처리

by 대마왕J 2015. 12. 18.

http://www.alanzucconi.com/2015/07/08/screen-shaders-and-postprocessing-effects-in-unity3d/

 

복습겸 ... 좋은 튜터리얼이 있길래 간단히 정리해 봅니다. 나중에 가르칠 수도 있으니까요

 

 

 

 

post effect를 만들기 위해서는 Shader와 스크립트, 두 개를 동시에 만들어야만 합니다.

 

일단 Shader부터 보면 다음과 같습니다.

 

Shader "Hidden/NewImageEffectShader"
{
 Properties
 {
  _MainTex ("Texture", 2D) = "white" {}
  _bwBlend ("Black & White" , Range(0,1)) = 1
 }
 SubShader
 {
  // No culling or depth
  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 = mul(UNITY_MATRIX_MVP, v.vertex);
    o.uv = v.uv;
    return o;
   }
   
   sampler2D _MainTex;
   uniform float _bwBlend;

   fixed4 frag (v2f i) : SV_Target
   {
    fixed4 col = tex2D(_MainTex, i.uv);
    half3 gray = col.r * 0.3 + col.g*0.59 + col.b * 0.11;
    col.rgb = lerp(col.rgb, gray,_bwBlend );
    return col;
   }
   ENDCG
  }
 }
}

다행히 포스트 이펙트를 위한 기본 템플릿을 제공해줘서 고맙...

 

기본적으로 아주 가벼운 텍스쳐 출력 shader인데 프레그먼트로 만들어진것이 제공됩니다.

여기서 텍스쳐를 받고 그 텍스쳐를  _bwBlend 인자에 따라 흑백으로 만들어 주기만 하면 shader는 끝납니다.

대부분의 post effect가 이 방식을 따르기 때문에 이것만 해 두면 응용이 무궁무진 해 지죠

여기서는 흑백 제작 방식을 매직 넘버를 이용해서 만들었습니다.

 

다음은 스크립트입니다.

 

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class testgray : MonoBehaviour {

 public float intensity;
 public Material material;

 // Use this for initialization
 void Awake () {

  material = new Material (Shader.Find ("Hidden/NewImageEffectShader"));
 
 }
 
 // Update is called once per frame
 void OnRenderImage (RenderTexture source , RenderTexture destination) {
  if (intensity == 0) {
   Graphics.Blit (source, destination);
   return;
  } else {
   material.SetFloat("_bwBlend",intensity);
   Graphics.Blit (source, destination, material);
   return ;
  }
 }
}


 

 

[ExecuteInEditMode] 는 에디터 모드에서도 실행될 수 있도록 해 줍니다.

여기서도 두 가지 인자를 받습니다.

하나는 float intensity, 하나는 material 입니다.  material은 직접 건드릴 일이 없기 때문에 private로 해도 충분합니다만

잘 되가는지 보고 싶어서 걍 public 걸었습니다.

 

Awake 타이밍에 메터리얼을 새로 생성해서 Shader를 직접 걸어줍니다. 이렇게 연결 끝

 

OnRenderImage 함수가 본격적인 후처리 함수입니다. 인자는 source 와 Destination을 받습니다. source는 후처리 이전의 원본 이미지, Destination은 후처리가 끝난 이미지입니다. 우리는 여기에 출력해 주면 됩니다.

 

코드를 보시면  intensity가 0일때는 Grahics.Blit 명령으로 소스가 그냥 데스티네이션으로 나오게 되어 있습니다.

아무런 효과가 없지요.

 

그렇지만 0이 아니면 shader를 거치게 만들면 됩니다.

그럴때 일단 이미 만든 material의 인자에 intensity 인자를 넣어주는 SetFloat 명령을 넣어줍니다. 이렇게 Shader에 접근하고요

Graphics.Blit 명령으로 (소스, 데스티네이션, 메터리얼) 로 써 주면 끝납니다.

초 간단하죠.

이후 카메라에 지금 만든 스크립트를 넣어주기만 하면 셰이더는 알아서 찾아서 실행하게 됩니다.

이상 끝 뿅

 

 

반응형

댓글