From b62c7ff48b967f9578cc1ad41a5454c65b0218fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tur=C3=A1nszki=20J=C3=A1nos?= Date: Wed, 28 Aug 2024 06:36:12 +0200 Subject: [PATCH] added per-object rim highlight --- .../ScriptingAPI-Documentation.md | 3 + Editor/MaterialWindow.cpp | 2 +- Editor/ObjectWindow.cpp | 42 +++++++++++++- Editor/ObjectWindow.h | 2 + WickedEngine/shaders/ShaderInterop_Renderer.h | 5 ++ WickedEngine/shaders/objectHF.hlsli | 6 ++ WickedEngine/shaders/visibility_shadeCS.hlsl | 3 + WickedEngine/wiScene.cpp | 1 + WickedEngine/wiScene.h | 2 +- WickedEngine/wiScene_BindLua.cpp | 56 +++++++++++++++++++ WickedEngine/wiScene_BindLua.h | 3 + WickedEngine/wiScene_Components.h | 2 + WickedEngine/wiScene_Serializers.cpp | 10 ++++ WickedEngine/wiVersion.cpp | 2 +- 14 files changed, 135 insertions(+), 4 deletions(-) diff --git a/Content/Documentation/ScriptingAPI-Documentation.md b/Content/Documentation/ScriptingAPI-Documentation.md index 20439d348..14bc8436c 100644 --- a/Content/Documentation/ScriptingAPI-Documentation.md +++ b/Content/Documentation/ScriptingAPI-Documentation.md @@ -1174,6 +1174,9 @@ TextureSlot = { - SetCascadeMask(int value) - SetRendertypeMask(int value) - SetColor(Vector value) +- SetRimHighlightColor(Vector value) -- set the RGB color for rim highlight +- SetRimHighlightIntensity(float value) -- set the intensity (multiplier) of rim hoghlight color +- SetRimHighlightFalloff(float value) -- set the falloff power of rim highlight - SetEmissiveColor(Vector value) - SetUserStencilRef(int value) - SetLodDistanceMultiplier(float value) diff --git a/Editor/MaterialWindow.cpp b/Editor/MaterialWindow.cpp index 8835f9899..a3848aab0 100644 --- a/Editor/MaterialWindow.cpp +++ b/Editor/MaterialWindow.cpp @@ -29,7 +29,7 @@ void MaterialWindow::Create(EditorComponent* _editor) { editor = _editor; wi::gui::Window::Create(ICON_MATERIAL " Material", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE); - SetSize(XMFLOAT2(300, 1400)); + SetSize(XMFLOAT2(300, 1460)); closeButton.SetTooltip("Delete MaterialComponent"); OnClose([=](wi::gui::EventArgs args) { diff --git a/Editor/ObjectWindow.cpp b/Editor/ObjectWindow.cpp index c34d893c8..7c69ab9d8 100644 --- a/Editor/ObjectWindow.cpp +++ b/Editor/ObjectWindow.cpp @@ -257,7 +257,7 @@ void ObjectWindow::Create(EditorComponent* _editor) editor = _editor; wi::gui::Window::Create(ICON_OBJECT " Object", wi::gui::Window::WindowControls::COLLAPSE | wi::gui::Window::WindowControls::CLOSE); - SetSize(XMFLOAT2(670, 880)); + SetSize(XMFLOAT2(670, 940)); closeButton.SetTooltip("Delete ObjectComponent"); OnClose([=](wi::gui::EventArgs args) { @@ -462,6 +462,32 @@ void ObjectWindow::Create(EditorComponent* _editor) }); AddWidget(&alphaRefSlider); + rimHighlightIntesitySlider.Create(0, 10, 0, 1000, "Rim Intensity: "); + rimHighlightIntesitySlider.SetTooltip("Strength of the rim highlight color."); + rimHighlightIntesitySlider.SetSize(XMFLOAT2(wid, hei)); + rimHighlightIntesitySlider.SetPos(XMFLOAT2(x, y += step)); + rimHighlightIntesitySlider.OnSlide([&](wi::gui::EventArgs args) { + ObjectComponent* object = editor->GetCurrentScene().objects.GetComponent(entity); + if (object != nullptr) + { + object->rimHighlightColor.w = args.fValue; + } + }); + AddWidget(&rimHighlightIntesitySlider); + + rimHighlightFalloffSlider.Create(0, 32, 8, 1000, "Rim Falloff: "); + rimHighlightFalloffSlider.SetTooltip("Rim falloff power of the rim highlight effect."); + rimHighlightFalloffSlider.SetSize(XMFLOAT2(wid, hei)); + rimHighlightFalloffSlider.SetPos(XMFLOAT2(x, y += step)); + rimHighlightFalloffSlider.OnSlide([&](wi::gui::EventArgs args) { + ObjectComponent* object = editor->GetCurrentScene().objects.GetComponent(entity); + if (object != nullptr) + { + object->rimHighlightFalloff = args.fValue; + } + }); + AddWidget(&rimHighlightFalloffSlider); + cascadeMaskSlider.Create(0, 3, 0, 3, "Cascade Mask: "); cascadeMaskSlider.SetTooltip("How many shadow cascades to skip when rendering this object into shadow maps? (0: skip none, it will be in all cascades, 1: skip first (biggest cascade), ...etc..."); cascadeMaskSlider.SetSize(XMFLOAT2(wid, hei)); @@ -896,6 +922,7 @@ void ObjectWindow::Create(EditorComponent* _editor) colorComboBox.SetPos(XMFLOAT2(x, y += step)); colorComboBox.AddItem("Base color"); colorComboBox.AddItem("Emissive color"); + colorComboBox.AddItem("Rim highlight"); colorComboBox.SetTooltip("Choose the destination data of the color picker."); AddWidget(&colorComboBox); @@ -919,6 +946,12 @@ void ObjectWindow::Create(EditorComponent* _editor) case 1: object->emissiveColor = args.color.toFloat4(); break; + case 2: + { + XMFLOAT3 col = args.color.toFloat3(); + object->rimHighlightColor = XMFLOAT4(col.x, col.y, col.z, object->rimHighlightColor.w); + } + break; } } }); @@ -989,6 +1022,8 @@ void ObjectWindow::SetEntity(Entity entity) cascadeMaskSlider.SetValue((float)object->cascadeMask); ditherSlider.SetValue(object->GetTransparency()); alphaRefSlider.SetValue(object->alphaRef); + rimHighlightIntesitySlider.SetValue(object->rimHighlightColor.w); + rimHighlightFalloffSlider.SetValue(object->rimHighlightFalloff); lodSlider.SetValue(object->lod_distance_multiplier); drawdistanceSlider.SetValue(object->draw_distance); sortPrioritySlider.SetValue((int)object->sort_priority); @@ -1002,6 +1037,9 @@ void ObjectWindow::SetEntity(Entity entity) case 1: colorPicker.SetPickColor(wi::Color::fromFloat4(object->emissiveColor)); break; + case 2: + colorPicker.SetPickColor(wi::Color::fromFloat4(object->rimHighlightColor)); + break; } lightmapBlockCompressionCheckBox.SetCheck(!object->IsLightmapDisableBlockCompression()); @@ -1068,6 +1106,8 @@ void ObjectWindow::ResizeLayout() add_right(navmeshCheckBox); add(ditherSlider); add(alphaRefSlider); + add(rimHighlightIntesitySlider); + add(rimHighlightFalloffSlider); add(cascadeMaskSlider); add(lodSlider); add(drawdistanceSlider); diff --git a/Editor/ObjectWindow.h b/Editor/ObjectWindow.h index 133f477c0..e99ef91a1 100644 --- a/Editor/ObjectWindow.h +++ b/Editor/ObjectWindow.h @@ -20,6 +20,8 @@ public: wi::gui::CheckBox wetmapCheckBox; wi::gui::Slider ditherSlider; wi::gui::Slider alphaRefSlider; + wi::gui::Slider rimHighlightIntesitySlider; + wi::gui::Slider rimHighlightFalloffSlider; wi::gui::Slider cascadeMaskSlider; wi::gui::Slider lodSlider; wi::gui::Slider drawdistanceSlider; diff --git a/WickedEngine/shaders/ShaderInterop_Renderer.h b/WickedEngine/shaders/ShaderInterop_Renderer.h index 2e0a7a3dd..6b7988a50 100644 --- a/WickedEngine/shaders/ShaderInterop_Renderer.h +++ b/WickedEngine/shaders/ShaderInterop_Renderer.h @@ -632,6 +632,9 @@ struct alignas(16) ShaderMeshInstance int lightmap; uint alphaTest_size; + uint2 rimHighlight; + uint2 padding; + float4 quaternion; ShaderTransform transform; ShaderTransform transformPrev; @@ -657,6 +660,7 @@ struct alignas(16) ShaderMeshInstance vb_wetmap = -1; alphaTest_size = 0; quaternion = float4(0, 0, 0, 1); + rimHighlight = uint2(0, 0); transform.init(); transformPrev.init(); transformRaw.init(); @@ -676,6 +680,7 @@ struct alignas(16) ShaderMeshInstance inline half3 GetEmissive() { return unpack_half3(emissive); } inline half GetAlphaTest() { return unpack_half2(alphaTest_size).x; } inline half GetSize() { return unpack_half2(alphaTest_size).y; } + inline half4 GetRimHighlight() { return unpack_half4(rimHighlight); } #endif // __cplusplus }; struct ShaderMeshInstancePointer diff --git a/WickedEngine/shaders/objectHF.hlsli b/WickedEngine/shaders/objectHF.hlsli index 42f4c1fe9..19ae0b27c 100644 --- a/WickedEngine/shaders/objectHF.hlsli +++ b/WickedEngine/shaders/objectHF.hlsli @@ -1060,6 +1060,12 @@ float4 main(PixelInput input, in bool is_frontface : SV_IsFrontFace) : SV_Target ApplyLighting(surface, lighting, color); +#ifdef OBJECTSHADER_USE_INSTANCEINDEX + half4 rimHighlight = meshinstance.GetRimHighlight(); + color.rgb += rimHighlight.rgb * pow(1 - surface.NdotV, rimHighlight.w); +#endif // OBJECTSHADER_USE_INSTANCEINDEX + + #ifdef UNLIT color = surface.baseColor; #endif // UNLIT diff --git a/WickedEngine/shaders/visibility_shadeCS.hlsl b/WickedEngine/shaders/visibility_shadeCS.hlsl index c6eafe942..c03728906 100644 --- a/WickedEngine/shaders/visibility_shadeCS.hlsl +++ b/WickedEngine/shaders/visibility_shadeCS.hlsl @@ -128,6 +128,9 @@ void main(uint Gid : SV_GroupID, uint groupIndex : SV_GroupIndex) ApplyLighting(surface, lighting, color); + half4 rimHighlight = surface.inst.GetRimHighlight(); + color.rgb += rimHighlight.rgb * pow(1 - surface.NdotV, rimHighlight.w); + ApplyFog(surface.hit_depth, surface.V, color); color = saturateMediump(color); diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index 8ee1f7dac..5b1fdf66c 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -4494,6 +4494,7 @@ namespace wi::scene inst.vb_wetmap = device->GetDescriptorIndex(&object.wetmap, SubresourceType::SRV); inst.alphaTest_size = wi::math::pack_half2(XMFLOAT2(1 - object.alphaRef, size)); inst.SetUserStencilRef(object.userStencilRef); + inst.rimHighlight = wi::math::pack_half4(XMFLOAT4(object.rimHighlightColor.x * object.rimHighlightColor.w, object.rimHighlightColor.y * object.rimHighlightColor.w, object.rimHighlightColor.z * object.rimHighlightColor.w, object.rimHighlightFalloff)); std::memcpy(instanceArrayMapped + args.jobIndex, &inst, sizeof(inst)); // memcpy whole structure into mapped pointer to avoid read from uncached memory diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h index ede9b31d6..7c9558231 100644 --- a/WickedEngine/wiScene.h +++ b/WickedEngine/wiScene.h @@ -35,7 +35,7 @@ namespace wi::scene wi::ecs::ComponentManager& materials = componentLibrary.Register("wi::scene::Scene::materials", 7); // version = 7 wi::ecs::ComponentManager& meshes = componentLibrary.Register("wi::scene::Scene::meshes", 3); // version = 3 wi::ecs::ComponentManager& impostors = componentLibrary.Register("wi::scene::Scene::impostors"); - wi::ecs::ComponentManager& objects = componentLibrary.Register("wi::scene::Scene::objects", 3); // version = 3 + wi::ecs::ComponentManager& objects = componentLibrary.Register("wi::scene::Scene::objects", 4); // version = 4 wi::ecs::ComponentManager& rigidbodies = componentLibrary.Register("wi::scene::Scene::rigidbodies", 4); // version = 4 wi::ecs::ComponentManager& softbodies = componentLibrary.Register("wi::scene::Scene::softbodies", 3); // version = 3 wi::ecs::ComponentManager& armatures = componentLibrary.Register("wi::scene::Scene::armatures"); diff --git a/WickedEngine/wiScene_BindLua.cpp b/WickedEngine/wiScene_BindLua.cpp index bd5174690..c9e8faffe 100644 --- a/WickedEngine/wiScene_BindLua.cpp +++ b/WickedEngine/wiScene_BindLua.cpp @@ -5406,6 +5406,9 @@ Luna::FunctionType ObjectComponent_BindLua::methods[] = lunamethod(ObjectComponent_BindLua, SetCascadeMask), lunamethod(ObjectComponent_BindLua, SetRendertypeMask), lunamethod(ObjectComponent_BindLua, SetColor), + lunamethod(ObjectComponent_BindLua, SetRimHighlightColor), + lunamethod(ObjectComponent_BindLua, SetRimHighlightIntensity), + lunamethod(ObjectComponent_BindLua, SetRimHighlightFalloff), lunamethod(ObjectComponent_BindLua, SetAlphaRef), lunamethod(ObjectComponent_BindLua, SetEmissiveColor), lunamethod(ObjectComponent_BindLua, SetUserStencilRef), @@ -5556,6 +5559,59 @@ int ObjectComponent_BindLua::SetColor(lua_State* L) return 0; } +int ObjectComponent_BindLua::SetRimHighlightColor(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + Vector_BindLua* value = Luna::lightcheck(L, 1); + if (value) + { + XMFLOAT3 f3 = value->GetFloat3(); + component->rimHighlightColor.x = f3.x; + component->rimHighlightColor.y = f3.y; + component->rimHighlightColor.z = f3.z; + } + else + { + wi::lua::SError(L, "SetRimHighlightColor(Vector value) argument must be Vector type!"); + } + } + else + { + wi::lua::SError(L, "SetRimHighlightColor(Vector value) not enough arguments!"); + } + + return 0; +} +int ObjectComponent_BindLua::SetRimHighlightIntensity(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + component->rimHighlightColor.w = wi::lua::SGetFloat(L, 1); + } + else + { + wi::lua::SError(L, "SetRimHighlightIntensity(float value) not enough arguments!"); + } + + return 0; +} +int ObjectComponent_BindLua::SetRimHighlightFalloff(lua_State* L) +{ + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + component->rimHighlightFalloff = wi::lua::SGetFloat(L, 1); + } + else + { + wi::lua::SError(L, "SetRimHighlightFalloff(float value) not enough arguments!"); + } + + return 0; +} int ObjectComponent_BindLua::SetAlphaRef(lua_State* L) { int argc = wi::lua::SGetArgCount(L); diff --git a/WickedEngine/wiScene_BindLua.h b/WickedEngine/wiScene_BindLua.h index bfaaecaa6..5c1525a82 100644 --- a/WickedEngine/wiScene_BindLua.h +++ b/WickedEngine/wiScene_BindLua.h @@ -809,6 +809,9 @@ namespace wi::lua::scene int SetCascadeMask(lua_State* L); int SetRendertypeMask(lua_State* L); int SetColor(lua_State* L); + int SetRimHighlightColor(lua_State* L); + int SetRimHighlightIntensity(lua_State* L); + int SetRimHighlightFalloff(lua_State* L); int SetAlphaRef(lua_State* L); int SetEmissiveColor(lua_State* L); int SetUserStencilRef(lua_State* L); diff --git a/WickedEngine/wiScene_Components.h b/WickedEngine/wiScene_Components.h index fc4d6670f..9f3e8624f 100644 --- a/WickedEngine/wiScene_Components.h +++ b/WickedEngine/wiScene_Components.h @@ -825,6 +825,8 @@ namespace wi::scene uint32_t sort_priority = 0; // increase to draw earlier (currently 4 bits will be used) wi::vector vertex_ao; float alphaRef = 1; + XMFLOAT4 rimHighlightColor = XMFLOAT4(1, 1, 1, 0); + float rimHighlightFalloff = 8; // Non-serialized attributes: uint32_t filterMaskDynamic = 0; diff --git a/WickedEngine/wiScene_Serializers.cpp b/WickedEngine/wiScene_Serializers.cpp index e59ef11ed..769b6756b 100644 --- a/WickedEngine/wiScene_Serializers.cpp +++ b/WickedEngine/wiScene_Serializers.cpp @@ -653,6 +653,11 @@ namespace wi::scene { archive >> vertex_ao; } + if (seri.GetVersion() >= 4) + { + archive >> rimHighlightColor; + archive >> rimHighlightFalloff; + } wi::jobsystem::Execute(seri.ctx, [&](wi::jobsystem::JobArgs args) { CreateRenderData(); @@ -699,6 +704,11 @@ namespace wi::scene { archive << vertex_ao; } + if (seri.GetVersion() >= 4) + { + archive << rimHighlightColor; + archive << rimHighlightFalloff; + } } } void RigidBodyPhysicsComponent::Serialize(wi::Archive& archive, EntitySerializer& seri) diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index dc4454421..b2ca45529 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 557; + const int revision = 558; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);