From a85abc310f5eefc606467bbbe8e4597397530b5c Mon Sep 17 00:00:00 2001 From: Benualdo Date: Sat, 28 Dec 2024 19:01:33 +0100 Subject: [PATCH] Add shadow resolution in rendering 'Quality" options + add support for signed enum types and remove signed enum flag property types. --- Renderer.xml | 14 ++- data/Scenes/Aiguelongue.scene | 2 +- data/Scenes/PBR.scene | 9 +- src/core/IProperty.h | 8 +- src/core/Object/ClassDesc.hpp | 8 +- src/core/Object/Factory.cpp | 57 +++++++-- src/core/Object/Object.cpp | 4 - src/core/Object/Property.h | 4 +- src/core/Object/Property.hpp | 31 +++-- src/editor/ImGui/Window/ImGuiWindow.cpp | 23 +--- .../GameObject/Prefab/PrefabGameObject.cpp | 8 -- src/renderer/IRendererOptions.h | 3 + .../Directional/DirectionalLightInstance.hpp | 2 +- src/renderer/Instance/Light/LightInstance.h | 33 ++++-- src/renderer/Instance/Light/LightInstance.hpp | 30 ++++- src/renderer/Options/RendererOptions.h | 23 +++- src/renderer/Options/RendererOptions.hpp | 112 ++++++++++++++---- src/version.h | 2 +- 18 files changed, 259 insertions(+), 114 deletions(-) diff --git a/Renderer.xml b/Renderer.xml index e5f2a8975..8ab9d1180 100644 --- a/Renderer.xml +++ b/Renderer.xml @@ -7,9 +7,19 @@ - + + + + + + + + + + + @@ -24,9 +34,11 @@ + + diff --git a/data/Scenes/Aiguelongue.scene b/data/Scenes/Aiguelongue.scene index 62630056b..975f48d77 100644 --- a/data/Scenes/Aiguelongue.scene +++ b/data/Scenes/Aiguelongue.scene @@ -602,7 +602,7 @@ - + diff --git a/data/Scenes/PBR.scene b/data/Scenes/PBR.scene index 64df29705..b791c7078 100644 --- a/data/Scenes/PBR.scene +++ b/data/Scenes/PBR.scene @@ -40,7 +40,7 @@ - + @@ -48,7 +48,7 @@ - + @@ -59,6 +59,8 @@ + + @@ -124,8 +126,9 @@ - + + diff --git a/src/core/IProperty.h b/src/core/IProperty.h index 5a87a3091..ab08dd13b 100644 --- a/src/core/IProperty.h +++ b/src/core/IProperty.h @@ -52,10 +52,6 @@ namespace vg::core EnumFlagsU16, EnumFlagsU32, EnumFlagsU64, - EnumFlagsI8, - EnumFlagsI16, - EnumFlagsI32, - EnumFlagsI64, BitMask, Resource, ResourcePtr, @@ -127,8 +123,8 @@ namespace vg::core virtual void SetDescription (const char * _description) = 0; virtual void SetEnumTypeName (const char * _enumTypeName) = 0; virtual bool SetEnumValueFlags (u64 _value, EnumValueFlags _flags, bool _enabled) = 0; - virtual EnumValueFlags GetEnumValueFlags (u64 _value) const = 0; - + virtual EnumValueFlags GetUnsignedEnumValueFlags (u64 _value) const = 0; + virtual EnumValueFlags GetSignedEnumValueFlags (i64 _value) const = 0; virtual const char * GetInterface () const = 0; virtual const char * GetName () const = 0; virtual const char * GetClassName () const = 0; diff --git a/src/core/Object/ClassDesc.hpp b/src/core/Object/ClassDesc.hpp index 30faf5fd1..ac9e312a5 100644 --- a/src/core/Object/ClassDesc.hpp +++ b/src/core/Object/ClassDesc.hpp @@ -327,7 +327,7 @@ namespace vg::core void ClassDesc::RegisterEnum(const char * _className, const char * _propertyName, const char * _enumTypeName, core::i8 * _offset, const char * _displayName, uint _enumCount, const char * _enumNames, const i8 * _enumValues, PropertyFlags _flags) { const bool bitfield = asBool(PropertyFlags::Bitfield & _flags); - pushProperty({ _className, _propertyName, bitfield ? PropertyType::EnumFlagsI8 : PropertyType::EnumI8, (uint_ptr)_offset, (u32)sizeof(i8), _displayName, _flags, _enumCount, _enumNames, _enumValues }); + pushProperty({ _className, _propertyName, PropertyType::EnumI8, (uint_ptr)_offset, (u32)sizeof(i8), _displayName, _flags, _enumCount, _enumNames, _enumValues }); auto & prop = properties.back(); prop.SetEnumTypeName(_enumTypeName); } @@ -336,7 +336,7 @@ namespace vg::core void ClassDesc::RegisterEnum(const char * _className, const char * _propertyName, const char * _enumTypeName, core::i16 * _offset, const char * _displayName, uint _enumCount, const char * _enumNames, const i16 * _enumValues, PropertyFlags _flags) { const bool bitfield = asBool(PropertyFlags::Bitfield & _flags); - pushProperty({ _className, _propertyName, bitfield ? PropertyType::EnumFlagsI16 : PropertyType::EnumI16, (uint_ptr)_offset, (u32)sizeof(i16), _displayName, _flags, _enumCount, _enumNames, _enumValues }); + pushProperty({ _className, _propertyName, PropertyType::EnumI16, (uint_ptr)_offset, (u32)sizeof(i16), _displayName, _flags, _enumCount, _enumNames, _enumValues }); auto & prop = properties.back(); prop.SetEnumTypeName(_enumTypeName); } @@ -345,7 +345,7 @@ namespace vg::core void ClassDesc::RegisterEnum(const char * _className, const char * _propertyName, const char * _enumTypeName, core::i32 * _offset, const char * _displayName, uint _enumCount, const char * _enumNames, const i32 * _enumValues, PropertyFlags _flags) { const bool bitfield = asBool(PropertyFlags::Bitfield & _flags); - pushProperty({ _className, _propertyName, bitfield ? PropertyType::EnumFlagsI32 : PropertyType::EnumI32, (uint_ptr)_offset, (u32)sizeof(i32), _displayName, _flags, _enumCount, _enumNames, _enumValues }); + pushProperty({ _className, _propertyName, PropertyType::EnumI32, (uint_ptr)_offset, (u32)sizeof(i32), _displayName, _flags, _enumCount, _enumNames, _enumValues }); auto & prop = properties.back(); prop.SetEnumTypeName(_enumTypeName); } @@ -354,7 +354,7 @@ namespace vg::core void ClassDesc::RegisterEnum(const char * _className, const char * _propertyName, const char * _enumTypeName, core::i64 * _offset, const char * _displayName, uint _enumCount, const char * _enumNames, const i64 * _enumValues, PropertyFlags _flags) { const bool bitfield = asBool(PropertyFlags::Bitfield & _flags); - pushProperty({ _className, _propertyName, bitfield ? PropertyType::EnumFlagsI64 : PropertyType::EnumI64, (uint_ptr)_offset, (u32)sizeof(i64), _displayName, _flags, _enumCount, _enumNames, _enumValues }); + pushProperty({ _className, _propertyName, PropertyType::EnumI64, (uint_ptr)_offset, (u32)sizeof(i64), _displayName, _flags, _enumCount, _enumNames, _enumValues }); auto & prop = properties.back(); prop.SetEnumTypeName(_enumTypeName); } diff --git a/src/core/Object/Factory.cpp b/src/core/Object/Factory.cpp index 21bac160d..394915bed 100644 --- a/src/core/Object/Factory.cpp +++ b/src/core/Object/Factory.cpp @@ -317,10 +317,6 @@ namespace vg::core case PropertyType::EnumFlagsU16: case PropertyType::EnumFlagsU32: case PropertyType::EnumFlagsU64: - case PropertyType::EnumFlagsI8: - case PropertyType::EnumFlagsI16: - case PropertyType::EnumFlagsI32: - case PropertyType::EnumFlagsI64: { const void * src = (void *)(uint_ptr(_object) + offset); @@ -733,28 +729,24 @@ namespace vg::core case PropertyType::Int8: case PropertyType::EnumI8: - case PropertyType::EnumFlagsI8: VG_ASSERT(!srcIsEnumArray, "EnumArray CopyProperties serialization not implemented for type '%s'", asString(srcPropType).c_str()); *_dstProp->GetPropertyInt8(_dstObj) = *_srcProp->GetPropertyInt8(_srcObj); break; case PropertyType::Int16: case PropertyType::EnumI16: - case PropertyType::EnumFlagsI16: VG_ASSERT(!srcIsEnumArray, "EnumArray CopyProperties serialization not implemented for type '%s'", asString(srcPropType).c_str()); *_dstProp->GetPropertyInt16(_dstObj) = *_srcProp->GetPropertyInt16(_srcObj); break; case PropertyType::Int32: case PropertyType::EnumI32: - case PropertyType::EnumFlagsI32: VG_ASSERT(!srcIsEnumArray, "EnumArray CopyProperties serialization not implemented for type '%s'", asString(srcPropType).c_str()); *_dstProp->GetPropertyInt32(_dstObj) = *_srcProp->GetPropertyInt32(_srcObj); break; case PropertyType::Int64: case PropertyType::EnumI64: - case PropertyType::EnumFlagsI64: VG_ASSERT(!srcIsEnumArray, "EnumArray CopyProperties serialization not implemented for type '%s'", asString(srcPropType).c_str()); *_dstProp->GetPropertyInt64(_dstObj) = *_srcProp->GetPropertyInt64(_srcObj); break; @@ -1089,10 +1081,6 @@ namespace vg::core case PropertyType::EnumFlagsU16: case PropertyType::EnumFlagsU32: case PropertyType::EnumFlagsU64: - case PropertyType::EnumFlagsI8: - case PropertyType::EnumFlagsI16: - case PropertyType::EnumFlagsI32: - case PropertyType::EnumFlagsI64: { void * dst = (void *)(uint_ptr(_object) + offset); if (isEnumArray) @@ -2028,6 +2016,31 @@ namespace vg::core serializeEnumPropertyFromXML(_object, prop, xmlPropElem); break; + case PropertyType::EnumU64: + VG_ASSERT(!isEnumArray, "EnumArray serialization from XML not implemented for type '%s'", asString(type).c_str()); + serializeEnumPropertyFromXML(_object, prop, xmlPropElem); + break; + + case PropertyType::EnumI8: + VG_ASSERT(!isEnumArray, "EnumArray serialization from XML not implemented for type '%s'", asString(type).c_str()); + serializeEnumPropertyFromXML(_object, prop, xmlPropElem); + break; + + case PropertyType::EnumI16: + VG_ASSERT(!isEnumArray, "EnumArray serialization from XML not implemented for type '%s'", asString(type).c_str()); + serializeEnumPropertyFromXML(_object, prop, xmlPropElem); + break; + + case PropertyType::EnumI32: + VG_ASSERT(!isEnumArray, "EnumArray serialization from XML not implemented for type '%s'", asString(type).c_str()); + serializeEnumPropertyFromXML(_object, prop, xmlPropElem); + break; + + case PropertyType::EnumI64: + VG_ASSERT(!isEnumArray, "EnumArray serialization from XML not implemented for type '%s'", asString(type).c_str()); + serializeEnumPropertyFromXML(_object, prop, xmlPropElem); + break; + case PropertyType::Uint8: if (isEnumArray) { @@ -2622,6 +2635,26 @@ namespace vg::core VG_ASSERT(!isEnumArray, "EnumArray serialization to XML not implemented for type '%s'", asString(type).c_str()); serializeEnumPropertyToXML(_object, prop, xmlPropElem); break; + + case PropertyType::EnumI8: + VG_ASSERT(!isEnumArray, "EnumArray serialization to XML not implemented for type '%s'", asString(type).c_str()); + serializeEnumPropertyToXML(_object, prop, xmlPropElem); + break; + + case PropertyType::EnumI16: + VG_ASSERT(!isEnumArray, "EnumArray serialization to XML not implemented for type '%s'", asString(type).c_str()); + serializeEnumPropertyToXML(_object, prop, xmlPropElem); + break; + + case PropertyType::EnumI32: + VG_ASSERT(!isEnumArray, "EnumArray serialization to XML not implemented for type '%s'", asString(type).c_str()); + serializeEnumPropertyToXML(_object, prop, xmlPropElem); + break; + + case PropertyType::EnumI64: + VG_ASSERT(!isEnumArray, "EnumArray serialization to XML not implemented for type '%s'", asString(type).c_str()); + serializeEnumPropertyToXML(_object, prop, xmlPropElem); + break; } if (!skipAttribute) diff --git a/src/core/Object/Object.cpp b/src/core/Object/Object.cpp index 85c02f09d..2edb82872 100644 --- a/src/core/Object/Object.cpp +++ b/src/core/Object/Object.cpp @@ -272,25 +272,21 @@ namespace vg::core case PropertyType::Int8: case PropertyType::EnumI8: - case PropertyType::EnumFlagsI8: *(i8 *)_previousValue = *(i8 *)_newValue; break; case PropertyType::Int16: case PropertyType::EnumI16: - case PropertyType::EnumFlagsI16: *(i16 *)_previousValue = *(i16 *)_newValue; break; case PropertyType::Int32: case PropertyType::EnumI32: - case PropertyType::EnumFlagsI32: *(i32 *)_previousValue = *(i32 *)_newValue; break; case PropertyType::Int64: case PropertyType::EnumI64: - case PropertyType::EnumFlagsI64: *(i64 *)_previousValue = *(i64 *)_newValue; break; diff --git a/src/core/Object/Property.h b/src/core/Object/Property.h index 902cb638e..78f99906d 100644 --- a/src/core/Object/Property.h +++ b/src/core/Object/Property.h @@ -35,8 +35,8 @@ namespace vg::core void SetDescription (const char * _description) final override; void SetEnumTypeName (const char * _enumTypeName) final override; bool SetEnumValueFlags (u64 _value, EnumValueFlags _flags, bool _enabled) final override; - EnumValueFlags GetEnumValueFlags (u64 _value) const final override; - + EnumValueFlags GetUnsignedEnumValueFlags (u64 _value) const final override; + EnumValueFlags GetSignedEnumValueFlags (i64 _value) const final override; const char * GetInterface () const final override; const char * GetName () const final override; const char * GetClassName () const final override; diff --git a/src/core/Object/Property.hpp b/src/core/Object/Property.hpp index b9b38724f..ea3a6c982 100644 --- a/src/core/Object/Property.hpp +++ b/src/core/Object/Property.hpp @@ -43,19 +43,15 @@ namespace vg::core break; case PropertyType::EnumI8: - case PropertyType::EnumFlagsI8: initEnum(_enumCount, _enumNames, _enumValues); break; case PropertyType::EnumI16: - case PropertyType::EnumFlagsI16: initEnum(_enumCount, _enumNames, _enumValues); break; case PropertyType::EnumI32: - case PropertyType::EnumFlagsI32: initEnum(_enumCount, _enumNames, _enumValues); break; case PropertyType::EnumI64: - case PropertyType::EnumFlagsI64: initEnum(_enumCount, _enumNames, _enumValues); break; @@ -144,7 +140,7 @@ namespace vg::core } //-------------------------------------------------------------------------------------- - EnumValueFlags Property::GetEnumValueFlags(u64 _value) const + EnumValueFlags Property::GetUnsignedEnumValueFlags(u64 _value) const { for (uint i = 0; i < GetEnumCount(); ++i) { @@ -158,6 +154,21 @@ namespace vg::core return (EnumValueFlags)0x0; } + //-------------------------------------------------------------------------------------- + EnumValueFlags Property::GetSignedEnumValueFlags(i64 _value) const + { + for (uint i = 0; i < GetEnumCount(); ++i) + { + if (_value == GetSignedEnumValue(i)) + { + const EnumDesc & desc = enums[i]; + return desc.flags; + } + } + + return (EnumValueFlags)0x0; + } + //-------------------------------------------------------------------------------------- Property::Property(const Property & _other) : name(_other.name), @@ -308,7 +319,7 @@ namespace vg::core //-------------------------------------------------------------------------------------- i64 Property::GetSignedEnumValue(uint index) const { - VG_ASSERT(PropertyType::EnumI8 == GetType() || PropertyType::EnumI16 == GetType() || PropertyType::EnumI32 == GetType() || PropertyType::EnumI64 == GetType() || PropertyType::EnumFlagsI8 == GetType() || PropertyType::EnumFlagsI16 == GetType() || PropertyType::EnumFlagsI32 == GetType() || PropertyType::EnumFlagsI64 == GetType()); + VG_ASSERT(PropertyType::EnumI8 == GetType() || PropertyType::EnumI16 == GetType() || PropertyType::EnumI32 == GetType() || PropertyType::EnumI64 == GetType()); return enums[index].value.s; } @@ -406,7 +417,7 @@ namespace vg::core core::i8 * Property::GetPropertyInt8(const IObject * _object) const { VG_ASSERT(nullptr != _object); - VG_ASSERT(PropertyType::Int8 == GetType() || PropertyType::EnumI8 == GetType() || PropertyType::EnumFlagsI8 == GetType()); + VG_ASSERT(PropertyType::Int8 == GetType() || PropertyType::EnumI8 == GetType()); return (i8 *)(uint_ptr(_object) + offset); } @@ -414,7 +425,7 @@ namespace vg::core core::i16 * Property::GetPropertyInt16(const IObject * _object) const { VG_ASSERT(nullptr != _object); - VG_ASSERT(PropertyType::Int16 == GetType() || PropertyType::EnumI16 == GetType() || PropertyType::EnumFlagsI16 == GetType()); + VG_ASSERT(PropertyType::Int16 == GetType() || PropertyType::EnumI16 == GetType()); return (i16 *)(uint_ptr(_object) + offset); } @@ -422,7 +433,7 @@ namespace vg::core core::i32 * Property::GetPropertyInt32(const IObject * _object) const { VG_ASSERT(nullptr != _object); - VG_ASSERT(PropertyType::Int32 == GetType() || PropertyType::EnumI32 == GetType() || PropertyType::EnumFlagsI32 == GetType()); + VG_ASSERT(PropertyType::Int32 == GetType() || PropertyType::EnumI32 == GetType()); return (i32 *)(uint_ptr(_object) + offset); } @@ -430,7 +441,7 @@ namespace vg::core core::i64 * Property::GetPropertyInt64(const IObject * _object) const { VG_ASSERT(nullptr != _object); - VG_ASSERT(PropertyType::Int64 == GetType() || PropertyType::EnumI64 == GetType() || PropertyType::EnumFlagsI64 == GetType()); + VG_ASSERT(PropertyType::Int64 == GetType() || PropertyType::EnumI64 == GetType()); return (i64 *)(uint_ptr(_object) + offset); } diff --git a/src/editor/ImGui/Window/ImGuiWindow.cpp b/src/editor/ImGui/Window/ImGuiWindow.cpp index 4d48b6171..036db6352 100644 --- a/src/editor/ImGui/Window/ImGuiWindow.cpp +++ b/src/editor/ImGui/Window/ImGuiWindow.cpp @@ -569,7 +569,8 @@ namespace vg::editor else { auto enumVal = (T)enumPairs[_index].value; - const bool disabled = asBool(EnumValueFlags::Disabled & _prop->GetEnumValueFlags(enumVal)); + const auto enumValueFlags = scalarTraits::is_signed ? _prop->GetSignedEnumValueFlags(enumVal) : _prop->GetUnsignedEnumValueFlags(enumVal); + const bool disabled = asBool(EnumValueFlags::Disabled & enumValueFlags); if (disabled) PushDisabledStyle(true); @@ -1403,41 +1404,21 @@ namespace vg::editor changed |= editEnumFlags(_object, _prop, propContext); break; - case PropertyType::EnumFlagsI8: - VG_ASSERT(!isEnumArray, "Display of EnumArray property not implemented for type '%s'", asString(type).c_str()); - changed |= editEnumFlags(_object, _prop, propContext); - break; - case PropertyType::EnumFlagsU16: VG_ASSERT(!isEnumArray, "Display of EnumArray property not implemented for type '%s'", asString(type).c_str()); changed |= editEnumFlags(_object, _prop, propContext); break; - case PropertyType::EnumFlagsI16: - VG_ASSERT(!isEnumArray, "Display of EnumArray property not implemented for type '%s'", asString(type).c_str()); - changed |= editEnumFlags(_object, _prop, propContext); - break; - case PropertyType::EnumFlagsU32: VG_ASSERT(!isEnumArray, "Display of EnumArray property not implemented for type '%s'", asString(type).c_str()); changed |= editEnumFlags(_object, _prop, propContext); break; - case PropertyType::EnumFlagsI32: - VG_ASSERT(!isEnumArray, "Display of EnumArray property not implemented for type '%s'", asString(type).c_str()); - changed |= editEnumFlags(_object, _prop, propContext); - break; - case PropertyType::EnumFlagsU64: VG_ASSERT(!isEnumArray, "Display of EnumArray property not implemented for type '%s'", asString(type).c_str()); changed |= editEnumFlags(_object, _prop, propContext); break; - case PropertyType::EnumFlagsI64: - VG_ASSERT(!isEnumArray, "Display of EnumArray property not implemented for type '%s'", asString(type).c_str()); - changed |= editEnumFlags(_object, _prop, propContext); - break; - case PropertyType::Uint8: { if (isEnumArray) diff --git a/src/engine/GameObject/Prefab/PrefabGameObject.cpp b/src/engine/GameObject/Prefab/PrefabGameObject.cpp index c937e2317..13ea43f40 100644 --- a/src/engine/GameObject/Prefab/PrefabGameObject.cpp +++ b/src/engine/GameObject/Prefab/PrefabGameObject.cpp @@ -241,7 +241,6 @@ namespace vg::engine case PropertyType::Int8: case PropertyType::EnumI8: - case PropertyType::EnumFlagsI8: { if (isEnumArray) return false; @@ -252,7 +251,6 @@ namespace vg::engine case PropertyType::Int16: case PropertyType::EnumI16: - case PropertyType::EnumFlagsI16: { if (isEnumArray) return false; @@ -263,7 +261,6 @@ namespace vg::engine case PropertyType::Int32: case PropertyType::EnumI32: - case PropertyType::EnumFlagsI32: { if (isEnumArray) return false; @@ -274,7 +271,6 @@ namespace vg::engine case PropertyType::Int64: case PropertyType::EnumI64: - case PropertyType::EnumFlagsI64: { if (isEnumArray) return false; @@ -453,25 +449,21 @@ namespace vg::engine case PropertyType::Int8: case PropertyType::EnumI8: - case PropertyType::EnumFlagsI8: newDynProp = new DynamicPropertyI8(_prop->GetName()); break; case PropertyType::Int16: case PropertyType::EnumI16: - case PropertyType::EnumFlagsI16: newDynProp = new DynamicPropertyI16(_prop->GetName()); break; case PropertyType::Int32: case PropertyType::EnumI32: - case PropertyType::EnumFlagsI32: newDynProp = new DynamicPropertyI32(_prop->GetName()); break; case PropertyType::Int64: case PropertyType::EnumI64: - case PropertyType::EnumFlagsI64: newDynProp = new DynamicPropertyI64(_prop->GetName()); break; } diff --git a/src/renderer/IRendererOptions.h b/src/renderer/IRendererOptions.h index b9d8dc9db..dcc160de6 100644 --- a/src/renderer/IRendererOptions.h +++ b/src/renderer/IRendererOptions.h @@ -28,6 +28,9 @@ namespace vg::renderer virtual gfx::MSAA GetMSAA () const = 0; virtual bool SetMSAA (gfx::MSAA _msaa) = 0; + virtual bool GetShadowsEnabled () const = 0; + virtual core::uint2 GetShadowDefaultResolution () const = 0; + virtual gfx::HDR GetHDR () const = 0; virtual bool SetHDR (gfx::HDR _hdr) = 0; diff --git a/src/renderer/Instance/Light/Directional/DirectionalLightInstance.hpp b/src/renderer/Instance/Light/Directional/DirectionalLightInstance.hpp index 0554a5003..efa23b481 100644 --- a/src/renderer/Instance/Light/Directional/DirectionalLightInstance.hpp +++ b/src/renderer/Instance/Light/Directional/DirectionalLightInstance.hpp @@ -79,7 +79,7 @@ namespace vg::renderer // Create view and start culling immediately Renderer * renderer = Renderer::get(); - ShadowView * shadowView = new ShadowView(this, _view->getWorld(), m_shadowResolution); + ShadowView * shadowView = new ShadowView(this, _view->getWorld(), getShadowResolution()); _view->addShadowView(shadowView); float4x4 shadowMatrix = this->getGlobalMatrix(); diff --git a/src/renderer/Instance/Light/LightInstance.h b/src/renderer/Instance/Light/LightInstance.h index c31b288b1..50eedbe9b 100644 --- a/src/renderer/Instance/Light/LightInstance.h +++ b/src/renderer/Instance/Light/LightInstance.h @@ -3,6 +3,14 @@ namespace vg::renderer { + vg_enum_class(ShadowResolution, core::i8, + ShadowResolution_VeryLow = -2, + ShadowResolution_Low = -1, + ShadowResolution_Medium = 0, + ShadowResolution_High = 1, + ShadowResolution_VeryHigh = 2 + ); + class LightDesc : public ILightDesc { public: @@ -10,16 +18,15 @@ namespace vg::renderer LightType GetLightType() const = 0; - bool m_shadow = false; - bool m_shadowCameraOffset = false; - core::float2 m_shadowRange = core::float2(0.1f, 100.0f); - float m_shadowBias = 0.01f; - core::uint2 m_shadowSize = core::uint2(16, 16); - core::uint2 m_shadowResolution = core::uint2(1024, 1024); - float m_shadowIntensity = 1.0f; - - core::float4 m_color = core::float4(1, 1, 1, 1); - float m_intensity = 1.0f; + bool m_shadow = false; + bool m_shadowCameraOffset = false; + core::float2 m_shadowRange = core::float2(0.1f, 100.0f); + float m_shadowBias = 0.01f; + core::uint2 m_shadowSize = core::uint2(16, 16); + ShadowResolution m_shadowResolution = ShadowResolution::ShadowResolution_Medium; + float m_shadowIntensity = 1.0f; + core::float4 m_color = core::float4(1, 1, 1, 1); + float m_intensity = 1.0f; }; class ShadowView; @@ -35,8 +42,8 @@ namespace vg::renderer bool Cull (CullingResult * _cullingResult, View * _view) override; bool OnUpdateRayTracing (gfx::CommandList * _cmdList, View * _view, core::uint _index) override { return false; } LightType GetLightType () const = 0; - bool IsCastShadow () const { return m_shadow;} - + bool IsCastShadow () const final override; + core::uint2 getShadowResolution () const; VG_INLINE float getIntensity () const { return m_intensity; } bool m_shadow; @@ -44,7 +51,7 @@ namespace vg::renderer core::float2 m_shadowRange; float m_shadowBias; core::uint2 m_shadowSize; - core::uint2 m_shadowResolution; + ShadowResolution m_shadowResolution; float m_shadowIntensity; float m_intensity; }; diff --git a/src/renderer/Instance/Light/LightInstance.hpp b/src/renderer/Instance/Light/LightInstance.hpp index 09ea41f52..05b958370 100644 --- a/src/renderer/Instance/Light/LightInstance.hpp +++ b/src/renderer/Instance/Light/LightInstance.hpp @@ -44,8 +44,8 @@ namespace vg::renderer registerProperty(LightDesc, m_shadowSize, "Size"); setPropertyDescription(LightDesc, m_shadowSize, "Shadow map size in world-space"); - registerProperty(LightDesc, m_shadowResolution, "Resolution"); - setPropertyDescription(LightDesc, m_shadowResolution, "Shadow map resolution in pixels"); + registerPropertyEnum(LightDesc, ShadowResolution, m_shadowResolution, "Resolution"); + setPropertyDescription(LightDesc, m_shadowResolution, "Shadow map resolution from 'VeryLow' (default size /4) to 'Very High' (default size x4)"); registerProperty(LightDesc, m_shadowIntensity, "Shadow Intensity"); setPropertyRange(LightDesc, m_shadowIntensity, float2(0.0f, 1.0f)); @@ -101,6 +101,32 @@ namespace vg::renderer } + //-------------------------------------------------------------------------------------- + bool LightInstance::IsCastShadow() const + { + if (m_shadow) + { + const auto * rendererOptions = RendererOptions::get(); + return rendererOptions->GetShadowsEnabled(); + } + + return false; + } + + //-------------------------------------------------------------------------------------- + core::uint2 LightInstance::getShadowResolution() const + { + const auto * rendererOptions = RendererOptions::get(); + uint2 resolution = rendererOptions->GetShadowDefaultResolution(); + const int shadowResInt = asInteger(m_shadowResolution); + if (shadowResInt > 0) + resolution <<= shadowResInt; + else if (shadowResInt < 0) + resolution >>= (uint)(-shadowResInt); + + return resolution; + } + //-------------------------------------------------------------------------------------- bool LightInstance::Cull(CullingResult * _cullingResult, View * _view) { diff --git a/src/renderer/Options/RendererOptions.h b/src/renderer/Options/RendererOptions.h index 130b079d3..5a4aa5960 100644 --- a/src/renderer/Options/RendererOptions.h +++ b/src/renderer/Options/RendererOptions.h @@ -30,10 +30,19 @@ namespace vg::renderer Deferred ); - vg_enum(Quality, core::u8, - Low = 0, - Medium = 1, - High = 2 + vg_enum(Quality, core::i8, + VeryLow = 0, + Low = 1, + Medium = 2, + High = 3, + VeryHigh= 4 + ); + + vg_enum(ShadowDefaultResolution, core::u16, + ShadowDefaultResolution_512 = 512, + ShadowDefaultResolution_1024 = 1024, + ShadowDefaultResolution_2048 = 2048, + ShadowDefaultResolution_4096 = 4096 ); class RendererOptions final : public IRendererOptions, public core::Singleton @@ -52,6 +61,9 @@ namespace vg::renderer bool IsToolModeEnabled () const final override { return isToolModeEnabled(); }; bool IsRayTracingEnabled () const final override { return isRayTracingEnabled(); }; + bool GetShadowsEnabled () const final override; + core::uint2 GetShadowDefaultResolution () const final override; + gfx::MSAA GetMSAA () const final override; bool SetMSAA (gfx::MSAA _msaa) final override; @@ -133,11 +145,14 @@ namespace vg::renderer gfx::AAPostProcess m_aaPostProcess = gfx::AAPostProcess::None; gfx::VSync m_VSync = gfx::VSync::VSync_1; LightingMode m_lightingMode = LightingMode::Forward; + bool m_shadows[core::enumCount()]; + ShadowDefaultResolution m_shadowsResolution[core::enumCount()]; PBRFlags m_pbrFlags = (PBRFlags)0x0; DisplayMode m_debugDisplayMode = DisplayMode::None; DisplayFlags m_displayFlags = DisplayFlags::AlbedoMap | DisplayFlags::NormalMap | DisplayFlags::VertexColor | DisplayFlags::MaterialColor | DisplayFlags::InstanceColor; RenderPassFlags m_renderPassFlags; const gfx::DeviceCaps * m_deviceCaps = nullptr; + core::IProperty * m_hdrProp = nullptr; core::IProperty * m_vsyncProp = nullptr; core::IProperty * m_msaaProp[core::enumCount()] = {}; diff --git a/src/renderer/Options/RendererOptions.hpp b/src/renderer/Options/RendererOptions.hpp index ec0533df5..2e04d6c80 100644 --- a/src/renderer/Options/RendererOptions.hpp +++ b/src/renderer/Options/RendererOptions.hpp @@ -14,25 +14,67 @@ namespace vg::renderer { VG_REGISTER_OBJECT_CLASS(RendererOptions, "Renderer Options"); + #define setPropertyHiddenCallbackQuality(className, propertyName) setPropertyHiddenCallback(className, propertyName[Quality::VeryLow], isVeryLowQualityPropertyHidden); \ + setPropertyHiddenCallback(className, propertyName[Quality::Low], isLowQualityPropertyHidden); \ + setPropertyHiddenCallback(className, propertyName[Quality::Medium], isMediumQualityPropertyHidden); \ + setPropertyHiddenCallback(className, propertyName[Quality::High], isHighQualityPropertyHidden); \ + setPropertyHiddenCallback(className, propertyName[Quality::VeryHigh], isVeryHighQualityPropertyHidden); + + #define registerPropertyQuality(className, propertyName, displayName) registerProperty(className, propertyName[Quality::VeryLow], displayName); \ + registerProperty(className, propertyName[Quality::Low], displayName); \ + registerProperty(className, propertyName[Quality::Medium], displayName); \ + registerProperty(className, propertyName[Quality::High], displayName); \ + registerProperty(className, propertyName[Quality::VeryHigh],displayName); \ + setPropertyHiddenCallbackQuality(className, propertyName); + + #define registerPropertyEnumQuality(className, enumClassName, propertyName, displayName) registerPropertyEnum(className, enumClassName, propertyName[Quality::VeryLow], displayName); \ + registerPropertyEnum(className, enumClassName, propertyName[Quality::Low], displayName); \ + registerPropertyEnum(className, enumClassName, propertyName[Quality::Medium], displayName); \ + registerPropertyEnum(className, enumClassName, propertyName[Quality::High], displayName); \ + registerPropertyEnum(className, enumClassName, propertyName[Quality::VeryHigh],displayName); \ + setPropertyHiddenCallbackQuality(className, propertyName); + + #define setPropertyDescriptionQuality(className, propertyName, desc) setPropertyDescription(className, propertyName[Quality::VeryLow], desc##" in 'VeryLow' quality mode"); \ + setPropertyDescription(className, propertyName[Quality::Low], desc##" in 'Low' quality mode"); \ + setPropertyDescription(className, propertyName[Quality::Medium], desc##" in 'Medium' quality mode"); \ + setPropertyDescription(className, propertyName[Quality::High], desc##" in 'High' quality mode"); \ + setPropertyDescription(className, propertyName[Quality::VeryHigh],desc##" in 'VeryHigh' quality mode"); + //-------------------------------------------------------------------------------------- - bool IsLowQualityPropertyHidden(const IObject * _object, const IProperty * _prop, core::uint _index) + bool isQualityLevelPropertyHidden(const IObject * _object, const IProperty * _prop, Quality _quality) { const RendererOptions * rendererOptions = VG_SAFE_STATIC_CAST(const RendererOptions, _object); - return rendererOptions->getCurrentQualityLevel() != Quality::Low; + return rendererOptions->getCurrentQualityLevel() != _quality; } //-------------------------------------------------------------------------------------- - bool IsMediumQualityPropertyHidden(const IObject * _object, const IProperty * _prop, core::uint _index) + bool isVeryLowQualityPropertyHidden(const IObject * _object, const IProperty * _prop, core::uint _index) { - const RendererOptions * rendererOptions = VG_SAFE_STATIC_CAST(const RendererOptions, _object); - return rendererOptions->getCurrentQualityLevel() != Quality::Medium; + return isQualityLevelPropertyHidden(_object, _prop, Quality::VeryLow); } //-------------------------------------------------------------------------------------- - bool IsHighQualityPropertyHidden(const IObject * _object, const IProperty * _prop, core::uint _index) + bool isLowQualityPropertyHidden(const IObject * _object, const IProperty * _prop, core::uint _index) { - const RendererOptions * rendererOptions = VG_SAFE_STATIC_CAST(const RendererOptions, _object); - return rendererOptions->getCurrentQualityLevel() != Quality::High; + return isQualityLevelPropertyHidden(_object, _prop, Quality::Low); + } + + //-------------------------------------------------------------------------------------- + bool isMediumQualityPropertyHidden(const IObject * _object, const IProperty * _prop, core::uint _index) + { + return isQualityLevelPropertyHidden(_object, _prop, Quality::Medium); + } + + //-------------------------------------------------------------------------------------- + bool isHighQualityPropertyHidden(const IObject * _object, const IProperty * _prop, core::uint _index) + { + return isQualityLevelPropertyHidden(_object, _prop, Quality::High); + } + + //-------------------------------------------------------------------------------------- + bool isVeryHighQualityPropertyHidden(const IObject * _object, const IProperty * _prop, core::uint _index) + { + return isQualityLevelPropertyHidden(_object, _prop, Quality::VeryHigh); } //-------------------------------------------------------------------------------------- @@ -56,6 +98,16 @@ namespace vg::renderer registerPropertyEnumBitfield(RendererOptions, PBRFlags, m_pbrFlags, "PBR"); setPropertyDescription(RendererOptions, m_pbrFlags, "PBR lighting flags"); + + registerPropertyGroupBegin(RendererOptions, "Shadows"); + { + registerPropertyQuality(RendererOptions, m_shadows, "Cast shadows"); + setPropertyDescriptionQuality(RendererOptions, m_shadows, "Enable realtime shadows"); + + registerPropertyEnumQuality(RendererOptions, ShadowDefaultResolution, m_shadowsResolution, "Resolution"); + setPropertyDescriptionQuality(RendererOptions, m_shadowsResolution, "Default resolution for realtime shadows"); + } + registerPropertyGroupEnd(RendererOptions); registerPropertyGroupBegin(RendererOptions, "Default environment"); { @@ -83,17 +135,8 @@ namespace vg::renderer registerPropertyEnum(RendererOptions, gfx::HDR, m_HDRmode, "HDR"); setPropertyDescription(RendererOptions, m_HDRmode, "High-dynamic range display mode"); - registerPropertyEnum(RendererOptions, gfx::MSAA, m_msaa[Quality::Low], "MSAA"); - setPropertyDescription(RendererOptions, m_msaa[Quality::Low], "Multisample anti-aliasing (low)"); - setPropertyHiddenCallback(RendererOptions, m_msaa[Quality::Low], IsLowQualityPropertyHidden); - - registerPropertyEnum(RendererOptions, gfx::MSAA, m_msaa[Quality::Medium], "MSAA"); - setPropertyDescription(RendererOptions, m_msaa[Quality::Medium], "Multisample anti-aliasing (high)"); - setPropertyHiddenCallback(RendererOptions, m_msaa[Quality::Medium], IsMediumQualityPropertyHidden); - - registerPropertyEnum(RendererOptions, gfx::MSAA, m_msaa[Quality::High], "MSAA"); - setPropertyDescription(RendererOptions, m_msaa[Quality::High], "Multisample anti-aliasing (high)"); - setPropertyHiddenCallback(RendererOptions, m_msaa[Quality::High], IsHighQualityPropertyHidden); + registerPropertyEnumQuality(RendererOptions, gfx::MSAA, m_msaa, "MSAA"); + setPropertyDescriptionQuality(RendererOptions, m_msaa, "MSAA sample count for antialiasing"); registerPropertyEnum(RendererOptions, gfx::VSync, m_VSync, "VSync"); setPropertyDescription(RendererOptions, m_VSync, "Sync display frequency with monitor refresh rate"); @@ -161,8 +204,19 @@ namespace vg::renderer for (uint i = 0; i < enumCount(); ++i) { m_msaa[i] = gfx::MSAA::None; + m_shadows[i] = true; + m_shadowsResolution[i] = ShadowDefaultResolution::ShadowDefaultResolution_1024; } + // Default shadow quality + m_shadowsResolution[Quality::Low] = ShadowDefaultResolution::ShadowDefaultResolution_512; + m_shadows[Quality::Low] = false; // Disable shadows for the less detailed quality level + + m_shadowsResolution[Quality::Low] = ShadowDefaultResolution::ShadowDefaultResolution_1024; + m_shadowsResolution[Quality::Medium] = ShadowDefaultResolution::ShadowDefaultResolution_2048; + m_shadowsResolution[Quality::High] = ShadowDefaultResolution::ShadowDefaultResolution_4096; + m_shadowsResolution[Quality::VeryHigh] = ShadowDefaultResolution::ShadowDefaultResolution_4096; // Will ultimately use RT anyway + m_customQualityLevel = autodetectQualityLevel(); } @@ -199,6 +253,9 @@ namespace vg::renderer Load(); + if (!m_useCustomQualityLevel) + m_customQualityLevel = autodetectQualityLevel(); + auto * renderer = Renderer::get(); renderer->SetVSync(m_VSync); renderer->SetHDR(m_HDRmode); @@ -213,8 +270,9 @@ namespace vg::renderer for (uint q = 0; q < enumCount(); ++q) { auto & prop = m_msaaProp[q]; - prop = classDesc->GetPropertyByName(fmt::sprintf("m_msaa[Quality::%s]", asString((Quality)q)).c_str()); - VG_ASSERT(prop); + auto propName = fmt::sprintf("m_msaa[Quality::%s]", asString((Quality)q)); + prop = classDesc->GetPropertyByName(propName.c_str()); + VG_ASSERT(prop, "Could not find property \"%s\"", propName.c_str()); if (nullptr != prop) { for (uint i = 0; i < enumCount(); ++i) @@ -352,6 +410,18 @@ namespace vg::renderer return false; } + //-------------------------------------------------------------------------------------- + bool RendererOptions::GetShadowsEnabled() const + { + return m_shadows[getCurrentQualityLevel()]; + } + + //-------------------------------------------------------------------------------------- + uint2 RendererOptions::GetShadowDefaultResolution() const + { + return m_shadowsResolution[getCurrentQualityLevel()]; + } + //-------------------------------------------------------------------------------------- gfx::AAPostProcess RendererOptions::GetAAPostProcess() const { diff --git a/src/version.h b/src/version.h index 77d40e0c9..36bb03482 100644 --- a/src/version.h +++ b/src/version.h @@ -2,4 +2,4 @@ #define VG_FRAMEWORK_VERSION_MAJOR 0 #define VG_FRAMEWORK_VERSION_MINOR 45 -#define VG_FRAMEWORK_VERSION_PATCH 1 \ No newline at end of file +#define VG_FRAMEWORK_VERSION_PATCH 2 \ No newline at end of file