diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 0c671ee3a..48782e7bb 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -420,6 +420,14 @@ void EditorComponent::ResizeBuffers() renderPath->width = 0; // force resize buffers renderPath->height = 0;// force resize buffers ResizeViewport3D(); + + TextureDesc desc; + desc.width = GetPhysicalWidth(); + desc.height = GetPhysicalHeight(); + desc.format = Format::R10G10B10A2_UNORM; + desc.bind_flags = BindFlag::RENDER_TARGET | BindFlag::SHADER_RESOURCE; + GetDevice()->CreateTexture(&desc, nullptr, &gui_background_effect); + GetDevice()->SetName(&gui_background_effect, "gui_background_effect"); } void EditorComponent::ResizeLayout() { @@ -445,7 +453,7 @@ void EditorComponent::ResizeLayout() projectCreatorWnd.SetSize(XMFLOAT2(projectCreatorWnd.backgroundColorPicker.GetSize().x * 2 + 4 * 3, std::min(780.0f, screenH * 0.8f))); projectCreatorWnd.SetPos(XMFLOAT2(screenW / 2.0f - projectCreatorWnd.scale.x / 2.0f, screenH / 2.0f - projectCreatorWnd.scale.y / 2.0f)); - themeEditorWnd.SetSize(XMFLOAT2(640, std::min(780.0f, screenH * 0.8f))); + themeEditorWnd.SetSize(XMFLOAT2(740, std::min(780.0f, screenH * 0.8f))); themeEditorWnd.SetPos(XMFLOAT2(screenW / 2.0f - themeEditorWnd.scale.x / 2.0f, screenH / 2.0f - themeEditorWnd.scale.y / 2.0f)); } @@ -3019,6 +3027,27 @@ void EditorComponent::Update(float dt) { wi::renderer::SetToDrawDebugSprings(generalWnd.springVisCheckBox.GetCheck()); } + + if (generalWnd.focusModeCheckBox.GetCheck() || themeEditorWnd.waveColor.getA() == 0) + { + topmenuWnd.background_overlay = {}; + componentsWnd.background_overlay = {}; + generalWnd.background_overlay = {}; + graphicsWnd.background_overlay = {}; + paintToolWnd.background_overlay = {}; + cameraWnd.background_overlay = {}; + materialPickerWnd.background_overlay = {}; + } + else + { + topmenuWnd.background_overlay = gui_background_effect; + componentsWnd.background_overlay = gui_background_effect; + generalWnd.background_overlay = gui_background_effect; + graphicsWnd.background_overlay = gui_background_effect; + paintToolWnd.background_overlay = gui_background_effect; + cameraWnd.background_overlay = gui_background_effect; + materialPickerWnd.background_overlay = gui_background_effect; + } } void EditorComponent::PostUpdate() { @@ -4378,6 +4407,26 @@ void EditorComponent::Render() const device->RenderPassEnd(cmd); } + if(!generalWnd.focusModeCheckBox.GetCheck() && themeEditorWnd.waveColor.getA() > 0) + { + device->EventBegin("Background wave effect", cmd); + device->RenderPassBegin(&gui_background_effect, cmd); + + Viewport vp; + vp.width = (float)gui_background_effect.desc.width; + vp.height = (float)gui_background_effect.desc.height; + device->BindViewports(1, &vp, cmd); + + Rect rect; + rect.from_viewport(vp); + device->BindScissorRects(1, &rect, cmd); + + wi::renderer::DrawWaveEffect(themeEditorWnd.waveColor, cmd); + + device->RenderPassEnd(cmd); + device->EventEnd(cmd); + } + device->EventEnd(cmd); } diff --git a/Editor/Editor.h b/Editor/Editor.h index bdb1dfa94..2b44cd2c6 100644 --- a/Editor/Editor.h +++ b/Editor/Editor.h @@ -88,6 +88,7 @@ public: wi::physics::PickDragOperation physicsDragOp; std::unique_ptr renderPath; + wi::graphics::Texture gui_background_effect; const wi::graphics::Texture* GetGUIBlurredBackground() const override { return renderPath->GetGUIBlurredBackground(); } void ResizeBuffers() override; diff --git a/Editor/GeneralWindow.cpp b/Editor/GeneralWindow.cpp index 90a00d31e..a2b29fb8d 100644 --- a/Editor/GeneralWindow.cpp +++ b/Editor/GeneralWindow.cpp @@ -394,6 +394,7 @@ void GeneralWindow::Create(EditorComponent* _editor) wi::Color theme_color_focus = wi::Color(70, 150, 170, 220); wi::Color theme_color_background = wi::Color(10, 10, 20, 220); XMFLOAT4 theme_color_gradient = theme_color_focus; + XMFLOAT4 theme_color_wave = theme_color_focus; wi::gui::Theme theme; theme.image.background = true; theme.image.blendFlag = wi::enums::BLENDMODE_OPAQUE; @@ -407,6 +408,7 @@ void GeneralWindow::Create(EditorComponent* _editor) case Theme::Dark: editor->main->config.GetSection("options").Set("theme", "Dark"); editor->themeEditorWnd.imageResource = {}; + theme_color_wave = wi::Color(99, 155, 220, 103); break; case Theme::Bright: editor->main->config.GetSection("options").Set("theme", "Bright"); @@ -416,6 +418,8 @@ void GeneralWindow::Create(EditorComponent* _editor) theme.shadow_color = wi::Color::Shadow(); theme.font.color = wi::Color(50, 50, 80, 255); theme_color_gradient = XMFLOAT4(1, 1, 1, 0.66f); + theme_color_wave = theme_color_focus; + theme_color_wave.w = 0.4f; editor->themeEditorWnd.imageResource = {}; break; case Theme::Soft: @@ -426,6 +430,8 @@ void GeneralWindow::Create(EditorComponent* _editor) theme.shadow_color = wi::Color(240, 190, 200, 180); theme.font.color = wi::Color(255, 230, 240, 255); theme_color_gradient = theme_color_focus; + theme_color_wave = theme_color_focus; + theme_color_wave.w = 0.4f; editor->themeEditorWnd.imageResource = {}; break; case Theme::Hacking: @@ -437,6 +443,8 @@ void GeneralWindow::Create(EditorComponent* _editor) theme.font.color = wi::Color(0, 200, 90, 255); theme.font.shadow_color = wi::Color::Shadow(); theme_color_gradient = theme_color_focus; + theme_color_wave = theme_color_focus; + theme_color_wave.w = 0.4f; editor->themeEditorWnd.imageResource = {}; break; case Theme::Nord: @@ -447,6 +455,7 @@ void GeneralWindow::Create(EditorComponent* _editor) theme.shadow_color = wi::Color(106, 112, 124, 200); theme.font.color = wi::Color(236, 239, 244, 255); theme_color_gradient = XMFLOAT4(1, 1, 1, 0.66f); + theme_color_wave = wi::Color(58, 75, 93, 153); editor->themeEditorWnd.imageResource = {}; break; case Theme::User: @@ -479,6 +488,17 @@ void GeneralWindow::Create(EditorComponent* _editor) { theme_color_gradient = theme_color_focus; } + if (version >= 3) + { + wi::Color wave; + archive >> wave.rgba; + theme_color_wave = wave; + } + else + { + theme_color_wave = theme_color_focus; + theme_color_wave.w = 0.4f; + } static uint64_t cnt = 0; if (imagedata.empty()) @@ -502,6 +522,7 @@ void GeneralWindow::Create(EditorComponent* _editor) theme.font.color = editor->themeEditorWnd.fontColor; theme.font.shadow_color = editor->themeEditorWnd.fontShadowColor; theme_color_gradient = editor->themeEditorWnd.gradientColor; + theme_color_wave = editor->themeEditorWnd.waveColor; break; } @@ -512,6 +533,7 @@ void GeneralWindow::Create(EditorComponent* _editor) editor->themeEditorWnd.fontColor = theme.font.color; editor->themeEditorWnd.fontShadowColor = theme.font.shadow_color; editor->themeEditorWnd.gradientColor = wi::Color::fromFloat4(theme_color_gradient); + editor->themeEditorWnd.waveColor = wi::Color::fromFloat4(theme_color_wave); editor->themeEditorWnd.UpdateColorPickerMode(); theme.shadow_highlight = !focusModeCheckBox.GetCheck(); @@ -965,11 +987,15 @@ void GeneralWindow::Create(EditorComponent* _editor) { editor->newEntityCombo.SetAngularHighlightWidth(0); editor->newEntityCombo.SetShadowRadius(2); + editor->componentsWnd.newComponentCombo.SetAngularHighlightWidth(0); + editor->componentsWnd.newComponentCombo.SetShadowRadius(2); } else { editor->newEntityCombo.SetAngularHighlightWidth(3); editor->newEntityCombo.SetShadowRadius(0); + editor->componentsWnd.newComponentCombo.SetAngularHighlightWidth(3); + editor->componentsWnd.newComponentCombo.SetShadowRadius(0); } wi::image::Params::Gradient gradient = wi::image::Params::Gradient::Linear; diff --git a/Editor/GraphicsWindow.cpp b/Editor/GraphicsWindow.cpp index 65c3831c6..88137a260 100644 --- a/Editor/GraphicsWindow.cpp +++ b/Editor/GraphicsWindow.cpp @@ -1588,12 +1588,12 @@ void GraphicsWindow::Update() if (editor->resolutionScale != editor->renderPath->resolutionScale) { editor->renderPath->resolutionScale = editor->resolutionScale; - //editor->ResizeBuffers(); + editor->ResizeBuffers(); } if (MSAAComboBox.GetItemUserData(MSAAComboBox.GetSelected()) != editor->renderPath->getMSAASampleCount()) { editor->renderPath->setMSAASampleCount((uint32_t)MSAAComboBox.GetItemUserData(MSAAComboBox.GetSelected())); - //editor->ResizeBuffers(); + editor->ResizeBuffers(); } if (IsCollapsed()) diff --git a/Editor/ThemeEditorWindow.cpp b/Editor/ThemeEditorWindow.cpp index af587b33f..ec157a7b4 100644 --- a/Editor/ThemeEditorWindow.cpp +++ b/Editor/ThemeEditorWindow.cpp @@ -110,6 +110,19 @@ void ThemeEditorWindow::Create(EditorComponent* _editor) }); AddWidget(&gradientButton); + waveButton.Create("themeWaveButton"); + waveButton.SetSize(XMFLOAT2(siz, siz)); + waveButton.SetDescription("Wave"); + waveButton.SetTooltip("The wave color."); + waveButton.SetText(""); + waveButton.font_description.params.v_align = wi::font::WIFALIGN_BOTTOM; + waveButton.font_description.params.h_align = wi::font::WIFALIGN_CENTER; + waveButton.OnClick([this](wi::gui::EventArgs args) { + mode = mode == ColorPickerMode::Wave ? ColorPickerMode::None : ColorPickerMode::Wave; + UpdateColorPickerMode(); + }); + AddWidget(&waveButton); + colorpicker.Create("themeColorPicker", wi::gui::Window::WindowControls::NONE); colorpicker.SetSize(XMFLOAT2(256, 256)); colorpicker.OnColorChanged([this](wi::gui::EventArgs args) { @@ -136,6 +149,9 @@ void ThemeEditorWindow::Create(EditorComponent* _editor) case ThemeEditorWindow::ColorPickerMode::Gradient: gradientColor = args.color; break; + case ThemeEditorWindow::ColorPickerMode::Wave: + waveColor = args.color; + break; default: break; } @@ -196,7 +212,7 @@ void ThemeEditorWindow::Create(EditorComponent* _editor) saveButton.OnClick([this](wi::gui::EventArgs args) { std::string directory = wi::helper::GetCurrentPath() + "/themes/"; wi::helper::DirectoryCreate(directory); - static const uint64_t version = 2; + static const uint64_t version = 3; wi::Archive archive; archive.SetReadModeAndResetPos(false); archive << version; @@ -222,6 +238,10 @@ void ThemeEditorWindow::Create(EditorComponent* _editor) { archive << gradientColor.rgba; } + if (version >= 3) + { + archive << waveColor.rgba; + } std::string name = nameInput.GetCurrentInputValue(); if (name.empty()) @@ -271,6 +291,9 @@ void ThemeEditorWindow::UpdateColorPickerMode() case ThemeEditorWindow::ColorPickerMode::Gradient: colorpicker.SetPickColor(gradientColor); break; + case ThemeEditorWindow::ColorPickerMode::Wave: + colorpicker.SetPickColor(waveColor); + break; default: break; } @@ -294,6 +317,7 @@ void ThemeEditorWindow::Update(const wi::Canvas& canvas, float dt) fontButton.SetShadowRadius(1); fontShadowButton.SetShadowRadius(1); gradientButton.SetShadowRadius(1); + waveButton.SetShadowRadius(1); const float rad = 6; switch (mode) @@ -326,6 +350,10 @@ void ThemeEditorWindow::Update(const wi::Canvas& canvas, float dt) gradientButton.SetShadowRadius(rad); colorpicker.label.SetText("Gradient color"); break; + case ThemeEditorWindow::ColorPickerMode::Wave: + waveButton.SetShadowRadius(rad); + colorpicker.label.SetText("Wave color"); + break; default: break; } @@ -337,6 +365,7 @@ void ThemeEditorWindow::Update(const wi::Canvas& canvas, float dt) fontButton.SetColor(fontColor); fontShadowButton.SetColor(fontShadowColor); gradientButton.SetColor(gradientColor); + waveButton.SetColor(waveColor); for (int i = 0; i < arraysize(editor->newSceneButton.sprites); ++i) { @@ -382,6 +411,12 @@ void ThemeEditorWindow::Update(const wi::Canvas& canvas, float dt) gradientButton.sprites[i].params.corners_rounding[2].radius = 20; gradientButton.sprites[i].params.corners_rounding[3].radius = 20; + waveButton.sprites[i].params.enableCornerRounding(); + waveButton.sprites[i].params.corners_rounding[0].radius = 20; + waveButton.sprites[i].params.corners_rounding[1].radius = 20; + waveButton.sprites[i].params.corners_rounding[2].radius = 20; + waveButton.sprites[i].params.corners_rounding[3].radius = 20; + imageButton.sprites[i].params.enableCornerRounding(); imageButton.sprites[i].params.corners_rounding[0].radius = 20; imageButton.sprites[i].params.corners_rounding[1].radius = 20; @@ -413,7 +448,7 @@ void ThemeEditorWindow::ResizeLayout() layout.jump(32); layout.padding = 20; - layout.add_right(idleButton, focusButton, backgroundButton, shadowButton, fontButton, fontShadowButton, gradientButton); + layout.add_right(idleButton, focusButton, backgroundButton, shadowButton, fontButton, fontShadowButton, gradientButton, waveButton); layout.padding = 4; layout.add_fullwidth(colorpicker); diff --git a/Editor/ThemeEditorWindow.h b/Editor/ThemeEditorWindow.h index 09a8e111f..f3e44a3a3 100644 --- a/Editor/ThemeEditorWindow.h +++ b/Editor/ThemeEditorWindow.h @@ -17,6 +17,7 @@ public: wi::gui::Button fontButton; wi::gui::Button fontShadowButton; wi::gui::Button gradientButton; + wi::gui::Button waveButton; wi::gui::ColorPicker colorpicker; @@ -32,6 +33,7 @@ public: wi::Color fontColor; wi::Color fontShadowColor; wi::Color gradientColor; + wi::Color waveColor; wi::Resource imageResource; std::string imageResourceName; @@ -45,7 +47,8 @@ public: Shadow, Font, FontShadow, - Gradient + Gradient, + Wave, } mode; void UpdateColorPickerMode(); diff --git a/WickedEngine/offlineshadercompiler.cpp b/WickedEngine/offlineshadercompiler.cpp index cc30a0767..807fb9c1d 100644 --- a/WickedEngine/offlineshadercompiler.cpp +++ b/WickedEngine/offlineshadercompiler.cpp @@ -273,6 +273,7 @@ wi::vector shaders = { {"copyStencilBitPS", wi::graphics::ShaderStage::PS }, {"extractStencilBitPS", wi::graphics::ShaderStage::PS }, {"trailPS", wi::graphics::ShaderStage::PS }, + {"waveeffectPS", wi::graphics::ShaderStage::PS }, {"hairparticleVS", wi::graphics::ShaderStage::VS }, diff --git a/WickedEngine/shaders/Shaders_SOURCE.vcxitems b/WickedEngine/shaders/Shaders_SOURCE.vcxitems index ebde0e02e..41e24b95d 100644 --- a/WickedEngine/shaders/Shaders_SOURCE.vcxitems +++ b/WickedEngine/shaders/Shaders_SOURCE.vcxitems @@ -994,6 +994,9 @@ Compute 4.0 + + Pixel + Compute 4.0 diff --git a/WickedEngine/shaders/Shaders_SOURCE.vcxitems.filters b/WickedEngine/shaders/Shaders_SOURCE.vcxitems.filters index d39ccf11f..b041caa27 100644 --- a/WickedEngine/shaders/Shaders_SOURCE.vcxitems.filters +++ b/WickedEngine/shaders/Shaders_SOURCE.vcxitems.filters @@ -1139,6 +1139,9 @@ PS + + PS + diff --git a/WickedEngine/shaders/renderlightmapPS.hlsl b/WickedEngine/shaders/renderlightmapPS.hlsl index b3a2c53e8..f1c67cc30 100644 --- a/WickedEngine/shaders/renderlightmapPS.hlsl +++ b/WickedEngine/shaders/renderlightmapPS.hlsl @@ -39,12 +39,14 @@ void BakeryPixelPush(inout float3 P, in float3 N, in float2 UV, inout RNG rng, i float3x3 TBN = compute_tangent_frame(N, P, UV); - for (uint i = 0; i < arraysize(tangent_directions); ++i) + bool valid = true; // AMD DX12 issue workaround for early break/return! + + for (uint i = 0; i < arraysize(tangent_directions) && WaveActiveAnyTrue(valid); ++i) { RayDesc ray; - ray.Origin = P + N * 0.0001; + ray.Origin = P + N * 0.001; ray.Direction = normalize(mul(float3(tangent_directions[i], 1), TBN)); - ray.TMin = 0.0001; + ray.TMin = 0.001; ray.TMax = dPos; bool backface_hit = false; @@ -55,8 +57,12 @@ void BakeryPixelPush(inout float3 P, in float3 N, in float2 UV, inout RNG rng, i surface.init(); surface.V = -ray.Direction; + valid = true; + #ifdef RTAPI - uint flags = 0; + uint flags = RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES; + flags |= RAY_FLAG_FORCE_OPAQUE; + flags |= RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH; wiRayQuery q; q.TraceRayInline( scene_acceleration_structure, // RaytracingAccelerationStructure AccelerationStructure @@ -80,7 +86,7 @@ void BakeryPixelPush(inout float3 P, in float3 N, in float2 UV, inout RNG rng, i surface.hit_depth = q.CommittedRayT(); if (!surface.load(prim, q.CommittedTriangleBarycentrics())) - return; + valid = false; hit_nor = surface.facenormal; } @@ -95,21 +101,21 @@ void BakeryPixelPush(inout float3 P, in float3 N, in float2 UV, inout RNG rng, i surface.hit_depth = hit.distance; if (!surface.load(hit.primitiveID, hit.bary)) - return; + valid = false; hit_nor = surface.facenormal; } #endif // RTAPI - if (backface_hit) + if (valid && backface_hit) { bakerydebug = 1; P = hit_pos - hit_nor * 0.001; - return; } } } +[earlydepthstencil] float4 main(Input input) : SV_TARGET { #ifdef DEBUG_CHARTS @@ -131,9 +137,9 @@ float4 main(Input input) : SV_TARGET BakeryPixelPush(P, surface.N, uv, rng, bakerydebug); RayDesc ray; - ray.Origin = P; + ray.Origin = P + surface.N * 0.001; ray.Direction = normalize(sample_hemisphere_cos(surface.N, rng)); - ray.TMin = 0.0001; + ray.TMin = 0.001; ray.TMax = FLT_MAX; float3 result = 0; float3 energy = 1; @@ -288,8 +294,8 @@ float4 main(Input input) : SV_TARGET float3 shadow = energy; RayDesc newRay; - newRay.Origin = surface.P; - newRay.TMin = 0.0001; + newRay.Origin = surface.P + surface.N * 0.001; + newRay.TMin = 0.001; newRay.TMax = dist; newRay.Direction = normalize(L + max3(surface.sss)); @@ -440,6 +446,8 @@ float4 main(Input input) : SV_TARGET ray.Direction = sample_hemisphere_cos(surface.N, rng); energy *= surface.albedo * (1 - surface.F) / max(0.001, 1 - specular_chance) / max(0.001, 1 - surface.transmission); } + + ray.Origin += surface.facenormal * 0.001; // NOTE: TMin on AMD doesn't handle CommittedTriangleFrontFace correctly, so origin is updated instead! } // Terminate ray's path or apply inverse termination bias: diff --git a/WickedEngine/shaders/screenVS.hlsl b/WickedEngine/shaders/screenVS.hlsl index e5a419184..3a1e0b082 100644 --- a/WickedEngine/shaders/screenVS.hlsl +++ b/WickedEngine/shaders/screenVS.hlsl @@ -1,8 +1,6 @@ #include "globals.hlsli" -float4 main(uint vertexID : SV_VertexID) : SV_Position +void main(uint vertexID : SV_VertexID, out float4 pos : SV_Position, out float2 uv : TEXCOORD) { - float4 pos; - vertexID_create_fullscreen_triangle(vertexID, pos); - return pos; + vertexID_create_fullscreen_triangle(vertexID, pos, uv); } diff --git a/WickedEngine/shaders/waveeffectPS.hlsl b/WickedEngine/shaders/waveeffectPS.hlsl new file mode 100644 index 000000000..9a8c56601 --- /dev/null +++ b/WickedEngine/shaders/waveeffectPS.hlsl @@ -0,0 +1,28 @@ +#include "globals.hlsli" +#include "ShaderInterop_Postprocess.h" + +PUSHCONSTANT(postprocess, PostProcess); + +float4 main(in float4 pos : SV_Position, in float2 uv : TEXCOORD) : SV_Target +{ + uv.y -= 0.26 * (1 - sqr(uv.x)); + float time = GetTime() * 0.32; + + float wave = 0; + const uint num = 2; + for (uint i = 0; i < num; ++i) + { + float2 clipspace = uv_to_clipspace(uv) + sin(uv.x * 3 + time * 0.8 + i * 5.234) * 0.34 * (i * 1.2334); + float linne = sin(clipspace.x * 4 + time * 0.6); + float dist = clipspace.y * 10 - linne; + wave += smoothstep(1.0, 0.0, abs(dist * (dist < 0 ? 0.01 : 10))); // long gradient down + wave += smoothstep(1.0, 0.0, abs(dist * (dist < 0 ? 0.6 : 10))); // short gradient down + } + + wave /= float(num * 2); + + float4 color = saturate(wave) * postprocess.params0; + color.rgb *= color.a; + color.a = 1; + return color; +} diff --git a/WickedEngine/wiColor.h b/WickedEngine/wiColor.h index 745954217..b9e03d719 100644 --- a/WickedEngine/wiColor.h +++ b/WickedEngine/wiColor.h @@ -12,9 +12,11 @@ namespace wi constexpr Color(uint8_t r = 0, uint8_t g = 0, uint8_t b = 0, uint8_t a = 255) : rgba(uint32_t(r) | (uint32_t(g) << 8) | (uint32_t(b) << 16) | (uint32_t(a) << 24)) {} constexpr Color(const char* hex) { - Color abgr; + int len = 0; + while (hex[len++] != 0) {} + rgba = 0; uint32_t shift = 0u; - for (int i = 0; i < 9; ++i) + for (int i = len - 1; i >= 0; i--) { const char c = hex[i]; switch (c) @@ -29,7 +31,7 @@ namespace wi case '7': case '8': case '9': - abgr.rgba |= (c - '0') << shift; + rgba |= (c - '0') << shift; shift += 4u; break; case 'A': @@ -38,7 +40,7 @@ namespace wi case 'D': case 'E': case 'F': - abgr.rgba |= (c - 'A' + 10) << shift; + rgba |= (c - 'A' + 10) << shift; shift += 4u; break; case 'a': @@ -47,24 +49,18 @@ namespace wi case 'd': case 'e': case 'f': - abgr.rgba |= (c - 'a' + 10) << shift; + rgba |= (c - 'a' + 10) << shift; shift += 4u; break; case '#': break; default: case 0: - setR(abgr.getA()); - setG(abgr.getB()); - setB(abgr.getG()); - setA(abgr.getR()); - return; + break; } + if (len < 8) + setA(255); } - setR(abgr.getA()); - setG(abgr.getB()); - setB(abgr.getG()); - setA(abgr.getR()); } constexpr uint8_t getR() const { return (rgba >> 0) & 0xFF; } @@ -106,12 +102,11 @@ namespace wi }; constexpr const char_return<9> to_hex() const { - const uint32_t abgr = Color(getA(), getB(), getG(), getR()).rgba; char_return<9> ret; - for (int i = 0; i < 8; ++i) + for (int i = 7; i >= 0; i--) { - const uint8_t v = (abgr >> (i * 4)) & 0xF; - ret.text[i] = v < 10 ? ('0' + v) : ('A' + v - 10); + const uint8_t v = (rgba >> (i * 4)) & 0xF; + ret.text[7 - i] = v < 10 ? ('0' + v) : ('A' + v - 10); } return ret; } diff --git a/WickedEngine/wiEnums.h b/WickedEngine/wiEnums.h index c016d2b50..c7c351cce 100644 --- a/WickedEngine/wiEnums.h +++ b/WickedEngine/wiEnums.h @@ -204,6 +204,7 @@ namespace wi::enums PSTYPE_COPY_STENCIL_BIT, PSTYPE_COPY_STENCIL_BIT_MSAA, PSTYPE_EXTRACT_STENCIL_BIT, + PSTYPE_WAVE_EFFECT, // geometry shaders diff --git a/WickedEngine/wiGUI.cpp b/WickedEngine/wiGUI.cpp index 6f3093102..17f08107a 100644 --- a/WickedEngine/wiGUI.cpp +++ b/WickedEngine/wiGUI.cpp @@ -4095,6 +4095,14 @@ namespace wi::gui } } wi::image::Draw(sprites[IDLE].GetTexture(), params, cmd); + + if (background_overlay.IsValid()) + { + params.blendFlag = wi::enums::BLENDMODE_ADDITIVE; + params.color.w = 0; + params.setBackgroundMap(&background_overlay); + wi::image::Draw(nullptr, params, cmd); + } } for (size_t i = 0; i < widgets.size(); ++i) diff --git a/WickedEngine/wiGUI.h b/WickedEngine/wiGUI.h index b4e6043a7..70b2a10e7 100644 --- a/WickedEngine/wiGUI.h +++ b/WickedEngine/wiGUI.h @@ -931,6 +931,8 @@ namespace wi::gui void ExportLocalization(wi::Localization& localization) const override; void ImportLocalization(const wi::Localization& localization) override; + + wi::graphics::Texture background_overlay; }; // HSV-Color Picker diff --git a/WickedEngine/wiRenderPath3D_PathTracing.cpp b/WickedEngine/wiRenderPath3D_PathTracing.cpp index f61c4b48d..9c3ba76c8 100644 --- a/WickedEngine/wiRenderPath3D_PathTracing.cpp +++ b/WickedEngine/wiRenderPath3D_PathTracing.cpp @@ -75,7 +75,6 @@ namespace wi { desc.bind_flags = BindFlag::UNORDERED_ACCESS | BindFlag::SHADER_RESOURCE; - desc.layout = ResourceState::UNORDERED_ACCESS; desc.format = Format::R32_FLOAT; device->CreateTexture(&desc, nullptr, &traceDepth); device->SetName(&traceDepth, "traceDepth"); diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index aac4be605..9d99fc78b 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -683,6 +683,8 @@ PipelineState PSO_copyStencilBit[8]; PipelineState PSO_copyStencilBit_MSAA[8]; PipelineState PSO_extractStencilBit[8]; +PipelineState PSO_waveeffect; + RaytracingPipelineState RTPSO_reflection; enum SKYRENDERING @@ -953,6 +955,7 @@ void LoadShaders() wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::PS, shaders[PSTYPE_COPY_STENCIL_BIT_MSAA], "copyStencilBitPS.cso", ShaderModel::SM_6_0, {"MSAA"}); }); wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::PS, shaders[PSTYPE_EXTRACT_STENCIL_BIT], "extractStencilBitPS.cso"); }); wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::PS, shaders[PSTYPE_PAINTDECAL], "paintdecalPS.cso"); }); + wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::PS, shaders[PSTYPE_WAVE_EFFECT], "waveeffectPS.cso"); }); wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::GS, shaders[GSTYPE_VOXELIZER], "objectGS_voxelizer.cso"); }); wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { LoadShader(ShaderStage::GS, shaders[GSTYPE_VOXEL], "voxelGS.cso"); }); @@ -1541,6 +1544,16 @@ void LoadShaders() device->CreatePipelineState(&desc, &PSO_extractStencilBit[i]); } }); + wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { + PipelineStateDesc desc; + + desc.vs = &shaders[VSTYPE_SCREEN]; + desc.ps = &shaders[PSTYPE_WAVE_EFFECT]; + desc.bs = &blendStates[BSTYPE_PREMULTIPLIED]; + desc.rs = &rasterizers[RSTYPE_DOUBLESIDED]; + desc.dss = &depthStencils[DSSTYPE_DEPTHDISABLED]; + device->CreatePipelineState(&desc, &PSO_waveeffect); + }); wi::jobsystem::Execute(ctx, [](wi::jobsystem::JobArgs args) { PipelineStateDesc desc; desc.vs = &shaders[VSTYPE_LENSFLARE]; @@ -10566,7 +10579,6 @@ void RayTraceScene( PushBarrier(GPUBarrier::Image(&output, output.desc.layout, ResourceState::UNORDERED_ACCESS)); - // Note: these are always in ResourceState::UNORDERED_ACCESS, no need to transition! if (output_albedo != nullptr) { device->BindUAV(output_albedo, 1, cmd); @@ -10578,10 +10590,12 @@ void RayTraceScene( if (output_depth != nullptr) { device->BindUAV(output_depth, 3, cmd); + PushBarrier(GPUBarrier::Image(output_depth, output_depth->desc.layout, ResourceState::UNORDERED_ACCESS)); } if (output_stencil != nullptr) { device->BindUAV(output_stencil, 4, cmd); + PushBarrier(GPUBarrier::Image(output_stencil, output_stencil->desc.layout, ResourceState::UNORDERED_ACCESS)); } FlushBarriers(cmd); @@ -10620,6 +10634,16 @@ void RayTraceScene( ); PushBarrier(GPUBarrier::Image(&output, ResourceState::UNORDERED_ACCESS, output.desc.layout)); + if (output_depth != nullptr) + { + PushBarrier(GPUBarrier::Image(output_depth, ResourceState::UNORDERED_ACCESS, output_depth->desc.layout)); + } + if (output_stencil != nullptr) + { + PushBarrier(GPUBarrier::Image(output_stencil, ResourceState::UNORDERED_ACCESS, output_stencil->desc.layout)); + } + FlushBarriers(cmd); + if (output_depth_stencil != nullptr) { CopyDepthStencil( @@ -10630,18 +10654,6 @@ void RayTraceScene( 0xFF ); } - else - { - if (output_depth != nullptr) - { - PushBarrier(GPUBarrier::Image(output_depth, ResourceState::UNORDERED_ACCESS, output_depth->desc.layout)); - } - if (output_stencil != nullptr) - { - PushBarrier(GPUBarrier::Image(output_stencil, ResourceState::UNORDERED_ACCESS, output_stencil->desc.layout)); - } - } - FlushBarriers(cmd); wi::profiler::EndRange(range); device->EventEnd(cmd); // RayTraceScene @@ -18049,9 +18061,6 @@ void CopyDepthStencil( if (manual_depthstencil_copy_required) { // Vulkan workaround: - PushBarrier(GPUBarrier::Image(input_depth, input_depth->desc.layout, ResourceState::SHADER_RESOURCE)); - PushBarrier(GPUBarrier::Image(input_stencil, input_stencil->desc.layout, ResourceState::SHADER_RESOURCE)); - FlushBarriers(cmd); RenderPassImage rp[] = { RenderPassImage::DepthStencil( @@ -18080,7 +18089,6 @@ void CopyDepthStencil( device->BindResource(input_depth, 0, cmd); device->Draw(3, 0, cmd); device->EventEnd(cmd); - PushBarrier(GPUBarrier::Image(input_depth, ResourceState::SHADER_RESOURCE, input_depth->desc.layout)); } if (input_stencil != nullptr) @@ -18115,13 +18123,10 @@ void CopyDepthStencil( stencil_bits_to_copy >>= 1; } device->EventEnd(cmd); - PushBarrier(GPUBarrier::Image(input_stencil, ResourceState::SHADER_RESOURCE, input_stencil->desc.layout)); } device->RenderPassEnd(cmd); - FlushBarriers(cmd); - } else { @@ -18402,6 +18407,23 @@ void ComputeReprojectedDepthPyramid( device->EventEnd(cmd); } +void DrawWaveEffect(const XMFLOAT4& color, CommandList cmd) +{ + device->EventBegin("DrawWaveEffect", cmd); + + BindCommonResources(cmd); + + device->BindPipelineState(&PSO_waveeffect, cmd); + + PostProcess postprocess = {}; + postprocess.params0 = color; + device->PushConstants(&postprocess, sizeof(postprocess), cmd); + + device->Draw(3, 0, cmd); + + device->EventEnd(cmd); +} + Ray GetPickRay(long cursorX, long cursorY, const wi::Canvas& canvas, const CameraComponent& camera) { diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index 6fa065bf0..a49ff2b78 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -1080,6 +1080,9 @@ namespace wi::renderer void DrawWaterRipples(const Visibility& vis, wi::graphics::CommandList cmd); + void DrawWaveEffect(const XMFLOAT4& color, wi::graphics::CommandList cmd); + + void SetShadowProps2D(int max_resolution); void SetShadowPropsCube(int max_resolution); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index f8e69b344..09cb6d7b1 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 = 802; + const int revision = 803; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);