본문 바로가기

Graphics/Ronja's Unity Shader tutorials

스프라이트 셰이더

 

Sprite Shaders

Summary In unity the way sprites are rendered is very similar to the way 3d objects are rendered. Most of the work is done by the sprite renderer component. I’ll go a bit over what the component is doing and how we can change our shader to do some of the

www.ronja-tutorials.com

Ronja 님의 허락을 받고 번역한 튜토리얼입니다. 원문은 위 링크에서 확인하실 수 있습니다.
몇몇 부분은 생략·추가하였습니다.
의역과 오역이 넘쳐날 수 있으니 편하게 봐주시고 잘못된 부분은 알려주시면 감사하겠습니다!

 

 

목차

  • 개요
  • 씬 설정
  • 셰이더 변경하기

 


 

개요

유니티에서 스프라이트가 렌더되는 방식은 3D 오브젝트가 렌더되는 방식과 매우 유사합니다. 대부분의 작업은 스프라이트 렌더러라는 컴포넌트를 통해 이루어집니다. 이 컴포넌트가 어떤 역할을 하는지와, 스프라이트 렌더러가 해주는 몇가지 작업을 할 수 있도록 어떻게 셰이더를 변경하는지에 대해 살펴보려 합니다.

이 튜토리얼은 이전에 만든 투명 셰이더를 기반으로 하기 때문에, 이를 먼저 이해하는 것이 도움이 될 것입니다.

 


 

씬 설정

스프라이트 셰이더를 작업하기 위해 씬을 단순하게 만들었습니다. 카메라를 othergraphic 으로 만들고, 스프라이트 렌더러 오브젝트를 배치한 뒤 사용할 이미지의 텍스처 타입을 스프라이트로 변환했습니다.

 

카메라 설정 / 스프라이트 오브젝트 / 이미지 설정

 


 

셰이더 변경하기

이러한 씬 설정과 함께 이전에 작업한 투명 메테리얼을 스프라이트 렌더러의 메테리얼 슬롯에 넣으면, 모든 것이 잘 동작하는 것처럼 보입니다.

스프라이트 렌더러 컴포넌트는 사용해왔던 3D 모델들처럼 자동으로 텍스처 이미지를 기반으로 한 메시를 생성하고 UV좌표를 설정해줍니다. 스프라이트 렌더러는 컴포넌트의 색상 값을 스프라이트의 생성된 메시의 버텍스 컬러로 입력하고, 우리가 Flip X, Y 옵션을 활성화했을 때 버텍스들을 뒤집힌 모양으로 맞춥니다. 또 높은 Sorting Layer 값을 가진 스프라이트들이 나중에 렌더되고 위에 그려질 수 있도록 유니티 렌더 파이프라인과 소통하기도 합니다.

 

현재 우리의 셰이더는 플립과 색상 변경을 지원하지 않으므로, 이제부터 이를 고쳐보도록 합시다.

우리의 스프라이트가 뒤집었을 때 사라지는 (그리고 다시 뒤집었을 때 나타나는) 이유는 스프라이트를 x축으로 뒤집기 위해 렌더러는 기본적으로 오브젝트를 y축 기반으로 180° 회전시켜 우리가 오브젝트의 뒷면을 보도록 하는데, 오브젝트의 뒷면들은 'Backface culling' 이라는 최적화 기법때문에 렌더되지 않았기 때문입니다.

지금의 경우 이러한 최적화에 대해 걱정할 필요가 없는데, 스프라이트들은 최적화될 수 있는 '내부' (3D 모델의 내부 빈 공간) 를 가지고 있지 않고, 라이팅도 적용되지 않기 때문에, 그냥 Backface culling 을 비활성화해버려도 됩니다. Subshader 또는 Shaderpass 내부에서 이를 적용할 수 있습니다.

 

Cull Off // Backface Culling 비활성화

 

이제 스프라이트 렌더러의 색상을 적용하기 위해, 버텍스 컬러값을 가져와야 합니다. 버텍스 컬러값을 가져오기 위해서 입력 구조체 (appdata) 와 v2f (vertex to fragment) 구조체에 4차원(R,G,B,A) 변수를 새로 추가하고 color라고 표시해줍니다. 그리고 컬러값을 입력 구조체에서 버텍스 셰이더 내부의 v2f 구조체로 넘기고, 프래그먼트 셰이더 안에서 컬러 반환값과 color 변수를 곱해줍니다.

 

Shader "Tutorial/007_Sprite" // Unity 상의 셰이더 경로
{
	Properties
	{
		_Color ("Tint", Color) = (0, 0, 0, 1)
		_MainTex ("Texture", 2D) = "white" {}
	}

	SubShader
	{
		Tags
		{ 
			"RenderType"="Transparent" 
			"Queue"="Transparent"
		}

		Blend SrcAlpha OneMinusSrcAlpha

		ZWrite off
		Cull off

		Pass
		{
			CGPROGRAM

			#include "UnityCG.cginc"
			#pragma vertex vert
			#pragma fragment frag

			sampler2D _MainTex;
			float4 _MainTex_ST;

			fixed4 _Color;

			struct appdata // 입력 구조체
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
				fixed4 color : COLOR; // 새 컬러 변수 (float, half, fixed 모두 사용 가능)
			};

			struct v2f // v2f 구조체
			{
				float4 position : SV_POSITION;
				float2 uv : TEXCOORD0;
				fixed4 color : COLOR; // 새 컬러 변수
			};

			v2f vert(appdata v) // 버텍스 셰이더 내부의 v2f 구조체
			{
				v2f o;
				o.position = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				o.color = v.color;
				return o;
			}

			fixed4 frag(v2f i) : SV_TARGET // 프래그먼트 셰이더
			{
				fixed4 col = tex2D(_MainTex, i.uv);
				col *= _Color;
				col *= i.color;
				return col;
			}

			ENDCG
		}
	}
}

 

이러한 변경점들로 셰이더는 이제 우리가 예상하는 대로 동작할 것이고, 이 셰이더를 확장해 추후 만들고 싶어할 다른 것들도 구현할 수 있습니다.

 

스프라이트 렌더러 컴포넌트는 스프라이트 시트, 폴리곤 스프라이트 및 애니메이션이 셰이더와 함께 동작할 수 있도록 메시를 준비하기도 합니다.

유니티의 스프라이트 셰이더가 지원하지만 우리의 셰이더가 지원하지 않는 것은 인스턴싱, 픽셀 스냅과 외부 알파 채널이지만, 이들은 지금 다루기엔 너무 복잡하거나 대부분의 사람들이 사용하지 않는 적은 케이스이기 때문에 이 글에서 다루지 않기로 결정했습니다.

 

 

 

'Graphics > Ronja's Unity Shader tutorials' 카테고리의 다른 글

색상 보간  (0) 2024.06.15
평면 매핑 (Planar Mapping)  (0) 2024.05.05
기본 투명 셰이더  (0) 2024.01.21
유니티 서피스 셰이더 기본  (0) 2023.11.19
기본 셰이더  (0) 2023.08.06