From 76d5d3831dee53761ab92755ee5876d56cb3a88c Mon Sep 17 00:00:00 2001 From: Wls50 Date: Mon, 24 Nov 2025 18:29:55 +0100 Subject: [PATCH] refractive material support contd. --- .../mashadercompiler/src/shader_compiler.cpp | 5 +++++ .../renderer/include/nvrenderer/nvrenderer.h | 3 ++- .../renderer/source/gbufferblitpass.cpp | 17 ++++++++++------- .../renderer/source/gbufferblitpass.h | 2 ++ betterRenderer/renderer/source/nvmaterial.cpp | 1 + betterRenderer/renderer/source/nvrenderer.cpp | 6 +++++- .../renderer/source/track_batching.cpp | 8 +++++++- betterRenderer/shaders/project.manul | 1 + betterRenderer/shaders/ps_windshield_rain.hlsl | 6 ++---- 9 files changed, 35 insertions(+), 14 deletions(-) diff --git a/betterRenderer/mashadercompiler/src/shader_compiler.cpp b/betterRenderer/mashadercompiler/src/shader_compiler.cpp index 3424cf24..42cc96e5 100644 --- a/betterRenderer/mashadercompiler/src/shader_compiler.cpp +++ b/betterRenderer/mashadercompiler/src/shader_compiler.cpp @@ -274,6 +274,11 @@ bool MaShaderCompiler::CompileMaterial(YAML::Node &dest, const YAML::Node &src, local_definitions.insert(local_definitions.end(), definitions.begin(), definitions.end()); + if (pass == MaterialRenderPass::Forward && + TemplateOverride("refraction", src, templates).as(false)) { + local_definitions.emplace_back(L"REFRACTION", L"1"); + } + auto blob = CompileShaderToBlob(file_name, ToWide(entry_name), local_definitions, target, platform); diff --git a/betterRenderer/renderer/include/nvrenderer/nvrenderer.h b/betterRenderer/renderer/include/nvrenderer/nvrenderer.h index 6933e7e7..80a86d95 100644 --- a/betterRenderer/renderer/include/nvrenderer/nvrenderer.h +++ b/betterRenderer/renderer/include/nvrenderer/nvrenderer.h @@ -504,6 +504,7 @@ class NvRenderer : public gfx_renderer, public MaResourceRegistry { bool disable_mip_bias = false; texture_handle m_default_texture; }; + bool m_enable_refraction = false; nvrhi::static_vector m_texture_bindings; std::array m_pipelines; @@ -699,7 +700,7 @@ class NvRenderer : public gfx_renderer, public MaResourceRegistry { bool BindMaterial(material_handle handle, DrawType draw_type, const RenderPass &pass, nvrhi::GraphicsState &gfx_state, - float &alpha_threshold); + float &alpha_threshold, bool *out_is_refractive = nullptr); bool BindLineMaterial(DrawType draw_type, const RenderPass &pass, nvrhi::GraphicsState &gfx_state); diff --git a/betterRenderer/renderer/source/gbufferblitpass.cpp b/betterRenderer/renderer/source/gbufferblitpass.cpp index b791c79f..2f0b253b 100644 --- a/betterRenderer/renderer/source/gbufferblitpass.cpp +++ b/betterRenderer/renderer/source/gbufferblitpass.cpp @@ -192,8 +192,7 @@ void GbufferBlitPass::UpdateConstants(nvrhi::ICommandList* command_list, const auto& daylight = Global.DayLight; - m_sky->CalcLighting(constants.m_light_dir, - constants.m_light_color); + 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 = @@ -201,7 +200,8 @@ void GbufferBlitPass::UpdateConstants(nvrhi::ICommandList* command_list, { float percipitation_intensity = glm::saturate(Global.Overcast - 1.); - constants.m_rain_params.x = percipitation_intensity; // % amount of droplets + 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; @@ -241,6 +241,13 @@ void GbufferBlitPass::UpdateConstants(nvrhi::ICommandList* command_list, 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())); +} + void GbufferBlitPass::Render(nvrhi::ICommandList* command_list, glm::dmat4& view, const glm::dmat4& projection) { UpdateConstants(command_list, view, projection); @@ -249,10 +256,6 @@ void GbufferBlitPass::Render(nvrhi::ICommandList* command_list, m_scene_depth, nvrhi::TextureSlice().resolve(m_scene_depth->getDesc()), m_gbuffer->m_gbuffer_depth, nvrhi::TextureSlice().resolve(m_scene_depth->getDesc())); - command_list->copyTexture( - m_output_copy, nvrhi::TextureSlice().resolve(m_output_copy->getDesc()), - m_output, - nvrhi::TextureSlice().resolve(m_output->getDesc())); } void GbufferBlitPass::Render(nvrhi::ICommandList* command_list) { diff --git a/betterRenderer/renderer/source/gbufferblitpass.h b/betterRenderer/renderer/source/gbufferblitpass.h index c4513f73..c3e1b392 100644 --- a/betterRenderer/renderer/source/gbufferblitpass.h +++ b/betterRenderer/renderer/source/gbufferblitpass.h @@ -18,6 +18,8 @@ struct GbufferBlitPass : public FullScreenPass, public MaResourceRegistry { void UpdateConstants(nvrhi::ICommandList* command_list, glm::dmat4& view, const glm::dmat4& projection); + void UpdateSceneColorForRefraction(nvrhi::ICommandList *command_list) const; + void Render(nvrhi::ICommandList* command_list, glm::dmat4& view, const glm::dmat4& projection); virtual void Render(nvrhi::ICommandList* command_list) override; diff --git a/betterRenderer/renderer/source/nvmaterial.cpp b/betterRenderer/renderer/source/nvmaterial.cpp index 137c9f2b..23afdf20 100644 --- a/betterRenderer/renderer/source/nvmaterial.cpp +++ b/betterRenderer/renderer/source/nvmaterial.cpp @@ -109,6 +109,7 @@ void NvRenderer::MaterialTemplate::Init(const YAML::Node &conf) { MaResourceMapping sampler_mapping_shadow{}; m_pipelines.fill(nullptr); m_masked_shadow_texture = conf["masked_shadow_texture"].as(); + m_enable_refraction = conf["refraction"].as(false); for (const auto it : conf["textures"]) { auto index = it.second["binding"].as(); m_texture_bindings.resize( diff --git a/betterRenderer/renderer/source/nvrenderer.cpp b/betterRenderer/renderer/source/nvrenderer.cpp index 3a41fd44..283f7f4e 100644 --- a/betterRenderer/renderer/source/nvrenderer.cpp +++ b/betterRenderer/renderer/source/nvrenderer.cpp @@ -1584,13 +1584,17 @@ void NvRenderer::BindConstants(const RenderPass &pass, bool NvRenderer::BindMaterial(material_handle handle, DrawType draw_type, const RenderPass &pass, nvrhi::GraphicsState &gfx_state, - float &alpha_threshold) { + float &alpha_threshold, bool *out_is_refractive) { if (pass.m_type == RenderPassType::RendererWarmUp) return true; if (!handle || handle > m_material_cache.size()) { return false; } MaterialCache &cache = m_material_cache[handle - 1]; + if(out_is_refractive) { + *out_is_refractive = cache.m_template->m_enable_refraction; + } + if (!cache.ShouldRenderInPass(pass)) return false; auto pipeline_index = Constants::GetPipelineIndex(pass.m_type, draw_type); diff --git a/betterRenderer/renderer/source/track_batching.cpp b/betterRenderer/renderer/source/track_batching.cpp index 7c40edba..f4ff2f02 100644 --- a/betterRenderer/renderer/source/track_batching.cpp +++ b/betterRenderer/renderer/source/track_batching.cpp @@ -1,4 +1,5 @@ #include "config.h" +#include "gbufferblitpass.h" #include "motioncache.h" #include "nvrenderer/nvrenderer.h" #include "nvrendererbackend.h" @@ -1014,18 +1015,23 @@ void NvRenderer::Render(const Renderable& renderable, const RenderPass& pass, nvrhi::GraphicsState gfx_state; nvrhi::DrawArguments draw_arguments{}; bool indexed; + bool refractive; float alpha_threshold; if (!BindGeometry(item.m_geometry, pass, gfx_state, draw_arguments, indexed)) continue; if (!BindMaterial(item.m_material, DrawType::Model, pass, gfx_state, - alpha_threshold)) + alpha_threshold, &refractive)) continue; BindConstants(pass, gfx_state); pass.m_command_list_draw->beginMarker(item.m_name.data()); + if(refractive && pass.m_type == RenderPassType::Forward) { + m_gbuffer_blit->UpdateSceneColorForRefraction(pass.m_command_list_draw); + } + pass.m_command_list_draw->setGraphicsState(gfx_state); auto transform = item.m_transform; diff --git a/betterRenderer/shaders/project.manul b/betterRenderer/shaders/project.manul index 1b610d08..d8964657 100644 --- a/betterRenderer/shaders/project.manul +++ b/betterRenderer/shaders/project.manul @@ -147,6 +147,7 @@ shaders: default: system/raindrops_buffer masked_shadow_texture: diffuse source: ps_windshield_rain + refraction: true utility: # Everything that does not belong to scene graph rendering # ImGui shaders diff --git a/betterRenderer/shaders/ps_windshield_rain.hlsl b/betterRenderer/shaders/ps_windshield_rain.hlsl index 0567490d..ec424b08 100644 --- a/betterRenderer/shaders/ps_windshield_rain.hlsl +++ b/betterRenderer/shaders/ps_windshield_rain.hlsl @@ -1,5 +1,3 @@ -#define REFRACTION 1 - #include "manul/math.hlsli" #include "manul/material.hlsli" #include "manul/color_transform.hlsli" @@ -53,7 +51,7 @@ void MaterialPass(inout MaterialData material) { material_glass.m_MaterialAlbedoAlpha.xyz = 0.; material_glass.m_MaterialNormal = material.m_Normal; material_glass.m_MaterialParams.g = .2; - float3 normal = CalculateSurfaceNormal(material_glass.m_Position, material_glass.m_Normal, gradient * -.005); + float3 normal = CalculateSurfaceNormal(material_glass.m_Position, material_glass.m_Normal, gradient * -.0075); material_glass.m_MaterialNormal = normal; float cosTheta = saturate(dot(-normalize(material_glass.m_Position), normal)); material.m_MaterialAlbedoAlpha.a = lerp(.1, FresnelSchlickRoughness(cosTheta, .04, 0.), smoothstep(0., .15, droplet_distance)); @@ -63,7 +61,7 @@ void MaterialPass(inout MaterialData material) { float4 glass_lit; ApplyMaterialLighting(glass_lit, material_glass, material_glass.m_PixelCoord); - material.m_MaterialEmission = glass_lit * smoothstep(0., .15, droplet_distance) * saturate(normal_world.y * .5 + .5); + material.m_MaterialEmission = glass_lit * smoothstep(0., .15, droplet_distance) * smoothstep(-1., 0., normal_world.y); material.m_MaterialAlbedoAlpha.xyz = 0.; material.m_RefractionOffset = normal.xy * (.005 / (length(material.m_Position) * tan(.5 * g_VerticalFov))) * smoothstep(0., .15, droplet_distance);