/* =========================================================================== Copyright (C) 2023-2024 Gian 'myT' Schellenbaum This file is part of Challenge Quake 3 (CNQ3). Challenge Quake 3 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Challenge Quake 3 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Challenge Quake 3. If not, see . =========================================================================== */ // Cinematic Rendering Pipeline - OIT resolve pass #include "crp_local.h" #include "compshaders/crp/fullscreen.h" #include "compshaders/crp/transp_resolve.h" #include "compshaders/crp/transp_resolve_vol.h" #pragma pack(push, 4) struct TranspResolveRC { float scissorMinX; float scissorMinY; float scissorMaxX; float scissorMaxY; uint32_t renderTargetTexture; uint32_t shaderIndexBuffer; uint32_t indexTexture; uint32_t fragmentBuffer; uint16_t centerPixelX; uint16_t centerPixelY; uint32_t scatterTexture; uint32_t scatterSampler; }; #pragma pack(pop) void TranspResolve::Init() { GraphicsPipelineDesc desc("OIT Resolve"); MakeFullScreenPipeline(desc, ShaderByteCode(g_transp_resolve_ps)); desc.AddRenderTarget(0, crp.renderTargetFormat); noVolPipeline = CreateGraphicsPipeline(desc); desc.pixelShader = ShaderByteCode(g_transp_resolve_vol_ps); volPipeline = CreateGraphicsPipeline(desc); } void TranspResolve::Draw(const drawSceneViewCommand_t& cmd) { if(cmd.numTranspSurfs <= 0 && crp_volLight->integer == 0) { return; } const bool vlEnabled = crp.volumetricLight.ShouldDraw(); HPipeline pipeline = noVolPipeline; if(vlEnabled) { pipeline = volPipeline; } srp.renderMode = RenderMode::World; SCOPED_RENDER_PASS("OIT Resolve", 1.0f, 0.5f, 0.5f); CmdSetViewportAndScissor(0, 0, glConfig.vidWidth, glConfig.vidHeight); crp.SwapRenderTargets(); CmdBeginBarrier(); if(vlEnabled) { CmdTextureBarrier(crp.volumetricLight.scatterTransTexture, ResourceStates::PixelShaderAccessBit); } CmdTextureBarrier(crp.GetReadRenderTarget(), ResourceStates::PixelShaderAccessBit); CmdTextureBarrier(crp.GetWriteRenderTarget(), ResourceStates::RenderTargetBit); CmdTextureBarrier(crp.oitIndexTexture, ResourceStates::UnorderedAccessBit); CmdTextureBarrier(crp.depthTexture, ResourceStates::PixelShaderAccessBit); CmdBufferBarrier(crp.oitFragmentBuffer, ResourceStates::UnorderedAccessBit); CmdBufferBarrier(srp.traceRenderBuffer, ResourceStates::UnorderedAccessBit); CmdEndBarrier(); TranspResolveRC rc = {}; rc.scissorMinX = backEnd.viewParms.viewportX; rc.scissorMinY = backEnd.viewParms.viewportY; rc.scissorMaxX = rc.scissorMinX + backEnd.viewParms.viewportWidth - 1; rc.scissorMaxY = rc.scissorMinY + backEnd.viewParms.viewportHeight - 1; rc.fragmentBuffer = GetBufferIndexUAV(crp.oitFragmentBuffer); rc.indexTexture = GetTextureIndexUAV(crp.oitIndexTexture, 0); rc.renderTargetTexture = GetTextureIndexSRV(crp.GetReadRenderTarget()); rc.shaderIndexBuffer = GetBufferIndexUAV(srp.traceRenderBuffer); rc.centerPixelX = glConfig.vidWidth / 2; rc.centerPixelY = glConfig.vidHeight / 2; if(vlEnabled) { rc.scatterTexture = GetTextureIndexSRV(crp.volumetricLight.scatterTransTexture); } rc.scatterSampler = GetSamplerIndex(TW_CLAMP_TO_EDGE, TextureFilter::Linear); CmdBindRenderTargets(1, &crp.renderTarget, NULL); CmdBindPipeline(pipeline); CmdSetGraphicsRootConstants(0, sizeof(rc), &rc); CmdDraw(3, 0); }