흠 뭐 전문가분들에게는 어그로 제목이고.. 막 초보자를 벗은 분들에게는 도움이 될 겁니다. ㅋㅋ
셰이더를 좀 익숙하게 쓰시다 보면 슬슬 이런저런 한계에 부딪히게 되는데요, 뭐 인터폴레이터 제한이라던가.. 샘플러 제한 같은거 말이죠.
만약 실무를 뛰시고 모바일 게임을 만드시고 계신다면, 하드웨어에 대해서도 슬슬 신경을 써 줘야 합니다.
보통은 뭐 초보에서 막 셰이더에 익숙해지면 즐겁게 막막 쓰게 되지요. 막 쓰게 되면 즐겁거든
그러다가 자주 마주하는 것 중 하나에 대한 이야기
텍스쳐 16장 넘게 사용하는 이야기
일단 셰이더 그래프에서 텍스쳐 하나를 받고요
이 텍스쳐 오브젝트를 이케 sampler Texture2D 에 연결해서 출력하면 ..
그리고 뭔가 텍스쳐를 미리 넣어 놓으면 이렇게 잘 뜹니다. 뭐 재밌죠.
그래서 재밌어서 16장을 막 섞고 난리를 쳤다고 칩시다. 와 노드 끔찍해.
그리고 16개가 지나고 17개가 넘어가면서 ..
에러 메세지가 뜨고 메인 프리뷰도 에러 이미지가 나옵니다.!!!
에러 메세지는
Shader error in 'Master': maximum ps_5_0 sampler register index (16) exceeded at line 1081 (on metal)
저는 지금 맥이라 metal 이지만 PC 라면 마지막은 DX11 , 안드로이드라면 Vulkan 이라고 나오겠지요
흐으으음 픽셀셰이더 5.0 에서는 샘플러를 16개까지 사용 가능하다고 합니다.
이 부분에 대한 메뉴얼을 찾아보면 https://docs.unity3d.com/kr/2019.4/Manual/SL-SamplerStates.html 여기입니다.
URP 가 아닌 레거시 설명으로 되어 있어요.
하여간, "Direct3D 11은 한 셰이더에 최대 128개의 텍스처와 16개의 샘플러를 지원합니다. " 라고 씌여 있어요.
보아하니 이건 뭐 벌칸이나 메탈도 마찬가지인듯 싶고..
여하간 텍스쳐는 128장까지 쓸 수 있지만, 샘플러는 16개 제한이라고 합니다. 그래서 포기하고 에러가 나온 것.
옛날 레거시때 셰이더 쓰셨던 분들은 기억하실지 모르겠지만,
tex2D(_MainTex,uv) 로 셰이더를 짜셨을 때에는 텍스쳐 오브젝트와 샘플러의 분리가 안되었었기 때문에 16장 이상 쓰려면 위의 링크대로 샘플러를 분리하여 사용하실 수 있었습니다.
그럼 셰이더 그래프에서는 어떻게 사용할까요?
셰이더 그래프에서 Sampler State(샘플러 상태) 공유하기
셰이더 그래프에서는 Sampler State 노드를 만들어서 샘플러를 공유하도록 해주면 됩니다. 한번 만들어 볼까요 ?
샘플러 상태(Sampler State)가 뭐더라? 하셨던 분들도 이걸 보면 아실 수 있을 겁니다. 텍스쳐의 필터링 옵션과 Wrap 옵션이예요.
왜 텍스쳐에 보면
여기에 Wrap Mode 와 Filter Mode 가 있잖아요.
일반적으로는 텍스쳐에서 이렇게 제어해 왔습니다만, 샘플러를 따로 만들어서 제어하면 여기와 상관없이 독립적으로 제어할 수 있게 됩니다.
보통 저걸 뭐 텍스쳐마다 막 다르게 쓰진 않잖아요? 특별한 경우에나 쓰지. 그러니까 공유해서 샘플러의 갯수를 줄일 수 있다면 좋을 것 같습니다.
큰 차이는 없지만, 저렇게 Property로 승격시켜서 한 번에 제어하는 것도 좋아요. 공유해서 계속 꺼내쓸 수 있으니까요. 마치 프리팹처럼.
이 옵션같은 경우는 프로퍼티에 올라간다고 인스펙터에 보이진 않습니다. 걍 프로퍼티에 있다.. 뭐 그거 뿐예요
요렇게 프로퍼티에 넣고 매번 쑉 쑉 뽑아서 각 텍스쳐에 연결해주면, 여러 텍스쳐 오브젝트들이 같은 샘플러를 공유하면서 샘플러의 사용 숫자가 줄어듭니다. 또한 샘플링과 Wrap 모드도 위에 보이듯, 여기서 한 번에 제어해 줄 수 있으니 더 좋네요!!
딸랑 세 개만 공유해서 썼는데도, 샘플러 사용량이 16개 이하로 떨어지니까 에러없이 잘 출력되는 모습을 볼 수 있습니다.
어차피 모든 텍스쳐의 샘플링 상태가 똑같다면, 저 하나로 모두를 다 써주면 더 좋겠지요?
이 기세를 몰아 128개까지 써 보아요 (가능은 하지만..텍스쳐 어레이를 써 그럴바엔..)
코딩에서 Sampler State(샘플러 상태) 공유하기
코드에서 사용하는 방법도 매우 쉬운데요. 저는 이게 더 쉬운듯. (노드 뜨개질 싫어...)
일단 간단하게 텍스쳐 한 장 출력하는 코드를 만들어 보았습니다.
hader "Example/URPUnlitShaderBasic"
{
Properties
{
_Tex1("tex1", 2D) = "white"{}
}
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
TEXTURE2D(_Tex1);
SAMPLER(sampler_Tex1);
CBUFFER_START(UnityPerMaterial)
float4 _Tex1_ST;
CBUFFER_END
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
OUT.uv = TRANSFORM_TEX(IN.uv, _Tex1);
return OUT;
}
half4 frag(Varyings IN) : SV_Target
{
half4 Color = SAMPLE_TEXTURE2D(_Tex1, sampler_Tex1, IN.uv);
return Color;
}
ENDHLSL
}
}
}
보시면 레거시때와 문법이 좀 바뀐걸 보실 수 있으실 텐데요, dx11 hlsl에서 사용하는 방법으로 바뀌었습니다.
옛날처럼 tex2D(_MainTex,uv) 식으로 텍스쳐 오브젝트와 uv만 넣어주면 자동으로 샘플러가 들어가던때와 다르게
TEXTURE2D(_Tex1);
SAMPLER(sampler_Tex1);
지금은 아예 텍스쳐 오브젝트와 샘플러를 따로 선언해 주고
half4 Color = SAMPLE_TEXTURE2D(_Tex1, sampler_Tex1, IN.uv);
SAMPLE_TEXTURE2D함수로 (텍스쳐 오브젝트, 샘플러, UV) 를 넣어주는 방식으로 바뀐 것을 볼 수 있습니다.
이러면 뭐 간단하죠. 샘플러 오브젝트가 나와 있으므로 말이죠.
일단 아까랑 동일한 에러 메세지를 만들어 주어 봅시다 17장을... 무식하게 받아서... 블렌딩해 주죠
Shader "Example/URPUnlitShaderBasic"
{
Properties
{
_Tex1("tex1", 2D) = "white"{}
_Tex2("tex2", 2D) = "white"{}
_Tex3("tex3", 2D) = "white"{}
_Tex4("tex4", 2D) = "white"{}
_Tex5("tex5", 2D) = "white"{}
_Tex6("tex6", 2D) = "white"{}
_Tex7("tex7", 2D) = "white"{}
_Tex8("tex8", 2D) = "white"{}
_Tex9("tex9", 2D) = "white"{}
_Tex10("tex10", 2D) = "white"{}
_Tex11("tex11", 2D) = "white"{}
_Tex12("tex12", 2D) = "white"{}
_Tex13("tex13", 2D) = "white"{}
_Tex14("tex14", 2D) = "white"{}
_Tex15("tex15", 2D) = "white"{}
_Tex16("tex16", 2D) = "white"{}
_Tex17("tex17", 2D) = "white"{}
}
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
TEXTURE2D(_Tex1);
TEXTURE2D(_Tex2);
TEXTURE2D(_Tex3);
TEXTURE2D(_Tex4);
TEXTURE2D(_Tex5);
TEXTURE2D(_Tex6);
TEXTURE2D(_Tex7);
TEXTURE2D(_Tex8);
TEXTURE2D(_Tex9);
TEXTURE2D(_Tex10);
TEXTURE2D(_Tex11);
TEXTURE2D(_Tex12);
TEXTURE2D(_Tex13);
TEXTURE2D(_Tex14);
TEXTURE2D(_Tex15);
TEXTURE2D(_Tex16);
TEXTURE2D(_Tex17);
SAMPLER(sampler_Tex1);
SAMPLER(sampler_Tex2);
SAMPLER(sampler_Tex3);
SAMPLER(sampler_Tex4);
SAMPLER(sampler_Tex5);
SAMPLER(sampler_Tex6);
SAMPLER(sampler_Tex7);
SAMPLER(sampler_Tex8);
SAMPLER(sampler_Tex9);
SAMPLER(sampler_Tex10);
SAMPLER(sampler_Tex11);
SAMPLER(sampler_Tex12);
SAMPLER(sampler_Tex13);
SAMPLER(sampler_Tex14);
SAMPLER(sampler_Tex15);
SAMPLER(sampler_Tex16);
SAMPLER(sampler_Tex17);
CBUFFER_START(UnityPerMaterial)
float4 _Tex1_ST;
float4 _Tex2_ST;
float4 _Tex3_ST;
float4 _Tex4_ST;
float4 _Tex5_ST;
float4 _Tex6_ST;
float4 _Tex7_ST;
float4 _Tex8_ST;
float4 _Tex9_ST;
float4 _Tex10_ST;
float4 _Tex11_ST;
float4 _Tex12_ST;
float4 _Tex13_ST;
float4 _Tex14_ST;
float4 _Tex15_ST;
float4 _Tex16_ST;
float4 _Tex17_ST;
CBUFFER_END
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
// OUT.uv = TRANSFORM_TEX(IN.uv, _Tex1); //이번엔 이건 제외
OUT.uv = IN.uv;
return OUT;
}
half4 frag(Varyings IN) : SV_Target
{
half4 Color = half4 (0,0,0,0);
Color += SAMPLE_TEXTURE2D(_Tex1, sampler_Tex1, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex2, sampler_Tex2, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex3, sampler_Tex3, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex4, sampler_Tex4, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex5, sampler_Tex5, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex6, sampler_Tex6, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex7, sampler_Tex7, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex8, sampler_Tex8, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex9, sampler_Tex9, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex10, sampler_Tex10, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex11, sampler_Tex11, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex12, sampler_Tex12, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex13, sampler_Tex13, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex14, sampler_Tex14, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex15, sampler_Tex15, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex16, sampler_Tex16, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex17, sampler_Tex17, IN.uv);
return Color/17;
}
ENDHLSL
}
}
}
와 무식합니다만 노드보단 마음이 편안하네요 . 역시 코드다.
이렇게 샘플러가 17개가 되니까.
오우야 역시 실망시키지 않고 에러가 떴습니다.
그럼 샘플러를 줄이면 되겠지요?
젤 무식한 방법은,
Color += SAMPLE_TEXTURE2D(_Tex1, sampler_Tex1, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex2, sampler_Tex2, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex3, sampler_Tex3, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex4, sampler_Tex4, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex5, sampler_Tex5, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex6, sampler_Tex6, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex7, sampler_Tex7, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex8, sampler_Tex8, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex9, sampler_Tex9, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex10, sampler_Tex10, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex11, sampler_Tex11, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex12, sampler_Tex12, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex13, sampler_Tex13, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex14, sampler_Tex14, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex15, sampler_Tex15, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex16, sampler_Tex16, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex17, sampler_Tex17, IN.uv);
여기의 sampler 들을 모두 sampler_Tex1 으로 바꿔주는 방법일 겁니다. 무식하고 간편한 해결법. 그럼 첫 번째 텍스쳐의 샘플러를 모두 따라가는 것이지요.
sampler state
그렇지만 저런 무식한 방법 말고도 이런 방법도 있습니다.
노드에서 프로퍼티에 샘플러를 넣어 놓았듯이, 샘플러 선언 대신 샘플러 상태를 선언해 두는 겁니다.
TEXTURE2D(_Tex1);
TEXTURE2D(_Tex2);
TEXTURE2D(_Tex3);
TEXTURE2D(_Tex4);
TEXTURE2D(_Tex5);
TEXTURE2D(_Tex6);
TEXTURE2D(_Tex7);
TEXTURE2D(_Tex8);
TEXTURE2D(_Tex9);
TEXTURE2D(_Tex10);
TEXTURE2D(_Tex11);
TEXTURE2D(_Tex12);
TEXTURE2D(_Tex13);
TEXTURE2D(_Tex14);
TEXTURE2D(_Tex15);
TEXTURE2D(_Tex16);
TEXTURE2D(_Tex17);
// SAMPLER(sampler_Tex1);
// SAMPLER(sampler_Tex2);
// SAMPLER(sampler_Tex3);
// SAMPLER(sampler_Tex4);
// SAMPLER(sampler_Tex5);
// SAMPLER(sampler_Tex6);
// SAMPLER(sampler_Tex7);
// SAMPLER(sampler_Tex8);
// SAMPLER(sampler_Tex9);
// SAMPLER(sampler_Tex10);
// SAMPLER(sampler_Tex11);
// SAMPLER(sampler_Tex12);
// SAMPLER(sampler_Tex13);
// SAMPLER(sampler_Tex14);
// SAMPLER(sampler_Tex15);
// SAMPLER(sampler_Tex16);
// SAMPLER(sampler_Tex17);
SamplerState Test_linear_repeat_sampler;
이렇게
SamplerState Test_linear_repeat_sampler;
샘플러 상태 오브젝트를 샘플러 대신 규칙에 맞게 선언해 두면, 이 샘플러를 사용할 수 있습니다.
즉 픽셀셰이더를 이렇게 쓰면 되는거죠
half4 frag(Varyings IN) : SV_Target
{
half4 Color = half4 (0,0,0,0);
Color += SAMPLE_TEXTURE2D(_Tex1, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex2, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex3, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex4, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex5, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex6, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex7, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex8, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex9, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex10, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex11, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex12, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex13, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex14, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex15, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex16, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex17, Test_linear_repeat_sampler, IN.uv);
return Color/17;
}
그럼 에러메세지도 없고, 이미지가 잘 나오게 됩니다.
요령이 더 있는데, 샘플러 블럭을 필요에 따라 몇 종류 조합으로 만들어 놓고 사용하면 더 좋습니다.
SamplerState Test_linear_repeat_sampler;
SamplerState Test_point_clamp_sampler;
SamplerState Test_point_ClampU_RepeatV_sampler;
SamplerState Test_trilinear_mirror_sampler;
SamplerState Test_point_mirrorOnce_sampler;
대충 요런 식으로 말이죠.
샘플링에 익숙하시지 않으신 분은 흠... 어디서 설명하지.. 다음에 설명해야 겠네요 이건. 만들어 놓은 강의자료는 있는데 블로그엔 없는(것 같아)
일단 메뉴얼이라도 던져 드리자면, 레거시이지만 저거랑 같으니까 이걸로 보셔도 샘플링 조합을 보시기는 무리 없습니다.
https://docs.unity3d.com/kr/2019.4/Manual/SL-SamplerStates.html
자 이렇게 되면 샘플링을 절약해서 텍스쳐를 16장 초과해서 사용하게 하는 법을 알아 보았습니다.
풀 코드는 아래와 같습니당
Shader "Example/URPUnlitShaderBasic"
{
Properties
{
_Tex1("tex1", 2D) = "white"{}
_Tex2("tex2", 2D) = "white"{}
_Tex3("tex3", 2D) = "white"{}
_Tex4("tex4", 2D) = "white"{}
_Tex5("tex5", 2D) = "white"{}
_Tex6("tex6", 2D) = "white"{}
_Tex7("tex7", 2D) = "white"{}
_Tex8("tex8", 2D) = "white"{}
_Tex9("tex9", 2D) = "white"{}
_Tex10("tex10", 2D) = "white"{}
_Tex11("tex11", 2D) = "white"{}
_Tex12("tex12", 2D) = "white"{}
_Tex13("tex13", 2D) = "white"{}
_Tex14("tex14", 2D) = "white"{}
_Tex15("tex15", 2D) = "white"{}
_Tex16("tex16", 2D) = "white"{}
_Tex17("tex17", 2D) = "white"{}
}
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
TEXTURE2D(_Tex1);
TEXTURE2D(_Tex2);
TEXTURE2D(_Tex3);
TEXTURE2D(_Tex4);
TEXTURE2D(_Tex5);
TEXTURE2D(_Tex6);
TEXTURE2D(_Tex7);
TEXTURE2D(_Tex8);
TEXTURE2D(_Tex9);
TEXTURE2D(_Tex10);
TEXTURE2D(_Tex11);
TEXTURE2D(_Tex12);
TEXTURE2D(_Tex13);
TEXTURE2D(_Tex14);
TEXTURE2D(_Tex15);
TEXTURE2D(_Tex16);
TEXTURE2D(_Tex17);
// SAMPLER(sampler_Tex1);
// SAMPLER(sampler_Tex2);
// SAMPLER(sampler_Tex3);
// SAMPLER(sampler_Tex4);
// SAMPLER(sampler_Tex5);
// SAMPLER(sampler_Tex6);
// SAMPLER(sampler_Tex7);
// SAMPLER(sampler_Tex8);
// SAMPLER(sampler_Tex9);
// SAMPLER(sampler_Tex10);
// SAMPLER(sampler_Tex11);
// SAMPLER(sampler_Tex12);
// SAMPLER(sampler_Tex13);
// SAMPLER(sampler_Tex14);
// SAMPLER(sampler_Tex15);
// SAMPLER(sampler_Tex16);
// SAMPLER(sampler_Tex17);
//샘플러 상태들을 여기다가 미리 선언해 놓고 초콜렛처럼 꺼내먹어요
SamplerState Test_linear_repeat_sampler;
SamplerState Test_point_clamp_sampler;
SamplerState Test_point_ClampU_RepeatV_sampler;
SamplerState Test_trilinear_mirror_sampler;
SamplerState Test_point_mirrorOnce_sampler;
CBUFFER_START(UnityPerMaterial)
float4 _Tex1_ST;
float4 _Tex2_ST;
float4 _Tex3_ST;
float4 _Tex4_ST;
float4 _Tex5_ST;
float4 _Tex6_ST;
float4 _Tex7_ST;
float4 _Tex8_ST;
float4 _Tex9_ST;
float4 _Tex10_ST;
float4 _Tex11_ST;
float4 _Tex12_ST;
float4 _Tex13_ST;
float4 _Tex14_ST;
float4 _Tex15_ST;
float4 _Tex16_ST;
float4 _Tex17_ST;
CBUFFER_END
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
// OUT.uv = TRANSFORM_TEX(IN.uv, _Tex1); //이번엔 이건 제외
OUT.uv = IN.uv;
return OUT;
}
half4 frag(Varyings IN) : SV_Target
{
half4 Color = half4 (0,0,0,0);
Color += SAMPLE_TEXTURE2D(_Tex1, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex2, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex3, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex4, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex5, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex6, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex7, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex8, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex9, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex10, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex11, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex12, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex13, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex14, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex15, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex16, Test_linear_repeat_sampler, IN.uv);
Color += SAMPLE_TEXTURE2D(_Tex17, Test_linear_repeat_sampler, IN.uv);
return Color/17;
}
ENDHLSL
}
}
}
블로그 주인장에게 커피값을 후원할 수 있습니다!
'Shader ' 카테고리의 다른 글
노말맵 블렌딩 (0) | 2022.03.06 |
---|---|
Unity Vertex Shader / Fragment Shader 의 설정 함수 (0) | 2021.08.10 |
유니티 셰이더 버전별 인터폴레이터 / 각 타겟별 성능 (0) | 2021.08.03 |
서피스 셰이더에서 버텍스 셰이더 인풋값 초기화 (0) | 2021.07.07 |
커스텀 셰이더 GUI 만들기 : 잠깐 정리 (0) | 2021.05.14 |
댓글