커스텀 렌더 텍스처는 사용자가 앞에 말한 텍스처를 셰이더로 쉽게 업데이트할 수 있도록 해주는 렌더 텍스처의 확장입니다. 이는 커스틱, 비 내리는 효과를 위한 잔물결 시뮬레이션, 벽에 액체를 뿌리는 것과 같은 모든 종류의 복잡한 상황을 구현하는 데 유용합니다. 또한 커스텀 렌더 텍스처는 부분 또는 멀티 패스 업데이트, 다른 업데이트 빈도와 같은 더 복잡한 설정을 위해 스크립팅과 셰이더 프레임워크를 제공합니다.
커스텀 렌더 텍스처를 사용하려면, 새로운 커스텀 렌더 텍스처 에셋을 생성하고 머티리얼을 에셋에 할당해야 합니다. 그 후, 이 머티리얼은 텍스처의 내용을 다양한 파라미터에 따라 업데이트합니다. 그런 다음, 커스텀 렌더 텍스처는 일반 텍스처는 물론 또 다른 커스텀 텍스처에 사용되는 텍스처와 같은 모든 종류의 머티리얼에 할당될 수 있습니다.
커스텀 렌더 텍스처의 인스펙터에는 렌더 텍스처 인스펙터에 있는 대부분의 프로퍼티와 함께 추가된 프로퍼티 항목이 표시됩니다.
프로퍼티: | 기능: |
---|---|
Dimension | 렌더 텍스처의 차원 |
2D | 렌더 텍스처가 2차원이 됩니다. |
Cube | 렌더 텍스처가 큐브맵이 됩니다. |
3D | 렌더 텍스처가 3차원이 됩니다. |
Size | 렌더 텍스처의 크기(단위: 픽셀)입니다. |
Color Format | 렌더 텍스처의 포맷입니다. |
sRGB(Color Render Texture) | 이 렌더 텍스처가 sRGB의 읽기/쓰기 변환(읽기 전용)을 사용할지 여부입니다. |
Enable Mip Maps | 이 렌더 텍스처가 밉맵을 사용할지 여부입니다. |
Auto generate Mip Maps | 자동으로 밉맵 생성을 활성화합니다. |
Wrap Mode | 바둑판식으로 배열될 때 텍스처의 동작 방식을 선택합니다. |
Repeat | 텍스처가(타일을) 반복합니다. |
Clamp | 텍스처의 에지가 늘어납니다. |
Filter Mode | 3D 변환으로 늘릴 때 텍스처 필터링 방법을 선택합니다. |
Point | 텍스처가 가까워지면 블럭 현상이 나타납니다. |
Bilinear | 텍스처가 가까워지면 흐릿해집니다. |
Trilinear | Bilinear와 유사하지만, 텍스처가 다른 밉 레벨 사이에서 흐릿해집니다. |
Aniso Level | 비스듬한 각도에서 텍스처를 볼 때 텍스처의 품질이 향상됩니다. 바닥이나 그라운드 텍스처에 적합합니다. |
커스텀 텍스처 파라미터는 다음 세 가지 주요 카테고리로 나뉩니다.
머티리얼: 텍스처를 업데이트하는 데 어떤 셰이더가 사용되는지 정의합니다.
초기화: 셰이더가 업데이트를 수행하기 전에 텍스처가 초기화되는 방법을 제어합니다.
업데이트: 셰이더가 텍스처를 업데이트하는 방법을 제어합니다.
프로퍼티: | 기능: |
---|---|
Material | 커스텀 렌더 텍스처를 업데이트하는 데 사용된 머티리얼 |
Shader Pass | 커스텀 텍스처를 업데이트하는 데 사용된 셰이더 패스. 콤보 상자에는 머티리얼에서 사용할 수 있는 모든 패스가 표시됩니다. |
Initialization Mode | 텍스처를 초기화해야 하는 속도입니다. |
OnLoad | 텍스처가 생성되는 즉시 초기화됩니다. |
Realtime | 모든 프레임에서 텍스처가 초기화됩니다. |
OnDemand | 텍스처가 필요에 따라 스크립트에서 초기화됩니다. |
Source | 텍스처가 초기화되는 방법입니다. |
Texture and Color | 컬러값이 곱해진 텍스처로 초기화됩니다. |
Initialization Color | 커스텀 텍스처가 초기화되는 컬러. 초기화된 텍스처도 제공되는 경우, 커스텀 텍스처는 컬러값과 텍스처값이 곱해져 초기화됩니다. |
Initialization Texture | 커스텀 텍스처가 초기화되는 텍스처. 초기화 컬러도 제공되는 경우, 커스텀 텍스처는 컬러값과 텍스처값이 곱해져 초기화됩니다. |
Material | 머티리얼에 의해 초기화되는 텍스처입니다. |
Initialization Material | 커스텀 텍스처가 초기화되는 머티리얼입니다. |
Update Mode | 셰이더가 텍스처를 업데이트해야 하는 속도입니다. |
OnLoad | 텍스처가 생성되는 즉시 업데이트됩니다. |
Realtime | 모든 프레임에서 텍스처가 업데이트됩니다. |
OnDemand | 텍스처가 필요에 따라 스크립트에서 업데이트됩니다. |
Period | (실시간만)실시간 텍스처가 업데이트되는 기간(단위: 초)입니다. 0.0은 모든 프레임을 업데이트합니다. |
Double Buffered | 텍스처가 이중 버퍼링됩니다. 각 업데이트는 두 개의 버퍼를 스왑하여 사용자가 셰이더에서 이전 업데이트의 결과를 읽을 수 있도록 합니다. |
Wrap Update Zones | 부분 업데이트 영역이 텍스처 경계를 래핑하도록 활성화합니다. |
Cubemap Faces | (큐브맵 전용)사용자가 각 큐브맵 면의 업데이트를 활성화/비활성화하도록 허용하는 일련의 토글 |
Update Zone Space | 업데이트 영역이 정의된 좌표 시스템입니다. |
Normalized | 모든 좌표와 크기는 0과 1사이에 존재하며 왼쪽 상단 코너는 (0, 0)에서 시작됩니다. |
Pixel | 모든 좌표와 크기는 텍스처의 너비와 높이로 제한된 픽셀로 표현됩니다. 왼쪽 상단 코너는 (0, 0)에서 시작됩니다. |
Update Zone List | 텍스처의 업데이트 영역 리스트(자세한 내용은 아래 참조) |
커스텀 렌더 텍스처는 상황별 “익스포트” 메뉴를 통해 텍스처 포맷에 따라 PNG 또는 EXR 파일로 익스포트할 수 있습니다.
기본적으로, 커스텀 렌더 텍스처가 업데이트될 때, 머티리얼이 전체 텍스처를 즉시 업데이트합니다. 커스텀 텍스처의 중요한 기능 중 하나는 사용자가 부분 업데이트 영역을 정의할 수 있는 기능입니다. 이 기능을 통해 사용자는 원하는 만큼의 영역을 정의하고 영역이 처리되는 순서를 정의할 수 있습니다.
업데이트 영역은 다양한 목적으로 사용될 수 있습니다. 예를 들어, 텍스처 위에 물방울이 튀는 여러 개의 작은 영역을 가질 수 있고, 그런 다음 잔물결을 시뮬레이션하기 위해 풀 패스를 수행할 수 있습니다. 또한 전체 텍스처를 업데이트할 필요가 없다는 것을 인지하고 있는 경우 최적화로서 이 업데이트 영역을 사용할 수 있습니다.
업데이트 영역에는 고유의 프로퍼티 집합이 있습니다. Update Zone Space 가 디스플레이에 반영됩니다. 텍스처의 Dimension 에 따라, 좌표는 2D(2D 및 큐브 텍스처의 경우) 또는 3D(3D 텍스처의 경우)가 됩니다.
프로퍼티: | 기능: |
---|---|
Center | 업데이트 영역 센터의 좌표입니다. |
Size | 업데이트 영역의 크기입니다. |
Rotation | 각도로 표시되는 업데이트 영역의 방향입니다(3D 텍스처에서는 사용 불가능). |
Shader Pass | 이 업데이트 영역에 사용될 셰이더 패스. 디폴트 설정을 유지하는 경우, 이 업데이트 영역은 인스펙터의 주요 부분에서 정의된 셰이더 패스를 사용하나, 그렇지 않은 경우에는 제공된 셰이더 패스를 사용합니다. |
Swap(Double Buffer) | (이중 버퍼링된 텍스처에만 해당)true일 경우, 버퍼는 이 업데이트 영역이 프로세스되기 전에 스왑됩니다. |
커스텀 렌더 텍스처는 “이중 버퍼링”됩니다. 내부적으로, 두 가지 텍스처가 있지만 사용자 관점에서 보면 두 가지는 동일합니다. 각각의 업데이트 후에, 두 텍스처는 스왑되며 이를 통해 사용자는 커스텀 렌더 텍스처에서 새로운 결과를 작성하는 동안 지난 업데이트 결과를 읽을 수 있습니다. 셰이더가 이미 텍스처에 쓰기가 완료된 내용을 사용해야 하지만 기존의 혼합 모드로는 그 값을 혼합할 수 없는 경우에 특히 유용합니다. 셰이더가 이전 결과의 다른 픽셀을 샘플링해야 하는 경우에 또한 필요합니다.
성능 경고: 몇 가지 전문적인 사항으로 인해, 현재 이중 버퍼링은 스왑 빈도와 텍스처 해상도에 따라 성능 저하를 초래할 수 있는 각 스왑에서의 텍스처 복사를 수반합니다.
커스텀 렌더 텍스처는 업데이트할 머티리얼을 필요로 합니다. 이 머티리얼은 입력으로 텍스처를 가질 수 있습니다. 이는 커스텀 텍스처가 또 다른 텍스처를 생성하는 입력으로 사용될 수 있음을 의미합니다. 이런 방법으로 사용자는 더 복잡한 다단계 시뮬레이션을 생성하기 위해 여러 커스텀 텍스처를 연결할 수 있습니다. 시스템은 서로 다른 업데이트가 올바른 순서로 일어나도록 모든 종속성을 올바르게 처리합니다.
커스텀 텍스처를 업데이트하는 것은 렌더 텍스처에서 2D 포스트 프로세스를 수행하는 것과 같습니다. 사용자가 커스텀 텍스처 셰이더를 작성하도록 지원하기 위해, Unity는 유틸리티 함수와 빌트인 헬퍼 변수가 있는 작은 프레임워크를 제공합니다.
다음은 컬러를 곱한 컬러로 텍스처를 채우는 간단한 예제입니다.
Shader "CustomRenderTexture/Simple"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_Tex("InputTex", 2D) = "white" {}
}
SubShader
{
Lighting Off
Blend One Zero
Pass
{
CGPROGRAM
#include "UnityCustomRenderTexture.cginc"
#pragma vertex CustomRenderTextureVertexShader
#pragma fragment frag
#pragma target 3.0
float4 _Color;
sampler2D _Tex;
float4 frag(v2f_customrendertexture IN) : COLOR
{
return _Color * tex2D(_Tex, IN.localTexcoord.xy);
}
ENDCG
}
}
}
커스텀 텍스처의 셰이더를 작성할 때 필수적인 단계는 다음과 같습니다.
* #include “UnityCustomRenderTexture.cginc”
제공된 버텍스 셰이더 CustomRenderTextureVertexShader 사용
픽셀 셰이더를 위해 제공된 입력 구조 v2f_customrendertexture 사용
무엇보다도, 사용자는 픽셀 셰이더를 원하는 대로 자유롭게 작성합니다.
다음은 초기화 머티리얼에서 사용되는 셰이더의 또 다른 예제입니다.
Shader "CustomRenderTexture/CustomTextureInit"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_Tex("InputTex", 2D) = "white" {}
}
SubShader
{
Lighting Off
Blend One Zero
Pass
{
CGPROGRAM
#include "UnityCustomRenderTexture.cginc"
#pragma vertex InitCustomRenderTextureVertexShader
#pragma fragment frag
#pragma target 3.0
float4 _Color;
sampler2D _Tex;
float4 frag(v2f_init_customrendertexture IN) : COLOR
{
_Color * tex2D(_Tex, IN.texcoord.xy);
}
ENDCG
}
}
}
업데이트 셰이더와 마찬가지로, 필수적인 단계는 다음과 같습니다.
* #include “UnityCustomRenderTexture.cginc”
제공되는 버텍스 셰이더 InitCustomRenderTextureVertexShader 사용
픽셀 셰이더에 대해 제공된 입력 구조 v2f_init_customrendertexture 사용
이 프로세스에서 사용자를 돕기 위해 일련의 빌트인 값이 제공됩니다.
v2f_customrendertexture 구조의 입력 값은 다음과 같습니다.
이름 | Type | 값 |
---|---|---|
localTexcoord |
float3 |
현재 처리 중인 업데이트 영역에 대한 상대적인 텍스처 좌표입니다. |
globalTexcoord |
float3 |
커스텀 렌더 텍스처 자체에 대한 상대적인 텍스처 좌표입니다. |
primitiveID |
uint |
현재 처리 중인 업데이트 영역의 인덱스입니다. |
direction |
float3 |
큐브 커스텀 렌더 텍스처의 경우, 큐브맵 내부의 현재 픽셀 방향입니다. |
v2f_init_customrendertexture 구조의 입력 값은 다음과 같습니다.
이름 | Type | 값 |
---|---|---|
texcoord |
float3 | 커스텀 렌더 텍스처 자체에 대한 상대적인 텍스처 좌표입니다. |
전역 값:
이름 | Type | 값 |
---|---|---|
_CustomRenderTextureWidth |
float |
커스텀 텍스처의 너비(단위: 픽셀) |
_CustomRenderTextureHeight |
float |
커스텀 텍스처의 높이(단위: 픽셀) |
_CustomRenderTextureDepth |
float |
커스텀 텍스처의 뎁스(단위: 픽셀)(3D 텍스처일 경우에만 해당하며 그 밖의 경우는 1과 동일함) |
_CustomRenderTextureCubeFace |
float |
큐브맵인 경우에만: 처리 중인 현재 큐브맵 면의 인덱스(-X, +X, -Y, +Y, -Z, +Z) |
_CustomRenderTexture3DSlice |
float |
3D 텍스처인 경우만: 처리 중인 현재 3D 슬라이스의 인덱스 |
_SelfTexture2D |
Sampler2D |
이중 버퍼링된 텍스처인 경우: 마지막 스왑 이전의 마지막 업데이트 결과를 포함하는 텍스처 |
_SelfTextureCube |
SamplerCUBE |
이중 버퍼링된 텍스처인 경우: 마지막 스왑 이전의 마지막 업데이트 결과를 포함하는 텍스처 |
_SelfTexture3D |
Sampler3D |
이중 버퍼링된 텍스처인 경우: 마지막 스왑 이전의 마지막 업데이트 결과를 포함하는 텍스처 |
여기에 설명된 대부분의 기능은 스크립팅 API를 통해 액세스할 수 있습니다. 머티리얼 파라미터, 업데이트 빈도, 업데이트 영역 변경 또는 업데이트 요청은 스크립트를 통해 수행할 수 있습니다.
그러나 커스텀 텍스처에 대해 요청되는 모든 업데이트가 커스텀 텍스처의 현재 상태를 포함한 프레임의 시작 부분에서 특정한 시간에 실행된다는 점을 명심해야 합니다. 이를 통해 이 텍스처를 사용하는 모든 머티리얼이 최신 결과를 보유하고 있음을 보장할 수 있습니다.
이는 다음과 같은 타입의 패턴을 의미합니다.
customRenderTexture.updateZones = updateZones1;
customRenderTexture.Update();
customRenderTexture.updateZones = updateZones2;
customRenderTexture.Update();
업데이트 영역의 첫 번째 배열에 대한 첫 업데이트 수행 후 다른 배열에 대한 두 번째 업데이트를 수행하는 “예상된” 결과를 생성하지 않습니다. 이는 두 번째 배열에 대한 두 가지 업데이트를 수행합니다.
썸(thumb)의 좋은 규칙은 모든 변경된 프로퍼티가 다음 프레임에서만 액티브된다는 점입니다.