foreground object rendering

This commit is contained in:
Turánszki János
2023-09-17 07:24:23 +02:00
parent 9383240fa7
commit 05fa9fd6dd
9 changed files with 196 additions and 48 deletions
+21 -1
View File
@@ -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, 700));
SetSize(XMFLOAT2(670, 730));
closeButton.SetTooltip("Delete ObjectComponent");
OnClose([=](wi::gui::EventArgs args) {
@@ -364,6 +364,24 @@ void ObjectWindow::Create(EditorComponent* _editor)
});
AddWidget(&navmeshCheckBox);
foregroundCheckBox.Create("Foreground: ");
foregroundCheckBox.SetTooltip("Set object to be rendered in the foreground. This is useful for first person hands or weapons.");
foregroundCheckBox.SetSize(XMFLOAT2(hei, hei));
foregroundCheckBox.SetPos(XMFLOAT2(x, y += step));
foregroundCheckBox.SetCheck(true);
foregroundCheckBox.OnClick([&](wi::gui::EventArgs args) {
wi::scene::Scene& scene = editor->GetCurrentScene();
for (auto& x : editor->translator.selected)
{
ObjectComponent* object = scene.objects.GetComponent(x.entity);
if (object != nullptr)
{
object->SetForeground(args.bValue);
}
}
});
AddWidget(&foregroundCheckBox);
ditherSlider.Create(0, 1, 0, 1000, "Transparency: ");
ditherSlider.SetTooltip("Adjust transparency of the object. Opaque materials will use dithered transparency in this case!");
ditherSlider.SetSize(XMFLOAT2(wid, hei));
@@ -672,6 +690,7 @@ void ObjectWindow::SetEntity(Entity entity)
renderableCheckBox.SetCheck(object->IsRenderable());
shadowCheckBox.SetCheck(object->IsCastingShadow());
foregroundCheckBox.SetCheck(object->IsForeground());
navmeshCheckBox.SetCheck(object->filterMask & wi::enums::FILTER_NAVIGATION_MESH);
cascadeMaskSlider.SetValue((float)object->cascadeMask);
ditherSlider.SetValue(object->GetTransparency());
@@ -747,6 +766,7 @@ void ObjectWindow::ResizeLayout()
add_right(renderableCheckBox);
add_right(shadowCheckBox);
add_right(foregroundCheckBox);
add_right(navmeshCheckBox);
add(ditherSlider);
add(cascadeMaskSlider);
+1
View File
@@ -14,6 +14,7 @@ public:
wi::gui::CheckBox renderableCheckBox;
wi::gui::CheckBox shadowCheckBox;
wi::gui::CheckBox navmeshCheckBox;
wi::gui::CheckBox foregroundCheckBox;
wi::gui::Slider ditherSlider;
wi::gui::Slider cascadeMaskSlider;
wi::gui::Slider lodSlider;
+4 -4
View File
@@ -5,21 +5,21 @@
#define TRANSPARENT_SHADOWMAP_SECONDARY_DEPTH_CHECK
#else
#define SHADOW_MASK_ENABLED
#endif
#endif // TRANSPARENT
#if !defined(TRANSPARENT) && !defined(PREPASS)
#define DISABLE_ALPHATEST
#endif
#endif // !defined(TRANSPARENT) && !defined(PREPASS)
#ifdef PLANARREFLECTION
#define DISABLE_ENVMAPS
#define DISABLE_VOXELGI
#endif
#endif // PLANARREFLECTION
#ifdef WATER
#define DISABLE_ENVMAPS
#define DISABLE_VOXELGI
#endif
#endif // WATER
#define LIGHTMAP_QUALITY_BICUBIC
@@ -5,6 +5,12 @@
//#define DISABLE_ENVMAPS
//#define DISABLE_SOFT_SHADOWMAP
//#define DISABLE_TRANSPARENT_SHADOWMAP
#ifdef PLANARREFLECTION
#define DISABLE_ENVMAPS
#define DISABLE_VOXELGI
#endif // PLANARREFLECTION
#include "globals.hlsli"
#include "ShaderInterop_Renderer.h"
#include "raytracingHF.hlsli"
+149 -33
View File
@@ -10,6 +10,7 @@ using namespace wi::enums;
namespace wi
{
static constexpr float foreground_depth_range = 0.01f;
void RenderPath3D::DeleteGPUResources()
{
@@ -832,15 +833,35 @@ namespace wi
device->EventBegin("Opaque Z-prepass", cmd);
auto range = wi::profiler::BeginRangeGPU("Z-Prepass", cmd);
Viewport vp;
vp.width = (float)depthBuffer_Main.GetDesc().width;
vp.height = (float)depthBuffer_Main.GetDesc().height;
device->BindViewports(1, &vp, cmd);
Rect scissor = GetScissorInternalResolution();
device->BindScissorRects(1, &scissor, cmd);
wi::renderer::DrawScene(visibility_main, RENDERPASS_PREPASS, cmd, drawscene_flags);
Viewport vp;
vp.width = (float)depthBuffer_Main.GetDesc().width;
vp.height = (float)depthBuffer_Main.GetDesc().height;
// Foreground:
vp.min_depth = 1 - foreground_depth_range;
vp.max_depth = 1;
device->BindViewports(1, &vp, cmd);
wi::renderer::DrawScene(
visibility_main,
RENDERPASS_PREPASS,
cmd,
wi::renderer::DRAWSCENE_OPAQUE |
wi::renderer::DRAWSCENE_FOREGROUND_ONLY
);
// Regular:
vp.min_depth = 0;
vp.max_depth = 1;
device->BindViewports(1, &vp, cmd);
wi::renderer::DrawScene(
visibility_main,
RENDERPASS_PREPASS,
cmd,
drawscene_flags
);
wi::profiler::EndRange(range);
device->EventEnd(cmd);
@@ -1041,11 +1062,6 @@ namespace wi
device->EventBegin("Planar reflections Z-Prepass", cmd);
auto range = wi::profiler::BeginRangeGPU("Planar Reflections Z-Prepass", cmd);
Viewport vp;
vp.width = (float)depthBuffer_Reflection.GetDesc().width;
vp.height = (float)depthBuffer_Reflection.GetDesc().height;
device->BindViewports(1, &vp, cmd);
RenderPassImage rp[] = {
RenderPassImage::DepthStencil(
&depthBuffer_Reflection,
@@ -1058,7 +1074,34 @@ namespace wi
};
device->RenderPassBegin(rp, arraysize(rp), cmd);
wi::renderer::DrawScene(visibility_reflection, RENDERPASS_PREPASS, cmd, wi::renderer::DRAWSCENE_OPAQUE | wi::renderer::DRAWSCENE_IMPOSTOR | wi::renderer::DRAWSCENE_SKIP_PLANAR_REFLECTION_OBJECTS);
Viewport vp;
vp.width = (float)depthBuffer_Reflection.GetDesc().width;
vp.height = (float)depthBuffer_Reflection.GetDesc().height;
// Foreground:
vp.min_depth = 1 - foreground_depth_range;
vp.max_depth = 1;
device->BindViewports(1, &vp, cmd);
wi::renderer::DrawScene(
visibility_reflection,
RENDERPASS_PREPASS,
cmd,
wi::renderer::DRAWSCENE_OPAQUE |
wi::renderer::DRAWSCENE_FOREGROUND_ONLY
);
// Regular:
vp.min_depth = 0;
vp.max_depth = 1;
device->BindViewports(1, &vp, cmd);
wi::renderer::DrawScene(
visibility_reflection,
RENDERPASS_PREPASS,
cmd,
wi::renderer::DRAWSCENE_OPAQUE |
wi::renderer::DRAWSCENE_IMPOSTOR |
wi::renderer::DRAWSCENE_SKIP_PLANAR_REFLECTION_OBJECTS
);
device->RenderPassEnd(cmd);
@@ -1111,11 +1154,6 @@ namespace wi
device->EventBegin("Planar reflections", cmd);
auto range = wi::profiler::BeginRangeGPU("Planar Reflections", cmd);
Viewport vp;
vp.width = (float)depthBuffer_Reflection.GetDesc().width;
vp.height = (float)depthBuffer_Reflection.GetDesc().height;
device->BindViewports(1, &vp, cmd);
RenderPassImage rp[] = {
RenderPassImage::RenderTarget(
&rtReflection,
@@ -1133,8 +1171,41 @@ namespace wi
};
device->RenderPassBegin(rp, arraysize(rp), cmd);
wi::renderer::DrawScene(visibility_reflection, RENDERPASS_MAIN, cmd, wi::renderer::DRAWSCENE_OPAQUE | wi::renderer::DRAWSCENE_IMPOSTOR | wi::renderer::DRAWSCENE_SKIP_PLANAR_REFLECTION_OBJECTS);
wi::renderer::DrawScene(visibility_reflection, RENDERPASS_MAIN, cmd, wi::renderer::DRAWSCENE_TRANSPARENT | wi::renderer::DRAWSCENE_SKIP_PLANAR_REFLECTION_OBJECTS); // separate renderscene, to be drawn after opaque and transparent sort order
Viewport vp;
vp.width = (float)depthBuffer_Reflection.GetDesc().width;
vp.height = (float)depthBuffer_Reflection.GetDesc().height;
// Foreground:
vp.min_depth = 1 - foreground_depth_range;
vp.max_depth = 1;
device->BindViewports(1, &vp, cmd);
wi::renderer::DrawScene(
visibility_reflection,
RENDERPASS_MAIN,
cmd,
wi::renderer::DRAWSCENE_OPAQUE |
wi::renderer::DRAWSCENE_FOREGROUND_ONLY
);
// Regular:
vp.min_depth = 0;
vp.max_depth = 1;
device->BindViewports(1, &vp, cmd);
wi::renderer::DrawScene(
visibility_reflection,
RENDERPASS_MAIN,
cmd,
wi::renderer::DRAWSCENE_OPAQUE |
wi::renderer::DRAWSCENE_IMPOSTOR |
wi::renderer::DRAWSCENE_SKIP_PLANAR_REFLECTION_OBJECTS
);
wi::renderer::DrawScene(
visibility_reflection,
RENDERPASS_MAIN,
cmd,
wi::renderer::DRAWSCENE_TRANSPARENT |
wi::renderer::DRAWSCENE_SKIP_PLANAR_REFLECTION_OBJECTS
); // separate renderscene, to be drawn after opaque and transparent sort order
wi::renderer::DrawSky(*scene, cmd);
if (scene->weather.IsRealisticSky() && scene->weather.IsRealisticSkyAerialPerspective())
@@ -1328,12 +1399,39 @@ namespace wi
if (visibility_shading_in_compute)
{
// In visibility compute shading, the impostors must still be drawn using rasterization:
wi::renderer::DrawScene(visibility_main, RENDERPASS_MAIN, cmd, wi::renderer::DRAWSCENE_IMPOSTOR);
wi::renderer::DrawScene(
visibility_main,
RENDERPASS_MAIN,
cmd,
wi::renderer::DRAWSCENE_IMPOSTOR
);
}
else
{
auto range = wi::profiler::BeginRangeGPU("Opaque Scene", cmd);
wi::renderer::DrawScene(visibility_main, RENDERPASS_MAIN, cmd, drawscene_flags);
// Foreground:
vp.min_depth = 1 - foreground_depth_range;
vp.max_depth = 1;
device->BindViewports(1, &vp, cmd);
wi::renderer::DrawScene(
visibility_main,
RENDERPASS_MAIN,
cmd,
wi::renderer::DRAWSCENE_OPAQUE |
wi::renderer::DRAWSCENE_FOREGROUND_ONLY
);
// Regular:
vp.min_depth = 0;
vp.max_depth = 1;
device->BindViewports(1, &vp, cmd);
wi::renderer::DrawScene(
visibility_main,
RENDERPASS_MAIN,
cmd,
drawscene_flags
);
wi::renderer::DrawSky(*scene, cmd);
wi::profiler::EndRange(range); // Opaque Scene
}
@@ -1750,11 +1848,6 @@ namespace wi
};
device->RenderPassBegin(rp, getMSAASampleCount() > 1 ? 3 : 2, cmd);
Viewport vp;
vp.width = (float)depthBuffer_Main.GetDesc().width;
vp.height = (float)depthBuffer_Main.GetDesc().height;
device->BindViewports(1, &vp, cmd);
Rect scissor = GetScissorInternalResolution();
device->BindScissorRects(1, &scissor, cmd);
@@ -1763,13 +1856,36 @@ namespace wi
auto range = wi::profiler::BeginRangeGPU("Transparent Scene", cmd);
device->EventBegin("Transparent Scene", cmd);
uint32_t drawscene_flags = 0;
drawscene_flags |= wi::renderer::DRAWSCENE_TRANSPARENT;
drawscene_flags |= wi::renderer::DRAWSCENE_OCCLUSIONCULLING;
drawscene_flags |= wi::renderer::DRAWSCENE_HAIRPARTICLE;
drawscene_flags |= wi::renderer::DRAWSCENE_TESSELLATION;
drawscene_flags |= wi::renderer::DRAWSCENE_OCEAN;
wi::renderer::DrawScene(visibility_main, RENDERPASS_MAIN, cmd, drawscene_flags);
Viewport vp;
vp.width = (float)depthBuffer_Main.GetDesc().width;
vp.height = (float)depthBuffer_Main.GetDesc().height;
// Foreground:
vp.min_depth = 1 - foreground_depth_range;
vp.max_depth = 1;
device->BindViewports(1, &vp, cmd);
wi::renderer::DrawScene(
visibility_main,
RENDERPASS_MAIN,
cmd,
wi::renderer::DRAWSCENE_TRANSPARENT |
wi::renderer::DRAWSCENE_FOREGROUND_ONLY
);
// Regular:
vp.min_depth = 0;
vp.max_depth = 1;
device->BindViewports(1, &vp, cmd);
wi::renderer::DrawScene(
visibility_main,
RENDERPASS_MAIN,
cmd,
wi::renderer::DRAWSCENE_TRANSPARENT |
wi::renderer::DRAWSCENE_OCCLUSIONCULLING |
wi::renderer::DRAWSCENE_HAIRPARTICLE |
wi::renderer::DRAWSCENE_TESSELLATION |
wi::renderer::DRAWSCENE_OCEAN
);
device->EventEnd(cmd);
wi::profiler::EndRange(range); // Transparent Scene
+2 -1
View File
@@ -5651,6 +5651,7 @@ void DrawScene(
const bool occlusion = (flags & DRAWSCENE_OCCLUSIONCULLING) && GetOcclusionCullingEnabled();
const bool ocean = flags & DRAWSCENE_OCEAN;
const bool skip_planar_reflection_objects = flags & DRAWSCENE_SKIP_PLANAR_REFLECTION_OBJECTS;
const bool foreground_only = flags & DRAWSCENE_FOREGROUND_ONLY;
device->EventBegin("DrawScene", cmd);
device->BindShadingRate(ShadingRate::RATE_1X1, cmd);
@@ -5689,7 +5690,7 @@ void DrawScene(
continue;
const ObjectComponent& object = vis.scene->objects[instanceIndex];
if (object.IsRenderable() && (object.GetFilterMask() & filterMask))
if (object.IsRenderable() && object.IsForeground() == foreground_only && (object.GetFilterMask() & filterMask))
{
const float distance = wi::math::Distance(vis.camera->Eye, object.center);
if (distance > object.fadeDistance + object.radius)
+9 -8
View File
@@ -199,14 +199,15 @@ namespace wi::renderer
enum DRAWSCENE_FLAGS
{
DRAWSCENE_OPAQUE = 1 << 0,
DRAWSCENE_TRANSPARENT = 1 << 1,
DRAWSCENE_OCCLUSIONCULLING = 1 << 2,
DRAWSCENE_TESSELLATION = 1 << 3,
DRAWSCENE_HAIRPARTICLE = 1 << 4,
DRAWSCENE_IMPOSTOR = 1 << 5,
DRAWSCENE_OCEAN = 1 << 6,
DRAWSCENE_SKIP_PLANAR_REFLECTION_OBJECTS = 1 << 7,
DRAWSCENE_OPAQUE = 1 << 0, // include opaque objects
DRAWSCENE_TRANSPARENT = 1 << 1, // include transparent objects
DRAWSCENE_OCCLUSIONCULLING = 1 << 2, // enable skipping objects based on occlusion culling results
DRAWSCENE_TESSELLATION = 1 << 3, // enable tessellation
DRAWSCENE_HAIRPARTICLE = 1 << 4, // include hair particles
DRAWSCENE_IMPOSTOR = 1 << 5, // include impostors
DRAWSCENE_OCEAN = 1 << 6, // include ocean
DRAWSCENE_SKIP_PLANAR_REFLECTION_OBJECTS = 1 << 7, // don't draw subsets which have planar reflection material
DRAWSCENE_FOREGROUND_ONLY = 1 << 8, // only include objects that are tagged as foreground
};
// Draw the world from a camera. You must call BindCameraCB() at least once in this frame prior to this
+3
View File
@@ -665,6 +665,7 @@ namespace wi::scene
REQUEST_PLANAR_REFLECTION = 1 << 4,
LIGHTMAP_RENDER_REQUEST = 1 << 5,
LIGHTMAP_DISABLE_BLOCK_COMPRESSION = 1 << 6,
FOREGROUND = 1 << 7,
};
uint32_t _flags = RENDERABLE | CAST_SHADOW;
@@ -703,6 +704,7 @@ namespace wi::scene
inline void SetRequestPlanarReflection(bool value) { if (value) { _flags |= REQUEST_PLANAR_REFLECTION; } else { _flags &= ~REQUEST_PLANAR_REFLECTION; } }
inline void SetLightmapRenderRequest(bool value) { if (value) { _flags |= LIGHTMAP_RENDER_REQUEST; } else { _flags &= ~LIGHTMAP_RENDER_REQUEST; } }
inline void SetLightmapDisableBlockCompression(bool value) { if (value) { _flags |= LIGHTMAP_DISABLE_BLOCK_COMPRESSION; } else { _flags &= ~LIGHTMAP_DISABLE_BLOCK_COMPRESSION; } }
inline void SetForeground(bool value) { if (value) { _flags |= FOREGROUND; } else { _flags &= ~FOREGROUND; } }
inline bool IsRenderable() const { return _flags & RENDERABLE; }
inline bool IsCastingShadow() const { return _flags & CAST_SHADOW; }
@@ -710,6 +712,7 @@ namespace wi::scene
inline bool IsRequestPlanarReflection() const { return _flags & REQUEST_PLANAR_REFLECTION; }
inline bool IsLightmapRenderRequested() const { return _flags & LIGHTMAP_RENDER_REQUEST; }
inline bool IsLightmapDisableBlockCompression() const { return _flags & LIGHTMAP_DISABLE_BLOCK_COMPRESSION; }
inline bool IsForeground() const { return _flags & FOREGROUND; }
inline float GetTransparency() const { return 1 - color.w; }
inline uint32_t GetFilterMask() const { return filterMask | filterMaskDynamic; }
+1 -1
View File
@@ -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 = 287;
const int revision = 288;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);