X-Ray Effet Using Depth
여러 게임들을 보면, 벽을 통해서도 오브젝트를 볼 수 있능 기능이 있다.
벽 너머에 있는 오브젝트를 렌더링 하기 위해서, Depth Buffer를 이용하면 된다.
오브젝트가 다른 벽보다 앞에 있으면 Less-Equal Depth Testing을 이용하고, 벽 뒤에 있게 되면 Greater Depth Testing을 진행하면 된다.
이 기능 또한 Render Object 를 이용하면 되지만, 쉐이더에서 한번 만들어보도록 하자.
Built-in 파이프라인에서는 2개의 Pass를 붙여서 사용해도 되지만, URP에서는 Normal 관련 이펙트는 여러 패스가 Single Shader로 묶여 처리된다.
이를 해결하기 위해 2개의 Shader 파일을 만들도록 하자.
XRay Effect Shader
Shader "Lucid-Boundary/DepthBuffer_XRay"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_BaseColor("Base Color", Color) = (1, 1, 1, 1)
_XRayColor("Xray Color", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags
{
"RenderType"="Opaque"
"Queue" = "Geometry"
"RenderPipeline" = "UniversalPipeline"
}
// XRay Pass
Pass
{
ZTest Greater
ZWrite Off
Tags
{
"LightMode" = "UniversalForward"
}
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
texture2D _MainTex;
CBUFFER_START(UnityPerMaterial)
float4 _XRayColor;
CBUFFER_END
v2f vert (appdata v)
{
v2f o;
o.vertex = TransformObjectToHClip(v.vertex.xyz);
return o;
}
float4 frag (v2f i) : SV_Target
{
return _XRayColor;
}
ENDHLSL
}
}
}
더할나위 없이 쉬운 코드이다.
딱 하나 추가 된점은 ZTest 와 ZWrite 뿐이다.
ZTest가 Greater 이므로 Depth Testing의 조건은 Depth Value가 해당 쉐이더보다 높을 때, 렌더링 하도록 하며
Testing을 통과 했더라도 덮어 쓰기는 하지 않는다로 되어 있다.
이 뜻은, 오브젝트가 벽 뒤에 가려진 부분은 _XRayColor 로 출력되며 그 외에 부분은 렌더링 하지 않는다. 이다.
만약에 XRay Texture Shader를 추가로 만들지 않으면 투명화된 오브젝트가 벽 뒤에 있을 때만 표시되는 현상이 발생한다.
XRay Texture Shader
Shader "Lucid-Boundary/DepthBuffer_XRayTexture"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_BaseColor("Base Color", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags
{
"RenderType"="Opaque"
"Queue" = "Geometry"
"RenderPipeline" = "UniversalPipeline"
}
// Textured Pass
Pass
{
ZTest LEqual
ZWrite On
Tags
{
"LightMode" = "UniversalForward"
}
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
texture2D _MainTex;
SamplerState sampler_MainTex;
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
float4 _BaseColor;
CBUFFER_END
v2f vert (appdata v)
{
v2f o;
o.vertex = TransformObjectToHClip(v.vertex.xyz);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
float4 frag (v2f i) : SV_Target
{
float4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
return col * _BaseColor;
}
ENDHLSL
}
}
}
아주 심플하게 Texture를 표시하는 쉐이더이다.
추가 된 점은 역시나 ZTest, ZWrite 뿐이다.
ZTest LEqual은 일반적인 디폴트 값으로 앞에 나와있으면 렌더링 하는 Depth Test 조건이고,
ZWrite On 이므로 Testing 에 통과 했다면 Depth Value를 덮어쓰도록 설정된다.
이 두 쉐이더를 같이 매트리얼에 적용 시켜보자.


URP Render Object를 이용한 X-Ray 이펙트 넣기
URP Render Object에 대해 지난 포스팅에서 다루었으니 바로 써먹어보자.





Render Pass 가지고 노는 것만으로도 XRay 이펙트를 구현 할 수 있었다.
Depth Buffer에 대해 이해하게 된 이상...생각해보니 정말 편한 방식이다...!!
마치며
Depth Buffer는 쉐이더에서 정말 중요한 구간이다.
Depth Buffer / Stencil Buffer / Depth Testing / Render Feature 까지
우리의 입맛대로 렌더링을 결정할 수 있는 유용한 파트였다.
그리고 쉐이더 내부 동작에 대해서도 좀 더 이해 할 수 있었던.. 이론적으로 재미있고 유익한 구간이였다.
'Game Dev > Unity Shader' 카테고리의 다른 글
| 11. Tranparancy And Alpha 심화 - 다니엘 릿 쉐이더 프로젝트 (0) | 2025.10.17 |
|---|---|
| 10. Transparency And Alpha - 다니엘 릿 쉐이더 프로젝트 (0) | 2025.10.17 |
| 08. Depth Buffer 심화 (2) - 다니엘 릿 쉐이더 프로젝트 (0) | 2025.10.16 |
| 07. Depth Buffer 심화 (1) - 다니엘 릿 쉐이더 프로젝트 (0) | 2025.10.15 |
| 06. 깊숙히, 더욱.. Depth Buffer - 다니엘 릿 쉐이더 프로젝트 (0) | 2025.10.12 |