반응형

3D 월드를 렌더링 파이프라인을 거쳐 우리가 보는 2D화면에 그려준다.

그 과정 중, 포스트 프로세싱에서 빛 효과 / 블러 효과 등 렌더링이 완료된 이미지에 추가적인 효과를 줄 수 있다.

 

포스트 프로세싱은 원래 화면 전체에 동일하게 적용되지만, 게임에서는 특정 오브젝트만 효과를 주고 싶을 때가 있다.

예시로 특정 캐릭터 윤곽선 / 화면에 가려진 메시를 가시화 등 효과를 줄 수 있는 Custom Depth & Stencil 기능이 있다.

 

이 기능을 위해선 포스트 프로세싱 머터리얼과 Custom Depth Stencil Pass 를 사용하면 된다.

 

엔진은 Custom Depth / Stencil 버퍼에

해당 메시의 Depth (얼마나 멀리있는가)와 Stencil(사용자가 임의로 지정한 값)을 픽셀 별로 기록한다.

 

 

 

우선 프로젝스 세팅에서 Enabled with Stencil 로 바꾸어준다.

 

 

포스트 볼륨 박스 하나를 만들어주고 포스트 프로세스 머터리얼을 추가하면되는데 이 머터리얼은 밑에서 기술하겠다.

Unbound 옵션이 해제되어있으면(기본값) 해당 박스 범위안에 카메라가 들어오면 렌더링이 적용되고, 활성화 되어있으면 포스트 볼륨 영역 상관없이 모두 적용이 된다.

카메라가 포스트 프로세스 볼륨 박스 안에 들어갔을때와 밖에 있을 때

 

 

렌더링이 적용될 메시는 따로 활성화를 해주어야 한다.

Render CustomDepth Pass를 활성화해주고, 스텐실 값도 조정할 수 있다.

Render CustomDepth Pass는 실제 화면에 출력되지 않는 텍스쳐에 화면을 렌더링하는것

Stencil 버퍼는 초기화 과정 중 0으로 세팅되므로 0을 제외한 1~255 값을 사용한다.

 

쉽게 메시마다 태그나 레이어를 붙이는 느낌이라고 생각하면 될것같다.

 

 

버퍼시각화 - 커스텀 스텐실에서 설정한 값을 확인할 수 있다.

사용자가 설정한 Stencil 값이 메시에 보여질 것이다.

 

여기까지가 Custom Depth & Stencil Pass 에 대한 설명이고 다음은 실제 예제를 해당 영상 토대로 따라하였다.

https://www.youtube.com/watch?v=453mdZhaC0w&feature=youtu.be

 

 

머터리얼 도메인을 Post Process 로 변경

 

 

SceneTexture 노드 뒤 PostProcessInput0 과 CustomDepth 는 디테일 패널에서 바꿀 수 있다.

PostProcessInput 뒤에 붙는 번호는 포스트 프로세싱 작업 단계마다 현재까지 계산된 화면 결과를 담아두는 버퍼 슬롯을 의미하고 (웬만하면 0만 쓴다 한다.)  CustomDepth는 아까 위에서 얘기했던 메시가 얼마만큼 떨어져있는지에 대한 값 이다.

 

 

커스텀 코드 내용

float3 CurColor=0;
float2 NewUV = UV;
int i=0;
float StepSize = Distance / (int) DistanceSteps;
float CurDistance=0;
float2 CurOffset=0;
float SubOffset = 0;
float TwoPi = 6.283185;
float accumdist=0;

float2 texelSize = View.ViewSizeAndInvSize.zw * Distance;

if (DistanceSteps < 1)
{
  return SceneTextureLookup(ViewportUVToBufferUV(UV), PPI_CustomStencil, false); // 14 == PostProcessInput0
}
else
{
  while (i < (int) DistanceSteps)
  {
    CurDistance += StepSize;
    for (int j = 0; j < (int) RadialSteps; j++)
    {
      SubOffset +=1;
      CurOffset.x = cos(TwoPi*(SubOffset / RadialSteps)) * texelSize.r;
      CurOffset.y = sin(TwoPi*(SubOffset / RadialSteps)) * texelSize.g;
      NewUV.x = UV.x + CurOffset.x * CurDistance;
      NewUV.y = UV.y + CurOffset.y * CurDistance;
      float distpow = pow(CurDistance, KernelPower);
      CurColor += SceneTextureLookup(ViewportUVToBufferUV(NewUV), PPI_CustomStencil, false)*distpow;
      accumdist += distpow;
    }
    SubOffset +=RadialOffset;
    i++;
  }
  CurColor = CurColor;
  CurColor /=accumdist;
  return CurColor;
}

코드가 거의 다 처리하는 것 같은데 커스텀 노드 또한 클릭 후 디테일 패널에 코드 입력과 변수를 추가해준다.

반응형

'언리얼' 카테고리의 다른 글

Deproject 위젯 -> 월드  (1) 2025.11.18
World Widget Depth Test  (0) 2025.09.24
언리얼 오브젝트 참조 관계  (4) 2025.07.30
FAB 플러그인 등록 과정  (1) 2025.04.24
모바일 EnableGestureRecognizer 관련  (0) 2025.01.02

+ Recent posts