mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
679 lines
31 KiB
C++
679 lines
31 KiB
C++
#include "nvmaterial.h"
|
|
#include "nvrenderer/nvrenderer.h"
|
|
|
|
#include <fmt/format.h>
|
|
#include <nvrhi/utils.h>
|
|
|
|
#include "utilities/Logs.h"
|
|
#include "csm.h"
|
|
#include "environment.h"
|
|
#include "gbuffer.h"
|
|
#include "gbufferblitpass.h"
|
|
#include "nvrendererbackend.h"
|
|
#include "nvtexture.h"
|
|
#include "sky.h"
|
|
|
|
bool NvRenderer::MaterialTemplate::CreateBindingSet(size_t pipeline_index,
|
|
MaterialCache &cache) {
|
|
// for (size_t i = 0; i < cache.m_pipelines.size(); ++i) {
|
|
auto pipeline = cache.m_pipelines[pipeline_index];
|
|
if (!pipeline) return false;
|
|
|
|
nvrhi::BindingSetDesc binding_set_desc{};
|
|
|
|
auto binding_layout = pipeline->getDesc().bindingLayouts[0];
|
|
|
|
if (!m_resource_mappings[pipeline_index].ToBindingSet(
|
|
binding_set_desc, &cache, binding_layout->getDesc()))
|
|
return false;
|
|
|
|
cache.m_binding_sets[pipeline_index] =
|
|
m_renderer->GetBackend()->GetDevice()->createBindingSet(binding_set_desc,
|
|
binding_layout);
|
|
//}
|
|
// nvrhi::BindingSetDesc binding_set_desc = nvrhi::BindingSetDesc();
|
|
// nvrhi::BindingSetDesc binding_set_desc_cube = nvrhi::BindingSetDesc();
|
|
// nvrhi::BindingSetDesc binding_set_desc_shadow = nvrhi::BindingSetDesc();
|
|
// nvrhi::static_vector<nvrhi::SamplerHandle, 8 + 1> samplers{};
|
|
// for (int i = 0; i < m_texture_bindings.size(); ++i) {
|
|
// const auto &binding = m_texture_bindings[i];
|
|
// if (binding.m_name.empty()) continue;
|
|
// auto texture = m_renderer->m_texture_manager->GetRhiTexture(
|
|
// cache.m_textures[i], pass.m_command_list_preparation);
|
|
// if (!texture) {
|
|
// texture = m_renderer->m_texture_manager->GetRhiTexture(
|
|
// 1, pass.m_command_list_preparation);
|
|
// }
|
|
// auto &sampler = samplers.emplace_back();
|
|
// auto &sampler_cubemap = samplers.emplace_back();
|
|
// sampler = m_renderer->m_texture_manager->GetSamplerForTraits(
|
|
// m_renderer->m_texture_manager->GetTraits(cache.m_textures[i]),
|
|
// RenderPassType::Deferred);
|
|
// sampler_cubemap = m_renderer->m_texture_manager->GetSamplerForTraits(
|
|
// m_renderer->m_texture_manager->GetTraits(cache.m_textures[i]),
|
|
// RenderPassType::CubeMap);
|
|
// binding_set_desc.addItem(nvrhi::BindingSetItem::Texture_SRV(i, texture));
|
|
// binding_set_desc.addItem(nvrhi::BindingSetItem::Sampler(i, sampler));
|
|
// binding_set_desc_cube.addItem(
|
|
// nvrhi::BindingSetItem::Texture_SRV(i, texture));
|
|
// binding_set_desc_cube.addItem(
|
|
// nvrhi::BindingSetItem::Sampler(i, sampler_cubemap));
|
|
// if (cache.m_masked_shadow && i == m_masked_shadow_texture) {
|
|
// auto &shadow_sampler = samplers.emplace_back();
|
|
// shadow_sampler = m_renderer->m_texture_manager->GetSamplerForTraits(
|
|
// m_renderer->m_texture_manager->GetTraits(cache.m_textures[i]),
|
|
// RenderPassType::ShadowMap);
|
|
// binding_set_desc_shadow.addItem(
|
|
// nvrhi::BindingSetItem::Texture_SRV(0, texture));
|
|
// binding_set_desc_shadow.addItem(
|
|
// nvrhi::BindingSetItem::Sampler(0, shadow_sampler));
|
|
// }
|
|
// }
|
|
// cache.m_binding_set =
|
|
// m_renderer->GetBackend()->GetDevice()->createBindingSet(
|
|
// binding_set_desc, m_binding_layout);
|
|
// cache.m_binding_set_cubemap =
|
|
// m_renderer->GetBackend()->GetDevice()->createBindingSet(
|
|
// binding_set_desc_cube, m_binding_layout);
|
|
// if (cache.m_masked_shadow) {
|
|
// cache.m_binding_set_shadow =
|
|
// m_renderer->GetBackend()->GetDevice()->createBindingSet(
|
|
// binding_set_desc_shadow,
|
|
// m_renderer->m_binding_layout_shadow_masked);
|
|
// }
|
|
cache.m_last_texture_updates[pipeline_index] = NvTexture::s_change_counter;
|
|
return true;
|
|
}
|
|
|
|
nvrhi::IGraphicsPipeline *NvRenderer::MaterialTemplate::GetPipeline(
|
|
RenderPassType pass_type, DrawType draw_type, bool alpha_masked) const {
|
|
if (auto pipeline =
|
|
m_pipelines[Constants::GetPipelineIndex(pass_type, draw_type)])
|
|
return pipeline;
|
|
if (pass_type == RenderPassType::ShadowMap) {
|
|
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;
|
|
}
|
|
|
|
void NvRenderer::MaterialTemplate::Init(const YAML::Node &conf) {
|
|
InitResourceRegistry();
|
|
std::vector<MaResourceMapping> texture_mappings{};
|
|
std::vector<MaResourceMapping> sampler_mappings{};
|
|
MaResourceMapping texture_mapping_shadow{};
|
|
MaResourceMapping sampler_mapping_shadow{};
|
|
m_pipelines.fill(nullptr);
|
|
m_masked_shadow_texture = conf["masked_shadow_texture"].as<std::string>();
|
|
m_enable_refraction = conf["refraction"].as<bool>(false);
|
|
for (const auto it : conf["textures"]) {
|
|
auto index = it.second["binding"].as<int>();
|
|
m_texture_bindings.resize(
|
|
glm::max(m_texture_bindings.size(), static_cast<size_t>(index) + 1));
|
|
auto &binding = m_texture_bindings[index];
|
|
|
|
binding.m_name = it.first.as<std::string>();
|
|
binding.m_sampler_name = fmt::format("{:s}_sampler", binding.m_name.c_str());
|
|
|
|
binding.disable_anisotropy = it.second["no_anisotropy"].as<bool>(false);
|
|
binding.disable_filter = it.second["no_filter"].as<bool>(false);
|
|
binding.disable_mip_bias = it.second["no_mip_bias"].as<bool>(false);
|
|
size_t default_texture = m_renderer->GetTextureManager()->FetchTexture(
|
|
it.second["default"].as<std::string>(""), binding.m_hint, 0, false);
|
|
if (!default_texture) {
|
|
default_texture = 1;
|
|
}
|
|
|
|
texture_mappings.emplace_back(
|
|
MaResourceMapping::Texture_SRV(index, binding.m_name.c_str()));
|
|
sampler_mappings.emplace_back(
|
|
MaResourceMapping::Sampler(index, binding.m_sampler_name.c_str()));
|
|
|
|
RegisterTexture(binding.m_name.c_str(), default_texture);
|
|
RegisterResource(
|
|
false, "masked_shadow_sampler",
|
|
GetTextureManager()->GetSamplerForTraits(0, RenderPassType::ShadowMap),
|
|
nvrhi::ResourceType::Sampler);
|
|
|
|
const static std::unordered_map<std::string_view, int> hints{
|
|
{"color", GL_SRGB_ALPHA}, {"linear", GL_RGBA}, {"normalmap", GL_RG}};
|
|
binding.m_hint = hints.at(it.second["hint"].as<std::string_view>());
|
|
|
|
if (it.first.Scalar() == conf["masked_shadow_texture"].Scalar()) {
|
|
texture_mapping_shadow = MaResourceMapping::Texture_SRV(0, binding.m_name.c_str());
|
|
sampler_mapping_shadow =
|
|
MaResourceMapping::Sampler(0, "masked_shadow_sampler");
|
|
}
|
|
}
|
|
std::array<nvrhi::ShaderHandle, static_cast<size_t>(RenderPassType::Num)>
|
|
pixel_shaders;
|
|
for (int i = 0; i < pixel_shaders.size(); ++i) {
|
|
pixel_shaders[i] = m_renderer->GetBackend()->CreateMaterialShader(
|
|
m_name, static_cast<RenderPassType>(i));
|
|
}
|
|
|
|
{
|
|
nvrhi::BindingLayoutDesc binding_layout_desc;
|
|
binding_layout_desc.setVisibility(nvrhi::ShaderType::Pixel);
|
|
for (int i = 0; i < m_texture_bindings.size(); ++i) {
|
|
if (m_texture_bindings[i].m_name.empty()) continue;
|
|
binding_layout_desc.addItem(nvrhi::BindingLayoutItem::Texture_SRV(i))
|
|
.addItem(nvrhi::BindingLayoutItem::Sampler(i));
|
|
}
|
|
m_binding_layout =
|
|
m_renderer->GetBackend()->GetDevice()->createBindingLayout(
|
|
binding_layout_desc);
|
|
}
|
|
for (size_t i = 0; i < Constants::NumMaterialPasses(); ++i) {
|
|
auto pass = static_cast<RenderPassType>(i);
|
|
for (size_t j = 0; j < Constants::NumDrawTypes(); ++j) {
|
|
auto draw = static_cast<DrawType>(j);
|
|
auto &mappings =
|
|
m_resource_mappings[Constants::GetPipelineIndex(pass, draw)];
|
|
nvrhi::GraphicsPipelineDesc pipeline_desc{};
|
|
auto pixel_shader = pixel_shaders[static_cast<size_t>(pass)];
|
|
if (!pixel_shader) {
|
|
if (pass == RenderPassType::ShadowMap) {
|
|
mappings.Add(MaResourceMapping::PushConstants<PushConstantsShadow>(1))
|
|
.Add(texture_mapping_shadow)
|
|
.Add(sampler_mapping_shadow);
|
|
}
|
|
if (pass == RenderPassType::DepthOnly) {
|
|
mappings
|
|
.Add(MaResourceMapping::ConstantBuffer(
|
|
0, "cb_draw_constants_static"))
|
|
.Add(MaResourceMapping::PushConstants<PushConstantsDraw>(1))
|
|
.Add(texture_mapping_shadow)
|
|
.Add(sampler_mapping_shadow);
|
|
}
|
|
continue;
|
|
}
|
|
pipeline_desc.setPixelShader(pixel_shader)
|
|
.setPrimType(nvrhi::PrimitiveType::TriangleList);
|
|
|
|
for (const auto &mapping : texture_mappings) mappings.Add(mapping);
|
|
for (const auto &mapping : sampler_mappings) mappings.Add(mapping);
|
|
|
|
nvrhi::IFramebuffer *framebuffer;
|
|
pipeline_desc.setInputLayout(
|
|
m_renderer->m_input_layout[static_cast<size_t>(draw)]);
|
|
switch (pass) {
|
|
case RenderPassType::DepthOnly:
|
|
case RenderPassType::Deferred:
|
|
case RenderPassType::Forward:
|
|
pipeline_desc.setVertexShader(
|
|
m_renderer->m_vertex_shader[static_cast<size_t>(draw)]);
|
|
break;
|
|
case RenderPassType::CubeMap:
|
|
pipeline_desc.setVertexShader(
|
|
m_renderer->m_vertex_shader_cubemap[static_cast<size_t>(draw)]);
|
|
break;
|
|
default:;
|
|
}
|
|
switch (pass) {
|
|
case RenderPassType::DepthOnly:
|
|
case RenderPassType::Deferred:
|
|
case RenderPassType::Forward:
|
|
mappings.Add(MaResourceMapping::PushConstants<PushConstantsDraw>(1))
|
|
.Add(MaResourceMapping::ConstantBuffer(
|
|
0, "cb_draw_constants_static"));
|
|
break;
|
|
case RenderPassType::CubeMap:
|
|
mappings
|
|
.Add(MaResourceMapping::PushConstants<PushConstantsCubemap>(1))
|
|
.Add(MaResourceMapping::ConstantBuffer(
|
|
0, "cb_draw_constants_static_cubemap"));
|
|
break;
|
|
default:;
|
|
}
|
|
switch (pass) {
|
|
case RenderPassType::Forward:
|
|
mappings
|
|
.Add(MaResourceMapping::VolatileConstantBuffer(
|
|
2, "gbuffer_lighting_constants"))
|
|
.Add(MaResourceMapping::ConstantBuffer(
|
|
11, "shadow_projection_buffer"))
|
|
.Add(MaResourceMapping::Texture_SRV(8, "env_dynamic_diffuse"))
|
|
.Add(MaResourceMapping::Texture_SRV(9, "env_dynamic_specular"))
|
|
.Add(MaResourceMapping::Texture_SRV(10, "env_brdf_lut"))
|
|
.Add(MaResourceMapping::Texture_SRV(11, "shadow_depths"))
|
|
.Add(MaResourceMapping::Texture_SRV(12, "gbuffer_depth"))
|
|
.Add(MaResourceMapping::Texture_SRV(13, "scene_lit_texture_copy"))
|
|
.Add(MaResourceMapping::Texture_SRV(14, "sky_aerial_lut"))
|
|
.Add(MaResourceMapping::Texture_SRV(15, "sky_clouds"))
|
|
.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"));
|
|
break;
|
|
default:;
|
|
}
|
|
switch (pass) {
|
|
case RenderPassType::Deferred:
|
|
framebuffer = m_renderer->m_gbuffer->m_framebuffer;
|
|
break;
|
|
case RenderPassType::Forward:
|
|
framebuffer = m_renderer->m_framebuffer_forward;
|
|
break;
|
|
case RenderPassType::CubeMap:
|
|
framebuffer = m_renderer->m_gbuffer_cube->m_framebuffer;
|
|
break;
|
|
default:;
|
|
}
|
|
switch (pass) {
|
|
case RenderPassType::Deferred:
|
|
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(
|
|
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())));
|
|
break;
|
|
case RenderPassType::Forward: {
|
|
auto render_state =
|
|
nvrhi::RenderState()
|
|
.setDepthStencilState(
|
|
nvrhi::DepthStencilState()
|
|
.enableDepthTest()
|
|
.disableDepthWrite()
|
|
.disableStencil()
|
|
.setDepthFunc(nvrhi::ComparisonFunc::Greater))
|
|
.setRasterState(nvrhi::RasterState()
|
|
.setFillSolid()
|
|
.enableDepthClip()
|
|
.disableScissor()
|
|
.setCullFront());
|
|
if (m_enable_refraction) {
|
|
render_state.setBlendState(nvrhi::BlendState().setRenderTarget(
|
|
0, nvrhi::BlendState::RenderTarget().disableBlend()));
|
|
} else {
|
|
render_state.setBlendState(
|
|
nvrhi::BlendState()
|
|
.setRenderTarget(
|
|
0,
|
|
nvrhi::BlendState::RenderTarget()
|
|
.enableBlend()
|
|
.setBlendOp(nvrhi::BlendOp::Add)
|
|
.setSrcBlend(nvrhi::BlendFactor::One)
|
|
.setDestBlend(nvrhi::BlendFactor::OneMinusSrcAlpha))
|
|
.setRenderTarget(
|
|
1, nvrhi::BlendState::RenderTarget().disableBlend()));
|
|
}
|
|
pipeline_desc.setRenderState(render_state);
|
|
} break;
|
|
default:;
|
|
}
|
|
|
|
nvrhi::BindingLayoutDesc bl_desc{};
|
|
bl_desc.visibility = nvrhi::ShaderType::All;
|
|
// for (const auto &bl : pipeline_desc.bindingLayouts) {
|
|
// bl_desc.visibility = bl_desc.visibility | bl->getDesc()->visibility;
|
|
// for (const auto &element : bl->getDesc()->bindings) {
|
|
// bl_desc.addItem(element);
|
|
// }
|
|
// }
|
|
|
|
mappings.ToBindingLayout(bl_desc);
|
|
|
|
pipeline_desc.bindingLayouts.resize(0);
|
|
pipeline_desc.addBindingLayout(
|
|
m_renderer->GetBackend()->GetDevice()->createBindingLayout(bl_desc));
|
|
|
|
m_pipelines[Constants::GetPipelineIndex(pass, draw)] =
|
|
m_renderer->GetBackend()->GetDevice()->createGraphicsPipeline(
|
|
pipeline_desc, framebuffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool NvRenderer::InitMaterials() {
|
|
m_drawconstant_buffer = m_backend->GetDevice()->createBuffer(
|
|
nvrhi::utils::CreateStaticConstantBufferDesc(sizeof(DrawConstants),
|
|
"Draw Constants")
|
|
.setInitialState(nvrhi::ResourceStates::ConstantBuffer)
|
|
.setKeepInitialState(true));
|
|
m_cubedrawconstant_buffer = m_backend->GetDevice()->createBuffer(
|
|
nvrhi::utils::CreateStaticConstantBufferDesc(sizeof(CubeDrawConstants),
|
|
"Draw Data")
|
|
.setInitialState(nvrhi::ResourceStates::ConstantBuffer)
|
|
.setKeepInitialState(true));
|
|
|
|
RegisterResource(true, "cb_draw_constants_static", m_drawconstant_buffer,
|
|
nvrhi::ResourceType::ConstantBuffer);
|
|
RegisterResource(true, "cb_draw_constants_static_cubemap",
|
|
m_cubedrawconstant_buffer,
|
|
nvrhi::ResourceType::ConstantBuffer);
|
|
|
|
{
|
|
nvrhi::CommandListHandle command_list =
|
|
GetBackend()->GetDevice()->createCommandList();
|
|
command_list->open();
|
|
CubeDrawConstants data;
|
|
data.m_face_projection = glm::perspectiveFovRH_ZO(
|
|
M_PI_2, 1., 1., .1,
|
|
static_cast<double>(Global.reflectiontune.range_instances));
|
|
command_list->writeBuffer(m_cubedrawconstant_buffer, &data, sizeof(data));
|
|
command_list->close();
|
|
GetBackend()->GetDevice()->executeCommandList(command_list);
|
|
}
|
|
|
|
nvrhi::utils::CreateBindingSetAndLayout(
|
|
m_backend->GetDevice(), nvrhi::ShaderType::AllGraphics, 0,
|
|
nvrhi::BindingSetDesc()
|
|
.addItem(
|
|
nvrhi::BindingSetItem::ConstantBuffer(0, m_drawconstant_buffer))
|
|
.addItem(nvrhi::BindingSetItem::PushConstants(
|
|
1, sizeof(PushConstantsDraw))),
|
|
m_binding_layout_drawconstants, m_binding_set_drawconstants);
|
|
nvrhi::utils::CreateBindingSetAndLayout(
|
|
m_backend->GetDevice(), nvrhi::ShaderType::AllGraphics, 0,
|
|
nvrhi::BindingSetDesc()
|
|
.addItem(nvrhi::BindingSetItem::ConstantBuffer(
|
|
0, m_cubedrawconstant_buffer))
|
|
.addItem(nvrhi::BindingSetItem::PushConstants(
|
|
1, sizeof(PushConstantsCubemap))),
|
|
m_binding_layout_cubedrawconstants, m_binding_set_cubedrawconstants);
|
|
nvrhi::utils::CreateBindingSetAndLayout(
|
|
m_backend->GetDevice(), nvrhi::ShaderType::AllGraphics, 0,
|
|
nvrhi::BindingSetDesc().addItem(
|
|
nvrhi::BindingSetItem::PushConstants(1, sizeof(PushConstantsShadow))),
|
|
m_binding_layout_shadowdrawconstants, m_binding_set_shadowdrawconstants);
|
|
m_binding_layout_forward = GetBackend()->GetDevice()->createBindingLayout(
|
|
nvrhi::BindingLayoutDesc()
|
|
.setVisibility(nvrhi::ShaderType::Pixel)
|
|
.addItem(nvrhi::BindingLayoutItem::VolatileConstantBuffer(2))
|
|
.addItem(nvrhi::BindingLayoutItem::ConstantBuffer(11))
|
|
.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::Sampler(8))
|
|
.addItem(nvrhi::BindingLayoutItem::Sampler(11))
|
|
.addItem(nvrhi::BindingLayoutItem::Sampler(13)));
|
|
for (int i = 0; i < m_binding_set_forward.size(); ++i) {
|
|
m_binding_set_forward[i] = m_backend->GetDevice()->createBindingSet(
|
|
nvrhi::BindingSetDesc()
|
|
.addItem(nvrhi::BindingSetItem::ConstantBuffer(
|
|
2, m_gbuffer_blit->m_draw_constants))
|
|
.addItem(nvrhi::BindingSetItem::ConstantBuffer(
|
|
11, m_shadow_map->m_projection_buffer))
|
|
.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_gbuffer->m_gbuffer_depth))
|
|
.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::Sampler(
|
|
8, m_backend->GetDevice()->createSampler(
|
|
nvrhi::SamplerDesc().setAllFilters(true))))
|
|
.addItem(nvrhi::BindingSetItem::Sampler(
|
|
11, m_backend->GetDevice()->createSampler(
|
|
nvrhi::SamplerDesc()
|
|
.setReductionType(
|
|
nvrhi::SamplerReductionType::Comparison)
|
|
.setComparisonFunc(nvrhi::ComparisonFunc::Greater)
|
|
.setAllAddressModes(
|
|
nvrhi::SamplerAddressMode::ClampToEdge)
|
|
.setAllFilters(true))))
|
|
.addItem(nvrhi::BindingSetItem::Sampler(
|
|
13, m_backend->GetDevice()->createSampler(
|
|
nvrhi::SamplerDesc()
|
|
.setAllAddressModes(
|
|
nvrhi::SamplerAddressMode::ClampToEdge)
|
|
.setAllFilters(true)))),
|
|
m_binding_layout_forward);
|
|
}
|
|
|
|
m_vertex_shader[static_cast<size_t>(DrawType::Model)] =
|
|
m_backend->CreateShader("default_vertex", nvrhi::ShaderType::Vertex);
|
|
m_vertex_shader_prepass[static_cast<size_t>(DrawType::Model)] =
|
|
m_backend->CreateShader("default_prepass_vertex",
|
|
nvrhi::ShaderType::Vertex);
|
|
m_vertex_shader[static_cast<size_t>(DrawType::InstancedModel)] =
|
|
m_backend->CreateShader("instanced_vertex", nvrhi::ShaderType::Vertex);
|
|
m_vertex_shader_prepass[static_cast<size_t>(DrawType::InstancedModel)] =
|
|
m_backend->CreateShader("instanced_prepass_vertex",
|
|
nvrhi::ShaderType::Vertex);
|
|
m_vertex_shader_shadow[static_cast<size_t>(DrawType::Model)] =
|
|
m_backend->CreateShader("shadow_vertex", nvrhi::ShaderType::Vertex);
|
|
m_vertex_shader_shadow[static_cast<size_t>(DrawType::InstancedModel)] =
|
|
m_backend->CreateShader("instanced_shadow_vertex",
|
|
nvrhi::ShaderType::Vertex);
|
|
m_vertex_shader_cubemap[static_cast<size_t>(DrawType::Model)] =
|
|
m_backend->CreateShader("cubemap_vertex", nvrhi::ShaderType::Vertex);
|
|
m_vertex_shader_cubemap[static_cast<size_t>(DrawType::InstancedModel)] =
|
|
m_backend->CreateShader("instanced_cubemap_vertex",
|
|
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()
|
|
.setBufferIndex(0)
|
|
.setElementStride(sizeof(gfx::basic_vertex))
|
|
.setFormat(nvrhi::Format::RGB32_FLOAT)
|
|
.setName("Position")
|
|
.setIsInstanced(false)
|
|
.setOffset(offsetof(gfx::basic_vertex, position)),
|
|
nvrhi::VertexAttributeDesc()
|
|
.setBufferIndex(0)
|
|
.setElementStride(sizeof(gfx::basic_vertex))
|
|
.setFormat(nvrhi::Format::RGB32_FLOAT)
|
|
.setName("Normal")
|
|
.setIsInstanced(false)
|
|
.setOffset(offsetof(gfx::basic_vertex, normal)),
|
|
nvrhi::VertexAttributeDesc()
|
|
.setBufferIndex(0)
|
|
.setElementStride(sizeof(gfx::basic_vertex))
|
|
.setFormat(nvrhi::Format::RG32_FLOAT)
|
|
.setName("TexCoord")
|
|
.setIsInstanced(false)
|
|
.setOffset(offsetof(gfx::basic_vertex, texture)),
|
|
nvrhi::VertexAttributeDesc()
|
|
.setBufferIndex(0)
|
|
.setElementStride(sizeof(gfx::basic_vertex))
|
|
.setFormat(nvrhi::Format::RGBA32_FLOAT)
|
|
.setName("Tangent")
|
|
.setIsInstanced(false)
|
|
.setOffset(offsetof(gfx::basic_vertex, tangent)),
|
|
nvrhi::VertexAttributeDesc()
|
|
.setBufferIndex(1)
|
|
.setElementStride(sizeof(glm::mat3x4))
|
|
.setFormat(nvrhi::Format::RGBA32_FLOAT)
|
|
.setName("InstanceTransform")
|
|
.setIsInstanced(true)
|
|
.setArraySize(3)
|
|
.setOffset(0)};
|
|
m_input_layout[static_cast<size_t>(DrawType::Model)] =
|
|
m_backend->GetDevice()->createInputLayout(
|
|
desc, std::size(desc) - 1,
|
|
m_vertex_shader[static_cast<size_t>(DrawType::Model)]);
|
|
m_input_layout[static_cast<size_t>(DrawType::InstancedModel)] =
|
|
m_backend->GetDevice()->createInputLayout(
|
|
desc, std::size(desc),
|
|
m_vertex_shader[static_cast<size_t>(DrawType::InstancedModel)]);
|
|
|
|
{
|
|
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<DrawType>(i);
|
|
bool masked = j;
|
|
nvrhi::BindingLayoutDesc desc_shadow =
|
|
*m_binding_layout_shadowdrawconstants->getDesc();
|
|
nvrhi::BindingLayoutDesc desc_prepass =
|
|
*m_binding_layout_drawconstants->getDesc();
|
|
desc_shadow.visibility = nvrhi::ShaderType::All;
|
|
desc_prepass.visibility = nvrhi::ShaderType::All;
|
|
if (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));
|
|
}
|
|
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<size_t>(draw)]);
|
|
|
|
m_pso_shadow[Constants::GetDefaultShadowPipelineIndex(draw, masked)] =
|
|
GetBackend()->GetDevice()->createGraphicsPipeline(
|
|
nvrhi::GraphicsPipelineDesc(pipeline_desc)
|
|
.setRenderState(render_state_shadow)
|
|
.setVertexShader(
|
|
m_vertex_shader_shadow[static_cast<size_t>(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<size_t>(draw)])
|
|
.setPixelShader(masked ? m_pixel_shader_prepass_masked
|
|
: nullptr)
|
|
.setRenderState(render_state_depthonly)
|
|
.addBindingLayout(binding_layout_prepass),
|
|
m_gbuffer->m_framebuffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
auto vs_line =
|
|
m_backend->CreateShader("vtx_line", nvrhi::ShaderType::Vertex);
|
|
auto gs_line =
|
|
m_backend->CreateShader("geo_line", nvrhi::ShaderType::Geometry);
|
|
auto ps_line =
|
|
m_backend->CreateShader("pix_line", nvrhi::ShaderType::Pixel);
|
|
nvrhi::BindingLayoutHandle binding_layout_line;
|
|
nvrhi::utils::CreateBindingSetAndLayout(
|
|
GetBackend()->GetDevice(), nvrhi::ShaderType::AllGraphics, 0,
|
|
nvrhi::BindingSetDesc()
|
|
.addItem(
|
|
nvrhi::BindingSetItem::ConstantBuffer(0, m_drawconstant_buffer))
|
|
.addItem(nvrhi::BindingSetItem::PushConstants(
|
|
1, sizeof(PushConstantsLine))),
|
|
binding_layout_line, m_binding_set_line);
|
|
|
|
m_pso_line = GetBackend()->GetDevice()->createGraphicsPipeline(
|
|
nvrhi::GraphicsPipelineDesc()
|
|
.setRenderState(
|
|
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())))
|
|
.setPrimType(nvrhi::PrimitiveType::LineList)
|
|
.setVertexShader(vs_line)
|
|
.setGeometryShader(gs_line)
|
|
.setPixelShader(ps_line)
|
|
.setInputLayout(
|
|
m_input_layout[static_cast<size_t>(DrawType::Model)])
|
|
.addBindingLayout(binding_layout_line),
|
|
m_gbuffer->m_framebuffer);
|
|
}
|
|
|
|
auto config = YAML::LoadFile("shaders/project.manul");
|
|
for (const auto item : config["shaders"]["materials"]) {
|
|
auto material =
|
|
std::make_shared<MaterialTemplate>(item.first.as<std::string>(), this);
|
|
m_material_templates[material->m_name] = material;
|
|
material->Init(item.second);
|
|
}
|
|
|
|
return true;
|
|
}
|