From e245d8a22a51084b5d9e688a720c83e739338189 Mon Sep 17 00:00:00 2001 From: Panos Karabelas Date: Wed, 13 Nov 2024 17:04:20 +0000 Subject: [PATCH] [material] alpha mask will now be packed into the albedo alpha using a min operator --- data/shaders/depth_light.hlsl | 13 ++------ data/shaders/depth_prepass.hlsl | 12 ++----- runtime/Rendering/Material.cpp | 47 ++++++++++++++------------- runtime/Rendering/Renderer_Passes.cpp | 9 +---- 4 files changed, 31 insertions(+), 50 deletions(-) diff --git a/data/shaders/depth_light.hlsl b/data/shaders/depth_light.hlsl index 483ed0bcb..692dbc952 100644 --- a/data/shaders/depth_light.hlsl +++ b/data/shaders/depth_light.hlsl @@ -45,18 +45,11 @@ gbuffer_vertex main_vs(Vertex_PosUvNorTan input, uint instance_id : SV_InstanceI float4 main_ps(gbuffer_vertex vertex) : SV_Target0 { - // alpha test - const float3 f3_value = pass_get_f3_value(); - const bool has_alpha_mask = f3_value.x == 1.0f; - const bool has_albedo = f3_value.y == 1.0f; - + const bool has_albedo = pass_get_f3_value().x == 1.0f; float alpha_threshold = get_alpha_threshold(vertex.position); // distance based alpha threshold - bool mask_alpha = has_alpha_mask && GET_TEXTURE(material_texture_index_mask).Sample(samplers[sampler_point_wrap], vertex.uv).r <= alpha_threshold; - bool mask_albedo = has_albedo && GET_TEXTURE(material_texture_index_albedo).Sample(samplers[sampler_anisotropic_wrap], vertex.uv).a <= alpha_threshold; - if (mask_alpha || mask_albedo) + if (has_albedo && GET_TEXTURE(material_texture_index_albedo).Sample(samplers[sampler_anisotropic_wrap], vertex.uv).a <= alpha_threshold) discard; - // colored transparent shadows - return GetMaterial().color; + return GetMaterial().color; // colored transparent shadows } diff --git a/data/shaders/depth_prepass.hlsl b/data/shaders/depth_prepass.hlsl index cc823403e..0a62821ea 100644 --- a/data/shaders/depth_prepass.hlsl +++ b/data/shaders/depth_prepass.hlsl @@ -39,15 +39,9 @@ gbuffer_vertex main_vs(Vertex_PosUvNorTan input, uint instance_id : SV_InstanceI void main_ps(gbuffer_vertex vertex) { - const float3 f3_value = pass_get_f3_value(); - const bool has_alpha_mask = f3_value.x == 1.0f; - const bool has_albedo = f3_value.y == 1.0f; - const float alpha = f3_value.z; + const bool has_albedo = pass_get_f3_value().x == 1.0f; + const float alpha_threshold = get_alpha_threshold(vertex.position); // distance based alpha threshold - float alpha_threshold = get_alpha_threshold(vertex.position); // distance based alpha threshold - bool mask_alpha = has_alpha_mask && GET_TEXTURE(material_texture_index_mask).Sample(samplers[sampler_point_wrap], vertex.uv).r <= alpha_threshold; - bool mask_albedo = alpha == 1.0f && has_albedo && GET_TEXTURE(material_texture_index_albedo).Sample(samplers[sampler_anisotropic_wrap], vertex.uv).a <= alpha_threshold; - - if (mask_alpha || mask_albedo) + if (has_albedo && GET_TEXTURE(material_texture_index_albedo).Sample(samplers[sampler_anisotropic_wrap], vertex.uv).a <= alpha_threshold) discard; } diff --git a/runtime/Rendering/Material.cpp b/runtime/Rendering/Material.cpp index b9315dfe5..e089426c2 100644 --- a/runtime/Rendering/Material.cpp +++ b/runtime/Rendering/Material.cpp @@ -136,23 +136,14 @@ namespace Spartan void merge_alpha_mask_into_color_alpha(vector& albedo, vector& mask) { SP_ASSERT_MSG(albedo.size() == mask.size(), "The dimensions must be equal"); - - const float alpha_threshold = 0.6f; - + for (size_t i = 0; i < albedo.size(); i += 4) { - float alpha_albedo = static_cast(albedo[i + 3]) / 255.0f; - float alpha_mask = static_cast(mask[i]) / 255.0f; - - // apply the alpha threshold - if (alpha_mask >= alpha_threshold) - { - albedo[i + 3] = static_cast(min(alpha_albedo, alpha_mask) * 255.0f); - } - else - { - albedo[i + 3] = static_cast(alpha_albedo * 255.0f); - } + float alpha_albedo = static_cast(albedo[i + 3]) / 255.0f; // channel a + float alpha_mask = static_cast(mask[i]) / 255.0f; // channel r + float alpha_combined = min(alpha_albedo, alpha_mask); + + albedo[i + 3] = static_cast(alpha_combined * 255.0f); } } } @@ -357,17 +348,27 @@ namespace Spartan void Material::PrepareForGPU() { - RHI_Texture* texture_color = GetTexture(MaterialTextureType::Color); - RHI_Texture* texture_alpha_mask = GetTexture(MaterialTextureType::Color); - if (texture_color && texture_alpha_mask) + // texture packing { + // pack alpha mask into albedo alpha // note: this can be tested by loading the subway default world - // todo: what if a mask is present but an albedo is not? + RHI_Texture* texture_color = GetTexture(MaterialTextureType::Color); + RHI_Texture* texture_alpha_mask = GetTexture(MaterialTextureType::AlphaMask); + if (texture_alpha_mask) + { + if (texture_color) + { + if (!texture_color->IsCompressedFormat(texture_color->GetFormat()) && !texture_alpha_mask->IsCompressedFormat(texture_alpha_mask->GetFormat())) + { + texture_packing::merge_alpha_mask_into_color_alpha(texture_color->GetMip(0, 0).bytes, texture_alpha_mask->GetMip(0, 0).bytes); + } + } + else + { + SetTexture(MaterialTextureType::Color, texture_alpha_mask); + } - if (!texture_color->IsCompressedFormat(texture_color->GetFormat()) && !texture_alpha_mask->IsCompressedFormat(texture_alpha_mask->GetFormat())) - { - //texture_packing::merge_alpha_mask_into_color_alpha(texture_color->GetMip(0, 0).bytes, texture_alpha_mask->GetMip(0, 0).bytes); - //SetTexture(MaterialTextureType::AlphaMask, nullptr); + SetTexture(MaterialTextureType::AlphaMask, nullptr); } } diff --git a/runtime/Rendering/Renderer_Passes.cpp b/runtime/Rendering/Renderer_Passes.cpp index 3acedbb2d..e0dc20693 100644 --- a/runtime/Rendering/Renderer_Passes.cpp +++ b/runtime/Rendering/Renderer_Passes.cpp @@ -588,7 +588,6 @@ namespace Spartan if (Material* material = renderable->GetMaterial()) { m_pcb_pass_cpu.set_f3_value(material->HasTextureOfType(MaterialTextureType::Color) ? 1.0f : 0.0f); - m_pcb_pass_cpu.set_is_transparent_and_material_index(is_transparent_pass, material->GetIndex()); } @@ -703,13 +702,7 @@ namespace Spartan { if (Material* material = renderable->GetMaterial()) { - // for alpha testing - m_pcb_pass_cpu.set_f3_value( - material->HasTextureOfType(MaterialTextureType::AlphaMask) ? 1.0f : 0.0f, - material->HasTextureOfType(MaterialTextureType::Color) ? 1.0f : 0.0f, - material->GetProperty(MaterialProperty::ColorA) - ); - + m_pcb_pass_cpu.set_f3_value(material->HasTextureOfType(MaterialTextureType::Color) ? 1.0f : 0.0f); // alpha testing m_pcb_pass_cpu.set_is_transparent_and_material_index(is_transparent_pass, material->GetIndex()); }