# Part 19 알파와 뎁스 버퍼 (Alpha & Depth buffer)

## 01 Z버퍼(Depth buffer)와 불투명(Opaque)

> **Z 버퍼(깊이 버퍼)?** 앞뒤 판정을 위해, 각 픽셀마다 카메라를 기준으로 가장 가까운 오브젝트의 깊이 값이 저장되어 있는 데이터 시트

불투명(Opaque) 오브젝트들이 앞에 있으면 Z 버퍼로 앞뒤 판정 가능

## 02 반투명 : 알파 블렌딩 (Alpha Blending)

반투명일 때 Z버퍼만 고려하면 투명한 부분들까지 뒤의 오브젝트가 그려지지 않기 때문에

* 불투명(Opaque) 오브젝트는 먼저 그린다
* 반투명(Transparent) 오브젝트는 나중에 그린다
* 반투명 오브젝트들끼리는 멀리 있는 것부터 차례대로 그린다 (Alpha Sorting)

이를 위해 이러한 연산들이 필요하다

* 셰이더가 Transparent인 오브젝트들은 Opaque 오브젝트들이 다 그려질 때까지 대기하고 있어야 한다
* 반투명 오브젝트들끼리 그려질 때, 각각 카메라와의 거리를 체크하는 연산을 추가해야 한다
* Opaque 오브젝트는 뒤 오브젝트들을 가리면 연산이 줄어드는데, Transparent 오브젝트는 연산이 무거워진다
* 디퍼드 렌더링(Deffered Rendering)에서는 아예 반투명을 처리할 수 없어서, 포워드 렌더링(Forward Rendering)으로 반투명을 따로 그려줘야 한다.

![](https://velog.velcdn.com/images/biomatrix117/post/4a030eaa-94e9-4322-903e-121dc1f7f055/image.png)

* Quad를 만들고, Unlit Shader Graph, 머테리얼, 나뭇잎 텍스쳐 준비
* Shader Graph > Graph Settings > Transparent : 알파 블렌딩 사용 가능하게 하기
* Graph Settings > Depth write > Force Enable : 강제로 Z버퍼에 쓰게 만든다
* 나뭇잎 텍스쳐를 연결하고, RGB와 A를 모두 연결한다

뒷 나뭇잎을 앞 나뭇잎보다 살짝 옆으로 빼보면, 앞 나뭇잎의 투명 부분이 뒷 나뭇잎을 가려버린다. 카메라의 위치에서부터 각 오브젝트의 피봇점까지의 거리로 알파 소팅을 하기 때문이다. 즉,

**알파 소팅을 써 봤자 완벽하게 앞뒤를 제대로 판정할 수가 없으니,**\
**알파 블렌딩을 사용하였을 때 앞뒤 문제는 늘 일어날 수밖에 없다. 포기해라.**

하지만 Z 값에 의해 사각으로 뚫리는 현상까지는 막을 수 있다.\
Transparent 계열의 셰이더로 작성하면, Z버퍼에 자신의 위치 값을 입력하지 않는다.\
(Zwrite를 off, 혹은 Depth에 Write 하지 않는다고 표현)

![](https://velog.velcdn.com/images/biomatrix117/post/f4728320-974e-4847-bc16-a8986e12f525/image.png)

Depth Write를 Force Disable로 바꾸면 앞뒤 문제는 해결되지 않지만,\
매쉬 모양으로 잘리는 문제까지는 사라진다.

## 03 알파 테스팅 / 클리핑 (Alpha Testing / Clipping)

이처럼 알파 블렌딩은 사용이 한정적이다. 앞뒤 판정은 명확하지 않으며 무겁다.\
그래서 알파 테스팅(클리핑)이라는 걸 사용한다.

* Surface Type은 Opaque
* Alpha Clipping 체크
* Fragment에 생긴 Alpha Clip Threshold는 0.5 유지

![](https://velog.velcdn.com/images/biomatrix117/post/2b0f673a-5a68-43e6-b27a-dea2cea5f264/image.png)

알파 클리핑 : threshold 기준으로 완전히 투명하거나 완전히 불투명하게 그려진다. 부드러운 외곽선을 만들 수는 없지만, Opaque처럼 자유롭게 쓸 수 있다.

알파 블렌딩의 부드러운 외곽과 알파 테스팅의 기능을 동시에 원하면, 알파 블렌딩과 클리핑을 동시에 켜는 방법도 있다.\
하지만 알파 블렌딩만큼 무거우면서 알파 블렌딩만큼 부드럽게 표현해주는 것도 아니라 애매하긴 하다.

또는 MSAA(Multisample Anti Aliasing)을 이용해서 알파테스트의 경계를 부드럽게 해주는 Alpha to Coverage라는 기법도 있다.

## 04 Depth Test

Depth Test : 내가 그려질 때 이미 있는 Z버퍼를 읽어서 그 값으로 어떻게 할 거냐를 결정. 그다지 많이 사용하진 않는다.

* Never : 절대로 그리지 않는다.
* Less : 내 Z 값이 이미 그려진 값 보다 더 가까울 때만 그린다
* Equal : 내 Z 값이 이미 그려진 값과 같을 때만 그린다.
* L Equal : Less and Equal. 내 Z 값이 이미 그려진 값 보다 더 가깝거나 같을 때만 그린다.
* Greater : 내 Z 값이 이미 그려진 값 보다 더 멀 때만 그린다.
* Not Equal : 내 Z 값이 이미 그려진 값과 다를 때만 그린다.
* G Equal : Greater and Equal. 내 Z 값이 이미 그려진 값 보다 더 멀거나 같을 때만 그린다.
* Always : 이미 그려진 Z 값과 상관 없이 언제나 그린다. (스텐실 기능과 함께 사용하여 벽 뒤에 가려졌을 때의 외곽선에 사용)

## 05 Blending Mode

이펙트는 반투명이 필수적이다. 알파 블렌딩에서 발생하는 앞뒤 문제를 피해가야 한다.

![](https://velog.velcdn.com/images/biomatrix117/post/524c5836-f6bc-4c4d-a649-2b2b4740806f/image.png)

이펙트가 들어 있는 아틀라스 이미지에

![](https://velog.velcdn.com/images/biomatrix117/post/a97435c3-0eb0-41e2-b127-b641d70e8d61/image.png)

Time을 곱하고 XY를 각각 5,5로 해준 Flipbook 노드를 연결하면 이미지가 애니메이션화 된다.

> **이펙트 팁**
>
> <img src="https://velog.velcdn.com/images/biomatrix117/post/cecd8a81-649c-4731-953a-04acfd660a67/image.png" alt="" data-size="original">
>
> 알파 블렌딩 이펙트로도 이펙트의 Bloom을 가동시키려면, 10제곱으로 밝은 부분만 추출해서 30배쯤 곱해주면 된다.\
> 이렇게 하면 밝은 폭발과 어두운 연기를 모두 표현 가능하다.

**Blending Mode 옵션 종류**

* Alpha : 알파 채널의 강도에 의해 투명도가 결정
* Premultiply : 알파 채널을 RGB 채널에 미리 곱해놓고 투명도를 떨어뜨려 보다 정상적으로 연산 (원래는 외곽선에 검은색이 안 묻어나오게 바꿔주는데, 2D에서만 티가 난다고 함)

![](https://velog.velcdn.com/images/biomatrix117/post/5c507837-fadb-4c41-aa88-0a71fa4e901f/image.png)

* Additive : 배경 이미지와 더해지면서 밝아진다.
  * 알파 채널 없이 배경이 검은색인 이미지에 Additive를 적용시키면 검은색이 투명해지면서 뒤의 이미지와 밝게 합성된다.
  * 알파도 추가로 연산되고 있기 때문에, 알파를 0으로 바꾸면 완전히 투명해진다.
  * 앞뒤 문제는 발생하고 있지만, 어차피 결과가 같기 때문에 상관 없다.
  * RGB에 10 정도를 곱해서 HDR Bloom을 만들면 잘 어울리기도 한다.

![](https://velog.velcdn.com/images/biomatrix117/post/88ae9df5-5f23-499c-bead-aa62be916daf/image.png)

* Multiply : 배경에 곱해준다.
  * 배경과 겹쳐지면 어두워지고, 겹치면 겹칠수록 점점 어두워진다.
  * 알파를 전혀 연산하지 않기 때문에, Alpha를 0으로 만들어 주어도 투명해지지 않는다.
  * 앞뒤 문제가 발생하지만, 역시 결과가 같아서 상관 없다.

이처럼 블렌딩 모드가 같다면 큰 티가 나지 않거나 문제가 일어나지 않는다.\
하지만 서로 다른 블렌딩끼리 겹치면 문제가 발생한다.\
앞뒤면에 따라 서로 다른 결과가 나올 수 있다.

알아서 잘 숨기거나, 피봇점 같은 트릭을 이용하거나, Render Queue로 그리는 순서를 조절한다.

## 06 Graph Settings

**Precision(정밀도)**\
셰이더 코드 전체의 기본 정밀도를 제어한다.\
Single은 32비트로, 셰이더에서 사용 가능한 가장 정밀한 부동 소수점 값이다.\
Half는 16비트다.

**Target Settings**\
Built-in, URP, Custom Shader들 중 대상 파이프라인 설정

**Material**\
셰이더 그래프의 재질 기본 설정을 바꾼다. Unlit, Lit, Decal, Sprite 등.

**Allow Material Override**\
Graph Settings의 옵션들을 머테리얼에서 덮어쓰기가 가능해진다.\
셰이더 하나만으로도 다양한 속성을 가진 셰이더로 사용할 수 있기 때문에 셰이더 개수가 줄어들고 작업 효율 증가한다.

**Blend Mode**\
Surface Type이 Transparent가 돼야만 나온다.

**Render Face**\
앞면 뒷면 어디를 그릴지

**Depth Write**\
Z buffer에 쓸지 안 쓸지.\
Opaque일 땐 기본 Enable, Transparet일 땐 기본 Disable

**Cast Shadow**\
그림자 켜고 끄기.\
Transparent 옵션에선 기본적으로 작동하지 않는다.\
이걸 끄면 Shadow Pass를 생성하지 않아서 좀 더 가벼운 셰이더가 된다.

**Custom Editor GUI** C#으로 Custom Editor를 작성하고 Custom Editor GUI의 이름을 입력하여\
Shader Properties를 커스텀할 수 있게 한다.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lazyartisan.gitbook.io/note/main-page/books/urp/part-19-alpha-and-depth-buffer.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
