
쉐이더는 기본적으로 GPU에서 실행되는 코드이며 캔버스의 각 픽셀의 위치 및 색상을 결정하는 과정이다.
GPU는 기본적으로 씬의 모든 픽셀에 대해 병렬적으로 계산하여 실시간 그래픽 화면을 보여줄 수 있다.
쉐이더를 통해 다양한 시각적 효과와 애니메이션을 제작할 수 있다.
우선 언리얼 엔진에서 Material을 하나 생성하자.

그리고 우클릭을 한 뒤, Custom Node 하나를 생성한다.

생성 시 기본적으로 Float3값을 출력하는 흰색의 Material이 보인다.

사진과 같이 TexCoord 변수를 추가하고 출력 타입을 CMOT Float2로 변경하자.
HLSL 코드를 수정하고 TextureCoordinate 노드를 입력으로 연결하자.
그러면 출력값으로 Texture UV의 색상이 나오는 것을 확인할 수 있다.
언리얼 엔진에서 텍스쳐는 기본적으로 왼쪽 상단을 기준점으로 피벗 되어있다.




(1, 1) 좌표는 녹색과 빨간색이 모두 1의 값을 지니므로 빨강 + 초록 = 노란색으로 표시되는 것을 볼 수 있다.
현재 UV 좌표계의 기준점이 왼쪽 상단에 있으므로 이를 중앙으로 옮겨보자.
float2 tex = TexCoord * 2 - 1;
return float3(tex.x, tex.y, 0.0);

해당 텍스쳐에서 각 UV 좌표의 거리를 나타내보자.
float2 tex = TexCoord * 2 - 1;
float d = length(tex);
return float3(d, d, d);

해당 코드를 통해 UV좌표와 원점 사이의 거리를 나타낼 수 있다.

이제 여기에 Input Parameter로 Radius를 추가하고 값을 0.5로 설정하고 노드에 연결한 뒤, 코드를 다음과 같이 변경하자.
float2 tex = TexCoord * 2 - 1;
float d = length(tex) - Radius;
return float3(d, d, d);
그러면 매우 간단한 원 형태의 SDF를 나타내는 Texture가 나타난다.

SDF는 경계를 기준으로 음과 양의 부호의 값으로 나뉘기에 이를 이용하여 다양한 모양의 거리 함수를 찾거나 직접 만들 수 있다.
현재는 원을 기준으로 외부는 양수이며 내부는 음수인 Texture이다.
이제 해당 HLSL 코드를 다음과 같이 바꿔보자.
float2 tex = TexCoord * 2 - 1;
float d = length(tex);
d -= Radius;
d = abs(d);
return float3(d, d, d);
원 내부의 음수값을 절대값 함수를 적용하면 다음과 같이 링 형태의 Texture가 생기는 것을 볼 수 있다.

경계면을 더욱 뚜렷하게 보이도록 하기 위해 다음 코드를 추가한다.
float2 tex = TexCoord * 2 - 1;
float d = length(tex);
d -= Radius;
d = abs(d);
d = step(0.1, d);
return float3(d, d, d);
그러면 이제 다음과 같이 뚜렷한 Edge Detection이 가능하다.

이제 해당 Texture를 반복해서 나타내보도록 하자.
파동함수의 주기와 진폭을 조절하여 반복되는 Texture를 생성할 수 있다.
float2 tex = TexCoord * 2 - 1;
float d = length(tex);
d -= Radius;
d = sin(d*8)/8; //cos(d*8)/8 가능
d = abs(d);
d = step(0.1, d);
return float3(d, d, d);


노드에 Time이라는 Input Parameter를 추가하고 Time 노드를 추가하자.
그리고 주기 함수 값에 Time을 더해주면 시간에 따라 움직이는 Texture가 생성된다.
float2 tex = TexCoord * 2 - 1;
float d = length(tex);
d -= Radius;
d = sin(d*8 + Time)/8; // Time 값 더함
d = abs(d);
d = step(0.1, d);
return float3(d, d, d);

그 외에도 다양한 수학적 계산을 통해 기하학적인 패턴이나 디자인을 만들 수 있다.
해당 코드는 참고 영상을 통해 만든 최종적인 결과물이다

// 색상 팔레트 정의
float3 b = float3(0.5, 0.5, 0.5); // 색상 진폭 (팔레트의 색 변화 크기)
float3 e = float3(0.263, 0.416, 0.557); // 색상 위상(phase shift), 색 조합을 다양하게 만듦
// uv 좌표를 0 ~ 1 범위로 변환 (중심 기준으로 대칭 좌표계 만들기)
uv = (uv * 2 - 1);
uv.y *= Resolution.x / Resolution.y;
float2 uv0 = uv;
float3 finalcolor = float3(0, 0, 0); // 최종 색상 누적 변수
// 3번 반복 루프 (각 반복에서 패턴을 조금씩 겹쳐 더 풍부한 결과 생성)
for (float i = 0; i < 4; i++) {
uv = frac(uv * 1.5) - 0.5;
// 현재 타일 내에서의 중심까지 거리
float d = length(uv) * exp(-length(uv0));
// 코사인 팔레트로 색상 생성
// a = 기본 색 오프셋, b = 진폭, c = 주파수, e = 위상
// d0 + time*0.4 → 시간에 따라 색상이 변하게 함
float3 col = a + b * cos(6.28318 * (c * (length(uv0) + (i * 0.4) + (time * 0.2)) + e));
// 거리값을 파동으로 변형
d = sin(d * 8 + time) / 8; // 사인파 변형
d = abs(d); // 음수 방지 (밝기용)
d = pow(0.01 / d, 1.2); // 거리 기반 가중치 (가까울수록 더 강하게)
// 최종 색상에 누적 (빛이 겹쳐지는 효과)
finalcolor += col * d;
}
// 최종 결과 출력 (알파=1)
return float4(finalcolor, 1);
추가적으로 HLSL 코드로 만들어진 Material은 블루프린트 노드로도 똑같이 구현이 가능하다.