Files
maszyna/betterRenderer/renderer/source/gbufferblitpass.cpp
2025-12-22 21:43:52 +01:00

282 lines
13 KiB
C++

#include "gbufferblitpass.h"
#include <chrono>
#include <Timer.h>
#include <nvrhi/utils.h>
#include "contactshadows.h"
#include "csm.h"
#include "environment.h"
#include "gbuffer.h"
#include "nvrendererbackend.h"
#include "sky.h"
#include "ssao.h"
GbufferBlitPass::GbufferBlitPass(NvRenderer* renderer, NvGbuffer* gbuffer,
NvGbuffer* gbuffer_shadow, NvSsao* ssao,
MaEnvironment* environment,
MaShadowMap* shadow_map,
MaContactShadows* contact_shadows, Sky* sky)
: FullScreenPass(renderer->GetBackend()),
MaResourceRegistry(renderer),
m_gbuffer(gbuffer),
m_gbuffer_shadow(gbuffer_shadow),
m_ssao(ssao),
m_environment(environment),
m_shadow_map(shadow_map),
m_contact_shadows(contact_shadows),
m_sky(sky) {}
void GbufferBlitPass::Init() {
InitResourceRegistry();
m_draw_constants = m_backend->GetDevice()->createBuffer(
nvrhi::utils::CreateVolatileConstantBufferDesc(
sizeof(DrawConstants), "GBuffer Lighting Constants", 16)
.setInitialState(nvrhi::ResourceStates::ConstantBuffer)
.setKeepInitialState(true));
RegisterResource(true, "gbuffer_lighting_constants", m_draw_constants,
nvrhi::ResourceType::VolatileConstantBuffer);
const nvrhi::SamplerHandle sampler_shadow_comp =
m_backend->GetDevice()->createSampler(
nvrhi::SamplerDesc()
.setReductionType(nvrhi::SamplerReductionType::Comparison)
.setComparisonFunc(nvrhi::ComparisonFunc::Greater)
.setAllAddressModes(nvrhi::SamplerAddressMode::ClampToEdge)
.setAllFilters(true));
const nvrhi::SamplerHandle sampler_linear =
m_backend->GetDevice()->createSampler(
nvrhi::SamplerDesc().setAllFilters(true));
const nvrhi::SamplerHandle sampler_linear_clamp =
m_backend->GetDevice()->createSampler(
nvrhi::SamplerDesc()
.setAllAddressModes(nvrhi::SamplerAddressMode::ClampToEdge)
.setAllFilters(true));
const nvrhi::SamplerHandle sampler_linear_clamp_v_repeat_h =
m_backend->GetDevice()->createSampler(
nvrhi::SamplerDesc()
.setAllAddressModes(nvrhi::SamplerAddressMode::ClampToEdge)
.setAddressU(nvrhi::SamplerAddressMode::Repeat)
.setAllFilters(true));
RegisterResource(true, "shadow_sampler_comp", sampler_shadow_comp,
nvrhi::ResourceType::Sampler);
RegisterResource(true, "sampler_linear_wrap", sampler_linear,
nvrhi::ResourceType::Sampler);
RegisterResource(true, "sampler_linear_clamp", sampler_linear_clamp,
nvrhi::ResourceType::Sampler);
RegisterResource(true, "sampler_linear_clamp_v_repeat_h", sampler_linear_clamp_v_repeat_h,
nvrhi::ResourceType::Sampler);
m_scene_depth = m_backend->GetDevice()->createTexture(
nvrhi::TextureDesc(m_gbuffer->m_gbuffer_depth->getDesc())
.setFormat(nvrhi::Format::R32_FLOAT)
.setDebugName("Scene Depth")
.setInitialState(nvrhi::ResourceStates::ShaderResource)
.setUseClearValue(false)
.setIsRenderTarget(false));
RegisterResource(true, "gbuffer_depth", m_scene_depth,
nvrhi::ResourceType::Texture_SRV);
m_output = m_backend->GetDevice()->createTexture(
nvrhi::TextureDesc()
.setWidth(m_gbuffer->m_framebuffer->getFramebufferInfo().width)
.setHeight(m_gbuffer->m_framebuffer->getFramebufferInfo().height)
.setFormat(nvrhi::Format::RGBA16_FLOAT)
.setIsUAV(true)
.setIsRenderTarget(true)
.setInitialState(nvrhi::ResourceStates::ShaderResource)
.setKeepInitialState(true));
RegisterResource(true, "scene_lit_texture", m_output,
nvrhi::ResourceType::Texture_SRV);
m_output_copy = m_backend->GetDevice()->createTexture(
nvrhi::TextureDesc()
.setWidth(m_gbuffer->m_framebuffer->getFramebufferInfo().width)
.setHeight(m_gbuffer->m_framebuffer->getFramebufferInfo().height)
.setFormat(nvrhi::Format::RGBA16_FLOAT)
.setInitialState(nvrhi::ResourceStates::ShaderResource)
.setKeepInitialState(true));
RegisterResource(true, "scene_lit_texture_copy", m_output_copy,
nvrhi::ResourceType::Texture_SRV);
m_binding_layout = m_backend->GetDevice()->createBindingLayout(
nvrhi::BindingLayoutDesc()
.addItem(nvrhi::BindingLayoutItem::VolatileConstantBuffer(2))
.addItem(nvrhi::BindingLayoutItem::ConstantBuffer(11))
.addItem(nvrhi::BindingLayoutItem::Texture_SRV(0))
.addItem(nvrhi::BindingLayoutItem::Texture_SRV(1))
.addItem(nvrhi::BindingLayoutItem::Texture_SRV(2))
.addItem(nvrhi::BindingLayoutItem::Texture_SRV(3))
.addItem(nvrhi::BindingLayoutItem::Texture_SRV(4))
.addItem(nvrhi::BindingLayoutItem::Texture_SRV(5))
.addItem(nvrhi::BindingLayoutItem::Texture_SRV(8))
.addItem(nvrhi::BindingLayoutItem::Texture_SRV(9))
.addItem(nvrhi::BindingLayoutItem::Texture_SRV(10))
.addItem(nvrhi::BindingLayoutItem::Texture_SRV(11))
.addItem(nvrhi::BindingLayoutItem::Texture_SRV(12))
.addItem(nvrhi::BindingLayoutItem::Texture_SRV(14))
.addItem(nvrhi::BindingLayoutItem::Texture_SRV(15))
.addItem(nvrhi::BindingLayoutItem::Texture_SRV(16))
.addItem(nvrhi::BindingLayoutItem::StructuredBuffer_SRV(17))
.addItem(nvrhi::BindingLayoutItem::StructuredBuffer_SRV(18))
.addItem(nvrhi::BindingLayoutItem::Sampler(8))
.addItem(nvrhi::BindingLayoutItem::Sampler(11))
.addItem(nvrhi::BindingLayoutItem::Sampler(13))
.addItem(nvrhi::BindingLayoutItem::Texture_UAV(0))
.setVisibility(nvrhi::ShaderType::Compute));
for (int i = 0; i < std::size(m_binding_set); ++i) {
m_binding_set[i] = m_backend->GetDevice()->createBindingSet(
nvrhi::BindingSetDesc()
.addItem(nvrhi::BindingSetItem::ConstantBuffer(2, m_draw_constants))
.addItem(nvrhi::BindingSetItem::ConstantBuffer(
11, m_shadow_map->m_projection_buffer))
.addItem(nvrhi::BindingSetItem::Texture_SRV(
0, m_gbuffer->m_gbuffer_diffuse))
.addItem(nvrhi::BindingSetItem::Texture_SRV(
1, m_gbuffer->m_gbuffer_emission))
.addItem(nvrhi::BindingSetItem::Texture_SRV(
2, m_gbuffer->m_gbuffer_params))
.addItem(nvrhi::BindingSetItem::Texture_SRV(
3, m_gbuffer->m_gbuffer_normal))
.addItem(nvrhi::BindingSetItem::Texture_SRV(
4, m_gbuffer->m_gbuffer_depth))
.addItem(nvrhi::BindingSetItem::Texture_SRV(5, m_ssao->m_outputAO))
.addItem(nvrhi::BindingSetItem::Texture_SRV(
8, m_environment->m_dynamic_envmap_diffuse[0]))
.addItem(nvrhi::BindingSetItem::Texture_SRV(
9, m_environment->m_dynamic_envmap_specular[0]))
.addItem(nvrhi::BindingSetItem::Texture_SRV(
10, m_environment->m_brdf_lut))
.addItem(nvrhi::BindingSetItem::Texture_SRV(
11, m_gbuffer_shadow->m_gbuffer_depth))
.addItem(nvrhi::BindingSetItem::Texture_SRV(
12, m_contact_shadows->m_output_texture))
.addItem(nvrhi::BindingSetItem::Texture_SRV(
14, m_sky->m_aerial_lut->m_lut))
.addItem(nvrhi::BindingSetItem::Texture_SRV(
15, m_environment->m_clouds_texture))
.addItem(nvrhi::BindingSetItem::Texture_SRV(
16, static_cast<nvrhi::ITexture*>(
GetResource("forwardplus_index_grid_opaque", nvrhi::ResourceType::Texture_SRV)
.m_resource)))
.addItem(nvrhi::BindingSetItem::StructuredBuffer_SRV(
17, static_cast<nvrhi::IBuffer*>(
GetResource("forwardplus_index_buffer_opaque", nvrhi::ResourceType::StructuredBuffer_SRV)
.m_resource)))
.addItem(nvrhi::BindingSetItem::StructuredBuffer_SRV(
18, static_cast<nvrhi::IBuffer*>(
GetResource("forwardplus_light_buffer", nvrhi::ResourceType::StructuredBuffer_SRV)
.m_resource)))
.addItem(nvrhi::BindingSetItem::Sampler(8, sampler_linear))
.addItem(nvrhi::BindingSetItem::Sampler(11, sampler_shadow_comp))
.addItem(nvrhi::BindingSetItem::Sampler(13, sampler_linear_clamp_v_repeat_h))
.addItem(nvrhi::BindingSetItem::Texture_UAV(0, m_output)),
m_binding_layout);
}
m_pixel_shader =
m_backend->CreateShader("gbuffer_lighting", nvrhi::ShaderType::Compute);
m_pso = m_backend->GetDevice()->createComputePipeline(
nvrhi::ComputePipelineDesc()
.setComputeShader(m_pixel_shader)
.addBindingLayout(m_binding_layout));
// m_framebuffer = m_backend->GetDevice()->createFramebuffer(
// nvrhi::FramebufferDesc().addColorAttachment(m_output));
// FullScreenPass::Init();
}
void GbufferBlitPass::CreatePipelineDesc(
nvrhi::GraphicsPipelineDesc& pipeline_desc) {
FullScreenPass::CreatePipelineDesc(pipeline_desc);
pipeline_desc.addBindingLayout(m_binding_layout);
pipeline_desc.setPixelShader(m_pixel_shader);
}
void GbufferBlitPass::UpdateConstants(nvrhi::ICommandList* command_list,
glm::dmat4& view,
const glm::dmat4& projection) {
DrawConstants constants{};
constants.m_inverse_model_view = glm::inverse(glm::dmat4(glm::dmat3(view)));
constants.m_inverse_projection = glm::inverse(projection);
const auto& daylight = Global.DayLight;
m_sky->CalcLighting(constants.m_light_dir, constants.m_light_color);
constants.m_altitude = Global.pCamera.Pos.y;
constants.m_time = Timer::GetTime();
constants.m_vertical_fov =
glm::radians(Global.FieldOfView / Global.ZoomFactor);
{
float percipitation_intensity = glm::saturate(Global.Overcast - 1.);
constants.m_rain_params.x =
percipitation_intensity; // % amount of droplets
constants.m_rain_params.y =
glm::mix(15., 1., percipitation_intensity); // Regeneration time
static glm::vec4 wiper_timer_out;
static glm::vec4 wiper_timer_return;
if (TDynamicObject const* owner = Global.pCamera.m_owner;
owner && !!owner->MoverParameters->CabActive) {
for (int i = 0; i < 4; ++i) {
if (i < owner->dWiperPos.size()) {
int index = owner->MoverParameters->CabActive > 0
? i
: static_cast<int>(owner->dWiperPos.size() - 1) - i;
constants.m_wiper_pos[i] = owner->dWiperPos[index];
if (owner->dWiperPos[index] > 0. && owner->wiperDirection[index]) {
constants.m_wiper_pos[i] += 1.;
}
if (owner->dWiperPos[index] < .025) {
wiper_timer_out[i] = constants.m_time;
}
if (owner->dWiperPos[index] > .975) {
wiper_timer_return[i] = constants.m_time;
}
constants.m_wiper_timer_out[i] = wiper_timer_out[i];
constants.m_wiper_timer_return[i] = wiper_timer_return[i];
} else {
constants.m_wiper_pos[i] = 0.;
wiper_timer_out[i] = constants.m_wiper_timer_out[i] = -1000.;
wiper_timer_return[i] = constants.m_wiper_timer_return[i] = -1000.;
}
}
} else {
constants.m_wiper_pos = glm::vec4{0.};
wiper_timer_out = constants.m_wiper_timer_out = glm::vec4{-1000.};
wiper_timer_return = constants.m_wiper_timer_return = glm::vec4{-1000.};
}
}
command_list->writeBuffer(m_draw_constants, &constants, sizeof(constants));
}
void GbufferBlitPass::UpdateSceneColorForRefraction(
nvrhi::ICommandList* command_list) const {
command_list->copyTexture(
m_output_copy, nvrhi::TextureSlice().resolve(m_output_copy->getDesc()),
m_output, nvrhi::TextureSlice().resolve(m_output->getDesc()));
command_list->setTextureState(m_output, nvrhi::AllSubresources,
nvrhi::ResourceStates::RenderTarget);
command_list->commitBarriers();
}
void GbufferBlitPass::Render(nvrhi::ICommandList* command_list,
glm::dmat4& view, const glm::dmat4& projection) {
UpdateConstants(command_list, view, projection);
Render(command_list);
command_list->copyTexture(
m_scene_depth, nvrhi::TextureSlice().resolve(m_scene_depth->getDesc()),
m_gbuffer->m_gbuffer_depth,
nvrhi::TextureSlice().resolve(m_scene_depth->getDesc()));
}
void GbufferBlitPass::Render(nvrhi::ICommandList* command_list) {
nvrhi::ComputeState graphics_state;
auto desc = m_output->getDesc();
// InitState(graphics_state);
graphics_state.setPipeline(m_pso);
graphics_state.addBindingSet(
m_binding_set[m_environment->GetCurrentSetIndex()]);
command_list->setComputeState(graphics_state);
#define DISPATCH_SIZE(size, groupsize) ((size + groupsize - 1) / groupsize)
command_list->dispatch(DISPATCH_SIZE(desc.width, 8),
DISPATCH_SIZE(desc.height, 8), 1);
// Draw(command_list);
}
nvrhi::IFramebuffer* GbufferBlitPass::GetFramebuffer() { return m_framebuffer; }