Skip to content

Commit

Permalink
[Renderer] Fixed an issue where the material structured buffer would …
Browse files Browse the repository at this point in the history
…not always update
  • Loading branch information
PanosK92 committed Nov 30, 2023
1 parent 38e9731 commit 92def3d
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 31 deletions.
5 changes: 3 additions & 2 deletions data/shaders/common_textures.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,14 @@ Texture2D tex_velocity : register(t13);
Texture2D tex_velocity_previous : register(t14);
Texture2D tex_depth : register(t15);

// lighting
Texture2D tex_light_diffuse : register(t16);
Texture2D tex_light_diffuse_transparent : register(t17);
Texture2D tex_light_specular : register(t18);
Texture2D tex_light_specular_transparent : register(t19);
Texture2D tex_light_volumetric : register(t20);

// light depth/color maps
// shadow maps (depth and color)
Texture2DArray tex_light_directional_depth : register(t21);
Texture2DArray tex_light_directional_color : register(t22);
TextureCube tex_light_point_depth : register(t23);
Expand Down Expand Up @@ -89,6 +90,6 @@ RWTexture2D<float4> tex_uav : register(u0);
RWTexture2D<float4> tex_uav2 : register(u1);
RWTexture2D<float4> tex_uav3 : register(u2);
RWTexture2DArray<float4> tex_uav_sss : register(u3);
RWStructuredBuffer<MaterialProperties> material_properties : register(u4); // matches ID/index to material properties, used by the lighting pass
RWStructuredBuffer<MaterialProperties> material_properties : register(u4); // matches ID/index to material properties, used for lighting
globallycoherent RWStructuredBuffer<uint> g_atomic_counter : register(u5); // used by FidelityFX SPD
globallycoherent RWTexture2D<float4> tex_uav_mips[12] : register(u6); // used by FidelityFX SPD
4 changes: 3 additions & 1 deletion runtime/Core/Event.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ namespace Spartan
Sdl, // An SDL event
// Window
WindowResized, // The window has been resized
WindowFullScreenToggled // The window has been toggled to fullscreen
WindowFullScreenToggled, // The window has been toggled to fullscreen
// Material
MaterialOnChange
};

class Entity;
Expand Down
2 changes: 1 addition & 1 deletion runtime/RHI/RHI_DescriptorSetLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ namespace Spartan

// update
descriptor.data = static_cast<void*>(structured_buffer);
descriptor.dynamic_offset = structured_buffer->GetOffset();
descriptor.range = structured_buffer->GetStride();
descriptor.dynamic_offset = structured_buffer->GetOffset();

return;
}
Expand Down
4 changes: 2 additions & 2 deletions runtime/RHI/RHI_Implemenation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ using namespace std;

namespace Spartan
{
// api specific
// api specific
#if defined(API_GRAPHICS_D3D12)
RHI_Api_Type RHI_Context::api_type = RHI_Api_Type::D3d12;
string RHI_Context::api_type_str = "D3D12";
Expand All @@ -55,7 +55,7 @@ namespace Spartan
bool RHI_Context::validation = true;
bool RHI_Context::gpu_markers = true;
bool RHI_Context::gpu_profiling = true;
bool RHI_Context::renderdoc = true;
bool RHI_Context::renderdoc = false;
#else
bool RHI_Context::validation = false;
bool RHI_Context::gpu_markers = false;
Expand Down
2 changes: 1 addition & 1 deletion runtime/RHI/Vulkan/Vulkan_DescriptorSetLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ namespace Spartan

// remove push constants since they are not part of the descriptor set layout
descriptors.erase(
std::remove_if(descriptors.begin(), descriptors.end(), [](RHI_Descriptor& descriptor)
remove_if(descriptors.begin(), descriptors.end(), [](RHI_Descriptor& descriptor)
{ return descriptor.type == RHI_Descriptor_Type::PushConstantBuffer;}
),
descriptors.end()
Expand Down
12 changes: 12 additions & 0 deletions runtime/Rendering/Material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,18 @@ namespace Spartan
m_properties[static_cast<uint32_t>(MaterialProperty::MultiplierRoughness)] = value * 0.5f;
}

if (property_type == MaterialProperty::Anisotropic ||
property_type == MaterialProperty::AnisotropicRotation ||
property_type == MaterialProperty::Clearcoat ||
property_type == MaterialProperty::Clearcoat_Roughness ||
property_type == MaterialProperty::Sheen ||
property_type == MaterialProperty::SheenTint ||
property_type == MaterialProperty::MultiplierSubsurfaceScattering ||
property_type == MaterialProperty::Ior)
{
SP_FIRE_EVENT(EventType::MaterialOnChange);
}

m_properties[static_cast<uint32_t>(property_type)] = value;
}

Expand Down
82 changes: 58 additions & 24 deletions runtime/Rendering/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ namespace Spartan
RHI_CommandPool* Renderer::m_cmd_pool = nullptr;
shared_ptr<Camera> Renderer::m_camera = nullptr;
uint32_t Renderer::m_resource_index = 0;
array<Sb_MaterialProperties, 1024> material_properties;
bool material_properties_dirty = true;

namespace
{
Expand Down Expand Up @@ -120,6 +118,52 @@ namespace Spartan
}
});
}

// material properties which are used for lighting but are not part of the g-buffer
// are set into a this array of structs, which is then accessed as a structured buffer from the GPU
namespace material_properties
{
array<Sb_MaterialProperties, 1024> properties;
bool is_dirty = true;

void update(const Material* material)
{
Sb_MaterialProperties mat = {};
mat.anisotropic = material->GetProperty(MaterialProperty::Anisotropic);
mat.anisotropic_rotation = material->GetProperty(MaterialProperty::AnisotropicRotation);
mat.clearcoat = material->GetProperty(MaterialProperty::Clearcoat);
mat.clearcoat_roughness = material->GetProperty(MaterialProperty::Clearcoat_Roughness);
mat.sheen = material->GetProperty(MaterialProperty::Sheen);
mat.sheen_tint = material->GetProperty(MaterialProperty::SheenTint);
mat.subsurface_scattering = material->GetProperty(MaterialProperty::MultiplierSubsurfaceScattering);
mat.ior = material->GetProperty(MaterialProperty::Ior);

uint32_t index = static_cast<uint32_t>(material->GetObjectId() % properties.size());
properties[index] = mat;
}

void update(vector<shared_ptr<Entity>>& entities)
{
for (shared_ptr<Entity> entity : entities)
{
if (shared_ptr<Renderable> renderable = entity->GetComponent<Renderable>())
{
if (const Material* material = renderable->GetMaterial())
{
update(material);
}
}
}
}

void refresh(unordered_map<Renderer_Entity, vector<shared_ptr<Entity>>>& renderables)
{
properties.fill(Sb_MaterialProperties{});
update(renderables[Renderer_Entity::Geometry]);
update(renderables[Renderer_Entity::GeometryTransparent]);
is_dirty = true;
}
}
}

void Renderer::Initialize()
Expand Down Expand Up @@ -220,6 +264,7 @@ namespace Spartan
SP_SUBSCRIBE_TO_EVENT(EventType::WorldResolved, SP_EVENT_HANDLER_VARIANT_STATIC(OnWorldResolved));
SP_SUBSCRIBE_TO_EVENT(EventType::WorldClear, SP_EVENT_HANDLER_STATIC(OnClear));
SP_SUBSCRIBE_TO_EVENT(EventType::WindowFullScreenToggled, SP_EVENT_HANDLER_STATIC(OnFullScreenToggled));
SP_SUBSCRIBE_TO_EVENT(EventType::MaterialOnChange, SP_EVENT_HANDLER_STATIC(OnMaterialChanged));

// fire
SP_FIRE_EVENT(EventType::RendererOnInitialized);
Expand Down Expand Up @@ -572,7 +617,12 @@ namespace Spartan
cmd_list->PushConstants(0, sizeof(Pcb_Pass), &m_cb_pass_cpu);
}

void Renderer::OnWorldResolved(sp_variant data)
void Renderer::OnMaterialChanged()
{
material_properties::refresh(m_renderables);
}

void Renderer::OnWorldResolved(sp_variant data)
{
// note: m_renderables is a vector of shared pointers.
// this ensures that if any entities are deallocated by the world.
Expand Down Expand Up @@ -634,7 +684,6 @@ namespace Spartan
if (!m_entities_to_add.empty())
{
// clear previous state
material_properties.fill(Sb_MaterialProperties{});
m_renderables.clear();
m_camera = nullptr;

Expand All @@ -649,22 +698,6 @@ namespace Spartan
{
is_transparent = material->GetProperty(MaterialProperty::ColorA) < 1.0f;
is_visible = material->GetProperty(MaterialProperty::ColorA) != 0.0f;

// save material properties - used in the lighting pass
{
Sb_MaterialProperties properties = {};
properties.anisotropic = material->GetProperty(MaterialProperty::Anisotropic);
properties.anisotropic_rotation = material->GetProperty(MaterialProperty::AnisotropicRotation);
properties.clearcoat = material->GetProperty(MaterialProperty::Clearcoat);
properties.clearcoat_roughness = material->GetProperty(MaterialProperty::Clearcoat_Roughness);
properties.sheen = material->GetProperty(MaterialProperty::Sheen);
properties.sheen_tint = material->GetProperty(MaterialProperty::SheenTint);
properties.subsurface_scattering = material->GetProperty(MaterialProperty::MultiplierSubsurfaceScattering);
properties.ior = material->GetProperty(MaterialProperty::Ior);

uint32_t index = static_cast<uint32_t>(material->GetObjectId() % material_properties.size());
material_properties[index] = properties;
}
}

if (is_visible)
Expand Down Expand Up @@ -707,8 +740,9 @@ namespace Spartan
sort_renderables(m_camera.get(), &m_renderables[Renderer_Entity::Geometry], false);
sort_renderables(m_camera.get(), &m_renderables[Renderer_Entity::GeometryTransparent], true);

material_properties::refresh(m_renderables);

m_entities_to_add.clear();
material_properties_dirty = true;
}

// generate mips
Expand Down Expand Up @@ -922,10 +956,10 @@ namespace Spartan
cmd_list->SetTexture(Renderer_BindingsSrv::gbuffer_velocity_previous, GetRenderTarget(Renderer_RenderTexture::gbuffer_velocity_previous));

// update material array
if (material_properties_dirty)
if (material_properties::is_dirty)
{
GetStructuredBuffer(Renderer_StructuredBuffer::Material)->Update(&material_properties[0]);
material_properties_dirty = false;
GetStructuredBuffer(Renderer_StructuredBuffer::Material)->Update(&material_properties::properties[0]);
material_properties::is_dirty = false;
}

cmd_list->SetStructuredBuffer(Renderer_BindingsUav::sb_materials, GetStructuredBuffer(Renderer_StructuredBuffer::Material));
Expand Down
1 change: 1 addition & 0 deletions runtime/Rendering/Renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ namespace Spartan
static void Pass_Ffx_Fsr2(RHI_CommandList* cmd_list, RHI_Texture* tex_in, RHI_Texture* tex_out);

// event handlers
static void OnMaterialChanged();
static void OnWorldResolved(sp_variant data);
static void OnClear();
static void OnFullScreenToggled();
Expand Down

0 comments on commit 92def3d

Please sign in to comment.