From d9174eb4bb24e23965c419ba5744106eb7361b28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tur=C3=A1nszki=20J=C3=A1nos?= Date: Sun, 19 Jun 2022 12:15:47 +0200 Subject: [PATCH] Envprobe MSAA (#466) * envprobe MSAA support; vulkan: transient attachment support; dx12: renderpass resolve subresource improvement; * envprobe window update * envprobe gi boost fix * probes will render fully diffuse scene, because inside probes there is no fallback reflection --- Editor/EnvProbeWindow.cpp | 39 +++++++- Editor/EnvProbeWindow.h | 2 + WickedEngine/shaders/objectHF.hlsli | 2 +- WickedEngine/shaders/surfaceHF.hlsli | 2 + WickedEngine/wiGraphics.h | 13 ++- WickedEngine/wiGraphicsDevice_DX12.cpp | 27 +++-- WickedEngine/wiGraphicsDevice_Vulkan.cpp | 16 ++- WickedEngine/wiRenderer.cpp | 9 +- WickedEngine/wiScene.cpp | 120 +++++++++++++++++------ WickedEngine/wiScene.h | 7 ++ WickedEngine/wiVersion.cpp | 2 +- 11 files changed, 185 insertions(+), 54 deletions(-) diff --git a/Editor/EnvProbeWindow.cpp b/Editor/EnvProbeWindow.cpp index a6d0243d0..eff080aca 100644 --- a/Editor/EnvProbeWindow.cpp +++ b/Editor/EnvProbeWindow.cpp @@ -8,12 +8,21 @@ using namespace wi::scene; void EnvProbeWindow::Create(EditorComponent* editor) { wi::gui::Window::Create("Environment Probe Window"); - SetSize(XMFLOAT2(300, 200)); + SetSize(XMFLOAT2(420, 220)); - float x = 100, y = 0, step = 35; + float x = 5, y = 0, step = 35; + + infoLabel.Create(""); + infoLabel.SetText("Environment probes can be used to capture the scene from a specific location in a 360 degrees panorama. The probes will be used for reflections fallback, where a better reflection type is not available. The probes can affect the ambient colors slightly.\nTip: You can scale, rotate and move the probes to set up parallax correct rendering to affect a specific area only. The parallax correction will take effect inside the probe's bounds (indicated with a cyan colored box)."); + infoLabel.SetSize(XMFLOAT2(400 - 10, 100)); + infoLabel.SetPos(XMFLOAT2(x, y)); + infoLabel.SetColor(wi::Color::Transparent()); + AddWidget(&infoLabel); + y += infoLabel.GetScale().y + 5; realTimeCheckBox.Create("RealTime: "); - realTimeCheckBox.SetPos(XMFLOAT2(x, y)); + realTimeCheckBox.SetTooltip("Enable continuous rendering of the probe in every frame."); + realTimeCheckBox.SetPos(XMFLOAT2(x + 100, y)); realTimeCheckBox.SetEnabled(false); realTimeCheckBox.OnClick([&](wi::gui::EventArgs args) { EnvironmentProbeComponent* probe = wi::scene::GetScene().probes.GetComponent(entity); @@ -25,7 +34,22 @@ void EnvProbeWindow::Create(EditorComponent* editor) }); AddWidget(&realTimeCheckBox); + msaaCheckBox.Create("MSAA: "); + msaaCheckBox.SetTooltip("Enable Multi Sampling Anti Aliasing for the probe, this will improve its quality."); + msaaCheckBox.SetPos(XMFLOAT2(x + 200, y)); + msaaCheckBox.SetEnabled(false); + msaaCheckBox.OnClick([&](wi::gui::EventArgs args) { + EnvironmentProbeComponent* probe = wi::scene::GetScene().probes.GetComponent(entity); + if (probe != nullptr) + { + probe->SetMSAA(args.bValue); + probe->SetDirty(); + } + }); + AddWidget(&msaaCheckBox); + generateButton.Create("Put"); + generateButton.SetTooltip("Put down a new probe in front of the camera and capture the scene."); generateButton.SetPos(XMFLOAT2(x, y += step)); generateButton.OnClick([=](wi::gui::EventArgs args) { XMFLOAT3 pos; @@ -48,7 +72,8 @@ void EnvProbeWindow::Create(EditorComponent* editor) AddWidget(&generateButton); refreshButton.Create("Refresh"); - refreshButton.SetPos(XMFLOAT2(x, y += step)); + refreshButton.SetTooltip("Re-renders the selected probe."); + refreshButton.SetPos(XMFLOAT2(x + 120, y)); refreshButton.SetEnabled(false); refreshButton.OnClick([&](wi::gui::EventArgs args) { EnvironmentProbeComponent* probe = wi::scene::GetScene().probes.GetComponent(entity); @@ -60,7 +85,8 @@ void EnvProbeWindow::Create(EditorComponent* editor) AddWidget(&refreshButton); refreshAllButton.Create("Refresh All"); - refreshAllButton.SetPos(XMFLOAT2(x, y += step)); + refreshAllButton.SetTooltip("Re-renders all probes in the scene."); + refreshAllButton.SetPos(XMFLOAT2(x + 240, y)); refreshAllButton.SetEnabled(true); refreshAllButton.OnClick([&](wi::gui::EventArgs args) { Scene& scene = wi::scene::GetScene(); @@ -90,12 +116,15 @@ void EnvProbeWindow::SetEntity(Entity entity) if (probe == nullptr) { realTimeCheckBox.SetEnabled(false); + msaaCheckBox.SetEnabled(false); refreshButton.SetEnabled(false); } else { realTimeCheckBox.SetCheck(probe->IsRealTime()); realTimeCheckBox.SetEnabled(true); + msaaCheckBox.SetCheck(probe->IsMSAA()); + msaaCheckBox.SetEnabled(true); refreshButton.SetEnabled(true); } } diff --git a/Editor/EnvProbeWindow.h b/Editor/EnvProbeWindow.h index 627314997..ccfc7e533 100644 --- a/Editor/EnvProbeWindow.h +++ b/Editor/EnvProbeWindow.h @@ -11,7 +11,9 @@ public: wi::ecs::Entity entity; void SetEntity(wi::ecs::Entity entity); + wi::gui::Label infoLabel; wi::gui::CheckBox realTimeCheckBox; + wi::gui::CheckBox msaaCheckBox; wi::gui::Button generateButton; wi::gui::Button refreshButton; wi::gui::Button refreshAllButton; diff --git a/WickedEngine/shaders/objectHF.hlsli b/WickedEngine/shaders/objectHF.hlsli index 1214ca285..e58f3d18f 100644 --- a/WickedEngine/shaders/objectHF.hlsli +++ b/WickedEngine/shaders/objectHF.hlsli @@ -569,7 +569,7 @@ inline void ForwardLighting(inout Surface surface, inout Lighting lighting) [branch] if ((surface.flags & SURFACE_FLAG_GI_APPLIED) == 0 && GetScene().ddgi.color_texture >= 0) { - lighting.indirect.diffuse = ddgi_sample_irradiance(surface.P, surface.N); + lighting.indirect.diffuse = ddgi_sample_irradiance(surface.P, surface.N) * GetFrame().gi_boost; surface.flags |= SURFACE_FLAG_GI_APPLIED; } diff --git a/WickedEngine/shaders/surfaceHF.hlsli b/WickedEngine/shaders/surfaceHF.hlsli index ec3c2cdc3..7fb93b7ad 100644 --- a/WickedEngine/shaders/surfaceHF.hlsli +++ b/WickedEngine/shaders/surfaceHF.hlsli @@ -161,7 +161,9 @@ struct Surface roughness = material.roughness; f0 = material.GetSpecular() * specularMap.rgb * specularMap.a; +#ifndef ENVMAPRENDERING if (GetFrame().options & OPTION_BIT_FORCE_DIFFUSE_LIGHTING) +#endif // ENVMAPRENDERING { f0 = material.metalness = material.reflectance = 0; } diff --git a/WickedEngine/wiGraphics.h b/WickedEngine/wiGraphics.h index 8d67d43bf..e7ab46c92 100644 --- a/WickedEngine/wiGraphics.h +++ b/WickedEngine/wiGraphics.h @@ -344,6 +344,7 @@ namespace wi::graphics BUFFER_STRUCTURED = 1 << 3, RAY_TRACING = 1 << 4, PREDICATION = 1 << 5, + TRANSIENT_ATTACHMENT = 1 << 6, // hint: used in renderpass, without needing to write content to memory (VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) }; enum class GraphicsDeviceCapability @@ -656,7 +657,8 @@ namespace wi::graphics StoreOp store_op = StoreOp::STORE, ResourceState initial_layout = ResourceState::SHADER_RESOURCE, ResourceState subpass_layout = ResourceState::RENDERTARGET, - ResourceState final_layout = ResourceState::SHADER_RESOURCE + ResourceState final_layout = ResourceState::SHADER_RESOURCE, + int subresource_RTV = -1 ) { RenderPassAttachment attachment; @@ -667,6 +669,7 @@ namespace wi::graphics attachment.initial_layout = initial_layout; attachment.subpass_layout = subpass_layout; attachment.final_layout = final_layout; + attachment.subresource = subresource_RTV; return attachment; } @@ -676,7 +679,8 @@ namespace wi::graphics StoreOp store_op = StoreOp::STORE, ResourceState initial_layout = ResourceState::DEPTHSTENCIL, ResourceState subpass_layout = ResourceState::DEPTHSTENCIL, - ResourceState final_layout = ResourceState::DEPTHSTENCIL + ResourceState final_layout = ResourceState::DEPTHSTENCIL, + int subresource_DSV = -1 ) { RenderPassAttachment attachment; @@ -687,13 +691,15 @@ namespace wi::graphics attachment.initial_layout = initial_layout; attachment.subpass_layout = subpass_layout; attachment.final_layout = final_layout; + attachment.subresource = subresource_DSV; return attachment; } static RenderPassAttachment Resolve( const Texture* resource = nullptr, ResourceState initial_layout = ResourceState::SHADER_RESOURCE, - ResourceState final_layout = ResourceState::SHADER_RESOURCE + ResourceState final_layout = ResourceState::SHADER_RESOURCE, + int subresource_SRV = -1 ) { RenderPassAttachment attachment; @@ -701,6 +707,7 @@ namespace wi::graphics attachment.texture = resource; attachment.initial_layout = initial_layout; attachment.final_layout = final_layout; + attachment.subresource = subresource_SRV; return attachment; } diff --git a/WickedEngine/wiGraphicsDevice_DX12.cpp b/WickedEngine/wiGraphicsDevice_DX12.cpp index 8c6088b9d..9c45b01bc 100644 --- a/WickedEngine/wiGraphicsDevice_DX12.cpp +++ b/WickedEngine/wiGraphicsDevice_DX12.cpp @@ -1481,7 +1481,7 @@ namespace dx12_internal const Texture* shading_rate_image = nullptr; // Due to a API bug, this resolve_subresources array must be kept alive between BeginRenderpass() and EndRenderpass()! - D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS resolve_subresources[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT] = {}; + wi::vector resolve_subresources[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT] = {}; }; struct SwapChain_DX12 { @@ -2314,7 +2314,7 @@ using namespace dx12_internal; } D3D_FEATURE_LEVEL featurelevels[] = { - D3D_FEATURE_LEVEL_12_2, + //D3D_FEATURE_LEVEL_12_2, D3D_FEATURE_LEVEL_12_1, D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_11_1, @@ -3827,22 +3827,31 @@ using namespace dx12_internal; if (resolve_src_counter == resolve_dst_counter) { auto src_internal = to_internal(src.texture); + int src_subresource = src.subresource; + const SingleDescriptor& src_descriptor = src_subresource < 0 ? src_internal->rtv : src_internal->subresources_rtv[src_subresource]; D3D12_RENDER_PASS_RENDER_TARGET_DESC& src_RTV = internal_state->RTVs[resolve_src_counter]; src_RTV.EndingAccess.Resolve.PreserveResolveSource = src_RTV.EndingAccess.Type == D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE; src_RTV.EndingAccess.Type = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_RESOLVE; src_RTV.EndingAccess.Resolve.Format = clear_value.Format; src_RTV.EndingAccess.Resolve.ResolveMode = D3D12_RESOLVE_MODE_AVERAGE; - src_RTV.EndingAccess.Resolve.SubresourceCount = 1; + src_RTV.EndingAccess.Resolve.PreserveResolveSource = src_RTV.EndingAccess.Type == D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_DISCARD ? FALSE : TRUE; src_RTV.EndingAccess.Resolve.pDstResource = texture_internal->resource.Get(); src_RTV.EndingAccess.Resolve.pSrcResource = src_internal->resource.Get(); - src_RTV.EndingAccess.Resolve.pSubresourceParameters = &internal_state->resolve_subresources[resolve_src_counter]; - internal_state->resolve_subresources[resolve_src_counter].SrcRect.left = 0; - internal_state->resolve_subresources[resolve_src_counter].SrcRect.right = (LONG)texture->desc.width; - internal_state->resolve_subresources[resolve_src_counter].SrcRect.bottom = (LONG)texture->desc.height; - internal_state->resolve_subresources[resolve_src_counter].SrcRect.top = 0; - + const SingleDescriptor& descriptor = subresource < 0 ? texture_internal->srv : texture_internal->subresources_srv[subresource]; + src_RTV.EndingAccess.Resolve.SubresourceCount = std::max(1u, std::min(src_descriptor.rtv.Texture2DMSArray.ArraySize, src.texture->desc.array_size)); + internal_state->resolve_subresources[resolve_src_counter].resize(src_RTV.EndingAccess.Resolve.SubresourceCount); + src_RTV.EndingAccess.Resolve.pSubresourceParameters = internal_state->resolve_subresources[resolve_src_counter].data(); + for (UINT i = 0; i < src_RTV.EndingAccess.Resolve.SubresourceCount; ++i) + { + internal_state->resolve_subresources[resolve_src_counter][i].SrcSubresource = D3D12CalcSubresource(0, src_descriptor.rtv.Texture2DMSArray.FirstArraySlice + i, 0, src.texture->desc.mip_levels, src.texture->desc.array_size); + internal_state->resolve_subresources[resolve_src_counter][i].DstSubresource = D3D12CalcSubresource(0, descriptor.srv.Texture2DArray.FirstArraySlice + i, 0, texture->desc.mip_levels, texture->desc.array_size); + internal_state->resolve_subresources[resolve_src_counter][i].SrcRect.left = 0; + internal_state->resolve_subresources[resolve_src_counter][i].SrcRect.right = (LONG)texture->desc.width; + internal_state->resolve_subresources[resolve_src_counter][i].SrcRect.bottom = (LONG)texture->desc.height; + internal_state->resolve_subresources[resolve_src_counter][i].SrcRect.top = 0; + } break; } resolve_src_counter++; diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.cpp b/WickedEngine/wiGraphicsDevice_Vulkan.cpp index 66733f538..22f9219cd 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.cpp +++ b/WickedEngine/wiGraphicsDevice_Vulkan.cpp @@ -2485,6 +2485,11 @@ using namespace vulkan_internal; enabled_deviceExtensions = required_deviceExtensions; + if (checkExtensionSupport(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, available_deviceExtensions)) + { + // The shader compiler can still be using this extension, even though it is core in Vulkan 1.2, so enable it for now: + enabled_deviceExtensions.push_back(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME); + } if (checkExtensionSupport(VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, available_deviceExtensions)) { enabled_deviceExtensions.push_back(VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME); @@ -3710,8 +3715,15 @@ using namespace vulkan_internal; { imageInfo.usage |= VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR; } - imageInfo.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - imageInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; + if (has_flag(texture->desc.misc_flags, ResourceMiscFlag::TRANSIENT_ATTACHMENT)) + { + imageInfo.usage |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; + } + else + { + imageInfo.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + imageInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; + } imageInfo.flags = 0; if (has_flag(texture->desc.misc_flags, ResourceMiscFlag::TEXTURECUBE)) diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index d4f8d85be..976d0b290 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -6319,7 +6319,14 @@ void RefreshEnvProbes(const Visibility& vis, CommandList cmd) RefreshAtmosphericScatteringTextures(cmd); } - device->RenderPassBegin(&vis.scene->renderpasses_envmap[probe.textureIndex], cmd); + if (probe.IsMSAA()) + { + device->RenderPassBegin(&vis.scene->renderpasses_envmap_MSAA[probe.textureIndex], cmd); + } + else + { + device->RenderPassBegin(&vis.scene->renderpasses_envmap[probe.textureIndex], cmd); + } // Scene will only be rendered if this is a real probe entity: if (probe_aabb.layerMask & vis.layerMask) diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index 761e234b6..6fc285a2b 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -3733,20 +3733,31 @@ namespace wi::scene TextureDesc desc; desc.array_size = 6; - desc.bind_flags = BindFlag::DEPTH_STENCIL; - desc.format = Format::D16_UNORM; desc.height = envmapRes; desc.width = envmapRes; desc.mip_levels = 1; - desc.misc_flags = ResourceMiscFlag::TEXTURECUBE; desc.usage = Usage::DEFAULT; - desc.layout = ResourceState::DEPTHSTENCIL; + desc.bind_flags = BindFlag::DEPTH_STENCIL; + desc.format = Format::D16_UNORM; + desc.layout = ResourceState::DEPTHSTENCIL; + desc.misc_flags = ResourceMiscFlag::TRANSIENT_ATTACHMENT; device->CreateTexture(&desc, nullptr, &envrenderingDepthBuffer); device->SetName(&envrenderingDepthBuffer, "envrenderingDepthBuffer"); + desc.sample_count = envmapMSAASampleCount; + device->CreateTexture(&desc, nullptr, &envrenderingDepthBuffer_MSAA); + device->SetName(&envrenderingDepthBuffer_MSAA, "envrenderingDepthBuffer_MSAA"); + desc.bind_flags = BindFlag::RENDER_TARGET; + desc.format = Format::R11G11B10_FLOAT; + desc.layout = ResourceState::RENDERTARGET; + desc.misc_flags = ResourceMiscFlag::TRANSIENT_ATTACHMENT; + device->CreateTexture(&desc, nullptr, &envrenderingColorBuffer_MSAA); + device->SetName(&envrenderingColorBuffer_MSAA, "envrenderingColorBuffer_MSAA"); + + desc.sample_count = 1; desc.array_size = envmapCount * 6; - desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::RENDER_TARGET | BindFlag::UNORDERED_ACCESS; + desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS | BindFlag::RENDER_TARGET; desc.format = Format::R11G11B10_FLOAT; desc.height = envmapRes; desc.width = envmapRes; @@ -3758,32 +3769,7 @@ namespace wi::scene device->CreateTexture(&desc, nullptr, &envmapArray); device->SetName(&envmapArray, "envmapArray"); - renderpasses_envmap.resize(envmapCount); - - for (uint32_t i = 0; i < envmapCount; ++i) - { - int subresource_index; - subresource_index = device->CreateSubresource(&envmapArray, SubresourceType::RTV, i * 6, 6, 0, 1); - assert(subresource_index == i); - - RenderPassDesc renderpassdesc; - renderpassdesc.attachments.push_back( - RenderPassAttachment::RenderTarget(&envmapArray, - RenderPassAttachment::LoadOp::DONTCARE - ) - ); - renderpassdesc.attachments.back().subresource = subresource_index; - - renderpassdesc.attachments.push_back( - RenderPassAttachment::DepthStencil( - &envrenderingDepthBuffer, - RenderPassAttachment::LoadOp::CLEAR, - RenderPassAttachment::StoreOp::DONTCARE - ) - ); - - device->CreateRenderPass(&renderpassdesc, &renderpasses_envmap[subresource_index]); - } + // Cube arrays per mip level: for (uint32_t i = 0; i < envmapArray.desc.mip_levels; ++i) { int subresource_index; @@ -3793,13 +3779,83 @@ namespace wi::scene assert(subresource_index == i); } - // debug probe views, individual cubes: + // individual cubes with mips: for (uint32_t i = 0; i < envmapCount; ++i) { int subresource_index; subresource_index = device->CreateSubresource(&envmapArray, SubresourceType::SRV, i * 6, 6, 0, -1); assert(subresource_index == envmapArray.desc.mip_levels + i); } + + // individual cubes only mip0: + for (uint32_t i = 0; i < envmapCount; ++i) + { + int subresource_index; + subresource_index = device->CreateSubresource(&envmapArray, SubresourceType::SRV, i * 6, 6, 0, 1); + assert(subresource_index == envmapArray.desc.mip_levels + envmapCount + i); + } + + renderpasses_envmap.resize(envmapCount); + renderpasses_envmap_MSAA.resize(envmapCount); + for (uint32_t i = 0; i < envmapCount; ++i) + { + // Non MSAA: + { + int subresource_index; + subresource_index = device->CreateSubresource(&envmapArray, SubresourceType::RTV, i * 6, 6, 0, 1); + assert(subresource_index == i); + + RenderPassDesc renderpassdesc; + renderpassdesc.attachments.push_back( + RenderPassAttachment::DepthStencil( + &envrenderingDepthBuffer, + RenderPassAttachment::LoadOp::CLEAR, + RenderPassAttachment::StoreOp::DONTCARE + ) + ); + renderpassdesc.attachments.push_back( + RenderPassAttachment::RenderTarget(&envmapArray, + RenderPassAttachment::LoadOp::DONTCARE, + RenderPassAttachment::StoreOp::STORE, + ResourceState::SHADER_RESOURCE, + ResourceState::RENDERTARGET, + ResourceState::SHADER_RESOURCE, + subresource_index + ) + ); + device->CreateRenderPass(&renderpassdesc, &renderpasses_envmap[i]); + } + + // MSAA: + { + RenderPassDesc renderpassdesc; + renderpassdesc.attachments.clear(); + renderpassdesc.attachments.push_back( + RenderPassAttachment::DepthStencil( + &envrenderingDepthBuffer_MSAA, + RenderPassAttachment::LoadOp::CLEAR, + RenderPassAttachment::StoreOp::DONTCARE + ) + ); + renderpassdesc.attachments.push_back( + RenderPassAttachment::RenderTarget(&envrenderingColorBuffer_MSAA, + RenderPassAttachment::LoadOp::DONTCARE, + RenderPassAttachment::StoreOp::DONTCARE, + ResourceState::RENDERTARGET, + ResourceState::RENDERTARGET, + ResourceState::RENDERTARGET + ) + ); + renderpassdesc.attachments.push_back( + RenderPassAttachment::Resolve(&envmapArray, + ResourceState::SHADER_RESOURCE, + ResourceState::SHADER_RESOURCE, + envmapArray.desc.mip_levels + envmapCount + i // subresource: individual cubes only mip0 + ) + ); + device->CreateRenderPass(&renderpassdesc, &renderpasses_envmap_MSAA[i]); + } + } } // reconstruct envmap array status: diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h index 02de73a67..3eeff08ae 100644 --- a/WickedEngine/wiScene.h +++ b/WickedEngine/wiScene.h @@ -967,6 +967,7 @@ namespace wi::scene EMPTY = 0, DIRTY = 1 << 0, REALTIME = 1 << 1, + MSAA = 1 << 2, }; uint32_t _flags = DIRTY; @@ -979,9 +980,11 @@ namespace wi::scene inline void SetDirty(bool value = true) { if (value) { _flags |= DIRTY; } else { _flags &= ~DIRTY; } } inline void SetRealTime(bool value) { if (value) { _flags |= REALTIME; } else { _flags &= ~REALTIME; } } + inline void SetMSAA(bool value) { if (value) { _flags |= MSAA; } else { _flags &= ~MSAA; } } inline bool IsDirty() const { return _flags & DIRTY; } inline bool IsRealTime() const { return _flags & REALTIME; } + inline bool IsMSAA() const { return _flags & MSAA; } void Serialize(wi::Archive& archive, wi::ecs::EntitySerializer& seri); }; @@ -1385,9 +1388,13 @@ namespace wi::scene static constexpr uint32_t envmapCount = 16; static constexpr uint32_t envmapRes = 128; static constexpr uint32_t envmapMIPs = 8; + static constexpr uint32_t envmapMSAASampleCount = 8; wi::graphics::Texture envrenderingDepthBuffer; + wi::graphics::Texture envrenderingDepthBuffer_MSAA; + wi::graphics::Texture envrenderingColorBuffer_MSAA; wi::graphics::Texture envmapArray; wi::vector renderpasses_envmap; + wi::vector renderpasses_envmap_MSAA; // Impostor state: static constexpr uint32_t maxImpostorCount = 8; diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index de18bca0f..99926c1f7 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 = 60; // minor bug fixes, alterations, refactors, updates - const int revision = 96; + const int revision = 97; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);