[Unity Shader Graph] Custom Triplanar Node For Texture2DArray

얼핏 보면 잘 모르겠지만, 자세히 들여다 보면 절벽 부분에 텍스처가 늘어나 있습니다. 쉐이더에서 월드 스페이스 xz를 UV로 설정했기 때문입니다. Y축은 고려하지 않은 거죠.
이럴 때는 보통 ShaderGraph가 제공하는 Triplanar 노드를 사용하면 됩니다. Triplanar 노드는 월드 좌표를 기반으로 x, y, z 모든 방향으로 텍스처를 투영하기 때문에 위와 같은 현상이 해결됩니다.
그렇지만 제 경우에는 Triplanar 노드를 사용할 수 없었습니다. Triplanar 노드는 Texture2D를 입력으로 받는데, 제가 가지고 있던 건 Texture2DArray였거든요.
그래서 Custom Function을 이용해 Texture2DArray를 입력으로 받는 Triplanar 노드를 만들었습니다. 그 과정에서 ChatGPT나 구글 검색으로 찾아봐도 자료가 잘 나오지 않아서 아래 코드를 공유합니다.

이건 적용 후 모습입니다. 이제 절벽 부분에서도 텍스처가 늘어나지 않습니다.
#ifndef TRIPLANAR_NORMAL_ARRAY_INCLUDED
#define TRIPLANAR_NORMAL_ARRAY_INCLUDED
float4 ArrayTriplanar_float(UnityTexture2DArray texture_array, UnitySamplerState _sampler, float index, float3 position, float3 normal, float tile, float blend, out float4 output)
{
output = float4(0, 0, 0, 1);
float3 pos = position * tile;
float3 weights = max(pow(abs(normal), blend), 0);
weights /= (weights.x + weights.y + weights.z);
float3 nX = SAMPLE_TEXTURE2D_ARRAY(texture_array, _sampler, pos.zy, index);
float3 nY = SAMPLE_TEXTURE2D_ARRAY(texture_array, _sampler, pos.xz, index);
float3 nZ = SAMPLE_TEXTURE2D_ARRAY(texture_array, _sampler, pos.xy, index);
float3 worldX = nX * weights.x;
float3 worldY = nY * weights.y;
float3 worldZ = nZ * weights.z;
float3 col = worldX + worldY + worldZ;
output = float4(col, 1.0);
return output;
}
#endif
쉐이더 코드입니다.

Shader Graph 설정입니다. 다른 연결선은 무시하시고, ArrayTriplanar 노드와 연결된 선만 참고해 주세요.