From 90538c8878b0cae70c4b3445fba03376dd7d58b0 Mon Sep 17 00:00:00 2001 From: Wls50 Date: Sun, 23 Nov 2025 10:39:56 +0100 Subject: [PATCH] initial rain material optimizations --- .../renderer/include/nvrenderer/nvrenderer.h | 3 +++ betterRenderer/renderer/source/nvmaterial.cpp | 21 ++++++++++-------- betterRenderer/renderer/source/nvrenderer.cpp | 22 +++++++++++-------- betterRenderer/renderer/source/nvtexture.cpp | 6 ++--- betterRenderer/renderer/source/nvtexture.h | 1 + betterRenderer/shaders/project.manul | 2 ++ .../shaders/ps_windshield_rain.hlsl | 14 ++++++++---- 7 files changed, 44 insertions(+), 25 deletions(-) diff --git a/betterRenderer/renderer/include/nvrenderer/nvrenderer.h b/betterRenderer/renderer/include/nvrenderer/nvrenderer.h index 2b4cce0f..17bf121c 100644 --- a/betterRenderer/renderer/include/nvrenderer/nvrenderer.h +++ b/betterRenderer/renderer/include/nvrenderer/nvrenderer.h @@ -498,6 +498,9 @@ class NvRenderer : public gfx_renderer, public MaResourceRegistry { std::string m_name; std::string m_sampler_name; int m_hint; + bool disable_anisotropy = false; + bool disable_filter = false; + bool disable_mip_bias = false; texture_handle m_default_texture; }; nvrhi::static_vector m_texture_bindings; diff --git a/betterRenderer/renderer/source/nvmaterial.cpp b/betterRenderer/renderer/source/nvmaterial.cpp index 1abca66c..a64f45bc 100644 --- a/betterRenderer/renderer/source/nvmaterial.cpp +++ b/betterRenderer/renderer/source/nvmaterial.cpp @@ -113,18 +113,21 @@ void NvRenderer::MaterialTemplate::Init(const YAML::Node &conf) { auto index = it.second["binding"].as(); m_texture_bindings.resize( glm::max(m_texture_bindings.size(), static_cast(index) + 1)); - auto &[name, sampler_name, hint, default_texture] = - m_texture_bindings[index]; + auto &binding = m_texture_bindings[index]; - name = it.first.as(); - sampler_name = fmt::format("{:s}_sampler", name.c_str()); + binding.m_name = it.first.as(); + binding.m_sampler_name = fmt::format("{:s}_sampler", binding.m_name.c_str()); + + binding.disable_anisotropy = it.second["no_anisotropy"].as(false); + binding.disable_filter = it.second["no_filter"].as(false); + binding.disable_mip_bias = it.second["no_mip_bias"].as(false); texture_mappings.emplace_back( - MaResourceMapping::Texture_SRV(index, name.c_str())); + MaResourceMapping::Texture_SRV(index, binding.m_name.c_str())); sampler_mappings.emplace_back( - MaResourceMapping::Sampler(index, sampler_name.c_str())); + MaResourceMapping::Sampler(index, binding.m_sampler_name.c_str())); - RegisterTexture(name.c_str(), 1); + RegisterTexture(binding.m_name.c_str(), 1); RegisterResource( false, "masked_shadow_sampler", GetTextureManager()->GetSamplerForTraits(0, RenderPassType::ShadowMap), @@ -132,10 +135,10 @@ void NvRenderer::MaterialTemplate::Init(const YAML::Node &conf) { const static std::unordered_map hints{ {"color", GL_SRGB_ALPHA}, {"linear", GL_RGBA}, {"normalmap", GL_RG}}; - hint = hints.at(it.second["hint"].as()); + binding.m_hint = hints.at(it.second["hint"].as()); if (it.first.Scalar() == conf["masked_shadow_texture"].Scalar()) { - texture_mapping_shadow = MaResourceMapping::Texture_SRV(0, name.c_str()); + texture_mapping_shadow = MaResourceMapping::Texture_SRV(0, binding.m_name.c_str()); sampler_mapping_shadow = MaResourceMapping::Sampler(0, "masked_shadow_sampler"); } diff --git a/betterRenderer/renderer/source/nvrenderer.cpp b/betterRenderer/renderer/source/nvrenderer.cpp index fa0d6c69..fac7cfe8 100644 --- a/betterRenderer/renderer/source/nvrenderer.cpp +++ b/betterRenderer/renderer/source/nvrenderer.cpp @@ -1004,19 +1004,23 @@ material_handle NvRenderer::Fetch_Material(std::string const &Filename, auto texture_manager = GetTextureManager(); for (int i = 0; i < material_template->m_texture_bindings.size(); ++i) { - const auto &[key, sampler_key, hint, m_default_texture] = - material_template->m_texture_bindings[i]; + const auto &binding = material_template->m_texture_bindings[i]; auto handle = texture_manager->FetchTexture( - static_cast(adapter.GetTexturePathForEntry(key)), hint, - adapter.GetTextureSizeBiasForEntry(key), true); + static_cast( + adapter.GetTexturePathForEntry(binding.m_name)), + binding.m_hint, adapter.GetTextureSizeBiasForEntry(binding.m_name), + true); cache.m_texture_handles[i] = handle; - cache.RegisterTexture(key.c_str(), handle); - cache.RegisterResource(false, sampler_key.c_str(), + auto traits = texture_manager->GetTraits(handle); + traits[MaTextureTraits_NoFilter] = binding.disable_filter; + traits[MaTextureTraits_NoAnisotropy] = binding.disable_anisotropy; + traits[MaTextureTraits_NoMipBias] = binding.disable_mip_bias; + cache.RegisterTexture(binding.m_name.c_str(), handle); + cache.RegisterResource(false, binding.m_sampler_name.c_str(), texture_manager->GetSamplerForTraits( - texture_manager->GetTraits(handle), - NvRenderer::RenderPassType::Deferred), + traits, RenderPassType::Deferred), nvrhi::ResourceType::Sampler); - if (key == cache.m_template->m_masked_shadow_texture && + if (binding.m_name == cache.m_template->m_masked_shadow_texture && texture_manager->IsValidHandle(handle)) { cache.m_masked_shadow = texture_manager->GetTexture(handle)->m_has_alpha; diff --git a/betterRenderer/renderer/source/nvtexture.cpp b/betterRenderer/renderer/source/nvtexture.cpp index a6c58a9c..0894f9e3 100644 --- a/betterRenderer/renderer/source/nvtexture.cpp +++ b/betterRenderer/renderer/source/nvtexture.cpp @@ -493,10 +493,10 @@ nvrhi::SamplerHandle NvTextureManager::GetSamplerForTraits( .setAddressV(traits[MaTextureTraits_ClampT] ? nvrhi::SamplerAddressMode::Clamp : nvrhi::SamplerAddressMode::Wrap) - .setAllFilters(true) + .setAllFilters(!traits[MaTextureTraits_NoFilter]) .setMipFilter(false) - .setMaxAnisotropy(traits[MaTextureTraits_NoAnisotropy] ? 0.f : 16.f) - .setMipBias(traits[MaTextureTraits_NoMipBias] ? 0.f : -1.76f); + .setMaxAnisotropy(traits[MaTextureTraits_NoAnisotropy] || traits[MaTextureTraits_NoFilter] ? 0.f : 16.f) + .setMipBias(traits[MaTextureTraits_NoMipBias] || traits[MaTextureTraits_NoFilter] ? 0.f : -1.76f); sampler = m_backend->GetDevice()->createSampler(desc); } return sampler; diff --git a/betterRenderer/renderer/source/nvtexture.h b/betterRenderer/renderer/source/nvtexture.h index 7eab94ad..c56e95fc 100644 --- a/betterRenderer/renderer/source/nvtexture.h +++ b/betterRenderer/renderer/source/nvtexture.h @@ -16,6 +16,7 @@ enum MaTextureTraits { MaTextureTraits_NoMipBias, MaTextureTraits_NoAnisotropy, + MaTextureTraits_NoFilter, MaTextureTraits_Num }; diff --git a/betterRenderer/shaders/project.manul b/betterRenderer/shaders/project.manul index 271919f8..b8ef027f 100644 --- a/betterRenderer/shaders/project.manul +++ b/betterRenderer/shaders/project.manul @@ -135,10 +135,12 @@ shaders: binding: 1 hint: color default: white + no_anisotropy: true wipermask: binding: 2 hint: color default: white + no_filter: true masked_shadow_texture: diffuse source: ps_windshield_rain utility: diff --git a/betterRenderer/shaders/ps_windshield_rain.hlsl b/betterRenderer/shaders/ps_windshield_rain.hlsl index f13e4440..e22e1f04 100644 --- a/betterRenderer/shaders/ps_windshield_rain.hlsl +++ b/betterRenderer/shaders/ps_windshield_rain.hlsl @@ -4,6 +4,8 @@ #include "manul/random.hlsli" sampler diffuse_sampler : register(s0); +sampler raindrop_sampler : register(s1); +sampler wipermask_sampler : register(s2); Texture2D diffuse : register(t0); Texture2D raindropsatlas : register(t1); Texture2D wipermask : register(t2); @@ -14,7 +16,7 @@ float4 getDropTex(float choice, float2 uv) { else if (choice < .5) offset = float2(0.5, 0.0); else if (choice < .75) offset = float2(0.0, 0.5); else offset = float2(0.5, 0.5); - return raindropsatlas.Sample(diffuse_sampler, offset + uv * 0.5); + return raindropsatlas.Sample(raindrop_sampler, offset + uv * 0.5); } float GetMixFactor(in float2 co, out float side); @@ -43,8 +45,11 @@ void MaterialPass(inout MaterialData material) { float dropMaskSum = 0.; // Grid of 9 droplets in immediate neighbourhood - for (int oy = -1; oy <= 1; oy++) { - for (int ox = -1; ox <= 1; ox++) { + [unroll] + for (int oy = -1; oy <= 1; ++oy) { + + [unroll] + for (int ox = -1; ox <= 1; ++ox) { float2 neighborCell = cell + float2(ox, oy); float2 neighborCenter = (neighborCell + .5) / gridSize; @@ -131,7 +136,7 @@ float GetMixFactor(in float2 co, out float side) { bool4 is_out = movePhase <= 1.; movePhase = select(is_out, movePhase, 2. - movePhase); - float4 mask = wipermask.Sample(diffuse_sampler, co); + float4 mask = wipermask.Sample(wipermask_sampler, co); float4 areaMask = step(.001, mask); @@ -153,6 +158,7 @@ float GetMixFactor(in float2 co, out float side) { float out_factor = 1.; // Find out the wiper blade that influences given grid cell the most + [unroll] for(int i = 0; i < 4; ++i) { bool is_candidate = factor_v[i] < out_factor;