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
#define LPRINT_RUN(a, b) {String sz;\
for (int n=0; n<Lawn::LDebug::m_iTabDepth; n++)\
sz += "\t";\
LPRINT(a, sz + b);}
#define LPRINT_RUN(a, b) ;
//#define LPRINT_RUN(a, b) {String sz;\
//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) {\
if (a >= Lawn::LDebug::m_iLoggingLevel)\

View File

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

View File

@ -36,6 +36,9 @@ LRoom::LRoom() {
m_iFirstSOB = 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
void LRoom::AddShadowCasters(LRoomManager &manager)
{
// return;
int last_sob = m_iFirstSOB + m_iNumSOBs;
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
if (bVisible)
continue;
// // already in list
// if (bVisible)
// continue;
manager.m_BF_render_SOBs.SetBit(n, true);
manager.m_RenderList_SOBs.push_back(n);
manager.m_BF_caster_SOBs.SetBit(n, true);
manager.m_CasterList_SOBs.push_back(n);
}
}
@ -189,22 +194,23 @@ void LRoom::AddShadowCasters(LRoomManager &manager)
// (it might be expensive)
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()));
// 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++)
{
const LDob &dob = m_DOBs[n];
@ -402,8 +408,8 @@ void LRoom::DetermineVisibility_Recursive(LRoomManager &manager, int depth, cons
//sob.m_bSOBVisible = true;
// sob is renderable and visible (not shadow only)
manager.m_BF_visible_SOBs.SetBit(n, true);
manager.m_BF_render_SOBs.SetBit(n, true);
manager.m_RenderList_SOBs.push_back(n);
//manager.m_BF_render_SOBs.SetBit(n, true);
manager.m_VisibleList_SOBs.push_back(n);
}
} // for through sobs

View File

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

View File

@ -42,6 +42,8 @@ void LRoomConverter::Convert(LRoomManager &manager)
int count = CountRooms();
LMAN->m_SOBs.clear();
LMAN->m_ShadowCasters_SOB.clear();
LMAN->m_Lights.clear();
// make sure bitfield is right size for number of rooms
LMAN->m_BF_visible_rooms.Create(count);
@ -57,21 +59,26 @@ void LRoomConverter::Convert(LRoomManager &manager)
Convert_Rooms();
Convert_Portals();
Convert_Bounds();
Convert_ShadowCasters();
// make sure manager bitfields are the correct size for number of objects
int num_sobs = LMAN->m_SOBs.size();
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_master_SOBs.Create(num_sobs);
// temp rooms no longer needed
m_TempRooms.clear(true);
Lawn::LDebug::m_bRunning = true;
}
void LRoomConverter::Convert_Rooms()
{
LPRINT(5,"Convert_Rooms");
@ -286,6 +293,18 @@ bool LRoomConverter::Convert_Bound(LRoom &lroom, MeshInstance * pMI)
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()
{
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
void LRoomConverter::LRoom_DetectPortalMeshes(LRoom &lroom, LTempRoom &troom)
{

View File

@ -93,6 +93,7 @@ private:
void Convert_Portals();
void Convert_Bounds();
bool Convert_Bound(LRoom &lroom, MeshInstance * pMI);
void Convert_ShadowCasters();
void LRoom_DetectPortalMeshes(LRoom &lroom, LTempRoom &troom);
@ -101,6 +102,8 @@ private:
void LRoom_DetectedPortalMesh(LRoom &lroom, LTempRoom &troom, MeshInstance * pMeshInstance, String szLinkRoom);
LPortal * LRoom_RequestNewPortal(LRoom &lroom);
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);

View File

@ -602,9 +602,13 @@ void LRoomManager::FrameUpdate_Prepare()
m_DebugPlanes.clear();
// clear the visible room list to write to each frame
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_master_SOBs.Blank();
// 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
@ -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
FrameUpdate_FinalizeRooms();
FrameUpdate_AddShadowCasters();
FrameUpdate_CreateMasterList();
// set soft visibility of objects within visible rooms
FrameUpdate_FinalizeVisibility_WithinRooms();
FrameUpdate_AddShadowCasters();
FrameUpdate_FinalizeVisibility_SoftShow();
// 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()
{
// 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()
{
// 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++)
{
int ID = m_RenderList_SOBs[n];
int ID = m_MasterList_SOBs[n];
const LSob &sob = m_SOBs[ID];
VisualInstance * pVI = sob.GetVI();

View File

@ -52,11 +52,15 @@ class LRoomManager : public Spatial {
// the render list is all objects that are in view,
// and also objects out of view but casting shadows INTO the view
LVector<int> m_RenderList_SOBs;
Lawn::LBitField_Dynamic m_BF_render_SOBs;
LVector<int> m_VisibleList_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_caster_SOBs;
Lawn::LBitField_Dynamic m_BF_master_SOBs;
LVector<int> m_VisibleRoomList_A;
LVector<int> m_VisibleRoomList_B;
@ -81,6 +85,10 @@ private:
// static objects
LVector<LSob> m_SOBs;
LVector<LLight> m_Lights;
// master list of shadow casters for each room
LVector<uint32_t> m_ShadowCasters_SOB;
protected:
static void _bind_methods();
@ -98,6 +106,7 @@ private:
void FrameUpdate_Prepare();
void FrameUpdate_FinalizeRooms();
void FrameUpdate_AddShadowCasters();
void FrameUpdate_CreateMasterList();
void FrameUpdate_FinalizeVisibility_WithinRooms();
void FrameUpdate_FinalizeVisibility_SoftShow();