diff --git a/Editor/ObjectWindow.cpp b/Editor/ObjectWindow.cpp index c541f9e98..7d7f7e8f1 100644 --- a/Editor/ObjectWindow.cpp +++ b/Editor/ObjectWindow.cpp @@ -44,6 +44,18 @@ ObjectWindow::ObjectWindow(wiGUI* gui) : GUI(gui) }); objectWindow->AddWidget(ditherSlider); + cascadeMaskSlider = new wiSlider(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(100, 30)); + cascadeMaskSlider->SetPos(XMFLOAT2(x, y += 30)); + cascadeMaskSlider->OnSlide([&](wiEventArgs args) { + if (object != nullptr) + { + object->cascadeMask = args.iValue; + } + }); + objectWindow->AddWidget(cascadeMaskSlider); + colorPicker = new wiColorPicker(GUI, "Object Color"); colorPicker->SetPos(XMFLOAT2(10, 30)); @@ -241,6 +253,7 @@ void ObjectWindow::SetObject(Object* obj) if (object != nullptr) { renderableCheckBox->SetCheck(object->renderable); + cascadeMaskSlider->SetValue((float)object->cascadeMask); ditherSlider->SetValue(object->transparency); if (object->rigidBody) diff --git a/Editor/ObjectWindow.h b/Editor/ObjectWindow.h index e8ae9a411..b85420de6 100644 --- a/Editor/ObjectWindow.h +++ b/Editor/ObjectWindow.h @@ -26,6 +26,7 @@ public: wiCheckBox* renderableCheckBox; wiSlider* ditherSlider; + wiSlider* cascadeMaskSlider; wiColorPicker* colorPicker; wiLabel* physicsLabel; diff --git a/WickedEngine/ArchiveVersionHistory.txt b/WickedEngine/ArchiveVersionHistory.txt index bbc7fa06c..2745ec172 100644 --- a/WickedEngine/ArchiveVersionHistory.txt +++ b/WickedEngine/ArchiveVersionHistory.txt @@ -1,5 +1,6 @@ This file contains changelog of wiArchive versions +19: serialized object cascade mask 18: serialized emitter properties: sph properties, fixed timestep 17: serialized light scattering property 16: environment probes are now serialized into Model diff --git a/WickedEngine/wiArchive.cpp b/WickedEngine/wiArchive.cpp index 841db8d4d..97888895c 100644 --- a/WickedEngine/wiArchive.cpp +++ b/WickedEngine/wiArchive.cpp @@ -7,7 +7,7 @@ using namespace std; // this should always be only INCREMENTED and only if a new serialization is implemeted somewhere! -uint64_t __archiveVersion = 18; +uint64_t __archiveVersion = 19; // this is the version number of which below the archive is not compatible with the current version uint64_t __archiveVersionBarrier = 1; diff --git a/WickedEngine/wiLoader.cpp b/WickedEngine/wiLoader.cpp index 22bf2a809..148c3b14a 100644 --- a/WickedEngine/wiLoader.cpp +++ b/WickedEngine/wiLoader.cpp @@ -4390,6 +4390,10 @@ void Object::Serialize(wiArchive& archive) { archive >> renderable; } + if (archive.GetVersion() >= 19) + { + archive >> cascadeMask; + } } else @@ -4421,6 +4425,10 @@ void Object::Serialize(wiArchive& archive) { archive << renderable; } + if (archive.GetVersion() >= 19) + { + archive << cascadeMask; + } } } diff --git a/WickedEngine/wiLoader.h b/WickedEngine/wiLoader.h index 198e42b60..04ec193aa 100644 --- a/WickedEngine/wiLoader.h +++ b/WickedEngine/wiLoader.h @@ -523,6 +523,7 @@ struct Object : public Cullable, public Transform Mesh* mesh; bool renderable; + int cascadeMask = 0; // which shadow cascades to skip (0: skip none, 1: skip first, etc...) //PARTICLE std::vector< wiEmittedParticle* > eParticleSystems; diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 2ae941dcb..2482c7be5 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -4801,21 +4801,25 @@ void wiRenderer::DrawForShadowMap(GRAPHICSTHREAD threadID) break; shadowCounter_2D += 3; // shadow indices are already complete so a shadow slot is consumed here even if no rendering actually happens! - for (int index = 0; index < 3; ++index) + for (int cascade = 0; cascade < 3; ++cascade) { - const float siz = l->shadowCam_dirLight[index].size * 0.5f; - const float f = l->shadowCam_dirLight[index].farplane; + const float siz = l->shadowCam_dirLight[cascade].size * 0.5f; + const float f = l->shadowCam_dirLight[cascade].farplane * 0.5f; AABB boundingbox; - boundingbox.createFromHalfWidth(XMFLOAT3(0, 0, 0), XMFLOAT3(siz, f, siz)); + boundingbox.createFromHalfWidth(XMFLOAT3(0, 0, 0), XMFLOAT3(siz, siz, f)); if (spTree != nullptr) { CulledList culledObjects; CulledCollection culledRenderer; - spTree->getVisible(boundingbox.get(XMMatrixInverse(0, XMLoadFloat4x4(&l->shadowCam_dirLight[index].View))), culledObjects); + spTree->getVisible(boundingbox.get(XMMatrixInverse(0, XMLoadFloat4x4(&l->shadowCam_dirLight[cascade].View))), culledObjects); bool transparentShadowsRequested = false; for (Cullable* x : culledObjects) { Object* object = (Object*)x; + if (cascade < object->cascadeMask) + { + continue; + } if (object->IsCastingShadow()) { culledRenderer[object->mesh].push_front(object); @@ -4829,17 +4833,17 @@ void wiRenderer::DrawForShadowMap(GRAPHICSTHREAD threadID) if (!culledRenderer.empty()) { CameraCB cb; - cb.mVP = l->shadowCam_dirLight[index].getVP(); + cb.mVP = l->shadowCam_dirLight[cascade].getVP(); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_CAMERA], &cb, threadID); - GetDevice()->ClearDepthStencil(Light::shadowMapArray_2D, CLEAR_DEPTH, 0.0f, 0, threadID, l->shadowMap_index + index); + GetDevice()->ClearDepthStencil(Light::shadowMapArray_2D, CLEAR_DEPTH, 0.0f, 0, threadID, l->shadowMap_index + cascade); - // unfortunately wi will always have to clear the associated transparent shadowmap to avoid discrepancy with shadowmap indexing changes across frames - GetDevice()->ClearRenderTarget(Light::shadowMapArray_Transparent, transparentShadowClearColor, threadID, l->shadowMap_index + index); + // unfortunately we will always have to clear the associated transparent shadowmap to avoid discrepancy with shadowmap indexing changes across frames + GetDevice()->ClearRenderTarget(Light::shadowMapArray_Transparent, transparentShadowClearColor, threadID, l->shadowMap_index + cascade); // render opaque shadowmap: - GetDevice()->BindRenderTargets(0, nullptr, Light::shadowMapArray_2D, threadID, l->shadowMap_index + index); - RenderMeshes(l->shadowCam_dirLight[index].Eye, culledRenderer, SHADERTYPE_SHADOW, RENDERTYPE_OPAQUE, threadID); + GetDevice()->BindRenderTargets(0, nullptr, Light::shadowMapArray_2D, threadID, l->shadowMap_index + cascade); + RenderMeshes(l->shadowCam_dirLight[cascade].Eye, culledRenderer, SHADERTYPE_SHADOW, RENDERTYPE_OPAQUE, threadID); if (GetTransparentShadowsEnabled() && transparentShadowsRequested) { @@ -4847,8 +4851,8 @@ void wiRenderer::DrawForShadowMap(GRAPHICSTHREAD threadID) Texture2D* rts[] = { Light::shadowMapArray_Transparent }; - GetDevice()->BindRenderTargets(ARRAYSIZE(rts), rts, Light::shadowMapArray_2D, threadID, l->shadowMap_index + index); - RenderMeshes(l->shadowCam_dirLight[index].Eye, culledRenderer, SHADERTYPE_SHADOW, RENDERTYPE_TRANSPARENT | RENDERTYPE_WATER, threadID); + GetDevice()->BindRenderTargets(ARRAYSIZE(rts), rts, Light::shadowMapArray_2D, threadID, l->shadowMap_index + cascade); + RenderMeshes(l->shadowCam_dirLight[cascade].Eye, culledRenderer, SHADERTYPE_SHADOW, RENDERTYPE_TRANSPARENT | RENDERTYPE_WATER, threadID); } } } @@ -4890,7 +4894,7 @@ void wiRenderer::DrawForShadowMap(GRAPHICSTHREAD threadID) GetDevice()->ClearDepthStencil(Light::shadowMapArray_2D, CLEAR_DEPTH, 0.0f, 0, threadID, l->shadowMap_index); - // unfortunately wi will always have to clear the associated transparent shadowmap to avoid discrepancy with shadowmap indexing changes across frames + // unfortunately we will always have to clear the associated transparent shadowmap to avoid discrepancy with shadowmap indexing changes across frames GetDevice()->ClearRenderTarget(Light::shadowMapArray_Transparent, transparentShadowClearColor, threadID, l->shadowMap_index); // render opaque shadowmap: diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 17e15cdfa..161e0d758 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wiVersion // minor features, major updates const int minor = 17; // minor bug fixes, alterations, refactors, updates - const int revision = 23; + const int revision = 24; long GetVersion()