PostProcess RenderPass

1. Depth Render

PostProcess

2. Fog

기존 FrameBuffer의 Back buffer를 텍스처로 사용하여 해당 텍스처 위에 Quad로 Fog를 그리는 방식으로 구현

원래 화면의 Pixel 색상과 Fog Quad의 색상 값을 interpolation 하도록 한다.

// Backbuffer를 RenderTargetTexture에 복사해 놓는 내용
void FGraphicsDevice::CreateSceneColorResources()
{
    ID3D11Texture2D* backBuffer = nullptr;
    HRESULT hr = SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backBuffer);

    if (FAILED(hr) || backBuffer == nullptr)
        return;

    D3D11_TEXTURE2D_DESC backBufferDesc;
    backBuffer->GetDesc(&backBufferDesc);
	  ...
    hr = Device->CreateShaderResourceView(RenderTargetTexture, &srvDesc, &SceneColorSRV);
    
    DeviceContext->CopyResource(RenderTargetTexture, backBuffer);
    DeviceContext->OMSetRenderTargets(1, &FrameBufferRTV, DepthStencilView);

    backBuffer->Release();
}

복사해놓은 backbuffer texture를 SRV로 만들고 이를 PS에 전달하여 사용

 Graphics->DeviceContext->PSSetShaderResources(5, 1, &Graphics->SceneColorSRV);

PS shader

float4 mainPS(VS_OUT input) : SV_TARGET
{
    // 전달한 백버퍼 텍스처와 DepthTexture를 샘플링
    float4 sceneColor = SceneTexture.Sample(SamplerLinear, input.uv);
    float depth = DepthTexture.Sample(SamplerLinear, input.uv).r;
    
    // Camera로 부터 Depth 정규화 및 Height를 위한 높이값 변환
    float linearDepth = (NearPlane * FarPlane) / (FarPlane - depth * (FarPlane - NearPlane));
    float normalized = saturate((linearDepth - DistanceFogNear) / (DistanceFotFar - DistanceFogNear));
    float3 worldPosition = ReconstructWorldPosition(input.uv, depth);
    
    // 높이 기반 안개 계산 - Exponential way
    float heightDiff = saturate((HeightFogEnd - worldPosition.z) / (HeightFogEnd - HeightFogStart));
    float heightFactor = saturate(1.f - exp(-heightDiff * 3.0f));
    
    // 정규화된 깊이 값을 사용하여 거리 기반 안개 계산 (from debug depth shader)
    float distanceFactor;
    
    // Mode에 따라 Exponent를 사용할 지 정규화된 깊이를 그대로 사용할 지 결정
    if (IsExponential != 0)
    {
        distanceFactor = saturate(1.f - exp(-normalized * 5.0));
    }
    else
    {
        distanceFactor = normalized;
    }
    
    float fogFactor = FogDensity * heightFactor * distanceFactor;
    ...
    float3 baseInscattering = InscatteringColor.rgb;
    float3 fogColor = baseInscattering + directionalInscattering;
    
    // 최종 결정된 Fogfactor를 기반으로 Backbuffer texture와 Fog Color를 interpolation
    return float4(lerp(sceneColor.rgb, fogColor, fogFactor), sceneColor.a);
}

PointLight Render