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
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS> 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++;
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
+88
-32
@@ -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:
|
||||
|
||||
@@ -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<wi::graphics::RenderPass> renderpasses_envmap;
|
||||
wi::vector<wi::graphics::RenderPass> renderpasses_envmap_MSAA;
|
||||
|
||||
// Impostor state:
|
||||
static constexpr uint32_t maxImpostorCount = 8;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user