diff --git a/betterRenderer/renderer/include/nvrenderer/nvrenderer.h b/betterRenderer/renderer/include/nvrenderer/nvrenderer.h index 9cded346..2b4cce0f 100644 --- a/betterRenderer/renderer/include/nvrenderer/nvrenderer.h +++ b/betterRenderer/renderer/include/nvrenderer/nvrenderer.h @@ -424,6 +424,7 @@ class NvRenderer : public gfx_renderer, public MaResourceRegistry { float m_opacity; float m_selfillum; glm::vec3 m_diffuse; + std::string_view m_name = ""; }; struct SpotLight { glm::vec3 m_color; @@ -610,16 +611,21 @@ class NvRenderer : public gfx_renderer, public MaResourceRegistry { nvrhi::BufferHandle m_cubedrawconstant_buffer; nvrhi::BufferHandle m_drawconstant_buffer; std::array m_vertex_shader; + std::array m_vertex_shader_prepass; std::array m_vertex_shader_cubemap; std::array m_vertex_shader_shadow; nvrhi::BindingLayoutHandle m_binding_layout_shadow_masked; + nvrhi::BindingLayoutHandle m_binding_layout_prepass; nvrhi::ShaderHandle m_pixel_shader_shadow_masked; + nvrhi::ShaderHandle m_pixel_shader_prepass_masked; std::array - m_input_layout; + m_input_layout; std::array m_pso_shadow; + std::array + m_pso_prepass; nvrhi::GraphicsPipelineHandle m_pso_line; std::condition_variable m_cv_next_frame; diff --git a/betterRenderer/renderer/include/nvrenderer/nvrenderer_enums.h b/betterRenderer/renderer/include/nvrenderer/nvrenderer_enums.h index ac8d6e74..d78d2e67 100644 --- a/betterRenderer/renderer/include/nvrenderer/nvrenderer_enums.h +++ b/betterRenderer/renderer/include/nvrenderer/nvrenderer_enums.h @@ -3,6 +3,7 @@ namespace RendererEnums { enum class RenderPassType { + DepthOnly, Deferred, Forward, CubeMap, diff --git a/betterRenderer/renderer/source/nvmaterial.cpp b/betterRenderer/renderer/source/nvmaterial.cpp index ec611fe0..1abca66c 100644 --- a/betterRenderer/renderer/source/nvmaterial.cpp +++ b/betterRenderer/renderer/source/nvmaterial.cpp @@ -94,6 +94,10 @@ nvrhi::IGraphicsPipeline *NvRenderer::MaterialTemplate::GetPipeline( return m_renderer->m_pso_shadow[Constants::GetDefaultShadowPipelineIndex( draw_type, alpha_masked)]; } + if (pass_type == RenderPassType::DepthOnly) { + return m_renderer->m_pso_prepass[Constants::GetDefaultShadowPipelineIndex( + draw_type, alpha_masked)]; + } return nullptr; } @@ -169,6 +173,14 @@ void NvRenderer::MaterialTemplate::Init(const YAML::Node &conf) { .Add(texture_mapping_shadow) .Add(sampler_mapping_shadow); } + if (pass == RenderPassType::DepthOnly) { + mappings + .Add(MaResourceMapping::ConstantBuffer( + 0, "cb_draw_constants_static")) + .Add(MaResourceMapping::PushConstants(1)) + .Add(texture_mapping_shadow) + .Add(sampler_mapping_shadow); + } continue; } pipeline_desc.setPixelShader(pixel_shader) @@ -181,6 +193,7 @@ void NvRenderer::MaterialTemplate::Init(const YAML::Node &conf) { pipeline_desc.setInputLayout( m_renderer->m_input_layout[static_cast(draw)]); switch (pass) { + case RenderPassType::DepthOnly: case RenderPassType::Deferred: case RenderPassType::Forward: pipeline_desc.setVertexShader( @@ -193,6 +206,7 @@ void NvRenderer::MaterialTemplate::Init(const YAML::Node &conf) { default:; } switch (pass) { + case RenderPassType::DepthOnly: case RenderPassType::Deferred: case RenderPassType::Forward: mappings.Add(MaResourceMapping::PushConstants(1)) @@ -220,12 +234,16 @@ void NvRenderer::MaterialTemplate::Init(const YAML::Node &conf) { .Add(MaResourceMapping::Texture_SRV(11, "shadow_depths")) .Add(MaResourceMapping::Texture_SRV(12, "gbuffer_depth")) .Add(MaResourceMapping::Texture_SRV(14, "sky_aerial_lut")) - .Add(MaResourceMapping::Texture_SRV(16, "forwardplus_index_grid_transparent")) - .Add(MaResourceMapping::StructuredBuffer_SRV(17, "forwardplus_index_buffer_transparent")) - .Add(MaResourceMapping::StructuredBuffer_SRV(18, "forwardplus_light_buffer")) + .Add(MaResourceMapping::Texture_SRV( + 16, "forwardplus_index_grid_transparent")) + .Add(MaResourceMapping::StructuredBuffer_SRV( + 17, "forwardplus_index_buffer_transparent")) + .Add(MaResourceMapping::StructuredBuffer_SRV( + 18, "forwardplus_light_buffer")) .Add(MaResourceMapping::Sampler(8, "sampler_linear_wrap")) .Add(MaResourceMapping::Sampler(11, "shadow_sampler_comp")) - .Add(MaResourceMapping::Sampler(13, "sampler_linear_clamp_v_repeat_h")); + .Add(MaResourceMapping::Sampler( + 13, "sampler_linear_clamp_v_repeat_h")); break; default:; } @@ -243,7 +261,22 @@ void NvRenderer::MaterialTemplate::Init(const YAML::Node &conf) { } switch (pass) { case RenderPassType::Deferred: - case RenderPassType::CubeMap: + pipeline_desc.setRenderState( + nvrhi::RenderState() + .setDepthStencilState( + nvrhi::DepthStencilState() + .enableDepthTest() + .disableStencil() + .setDepthFunc(nvrhi::ComparisonFunc::Equal)) + .setRasterState(nvrhi::RasterState() + .setFillSolid() + .enableDepthClip() + .disableScissor() + .setCullFront()) + .setBlendState(nvrhi::BlendState().setRenderTarget( + 0, nvrhi::BlendState::RenderTarget().disableBlend()))); + break; + case RenderPassType::CubeMap: pipeline_desc.setRenderState( nvrhi::RenderState() .setDepthStencilState( @@ -419,8 +452,14 @@ bool NvRenderer::InitMaterials() { m_vertex_shader[static_cast(DrawType::Model)] = m_backend->CreateShader("default_vertex", nvrhi::ShaderType::Vertex); + m_vertex_shader_prepass[static_cast(DrawType::Model)] = + m_backend->CreateShader("default_prepass_vertex", + nvrhi::ShaderType::Vertex); m_vertex_shader[static_cast(DrawType::InstancedModel)] = m_backend->CreateShader("instanced_vertex", nvrhi::ShaderType::Vertex); + m_vertex_shader_prepass[static_cast(DrawType::InstancedModel)] = + m_backend->CreateShader("instanced_prepass_vertex", + nvrhi::ShaderType::Vertex); m_vertex_shader_shadow[static_cast(DrawType::Model)] = m_backend->CreateShader("shadow_vertex", nvrhi::ShaderType::Vertex); m_vertex_shader_shadow[static_cast(DrawType::InstancedModel)] = @@ -433,6 +472,8 @@ bool NvRenderer::InitMaterials() { nvrhi::ShaderType::Vertex); m_pixel_shader_shadow_masked = m_backend->CreateShader("shadow_masked", nvrhi::ShaderType::Pixel); + m_pixel_shader_prepass_masked = + m_backend->CreateShader("prepass_masked", nvrhi::ShaderType::Pixel); nvrhi::VertexAttributeDesc desc[]{ nvrhi::VertexAttributeDesc() @@ -481,55 +522,82 @@ bool NvRenderer::InitMaterials() { m_vertex_shader[static_cast(DrawType::InstancedModel)]); { - m_binding_layout_shadow_masked = - m_backend->GetDevice()->createBindingLayout( - nvrhi::BindingLayoutDesc() - .setVisibility(nvrhi::ShaderType::Pixel) - .addItem(nvrhi::BindingLayoutItem::Texture_SRV(0)) - .addItem(nvrhi::BindingLayoutItem::Sampler(0))); + auto constexpr render_state_shadow = + nvrhi::RenderState() + .setDepthStencilState( + nvrhi::DepthStencilState() + .enableDepthTest() + .enableDepthWrite() + .disableStencil() + .setDepthFunc(nvrhi::ComparisonFunc::Greater)) + .setRasterState(nvrhi::RasterState() + .setFillSolid() + .disableDepthClip() + .disableScissor() + .setCullBack() + .setDepthBias(1) + .setSlopeScaleDepthBias(-4.f)) + .setBlendState(nvrhi::BlendState().setRenderTarget( + 0, nvrhi::BlendState::RenderTarget().disableBlend())); + auto constexpr render_state_depthonly = + nvrhi::RenderState() + .setDepthStencilState( + nvrhi::DepthStencilState() + .enableDepthTest() + .enableDepthWrite() + .disableStencil() + .setDepthFunc(nvrhi::ComparisonFunc::Greater)) + .setRasterState(nvrhi::RasterState() + .setFillSolid() + .enableDepthClip() + .disableScissor() + .setCullFront()) + .setBlendState(nvrhi::BlendState().setRenderTarget( + 0, nvrhi::BlendState::RenderTarget().disableBlend())); for (int i = 0; i < Constants::NumDrawTypes(); ++i) { for (int j = 0; j < 2; ++j) { DrawType draw = static_cast(i); bool masked = j; - nvrhi::BindingLayoutDesc desc = + nvrhi::BindingLayoutDesc desc_shadow = *m_binding_layout_shadowdrawconstants->getDesc(); - desc.visibility = nvrhi::ShaderType::All; - if (masked) - desc.addItem(nvrhi::BindingLayoutItem::Texture_SRV(0)) - .addItem(nvrhi::BindingLayoutItem::Sampler(0)); - auto binding_layout = - GetBackend()->GetDevice()->createBindingLayout(desc); - auto pipeline_desc = - nvrhi::GraphicsPipelineDesc() - .setRenderState( - nvrhi::RenderState() - .setDepthStencilState( - nvrhi::DepthStencilState() - .enableDepthTest() - .enableDepthWrite() - .disableStencil() - .setDepthFunc(nvrhi::ComparisonFunc::Greater)) - .setRasterState(nvrhi::RasterState() - .setFillSolid() - .disableDepthClip() - .disableScissor() - .setCullBack() - .setDepthBias(1) - .setSlopeScaleDepthBias(-4.f)) - .setBlendState(nvrhi::BlendState().setRenderTarget( - 0, - nvrhi::BlendState::RenderTarget().disableBlend()))) - .setVertexShader( - m_vertex_shader_shadow[static_cast(draw)]) - .setInputLayout(m_input_layout[static_cast(draw)]); + nvrhi::BindingLayoutDesc desc_prepass = + *m_binding_layout_drawconstants->getDesc(); + desc_shadow.visibility = nvrhi::ShaderType::All; + desc_prepass.visibility = nvrhi::ShaderType::All; if (masked) { - pipeline_desc.setPixelShader(m_pixel_shader_shadow_masked); + desc_shadow.addItem(nvrhi::BindingLayoutItem::Texture_SRV(0)) + .addItem(nvrhi::BindingLayoutItem::Sampler(0)); + desc_prepass.addItem(nvrhi::BindingLayoutItem::Texture_SRV(0)) + .addItem(nvrhi::BindingLayoutItem::Sampler(0)); } - pipeline_desc.addBindingLayout(binding_layout); + auto binding_layout_shadow = + GetBackend()->GetDevice()->createBindingLayout(desc_shadow); + auto binding_layout_prepass = + GetBackend()->GetDevice()->createBindingLayout(desc_prepass); + auto pipeline_desc = nvrhi::GraphicsPipelineDesc().setInputLayout( + m_input_layout[static_cast(draw)]); m_pso_shadow[Constants::GetDefaultShadowPipelineIndex(draw, masked)] = GetBackend()->GetDevice()->createGraphicsPipeline( - pipeline_desc, m_gbuffer_shadow->m_framebuffer); + nvrhi::GraphicsPipelineDesc(pipeline_desc) + .setRenderState(render_state_shadow) + .setVertexShader( + m_vertex_shader_shadow[static_cast(draw)]) + .setPixelShader(masked ? m_pixel_shader_shadow_masked + : nullptr) + .addBindingLayout(binding_layout_shadow), + m_gbuffer_shadow->m_framebuffer); + + m_pso_prepass[Constants::GetDefaultShadowPipelineIndex(draw, masked)] = + GetBackend()->GetDevice()->createGraphicsPipeline( + nvrhi::GraphicsPipelineDesc(pipeline_desc) + .setVertexShader( + m_vertex_shader_prepass[static_cast(draw)]) + .setPixelShader(masked ? m_pixel_shader_prepass_masked + : nullptr) + .setRenderState(render_state_depthonly) + .addBindingLayout(binding_layout_prepass), + m_gbuffer->m_framebuffer); } } } diff --git a/betterRenderer/renderer/source/nvrenderer.cpp b/betterRenderer/renderer/source/nvrenderer.cpp index b48eb18a..fa0d6c69 100644 --- a/betterRenderer/renderer/source/nvrenderer.cpp +++ b/betterRenderer/renderer/source/nvrenderer.cpp @@ -413,6 +413,18 @@ bool NvRenderer::Render() { pass.m_history_transform = std::exchange(m_previous_view, pass.m_transform); + command_list->beginMarker("Depth only"); + pass.m_type = RenderPassType::DepthOnly; + RenderKabina(pass); + RenderShapes(pass); + RenderBatches(pass); + RenderTracks(pass); + RenderAnimateds(pass); + RenderLines(pass); + command_list->endMarker(); + + command_list->beginMarker("Gbuffer fill"); + pass.m_type = RenderPassType::Deferred; Timer::subsystem.gfx_color.start(); RenderKabina(pass); RenderShapes(pass); @@ -420,6 +432,7 @@ bool NvRenderer::Render() { RenderTracks(pass); RenderAnimateds(pass); RenderLines(pass); + command_list->endMarker(); GatherSpotLights(pass); @@ -1495,6 +1508,7 @@ void NvRenderer::UpdateDrawData(const RenderPass &pass, pass.m_command_list_draw->setPushConstants(&data, sizeof(data)); break; } + case RenderPassType::DepthOnly: case RenderPassType::Deferred: case RenderPassType::Forward: { PushConstantsDraw data{}; @@ -1967,6 +1981,8 @@ void NvRenderer::Animate(Renderable &renderable, TSubModel *Submodel, m_batched_instances.end()) { auto &item = renderable.m_items.emplace_back(); + item.m_name = Submodel->pName.c_str(); + auto &motion_cache = m_motion_cache->Get(Submodel); motion_cache.m_history_transform = diff --git a/betterRenderer/renderer/source/track_batching.cpp b/betterRenderer/renderer/source/track_batching.cpp index 65317a4f..7c40edba 100644 --- a/betterRenderer/renderer/source/track_batching.cpp +++ b/betterRenderer/renderer/source/track_batching.cpp @@ -959,13 +959,19 @@ void NvRenderer::RenderAnimateds(const RenderPass& pass) { switch (command.m_type) { case RenderCommand::ObjectType_Animated: m_drawcall_counter = &m_drawcalls_tanimobj; + pass.m_command_list_draw->beginMarker( + m_animateds[command.m_index].m_model->name().c_str()); Render(m_animateds[command.m_index].m_renderable, pass, history_origin, m_animateds[command.m_index].m_distance); + pass.m_command_list_draw->endMarker(); break; case RenderCommand::ObjectType_Dynamic: m_drawcall_counter = &m_drawcalls_dynamic; + pass.m_command_list_draw->beginMarker( + m_dynamics[command.m_index].m_dynamic->name().c_str()); Render(m_dynamics[command.m_index].m_renderable, pass, history_origin, m_dynamics[command.m_index].m_distance); + pass.m_command_list_draw->endMarker(); break; } } @@ -989,7 +995,9 @@ void NvRenderer::RenderKabina(const RenderPass& pass) { default: if (!dynamic.m_renderable_kabina.m_render_in_deferred) return; } + pass.m_command_list_draw->beginMarker("Render cab"); Render(dynamic.m_renderable_kabina, pass, history_origin, dynamic.m_distance); + pass.m_command_list_draw->endMarker(); } void NvRenderer::Render(const Renderable& renderable, const RenderPass& pass, @@ -1009,13 +1017,15 @@ void NvRenderer::Render(const Renderable& renderable, const RenderPass& pass, float alpha_threshold; if (!BindGeometry(item.m_geometry, pass, gfx_state, draw_arguments, indexed)) - return; + continue; if (!BindMaterial(item.m_material, DrawType::Model, pass, gfx_state, alpha_threshold)) - return; + continue; BindConstants(pass, gfx_state); + pass.m_command_list_draw->beginMarker(item.m_name.data()); + pass.m_command_list_draw->setGraphicsState(gfx_state); auto transform = item.m_transform; @@ -1034,6 +1044,8 @@ void NvRenderer::Render(const Renderable& renderable, const RenderPass& pass, else pass.m_command_list_draw->draw(draw_arguments); m_drawcall_counter->Draw(draw_arguments); + + pass.m_command_list_draw->endMarker(); } } diff --git a/betterRenderer/shaders/default_vertex.hlsl b/betterRenderer/shaders/default_vertex.hlsl index b7db5b0b..481df309 100644 --- a/betterRenderer/shaders/default_vertex.hlsl +++ b/betterRenderer/shaders/default_vertex.hlsl @@ -7,6 +7,12 @@ struct VertexInput { float4 m_Tangent : Tangent; }; +#ifdef PREPASS +struct VertexOutput { + float2 m_TexCoord : TexCoord; + float4 m_PositionSV : SV_Position; +}; +#else struct VertexOutput { float3 m_Position : Position; float3 m_Normal : Normal; @@ -16,6 +22,7 @@ struct VertexOutput { float4 m_PositionCS : PositionCS; float4 m_HistoryPositionCS : HistoryPositionCS; }; +#endif cbuffer VertexConstants : register(b0) { float4x4 g_JitteredProjection; @@ -29,14 +36,17 @@ VertexOutput main(in VertexInput vs_in) { VertexOutput result; float4x3 model_view = GetModelView(); float4x3 model_view_history = GetModelViewHistory(); - result.m_Position = mul(float4(vs_in.m_Position, 1.), model_view).xyz; - result.m_Normal = mul(float4(vs_in.m_Normal, 0.), model_view).xyz; + float3 view_space_position = mul(float4(vs_in.m_Position, 1.), model_view).xyz; result.m_TexCoord = vs_in.m_TexCoord; + result.m_PositionSV = mul(g_JitteredProjection, float4(view_space_position, 1.)); +#ifndef PREPASS + result.m_Normal = mul(float4(vs_in.m_Normal, 0.), model_view).xyz; + result.m_Position = view_space_position; result.m_Tangent.xyz = mul(float4(vs_in.m_Tangent.xyz, 0.), model_view).xyz; result.m_Tangent.w = vs_in.m_Tangent.w; - result.m_PositionSV = mul(g_JitteredProjection, float4(result.m_Position, 1.)); result.m_PositionCS = mul(g_Projection, float4(result.m_Position, 1.)); float3 history_position = mul(float4(vs_in.m_Position, 1.), model_view_history); result.m_HistoryPositionCS = mul(g_ProjectionHistory, float4(history_position, 1.)); +#endif return result; } diff --git a/betterRenderer/shaders/instanced_vertex.hlsl b/betterRenderer/shaders/instanced_vertex.hlsl index 9b29e67d..01f2aaf1 100644 --- a/betterRenderer/shaders/instanced_vertex.hlsl +++ b/betterRenderer/shaders/instanced_vertex.hlsl @@ -8,6 +8,12 @@ struct VertexInput { float4 m_InstanceTransform[3] : InstanceTransform; }; +#ifdef PREPASS +struct VertexOutput { + float2 m_TexCoord : TexCoord; + float4 m_PositionSV : SV_Position; +}; +#else struct VertexOutput { float3 m_Position : Position; float3 m_Normal : Normal; @@ -17,6 +23,7 @@ struct VertexOutput { float4 m_PositionCS : PositionCS; float4 m_HistoryPositionCS : HistoryPositionCS; }; +#endif cbuffer VertexConstants : register(b0) { float4x4 g_JitteredProjection; @@ -32,14 +39,17 @@ VertexOutput main(in VertexInput vs_in) { float4x3 model_view_history = GetModelViewHistory(); float4x4 instance_transform = transpose(float4x4(vs_in.m_InstanceTransform[0], vs_in.m_InstanceTransform[1], vs_in.m_InstanceTransform[2], float4(0., 0., 0., 1.))); float3 position = mul(float4(vs_in.m_Position, 1.), instance_transform).xyz; - result.m_Position = mul(float4(position, 1.), model_view).xyz; - result.m_Normal = mul(mul(float4(vs_in.m_Normal, 0.), instance_transform), model_view); + float3 view_space_position = mul(float4(position, 1.), model_view).xyz; + result.m_PositionSV = mul(g_JitteredProjection, float4(view_space_position, 1.)); result.m_TexCoord = vs_in.m_TexCoord; +#ifndef PREPASS + result.m_Position = view_space_position; + result.m_Normal = mul(mul(float4(vs_in.m_Normal, 0.), instance_transform), model_view); result.m_Tangent.xyz = mul(mul(float4(vs_in.m_Tangent.xyz, 0.), instance_transform), model_view); result.m_Tangent.w = vs_in.m_Tangent.w; - result.m_PositionSV = mul(g_JitteredProjection, float4(result.m_Position, 1.)); result.m_PositionCS = mul(g_Projection, float4(result.m_Position, 1.)); float3 history_position = mul(float4(position, 1.), model_view_history).xyz; result.m_HistoryPositionCS = mul(g_ProjectionHistory, float4(history_position, 1.)); +#endif return result; } diff --git a/betterRenderer/shaders/manul/alpha_mask.hlsli b/betterRenderer/shaders/manul/alpha_mask.hlsli index f23bc898..f890d7f8 100644 --- a/betterRenderer/shaders/manul/alpha_mask.hlsli +++ b/betterRenderer/shaders/manul/alpha_mask.hlsli @@ -2,7 +2,9 @@ #define ALPHA_MASK_HLSLI void AlphaMask(in float alpha) { +#if (PASS & FORWARD_LIGHTING) || defined (SHADOW) if(g_DrawConstants.m_AlphaThreshold >= 0. ? (alpha < g_DrawConstants.m_AlphaThreshold) : (alpha >= -g_DrawConstants.m_AlphaThreshold)) discard; +#endif } #endif diff --git a/betterRenderer/shaders/project.manul b/betterRenderer/shaders/project.manul index 92f1821d..271919f8 100644 --- a/betterRenderer/shaders/project.manul +++ b/betterRenderer/shaders/project.manul @@ -157,6 +157,12 @@ shaders: source: ps_shadow_masked target: pixel entrypoint: main + prepass_masked: + source: ps_shadow_masked + target: pixel + entrypoint: main + definitions: + PREPASS: 1 # Contact shadows # TODO Depth conversion is broken since converting to reversed depth buffer contact_shadows: @@ -173,6 +179,12 @@ shaders: source: default_vertex target: vertex entrypoint: main + default_prepass_vertex: + source: default_vertex + target: vertex + entrypoint: main + definitions: + PREPASS: 1 shadow_vertex: source: shadow_vertex target: vertex @@ -185,6 +197,12 @@ shaders: source: instanced_vertex target: vertex entrypoint: main + instanced_prepass_vertex: + source: instanced_vertex + target: vertex + entrypoint: main + definitions: + PREPASS: 1 instanced_shadow_vertex: source: instanced_shadow_vertex target: vertex diff --git a/betterRenderer/shaders/ps_shadow_masked.hlsl b/betterRenderer/shaders/ps_shadow_masked.hlsl index eb19eff4..d666507b 100644 --- a/betterRenderer/shaders/ps_shadow_masked.hlsl +++ b/betterRenderer/shaders/ps_shadow_masked.hlsl @@ -3,8 +3,13 @@ sampler diffuse_sampler : register(s0); Texture2D diffuse : register(t0); +#ifdef PREPASS +#include "manul/draw_constants.hlsli" +#else #include "manul/draw_constants_shadow.hlsli" +#endif +#define SHADOW #include "manul/alpha_mask.hlsli" struct VertexOutput {