내배캠 TIL

[ 내배캠 TIL 260403] Unreal RenderTarget 기반 Fog of War 구현

xodn246 2026. 4. 3. 21:21

1. FogManager.cpp (핵심 로직)

안개 시스템의 중심 역할
RenderTarget 초기화 + 유닛 시야를 기반으로 안개를 제거

 
 
#include "Kismet/KismetRenderingLibrary.h"
#include "Kismet/KismetMaterialLibrary.h"

void AFogManager::BeginPlay()
{
    Super::BeginPlay();

    // RenderTarget 초기화 (검정 = 안개 상태)
    if (CurrentFogRT)
        UKismetRenderingLibrary::ClearRenderTarget2D(GetWorld(), CurrentFogRT, FLinearColor::Black);
    
    if (ExploredFogRT)
        UKismetRenderingLibrary::ClearRenderTarget2D(GetWorld(), ExploredFogRT, FLinearColor::Black);

    // MPC에 맵 크기 전달 (머티리얼에서 좌표 계산용)
    UKismetMaterialLibrary::SetVectorParameterValue(
        GetWorld(),
        FogMPC,
        TEXT("MapSize"),
        FLinearColor(MapSize.X, MapSize.Y, 0, 0)
    );
}

void AFogManager::UpdateFog(float DeltaTime)
{
    // 등록된 모든 VisionComponent 순회
    for (UVisionComponent* VisionComp : RegisteredUnits)
    {
        FVector ActorLoc = VisionComp->GetOwner()->GetActorLocation();
        
        // World → UV 변환 (0~1 범위)
        FVector2D UV;
        UV.X = (ActorLoc.X - MapOrigin.X) / MapSize.X;
        UV.Y = (ActorLoc.Y - MapOrigin.Y) / MapSize.Y;

        // 시야 반경 보정
        float FinalRadius = (VisionComp->VisionRadius / MapSize.X) * 2.5f;

        // 머티리얼 파라미터 전달
        DrawMID->SetVectorParameterValue(TEXT("VisionPos"), FLinearColor(UV.X, UV.Y, 0, 0));
        DrawMID->SetScalarParameterValue(TEXT("Radius"), FinalRadius);

        // RenderTarget에 시야 그리기
        UKismetRenderingLibrary::DrawMaterialToRenderTarget(GetWorld(), CurrentFogRT, DrawMID);
    }
}

 

  • RenderTarget은 UV(0~1) 기준으로 동작
  • 월드 좌표 → UV 변환 필수
  • DrawMaterialToRenderTarget으로 시야 누적

2. M_DrawVision (시야 그리기 머티리얼)

RenderTarget에 흰색 원을 그리는 머티리얼

 

설정

  • Domain: Surface (또는 Post Process)
  • Blend Mode: Additive

노드 구조

 

핵심

  • Distance 기반 원 생성
  • Saturate로 값 안정화 (0~1)
  • Power로 경계 부드럽게 처리
  • RGB 동일 값으로 흰색 유지

3. M_FinalFogPostProcess (최종 출력)

게임 화면 위에 Fog를 덮는 포스트 프로세스 머티리얼

설정

  • Domain: Post Process

노드 구조

 

핵심

  • Alpha = Fog 정보
  • 1 → 보임 / 0 → 가림
  • R 채널만 사용해서 마스크 처리

4. VisionComponent.cpp

유닛에 붙여 시야 정보를 제공하는 컴포넌트

 
void UVisionComponent::BeginPlay()
{
    Super::BeginPlay();

    AActor* FoundActor = UGameplayStatics::GetActorOfClass(GetWorld(), AFogManager::StaticClass());
    AFogManager* FogMgr = Cast<AFogManager>(FoundActor);
    
    if (FogMgr)
    {
        FogMgr->RegisterUnit(this);
    }
}
 

핵심

  • BeginPlay에서 FogManager에 자신 등록
  • FogManager가 모든 시야를 중앙에서 관리

정리

  • VisionComponent → 시야 제공
  • FogManager → RenderTarget에 시야 기록
  • PostProcess → 화면에 Fog 적용