cnq3/code/renderer/crp_transp_resolve.cpp
myT 30150e889e added sunlight and volumetric lighting
fixed depth linearization
2024-03-29 04:19:38 +01:00

116 lines
3.8 KiB
C++

/*
===========================================================================
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 <https://www.gnu.org/licenses/>.
===========================================================================
*/
// 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);
}