Unity Shader - 전역 변수의 초기화
(Unity에서만 그런지는 모르겠지만) shader 코드에서 전역 변수 정의 시 초기화 값이 적용이 안 됩니다. shader가 C 언어와 비슷하다고 해서 진짜로 C언어 사용하듯이 다음과 같이 코딩하면,
Shader "My/dummyShader"
{
Properties
{
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
float4 _Color = float4(1.0, 1.0, 1.0, 1.0);
fixed4 frag(v2f i) : SV_Target
{
return _Color;
}
ENDCG
}
}
}
위의 _Color 전역 변수는 (1.0, 1.0, 1.0, 1.0)이 아닌 (0.0, 0.0, 0.0, 0.0)을 가지고 있다는 것에 주의를 해야 합니다. shader에선 Properties를 통한 외부 설정이 가능하도록 매핑을 하지 않는 한 이 코드는 C 언어의 readonly 데이터를 모아놓는 세그먼트 같은 개념이 없기 때문에 초기화 변수로써 대우받지 못합니다.
GLSL - Declaring global variables outside of the main function scope
; https://gamedev.stackexchange.com/questions/61257/glsl-declaring-global-variables-outside-of-the-main-function-scope
물론, 선언은 했기 때문에 그냥 로컬 scope에서 다음과 같이 초기화(?)를 하는 것은 상관없습니다.
float4 _Color;
fixed4 frag(v2f i) : SV_Target
{
_Color = float4(1.0, 1.0, 1.0, 1.0);
return _Color;
}
그런데 저렇게 할 거면 차라리 명시적으로 로컬 변수로 사용하는 것이 더 바람직할 것입니다.
fixed4 frag(v2f i) : SV_Target
{
float4 _Color = float4(1.0, 1.0, 1.0, 1.0);
return _Color;
}
정리하면, shader에서는 전역 변수를 사용하지 말고, 사용하는 경우라면 Properties를 통해 연결해 초기화 값을 주어야 합니다.
Shader "My/dummyShader"
{
Properties
{
_Color("Main Color", Color) = (1.0, 1.0, 1.0, 1.0)
}
SubShader
{
Pass
{
// ...[생략]...
float4 _Color;
// ...[생략]...
}
}
}
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]