Depth Buffer. Z-Buffer라고도 하며 카메라 기준으로 픽셀의 깊이 정보를 뜻합니다,
위 사진은 해당 정보를 시각화 하여 출력한 결과입니다.
Depth Buffer를 이용해 Soft Particle이나 Depth of Field효과 만들 수 있습니다.
Depth Buffer 후처리 쉐이더
Shader "Hidden/PP_DepthBuffer"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_DepthDistance("DepthDistance", float) = 25
}
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
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
float4 _MainTex_TexelSize;
sampler2D_float _CameraDepthTexture; //! 카메라로부터 뎁스텍스처를 받아옴
half _DepthDistance;
fixed4 frag (v2f i) : SV_Target
{
float fDepthData = tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(float4(i.uv, 1, 1))).r; //! 텝스텍스처 샘플러에서 텍셀정보를 가져옴
float fSceneZ = LinearEyeDepth(fDepthData); //! DepthData를 0~1 Linear데이터로 변환(0 = 카메라, 1 = 먼거리)
float fCalc_Depth = 1 - saturate(fSceneZ / _DepthDistance); //! 거리 값 조절용 계산
return fCalc_Depth;
}
ENDCG
}
}
}
뎁스버퍼 후처리 쉐이더입니다.
해당 쉐이더 적용 방법은 이전 포스팅을 참고해 주시길 바랍니다.
https://darkcatgame.tistory.com/78?category=814684
sampler2D_float _CameraDepthTexture;에는 뎁스 버퍼 정보가 들어오는데 이게 가능하기 위해서는
렌더링 패쓰가 Deffered로 되어있거나 DepthTextureMode를 활성화 시켜야합니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class CameraDepthOn : MonoBehaviour
{
void OnEnable()
{
Camera pCamera = GetComponent<Camera>();
if (pCamera == null) return;
Debug.Log("Depth On");
pCamera.depthTextureMode = DepthTextureMode.DepthNormals;
}
void OnDisable()
{
Camera pCamera = GetComponent<Camera>();
if (pCamera == null) return;
Debug.Log("Depth Off");
pCamera.depthTextureMode = DepthTextureMode.None;
}
}
해당 C#코드를 카메라에 적용시키면 됩니다.
간단한 Depth of Field 구현하기
Shader "Hidden/PP_DepthBuffer"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_DepthDistance("DepthDistance", float) = 25
_BlurIntensity("_BlurIntensity", Range(2, 10)) = 4
}
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
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
float4 _MainTex_TexelSize;
sampler2D_float _CameraDepthTexture; //! 카메라로부터 뎁스텍스처를 받아옴
half _DepthDistance;
half _BlurIntensity;
fixed4 frag(v2f i) : SV_Target
{
float4 fMainTex = tex2D(_MainTex, i.uv);
_BlurIntensity = ceil(_BlurIntensity); //! 텍스처 블러
float4 fBlurTex = 0;
for (int u = -_BlurIntensity; u <= _BlurIntensity; u++)
{
for (int v = -_BlurIntensity; v <= _BlurIntensity; v++)
{
float2 o = float2(u, v) * _MainTex_TexelSize.xy;
fBlurTex += tex2D(_MainTex, i.uv + o);
}
}
fBlurTex *= 1.0f / pow((_BlurIntensity * 2.0f), 2);
float fDepthData = tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(float4(i.uv, 1, 1))).r; //! 텝스텍스처 샘플러에서 텍셀정보를 가져옴
float fSceneZ = LinearEyeDepth(fDepthData); //! DepthData를 0~1 Linear데이터로 변환(0 = 카메라, 1 = 먼거리)
float fCalc_Depth = 1 - saturate(fSceneZ / _DepthDistance); //! 거리 값 조절용 계산
//return fCalc_Depth;
return lerp(fBlurTex, fMainTex, saturate(fCalc_Depth)); //! 뎁스데이터를 이용해 일반 텍스처랑 블러 텍스처 lerp
}
ENDCG
}
}
}
뎁스 버퍼를 이용해 간단하게 DOF효과를 구현했습니다.
원리는 간단합니다.
이전에 구현한 뎁스버퍼를 통해 0~1로 뎁스 데이터를 얻었습니다.
일반 텍스처와 블러텍스처를 뎁스값으로 lerp 계산하여 구현했습니다.
추가 정보 & 의문
float fDepthData = tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(float4(i.uv, 1, 1))).r;
위 코드는 뎁스텍스처 샘플링할때 사용했던 코드입니다, 구글링하면 대부분 자료가 해당 코드를 이용하는데
분석해보면 후처리 단계에서는 어차피 화면이미지 자체를 이용하는데 프로젝션 계산이 무슨 의미가 있나 싶어서
float fDepthData = tex2D(_CameraDepthTexture, i.uv).r;
위 코드로 변경했더니 결과는 같았습니다.
추측상 tex2Dproj를 사용해야 될 때는 일반 오브젝트 픽셀 쉐이더에서 Soft Particle이나 데칼을 구현 할 때 뎁스버퍼가 필요한데 해당 뎁스 버퍼의 텍셀정보를 가져오기 위해서는 스크린UV로 프로젝션 행렬로 텍셀정보를 가져오기 위해 사용하는 것으로 생각됩니다.
'Unity > Shader & VFX' 카테고리의 다른 글
Hexagon Barrier (1) | 2020.01.31 |
---|---|
[Unity Shader Effect] Cosmic Shader - ScreenPos UV (1) | 2020.01.08 |
[Unity PostProcess] Custom PostProcess 쉐이더 제작 & 적용 (0) | 2020.01.02 |
Unity Shader Properties 응용 & multi_compile (0) | 2019.12.29 |
[Unity Shader Effect] Soft Particles Shader (0) | 2019.12.28 |
WRITTEN BY
- CatDarkGame
Technical Artist dhwlgn12@gmail.com