기본 Bloom Texture에 접근할 수 없는 문제

1. 문제


2. 시도


나는 Bloom을 재현해서 내 커스텀 포스트 프로세스 패스에 추가하기로 결정하였음.

2.1. 기본 Bloom 분석


일단 Bloom을 분석하기 위해 RenderDoc을 사용함
4. Archive/Unreal Lab/__Attachments/Pasted image 20251016225919.png

프레임을 분석해 보면 Bloom은 3단계로 렌더링 할 수 있음

  1. BloomSetup 단계에서 Half-size SceneColor를 가공
  2. BloomSetup 텍스처를 다운 샘플링.(1/4 ~ 1/64)
  3. 다운샘플링된 텍스처에 GaussianBlur를 하여 Bloom 텍스처 렌더링

소스코드 분석은 PostProcessing.cpp 파일의 1261줄부터 BloomSetup이 시작된다. (5.5.4 버전)

if (bFFTBloomEnabled)
{
	[...]
}
else
{
	[...]
			// Line 1261, 1. Bloom Setup
			DownsampleInput = FScreenPassTextureSlice::CreateFromScreenPassTexture(GraphBuilder, AddBloomSetupPass(GraphBuilder, View, SetupPassInputs));
		}

		const bool bLogLumaInAlpha = false;
		// 2. 다운 샘플링
		BloomDownsampleChain.Init(GraphBuilder, View, EyeAdaptationParameters, DownsampleInput, DownsampleChainQuality, bLogLumaInAlpha);

		LensFlareSceneDownsampleChain = &BloomDownsampleChain;
	}
	// 3. Bloom 렌더링
	Bloom = AddGaussianBloomPasses(GraphBuilder, View, LensFlareSceneDownsampleChain);
}

이 부분부터 시작해 함수를 추적하며

2.2. 구현


TyTSceneViewExtension.cpp


[...]
// Line 257
if (bBloom)
{
	HalfSceneColor = AddTyTDownSamplePass(
		GraphBuilder,
		ViewInfo,
		TEXT("Half Res Scene Color"),
		SceneColorTexture.Texture,
		Viewport
	);

	FTyTBloomDownSampleChain BloomDownSampleChain;
	BloomDownSampleChain.Init(
		GraphBuilder,
		ViewInfo,
		AddTyTBloomSetupPass(GraphBuilder, ViewInfo, HalfSceneColor, HalfResViewport),
		HalfResViewport
	);

	Bloom = AddTyTGaussianBloomPass(GraphBuilder, ViewInfo, BloomDownSampleChain);
}
[...]

TyTPostProcessBloom.cpp

[...]
FRDGTextureRef AddTyTBloomSetupPass(
    FRDGBuilder& GraphBuilder,
    const FViewInfo& ViewInfo,
    FRDGTextureRef HalfResSceneColor,
    const FIntRect& HalfResViewport
)
{
    // Unreal Insights
    RDG_GPU_STAT_SCOPE(GraphBuilder, TyTBloomSetup);
    // Render Doc
    RDG_EVENT_SCOPE(GraphBuilder, "TyTBloomSetup");

    const FTyTBloomSettings* Settings = UTyTPostProcessSettingsAsset::GetBloomSettings();
    float Threshold = Settings ? Settings->Threshold : -1;
    const bool bThresholdEnabled = Threshold > -1;

    FRDGTextureDesc TextureDesc;
    TextureDesc.Reset();
    TextureDesc.Extent = HalfResViewport.Size();
    TextureDesc.Format = EPixelFormat::PF_FloatRGB;
    TextureDesc.ClearValue = FClearValueBinding::Black;
    FRDGTextureRef OutTexture = GraphBuilder.CreateTexture(TextureDesc, TEXT("TyTBloomSetup"));
	
    FTyTBloomSetupPS::FParameters* Parameters = GraphBuilder.AllocParameters<FTyTBloomSetupPS::FParameters>();
    Parameters->ViewUniformShaderParameters = ViewInfo.ViewUniformBuffer;
    Parameters->InputTexture = HalfResSceneColor;
    Parameters->InputSampler = TStaticSamplerState<SF_Bilinear>::GetRHI();
    Parameters->BloomThreshold = Threshold;
    Parameters->RenderTargets[0] = FRenderTargetBinding(OutTexture, ERenderTargetLoadAction::ELoad);

    FTyTBloomSetupPS::FPermutationDomain PermutationVector;
    PermutationVector.Set<FTyTBloomSetupPS::FThresholdDim>(bThresholdEnabled);

    TShaderMapRef<FTyTScreenPassVS> VS(ViewInfo.ShaderMap);
    TShaderMapRef<FTyTBloomSetupPS> PS(ViewInfo.ShaderMap, PermutationVector);

    AddTyTScreenPass(
        GraphBuilder,
        TEXT("TyTBloomSetup(1/2)"),
        Parameters,
        VS,
        PS,
        TStaticBlendState<>::GetRHI(),
        HalfResViewport
    );

	return OutTexture;
}
[...]

2.3. 기존 Bloom 비활성화


가장 초기 상태에서, PostProcessVolume이 레벨에 존재하지 않더라도 Bloom은 기본적으로 적용되어 있다. 따라서 PostProcessVolume을 추가하여 수동으로 꺼주어야 한다.
4. Archive/Unreal Lab/__Attachments/Pasted image 20251016232021.png
Bloom 효과를 제거한 모습이다.

3. 결과


기본 블룸
4. Archive/Unreal Lab/__Attachments/Pasted image 20251016231909.png

커스텀 블룸
4. Archive/Unreal Lab/__Attachments/Pasted image 20251016232132.png