# Part 20 | 응용하기

## 01 투명해지는 오브젝트 만들기

**하프톤 디더링으로 투명해지게 만들기**

게임 오브젝트가 사라지게 해야할 때가 있다.\
먼저 패턴 디더링(Pattern Dithering) 방법이 있다. 망점으로 서서히 사라지는 기법이다.\
망점을 이용하는 방법은 망점 텍스쳐를 이용하는 방법과 연산으로 만드는 방법이 있다.\
Shader Graph에는 간편하게 연산으로 만들 수 있는 Dither 노드가 들어있다.

> **Dither 노드**

* in값을 0에서 1사이의 값으로 조절해보면 1에 가까워질수록 망점이 점점 생긴다
* UV는 화면 그 자체를 UV로 사용하는 Screen Position이다.

![](https://velog.velcdn.com/images/biomatrix117/post/5851ac69-4c6e-405f-b4c3-3ef740122e25/image.png)

* Graph Settings > Alpha Clipping 활성화
* Dither 노드를 Alpha에 연결
* Float Slider 프로퍼티를 만들고 Dither의 In에 연결

**깨끗한 반투명으로 사라지게 만들기**

점박이로 사라지지 않고 깨끗하게 투명하게 사라지게 만들기 : 알파 블렌딩

![](https://velog.velcdn.com/images/biomatrix117/post/b8bb13d3-f515-4275-8e9b-742f7d61831d/image.png)

* Graph Settings > Surface Type > Transparent
* Alpha에 0에서 1 Slider 만들기

이렇게 하면 점박이는 없어지지만, 앞뒤 문제가 발생하고 뒤에 있는 오브젝트가 겹쳐 보이면서 지저분해진다.

비용이 들지만, 2Pass로 더 깨끗하게 사라지는 반투명을 만들 수 있다.\
Custom Renderer Feature를 이용하여 **투명하지만 Z write를 하는 오브젝트**를 먼저 그리고, 그 위에 다시 반투명 오브젝트를 그리면 된다.

![](https://velog.velcdn.com/images/biomatrix117/post/bd72fae9-8ac5-49e3-93fd-ca352b98e004/image.png)

1. **보이지는 않지만 Z값을 쓰기만 하는 오브젝트를 만든다.** 이 오브젝트를 그리는 순서는 Opaque(불투명) 다음에 Transparent(반투명)이 그려지기 직전.

* 새 Unlit Shader와 Material 만들고 DepthOnly로 명명
* Graph Settings에서 Surface Type은 Transparent, Depth Write는 Force Enabled
* Screen Position을 연결한 Screen Color를 Base Color에 연결

이렇게 되면 Z값을 쓴 오브젝트가 그려지긴 하지만, 배경을 캡쳐한 이미지를 그대로 덧씌워 마치 투명 망토처럼 보이지 않게 된다.\
코드로는 ColorMask 0로 그려지지 않게 할 수 있지만, 노드에는 해당하는 기능이 없어서 이렇게 한 것.

![](https://velog.velcdn.com/images/biomatrix117/post/1a3ac0aa-0014-4d7c-b836-8b0d3681dc07/image.png)

2. **여기에 반투명으로 오브젝트를 그린다.** 이전에는 반투명으로 그릴 때 앞뒤 판정이 안되어서 뒷면에 있는 것까지 그려졌다면, 지금은 Z값이 이미 쓰여있기 때문에 뒤에 있는 것은 그려지지 않는다.

* 오브젝트의 머테리얼을 처음 만들었던 알파 블렌딩 적용된 (그리는 순서 문제는 있는) 머테리얼로 교체한다
* 오브젝트에 Layer를 설정한다
* 프로젝트 뷰 > Asset > Settings에서 현재 사용하고 있는 URP Asset 선택하고 Opaque Texture 체크
* URP Asset에 적용된 Renderer을 선택하고 Add Renderer Feature > Render Objects
  * Event : 그려질 순서. Before Rendering Transparents로 설정한다.
  * Queue : Transparent
  * Layer Mask : 오브젝트에 설정했던 Layer
  * Material : 보이지는 않지만 Z 버퍼에 값을 쓰는 DepthOnly 머테리얼 설정

**과정 정리**

1. 배경을 그린다 (Opaque 다음에 Skybox가 그려짐. Opaque Texture에 현재 상태가 캡쳐됨.)
2. Transparent가 그려지기 직전에 Renderer Feature가 실행되고, 보이지는 않지만 Z 값을 쓴 레이어 오브젝트가 그려진다.
3. 반투명 오브젝트가 그려진다. Z 값이 로봇 모양으로 쓰여져 있기 때문에, 뒤에 가려진 면은 보이지 않게 된다.

(평소에는 일반 셰이더를 쓰다가, 투명해져야 할 때 이 셰이더로 교체하면 됨)

**더 투명하고 안 보이게 만들기**

* Smoothness 떨어뜨려서 정반사를 줄여서 눈에 덜 띄게 만들기
* Unlit으로 바꿔서 빛과의 상호작용 없애기

> **Opaque Texture?**\
> Opaque(불투명 오브젝트)가 다 그려진 후 그려진 이미지(프레임 버퍼)를 저장해 놓는 것.\
> 쉽게 말하면, 계속 스크린샷을 찍어서 갖고 있는 것. 아직 Transparent 오브젝트들은 그려지지 않았기 때문에 찍혀있지 않다.\
> 가벼운 기능은 아니므로 타협하면서 사용할 필요가 있다.

## 02 굴절되는 셰이더 만들기

굴절 활용 예시

* 고급 퀄리티의 유리병
* 총알 혹은 검의 궤적
* 큰 폭발에서 공기가 흔들리는 효과
* 물 아래 바닥이 굴절되어 일렁이게 만듦

레이트레이싱을 이용한 진짜 굴절을 이용할 수도 있겠지만,\
일반적으론 이미지를 캡쳐해서 UV를 이동시켜 굴절처럼 보이게 한다.\
굴절은 꽤 무거운 기능이니 특히 모바일이라면 주의해서 사용해야 한다.

![](https://velog.velcdn.com/images/biomatrix117/post/74a16550-d35f-4818-bd88-12e660f6c11d/image.png)

* URP Asset에서 Opaque Texture 활성화
* 왜곡할 오브젝트 앞에 적당한 Quad 오브젝트 생성
* 셰이더 Transparent로 설정
* Screen Position을 넣은 Scene Color를 Base Color에 설정
* Gradient Noise 노드를 꺼내서 0.1을 곱하고, 이를 Screen Position에 더한다

![](https://velog.velcdn.com/images/biomatrix117/post/2334f3ff-b716-4083-b5a5-0dc25dadbaa3/image.png)

* Time과 Rotate 노드를 이용하여 회전시키고, 이를 Spherize 노드를 이용해서 볼록하게 왜곡한다
* 왜곡되고 회전되는 노이즈를 텍스쳐와 곱해서 중앙 부분에만 효과가 나오도록 만들었다

## 03 원하는 타이밍에 눈이 깜빡이는 효과

**노이즈를 이용해서 랜덤하게 깜빡이기**

![](https://velog.velcdn.com/images/biomatrix117/post/168f3ca0-e86f-492f-93bd-18206e01542b/image.png)

* Simle Noise 노드를 꺼내어 UV에 Time을 넣어주면, 대각선으로 UV 좌표가 움직이며 Noise 값을 받아와서 깜빡이게 된다
* 그걸 HDR Color와 곱해주면 Bloom에 의해 밝게 깜박인다
* 마스킹 텍스쳐를 추가하여 특정 부분만 빛나게 할 수도 있다

이대로면 노이즈에 밝은 부분이 많아서 꺼지는 부분보다 빛나는 부분이 더 많다. power 연산을 통해 적절히 빈도를 조절할 수 있다.

참고로, Noise 노드는 사용하기 편하고 해상도도 무제한이지만, 수한 계산에 의해 만들어진 것이므로 GPU의 연산을 소모하게 되는 문제가 있다. 최적화를 위해선 이를 노이즈 텍스쳐로 바꾸어 줘야 한다.

![](https://velog.velcdn.com/images/biomatrix117/post/179d8ba0-9977-41f2-8cae-722dc906d121/image.png)

![](https://velog.velcdn.com/images/biomatrix117/post/0fd59bbe-3ed2-4d37-833c-273e9c0ed78a/image.png)

텍스쳐를 사용하면 모스 부호로 깜빡이게 할 수도 있다.

**타들어가며 없어지는 효과**

몬스터가 죽을 때 타들어가면서 재가 되는 느낌 구현하기.\
타들어가면서 흩날리는 재는 파티클로 처리하더라도, 실제 타들어가는 기능은 일반적으로 셰이더로 처리한다.\
(물론 방법이 셰이더만 있는 건 아니다)

![](https://velog.velcdn.com/images/biomatrix117/post/3130e120-9e3d-4c2a-9be4-a2320efdd091/image.png)

* Lit 셰이더를 만들고, Alpha Clipping 옵션을 켠다
* Simple Noise를 만들고 Alpha에 넣는데, 0.5를 더해주면 모든 면이 다 보일 것이고, 0.5를 빼주면 모든 면이 안 보일 것이다
* 값을 더한 결과에 step 노드를 통해 이미 사라진 영역들과 잠시 후 사라질 영역들을 뽑아낸다
* color를 곱하여 Emission에 넣어준다

처음엔 바로 이해 안됐는데, 텍스쳐가 섬이고, Alpha가 차오르는 물이라고 생각하니 이해됨.

## 04 흔들리는 풀 만들기

풀이나 깃발 흔들릴 때 Bone으로 처리하는 건 생각보다 훨씬 작업량이 많고, 매우 무겁다.\
특정하고 정확한 애니메이션이 필요한 경우는 다르겠지만, 간단한 오브젝트들을 가볍게 흔들리게 하려면 셰이더로 처리하는 것이 훨씬 가볍고 편리하다.

![](https://velog.velcdn.com/images/biomatrix117/post/7094b7c7-f0d4-45c1-9e63-3d583c515f06/image.png)

* Lit Shader를 만들고 Render Face를 Both로, Alpha Clipping 체크, Smoothness를 0으로
* Position 노드를 꺼내서 split으로 Green(y 좌표)만 분리했다가, Time을 x축으로 갖는 Sine을 Green에 더해주고 다시 합친다. 그걸 Position에 넣어준다.
* Time에는 2를 곱해서 더 빠르게 흔들리게 하고, sine 결과값에는 0.2를 더해서 덜 흔들리게 한다.

그럼 위아래로 흔들린다

![](https://velog.velcdn.com/images/biomatrix117/post/defcc0ed-6fe6-48fd-8e74-230977ae7ee2/image.png)

흔들리게 하고 싶은 부분만 버텍스 칼라를 칠해준 뒤 (기본 밑색은 검은색 칠해야됨)

![](https://velog.velcdn.com/images/biomatrix117/post/df3bc7f8-3e03-4c2f-bea7-c2970fc5d276/image.png)

버텍스 칼라 R을 마스킹한 곳만 위아래로 흔들리도록 곱해준다

![](https://velog.velcdn.com/images/biomatrix117/post/c2fbe22e-b4fb-4efd-9197-885e3fab522d/image.png)

버텍스 칼라에 노란색을 칠해준다.\
만약 G 채널이 있는 곳이라면 시간이 살짝 앞서 있어서 타이밍이 달라진다.

참고로 Vertex Color는 Vertex > Position과 Fragment > Base Color에 동시에 연결이 안된다.\
코드가 양쪽에서 동시에 사용할 수 있게 만들어지지 않기 때문이다.\
Preview 노드를 통해 중개하거나, Vertex Color 노드를 2개 만들어서 연결해주면 된다.

## 05 맷캡(Matcap)

맷캡(Matcap : Material Capture) : Ramp Texture와 비슷하게 이미지로 조명을 대신하는 방식 중 하나

* 모바일 게임에서 조명 최적화를 위해 자주 사용된다
* ViewDir을 기반하기 때문에 카메라를 회전하지 않는 상황에서 사용하기 좋다
* 라이팅을 전혀 사용하지 않고도 라이팅 효과 낼 수 있다

![](https://velog.velcdn.com/images/biomatrix117/post/67655541-eeb1-48c6-a05a-f40ebf65feba/image.png)

우선 view 방향 normal vector의 x와 y를 가져온다.

![](https://velog.velcdn.com/images/biomatrix117/post/6f16b6ba-d5fb-41af-aa5f-1cb3e3eef42a/image.png)

검은색 부분의 끝은 0이 아니라 -1이므로 `*0.5+0.5`를 할 수도 있지만\
remap 노드를 쓰면 더 간편하게 0에서 1로 만들어줄 수 있다. 살짝 더 무겁지만 범위를 자유자재로 조절할 수 있음.\
그걸 matcap 텍스쳐의 UV로 넣어주면 된다.

노말맵으로 Matcap을 만들 수도 있다.\
Transform 노드로 Tangent에서 View 공간으로 바꿔주면 된다.

## 06 트라이플래너(Triplaner)

Triplaner는 UV 좌표 없이 균일한 텍스쳐를 입힐 수 있는 좌표를 만든다.\
UV를 펼 시간이 없거나, 동적으로 지형이 변경되는 상황에 사용할 수 있다.

![](https://velog.velcdn.com/images/biomatrix117/post/2e291bc0-7a16-4506-bee5-0a67c41b2ead/image.png)

위(Y축)에서 내려다봤을 때 문제없는, 일반적인 UV.\
U는 Z축이 되고, V는 X축이 된다.

![](https://velog.velcdn.com/images/biomatrix117/post/c4c56ead-cc1c-43e0-8672-823cd2b73de0/image.png)

오른쪽(X축)에서 봤을 때 문제 없는 UV.\
U는 Z축이 되고, V는 Y축이 된다.

![](https://velog.velcdn.com/images/biomatrix117/post/91485d61-926c-48aa-b50a-f84e090a8ca0/image.png)

각 축에 대해 뽑아낸 normal vector를, 각 축에 대한 UV를 입력한 텍스쳐와 곱하고\
(Absolute를 해주는 이유는, 반대편에서도 보이게 하기 위함)

![](https://velog.velcdn.com/images/biomatrix117/post/1a83f680-2679-4c3c-ab9b-110d9db332d8/image.png)

전부 더해주면 모든 축의 시선에 대해 UV가 제대로 입혀진다.

물론 내장된 Triplaner 노드도 있긴 하지만,\
직접 만들면 옆면에 한해 다른 텍스쳐를 입히기, 일정 각도 이상이 되면 옆면에 다른 텍스쳐 입히기 등 다양한 응용을 할 수 있다.

## 07 뎁스 페이드 (Depth Fade)

**뎁스 페이드**

* 물체에 닿았을 때 부드럽게 사라지는 효과
* 유니티 파티클 기능에선 소프트 파티클이라고도 한다
* 물이 육지에 닿는 부분에서 사용할 수 있다
* 보호막 이펙트에도 사용할 수 있다

![](https://velog.velcdn.com/images/biomatrix117/post/71c38483-d8bd-4d09-a0ee-5b135b811cf6/image.png)

* 렌더링 파이프라인 애셋에서 Detph Texture를 활성화시킨다
* Scene Depth 노드를 꺼내어 Sampling을 Eye로 설정한다
* Graph Settings > Surface Type > Transparent로 설정한다
* Scene Depth 노드를 꺼낸다. Transparent로 설정했었으므로, 이 셰이더가 적용된 물체는 모든 Opaque(불투명)가 그려진 후에 그려진다.
* Scene Position 노드를 꺼낸다. Raw 모드의 A값(w값)은 해당 오브젝트의 깊이값이다.
* 두 depth 값을 빼고, Saturate를 이용하여 0에서 1 사이로 잘라준다.
* 깊이 차가 별로 없는 부분은 0, 깊이 차가 큰 부분은 1에 가까워질텐데, 이것을 one minus 노드로 반전시키고, saturate한 뒤 alpha 값에 넣어준다.

> **Troubleshooting**

* scene depth와 물체의 depth값의 차이가 책과 다름.
* 예제 파일을 확인해보니 Blending Mode가 Additive였고, Quad가 아닌 Plane이었음. (Plane이 Quad보다 10배 커서 깊이값이 달랐다)


---

# 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-20-or.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.
