Starting to optimize shadow caster list

This commit is contained in:
lawnjelly 2019-09-26 08:53:15 +01:00 committed by GitHub
parent 7dd45301fa
commit 47fc1fa319
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 206 additions and 36 deletions

View File

@ -1,9 +1,11 @@
#pragma once #pragma once
#define LPRINT_RUN(a, b) {String sz;\ #define LPRINT_RUN(a, b) ;
for (int n=0; n<Lawn::LDebug::m_iTabDepth; n++)\
sz += "\t";\ //#define LPRINT_RUN(a, b) {String sz;\
LPRINT(a, sz + b);} //for (int n=0; n<Lawn::LDebug::m_iTabDepth; n++)\
//sz += "\t";\
//LPRINT(a, sz + b);}
#define LPRINT(a, b) if (!Lawn::LDebug::m_bRunning) {\ #define LPRINT(a, b) if (!Lawn::LDebug::m_bRunning) {\
if (a >= Lawn::LDebug::m_iLoggingLevel)\ if (a >= Lawn::LDebug::m_iLoggingLevel)\

View File

@ -33,6 +33,14 @@
class LRoom; class LRoom;
class LRoomManager; class LRoomManager;
class LLight
{
public:
Vector3 m_ptDir;
};
class LPortal { class LPortal {
public: public:

View File

@ -36,6 +36,9 @@ LRoom::LRoom() {
m_iFirstSOB = 0; m_iFirstSOB = 0;
m_iNumSOBs = 0; m_iNumSOBs = 0;
m_iFirstShadowCaster_SOB = 0;
m_iNumShadowCasters_SOB = 0;
} }
@ -169,17 +172,19 @@ void LRoom::SoftShow(VisualInstance * pVI, bool bShow)
// naive version, adds all the non visible objects in visible rooms as shadow casters // naive version, adds all the non visible objects in visible rooms as shadow casters
void LRoom::AddShadowCasters(LRoomManager &manager) void LRoom::AddShadowCasters(LRoomManager &manager)
{ {
// return;
int last_sob = m_iFirstSOB + m_iNumSOBs; int last_sob = m_iFirstSOB + m_iNumSOBs;
for (int n=m_iFirstSOB; n<last_sob; n++) for (int n=m_iFirstSOB; n<last_sob; n++)
{ {
bool bVisible = manager.m_BF_visible_SOBs.GetBit(n) != 0; // bool bVisible = manager.m_BF_visible_SOBs.GetBit(n) != 0;
// already in list // // already in list
if (bVisible) // if (bVisible)
continue; // continue;
manager.m_BF_render_SOBs.SetBit(n, true); manager.m_BF_caster_SOBs.SetBit(n, true);
manager.m_RenderList_SOBs.push_back(n); manager.m_CasterList_SOBs.push_back(n);
} }
} }
@ -189,22 +194,23 @@ void LRoom::AddShadowCasters(LRoomManager &manager)
// (it might be expensive) // (it might be expensive)
void LRoom::FinalizeVisibility(LRoomManager &manager) void LRoom::FinalizeVisibility(LRoomManager &manager)
{ {
int last_sob = m_iFirstSOB + m_iNumSOBs;
for (int n=m_iFirstSOB; n<last_sob; n++)
{
LSob &sob = manager.m_SOBs[n];
Spatial * pS = sob.GetSpatial();
if (!pS)
continue;
if (manager.m_BF_master_SOBs.GetBit(n))
pS->show();
else
pS->hide();
}
//print_line("FinalizeVisibility room " + get_name() + " NumSOBs " + itos(m_SOBs.size()) + ", NumDOBs " + itos(m_DOBs.size())); //print_line("FinalizeVisibility room " + get_name() + " NumSOBs " + itos(m_SOBs.size()) + ", NumDOBs " + itos(m_DOBs.size()));
// int last_sob = m_iFirstSOB + m_iNumSOBs;
// for (int n=m_iFirstSOB; n<last_sob; n++)
// {
// const LSob &sob = manager.m_SOBs[n];
// VisualInstance * pVI = sob.GetVI();
// if (pVI)
// {
// //SoftShow(pVI, sob.m_bSOBVisible);
// bool bVisible = manager.m_BF_visible_SOBs.GetBit(n) != 0;
// SoftShow(pVI, bVisible);
// }
// }
for (int n=0; n<m_DOBs.size(); n++) for (int n=0; n<m_DOBs.size(); n++)
{ {
const LDob &dob = m_DOBs[n]; const LDob &dob = m_DOBs[n];
@ -402,8 +408,8 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons
//sob.m_bSOBVisible = true; //sob.m_bSOBVisible = true;
// sob is renderable and visible (not shadow only) // sob is renderable and visible (not shadow only)
manager.m_BF_visible_SOBs.SetBit(n, true); manager.m_BF_visible_SOBs.SetBit(n, true);
manager.m_BF_render_SOBs.SetBit(n, true); //manager.m_BF_render_SOBs.SetBit(n, true);
manager.m_RenderList_SOBs.push_back(n); manager.m_VisibleList_SOBs.push_back(n);
} }
} // for through sobs } // for through sobs

View File

@ -68,6 +68,9 @@ public:
int m_iFirstPortal; int m_iFirstPortal;
int m_iNumPortals; int m_iNumPortals;
int m_iFirstShadowCaster_SOB;
int m_iNumShadowCasters_SOB;
// Just very rough, room centre for determining start rooms of dobs // Just very rough, room centre for determining start rooms of dobs
Vector3 m_ptCentre; Vector3 m_ptCentre;
AABB m_AABB; // world bound AABB m_AABB; // world bound

View File

@ -42,6 +42,8 @@ void LRoomConverter::Convert(LRoomManager &manager)
int count = CountRooms(); int count = CountRooms();
LMAN->m_SOBs.clear(); LMAN->m_SOBs.clear();
LMAN->m_ShadowCasters_SOB.clear();
LMAN->m_Lights.clear();
// make sure bitfield is right size for number of rooms // make sure bitfield is right size for number of rooms
LMAN->m_BF_visible_rooms.Create(count); LMAN->m_BF_visible_rooms.Create(count);
@ -57,21 +59,26 @@ void LRoomConverter::Convert(LRoomManager &manager)
Convert_Rooms(); Convert_Rooms();
Convert_Portals(); Convert_Portals();
Convert_Bounds(); Convert_Bounds();
Convert_ShadowCasters();
// make sure manager bitfields are the correct size for number of objects // make sure manager bitfields are the correct size for number of objects
int num_sobs = LMAN->m_SOBs.size(); int num_sobs = LMAN->m_SOBs.size();
LPRINT(5,"Total SOBs " + itos(num_sobs)); LPRINT(5,"Total SOBs " + itos(num_sobs));
LMAN->m_BF_render_SOBs.Create(num_sobs); LMAN->m_BF_caster_SOBs.Create(num_sobs);
LMAN->m_BF_visible_SOBs.Create(num_sobs); LMAN->m_BF_visible_SOBs.Create(num_sobs);
LMAN->m_BF_master_SOBs.Create(num_sobs);
// temp rooms no longer needed // temp rooms no longer needed
m_TempRooms.clear(true); m_TempRooms.clear(true);
Lawn::LDebug::m_bRunning = true; Lawn::LDebug::m_bRunning = true;
} }
void LRoomConverter::Convert_Rooms() void LRoomConverter::Convert_Rooms()
{ {
LPRINT(5,"Convert_Rooms"); LPRINT(5,"Convert_Rooms");
@ -286,6 +293,18 @@ bool LRoomConverter::Convert_Bound(LRoom &lroom, MeshInstance * pMI)
return false; return false;
} }
void LRoomConverter::Convert_ShadowCasters()
{
LPRINT(5,"Convert_ShadowCasters");
for (int n=0; n<LMAN->m_Rooms.size(); n++)
{
LRoom &lroom = LMAN->m_Rooms[n];
LRoom_FindShadowCasters(lroom);
}
}
void LRoomConverter::Convert_Bounds() void LRoomConverter::Convert_Bounds()
{ {
for (int n=0; n<LMAN->m_Rooms.size(); n++) for (int n=0; n<LMAN->m_Rooms.size(); n++)
@ -364,6 +383,94 @@ int LRoomConverter::CountRooms()
} }
// find all objects that cast shadows onto the objects in this room
void LRoomConverter::LRoom_FindShadowCasters(LRoom &lroom)
{
return;
// first add all objects in this room as casters
for (int n=0; n<lroom.m_iNumSOBs; n++)
{
}
// just a constant light direction for now
LLight light;
light.m_ptDir = Vector3(1.0f, -1.0f, 0.0f);
light.m_ptDir.normalize();
// reset the planes pool for each render out from the source room
LMAN->m_Pool.Reset();
// the first set of planes are blank
unsigned int pool_member = LMAN->m_Pool.Request();
assert (pool_member != -1);
LVector<Plane> &planes = LMAN->m_Pool.Get(pool_member);
planes.clear();
LRoom_FindShadowCasters_Recursive(lroom, light, planes);
}
void LRoomConverter::LRoom_FindShadowCasters_Recursive(LRoom &lroom, const LLight &light, const LVector<Plane> &planes)
{
// look through every portal out
for (int n=0; n<lroom.m_iNumPortals; n++)
{
int portalID = lroom.m_iFirstPortal + n;
const LPortal &port = LMAN->m_Portals[portalID];
// cull with light direction
float dot = port.m_Plane.normal.dot(light.m_ptDir);
if (dot <= 0.0f)
continue;
LRoom &linked_room = LMAN->Portal_GetLinkedRoom(port);
// recurse into that portal
unsigned int uiPoolMem = LMAN->m_Pool.Request();
if (uiPoolMem != -1)
{
// get a vector of planes from the pool
LVector<Plane> &new_planes = LMAN->m_Pool.Get(uiPoolMem);
// copy the existing planes
new_planes.copy_from(planes);
// add the planes for the portal
// port.AddPlanes(manager, cam.m_ptPos, new_planes);
LRoom_FindShadowCasters_Recursive(linked_room, light, new_planes);
// for debugging need to reset tab depth
//Lawn::LDebug::m_iTabDepth = depth;
// we no longer need these planes
LMAN->m_Pool.Free(uiPoolMem);
}
else
{
// planes pool is empty!
// This will happen if the view goes through shedloads of portals
// The solution is either to increase the plane pool size, or build levels
// with views through multiple portals. Looking through multiple portals is likely to be
// slow anyway because of the number of planes to test.
WARN_PRINT_ONCE("LRoom_FindShadowCasters_Recursive : Planes pool is empty");
}
}
}
// go through the nodes hanging off the room looking for those that are meshes to mark portal locations // go through the nodes hanging off the room looking for those that are meshes to mark portal locations
void LRoomConverter::LRoom_DetectPortalMeshes(LRoom &lroom, LTempRoom &troom) void LRoomConverter::LRoom_DetectPortalMeshes(LRoom &lroom, LTempRoom &troom)
{ {

View File

@ -93,6 +93,7 @@ private:
void Convert_Portals(); void Convert_Portals();
void Convert_Bounds(); void Convert_Bounds();
bool Convert_Bound(LRoom &lroom, MeshInstance * pMI); bool Convert_Bound(LRoom &lroom, MeshInstance * pMI);
void Convert_ShadowCasters();
void LRoom_DetectPortalMeshes(LRoom &lroom, LTempRoom &troom); void LRoom_DetectPortalMeshes(LRoom &lroom, LTempRoom &troom);
@ -101,6 +102,8 @@ private:
void LRoom_DetectedPortalMesh(LRoom &lroom, LTempRoom &troom, MeshInstance * pMeshInstance, String szLinkRoom); void LRoom_DetectedPortalMesh(LRoom &lroom, LTempRoom &troom, MeshInstance * pMeshInstance, String szLinkRoom);
LPortal * LRoom_RequestNewPortal(LRoom &lroom); LPortal * LRoom_RequestNewPortal(LRoom &lroom);
void LRoom_PushBackSOB(LRoom &lroom, const LSob &sob); void LRoom_PushBackSOB(LRoom &lroom, const LSob &sob);
void LRoom_FindShadowCasters(LRoom &lroom);
void LRoom_FindShadowCasters_Recursive(LRoom &lroom, const LLight &light, const LVector<Plane> &planes);
void TRoom_MakeOppositePortal(const LPortal &port, int iRoomOrig); void TRoom_MakeOppositePortal(const LPortal &port, int iRoomOrig);

View File

@ -602,9 +602,13 @@ void LRoomManager::FrameUpdate_Prepare()
m_DebugPlanes.clear(); m_DebugPlanes.clear();
// clear the visible room list to write to each frame // clear the visible room list to write to each frame
m_pCurr_VisibleRoomList->clear(); m_pCurr_VisibleRoomList->clear();
m_RenderList_SOBs.clear();
m_BF_render_SOBs.Blank(); m_VisibleList_SOBs.clear();
m_CasterList_SOBs.clear();
m_BF_caster_SOBs.Blank();
m_BF_visible_SOBs.Blank(); m_BF_visible_SOBs.Blank();
m_BF_master_SOBs.Blank();
// as we hit visible rooms we will mark them in a bitset, so we can hide any rooms // as we hit visible rooms we will mark them in a bitset, so we can hide any rooms
// that are showing that haven't been hit this frame // that are showing that haven't been hit this frame
@ -695,11 +699,13 @@ void LRoomManager::FrameUpdate()
// finally hide all the rooms that are currently visible but not in the visible bitfield as having been hit // finally hide all the rooms that are currently visible but not in the visible bitfield as having been hit
FrameUpdate_FinalizeRooms(); FrameUpdate_FinalizeRooms();
FrameUpdate_AddShadowCasters();
FrameUpdate_CreateMasterList();
// set soft visibility of objects within visible rooms // set soft visibility of objects within visible rooms
FrameUpdate_FinalizeVisibility_WithinRooms(); FrameUpdate_FinalizeVisibility_WithinRooms();
FrameUpdate_AddShadowCasters();
FrameUpdate_FinalizeVisibility_SoftShow(); FrameUpdate_FinalizeVisibility_SoftShow();
// swap the current and previous visible room list // swap the current and previous visible room list
@ -745,6 +751,32 @@ void LRoomManager::FrameUpdate_FinalizeRooms()
} }
} }
// to optimize just 1 call to the visual server, we want a list of all sobs that are either visible or casters
// this allows 1 call to show / hide, and 1 call to layer flags
void LRoomManager::FrameUpdate_CreateMasterList()
{
for (int n=0; n<m_VisibleList_SOBs.size(); n++)
{
int sob_id = m_VisibleList_SOBs[n];
m_MasterList_SOBs.push_back(sob_id);
m_BF_master_SOBs.SetBit(sob_id, true);
}
for (int n=0; n<m_CasterList_SOBs.size(); n++)
{
int sob_id = m_CasterList_SOBs[n];
// if not already on master list
if (m_BF_master_SOBs.GetBit(sob_id) == 0)
{
m_MasterList_SOBs.push_back(sob_id);
m_BF_master_SOBs.SetBit(sob_id, true);
}
}
}
void LRoomManager::FrameUpdate_AddShadowCasters() void LRoomManager::FrameUpdate_AddShadowCasters()
{ {
// simple for the moment, add all objects in visible rooms as casters if they are not already visible // simple for the moment, add all objects in visible rooms as casters if they are not already visible
@ -759,11 +791,11 @@ void LRoomManager::FrameUpdate_AddShadowCasters()
void LRoomManager::FrameUpdate_FinalizeVisibility_SoftShow() void LRoomManager::FrameUpdate_FinalizeVisibility_SoftShow()
{ {
// apply the appropriate soft show for each sob in the render list // apply the appropriate soft show for each sob in the render list
int nSOBs = m_RenderList_SOBs.size(); int nSOBs = m_MasterList_SOBs.size();
for (int n=0; n<nSOBs; n++) for (int n=0; n<nSOBs; n++)
{ {
int ID = m_RenderList_SOBs[n]; int ID = m_MasterList_SOBs[n];
const LSob &sob = m_SOBs[ID]; const LSob &sob = m_SOBs[ID];
VisualInstance * pVI = sob.GetVI(); VisualInstance * pVI = sob.GetVI();

View File

@ -52,11 +52,15 @@ class LRoomManager : public Spatial {
// the render list is all objects that are in view, // the render list is all objects that are in view,
// and also objects out of view but casting shadows INTO the view // and also objects out of view but casting shadows INTO the view
LVector<int> m_RenderList_SOBs; LVector<int> m_VisibleList_SOBs;
Lawn::LBitField_Dynamic m_BF_render_SOBs; LVector<int> m_CasterList_SOBs;
LVector<int> m_MasterList_SOBs;
// visible bit marks in view, if not set, it is a shadow caster only
Lawn::LBitField_Dynamic m_BF_visible_SOBs; Lawn::LBitField_Dynamic m_BF_visible_SOBs;
Lawn::LBitField_Dynamic m_BF_caster_SOBs;
Lawn::LBitField_Dynamic m_BF_master_SOBs;
LVector<int> m_VisibleRoomList_A; LVector<int> m_VisibleRoomList_A;
LVector<int> m_VisibleRoomList_B; LVector<int> m_VisibleRoomList_B;
@ -81,6 +85,10 @@ private:
// static objects // static objects
LVector<LSob> m_SOBs; LVector<LSob> m_SOBs;
LVector<LLight> m_Lights;
// master list of shadow casters for each room
LVector<uint32_t> m_ShadowCasters_SOB;
protected: protected:
static void _bind_methods(); static void _bind_methods();
@ -98,6 +106,7 @@ private:
void FrameUpdate_Prepare(); void FrameUpdate_Prepare();
void FrameUpdate_FinalizeRooms(); void FrameUpdate_FinalizeRooms();
void FrameUpdate_AddShadowCasters(); void FrameUpdate_AddShadowCasters();
void FrameUpdate_CreateMasterList();
void FrameUpdate_FinalizeVisibility_WithinRooms(); void FrameUpdate_FinalizeVisibility_WithinRooms();
void FrameUpdate_FinalizeVisibility_SoftShow(); void FrameUpdate_FinalizeVisibility_SoftShow();