View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0005172 | The Dark Mod | Coding | public | 09.03.2020 04:31 | 06.06.2023 08:00 |
Reporter | stgatilov | Assigned To | stgatilov | ||
Priority | normal | Severity | minor | Reproducibility | N/A |
Status | resolved | Resolution | fixed | ||
Product Version | TDM 2.08 | ||||
Target Version | TDM 2.12 | Fixed in Version | TDM 2.12 | ||
Summary | 0005172: Improve interaction culling: case when player-visible object is not visible from light | ||||
Description | The engine does not cull away some shadows when it can. Consider a typical scenario of two large rooms with one small open portal between them, Suppose that an object is near the common wall between rooms, but far from the portal on this wall. If the object is behind the wall, then player does not see it, and in most cases its shadow is culled away. If the object is in front of the wall but the light source is behind the wall, then its shadow is also not visible. In fact, in this case the light does not light the object at all. The engine can detect this by seeing that light rays cannot pass into the object's area through the portal. It seems that such interaction is not culled away, which is an opportunity for improvement. | ||||
Additional Information | Explained on dev forums: https://forums.thedarkmod.com/index.php?/topic/20195-performance-regression-shadowhide/&do=findComment&comment=442331 | ||||
Tags | No tags attached. | ||||
The reason such culling is not done is that traditional stencil shadows are not cast from front surfaces: // if we have a prelight model that includes all the shadows for the major world occluders, // we can limit the area references to those visible through the portals from the light center. // We can't do this in the normal case, because shadows are cast from back facing triangles, which // may be in areas not directly visible to the light projection center. if ( light->parms.prelightModel && r_useLightPortalFlow.GetBool() && light->lightShader->LightCastsShadows() ) { light->world->FlowLightThroughPortals( light ); } else { // push these points down the BSP tree into areas light->world->PushFrustumIntoTree( NULL, light, light->inverseBaseLightProject, bounds_zeroOneCube ); } Suppose there is a wall between areaA and areaB, with light in areaA. The light sees the front side of the wall in areaA, which he won't cull away no matter what, but it does not drop shadows. The back side of the wall is in areaB, which cast the shadows. But the light does not see it: it is occluded by the wall and not visible through portals. Pretty sad. |
|
I think the line here must be crossed between closed (solid) and open (sheet) surfaces. If an entity is composed of closed surfaces, then we can cull away its interaction if the entity is not visible from the light (shadow-casting one, of course). The "if" above is not entirely right: it checks for prelightModel, which is the precomputed shadow for all world-area surfaces. In reality, area surfaces are not closed in most cases, thus it is not correct to prune them as suggested. However, most of the models are closed, and it is entirely OK to prune their interactions away, which could yield noticeable improvement in some cases. So the idea is to store "closed" bit for surfaces and models, and do both branches here: FlowLightThroughPortals should decide which closed entities to consider for interactions PushFrustumIntoTree should decide which non-closed entities to consider for interactions The problem is that this piece of code only decides which AREAs are visible by lights, not entities. Moreover, it is done only when light position changes: it is not done every frame. Perhaps it would make sense to run the same portal flow in idRenderWorldLocal::CreateLightDefInteractions. Instead of simply taking all entities in all areas, go through portals and take only light-visible entities among closed ones. Non-closed entities should be handled separately, e.g. by traversing areas -> entities. |
|
This forum thread shows that a lot of models are not closed enough: https://forums.thedarkmod.com/index.php?/topic/20850-improving-shadow-mapping-for-210/&do=findComment&comment=458348 (or we don't be able to detect it) |
|
I had logged a seperate tracker before it was suggested I like it here - - https://bugs.thedarkmod.com/view.php?id=6243 |
|
I reread the above statement many times, and finally got to conclusion that "prelight" model is not something special. The important part is to ensure that world models of all covered areas do cast shadows: whether these shadows are precomputed or dynamically generated does not matter. So I extended this "light portal flow" optimization: r10392 Refactoring methods for creating area-entity/light refs. r10394 Use "light portal flow" code for all shadowing lights (to determine the areas light acts in). Basically, the areas which are covered by light volume but are not reached by light flow are saved in a separate place. When interactions are generated, we do special treatment for these areas, adding interactions only with special world-area entities. The new code is under "r_useLightPortalFlow 2" cvar. This helps a lot with number of lights and shadows in the view on a few maps I tested. (Note: this info is displayed by r_showDefs cvar, but restarting/reloading save is necessary after a change in portal flow cvar). Still, it does not help when light rays hit the area with entity but don't hit the entity itself. Like the B2 case from the original investigation: https://forums.thedarkmod.com/index.php?/topic/20195-performance-regression-shadowhide/page/2/#elControls_442331_menu |
|
Light portal flow is more useful now: r10396 Use results of FlowLightThroughPortals / "light portal flow" to cull entities against it. So now we avoid creation of light-entity interaction if we see that entity is in different area and light beams which hit this area surely don't hit entity. This finally covers the case B2 from the original discussion. In a sense, noshadowing lights might be more expensive now because they pass through walls, while shadowing lights don't =) The optimization is enabled under cvar useLightPortalFlowCulling. In the missions I tested, it took negligible time, so I hope there will be no problem with this new culling. |
|
Date Modified | Username | Field | Change |
---|---|---|---|
09.03.2020 04:31 | stgatilov | New Issue | |
09.03.2020 04:31 | stgatilov | Status | new => assigned |
09.03.2020 04:31 | stgatilov | Assigned To | => stgatilov |
09.03.2020 04:32 | stgatilov | Relationship added | related to 0005084 |
21.03.2020 17:43 | stgatilov | Target Version | => TDM 2.09 |
05.12.2020 12:35 | stgatilov | Target Version | TDM 2.09 => TDM 2.10 |
13.12.2020 17:32 | stgatilov | Note Added: 0013120 | |
22.12.2020 18:13 | stgatilov | Note Added: 0013176 | |
26.03.2021 12:33 | stgatilov | Note Added: 0013805 | |
22.11.2021 14:04 | stgatilov | Target Version | TDM 2.10 => TDM 2.11 |
15.11.2022 04:04 | nbohr1more | Target Version | TDM 2.11 => TDM 2.12 |
25.01.2023 12:40 | Bikerdude | Relationship added | related to 0006243 |
25.01.2023 12:43 | Bikerdude | Note Added: 0015883 | |
04.06.2023 11:57 | stgatilov | Note Added: 0016011 | |
06.06.2023 08:00 | stgatilov | Note Added: 0016013 | |
06.06.2023 08:00 | stgatilov | Status | assigned => resolved |
06.06.2023 08:00 | stgatilov | Resolution | open => fixed |
06.06.2023 08:00 | stgatilov | Fixed in Version | => TDM 2.12 |