perf(terrain): Hoist global light ray computation out of per-vertex loop#2500
perf(terrain): Hoist global light ray computation out of per-vertex loop#2500Cellcote wants to merge 1 commit intoTheSuperHackers:mainfrom
Conversation
|
| Filename | Overview |
|---|---|
| Core/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp | Hoists the per-light-index lightRay computation from the inner i,j quad loop to just before the outer loop; removes the now-unnecessary lightPos pointer local variable. |
| Core/GameEngineDevice/Include/W3DDevice/GameClient/BaseHeightMap.h | Declaration of doTheLight updated to take const Vector3* for the light parameter — a correct const-correctness improvement. |
| Core/GameEngineDevice/Source/W3DDevice/GameClient/BaseHeightMap.cpp | Definition of doTheLight updated to match the header's new const Vector3* parameter; implementation reads but never writes through the pointer, so const is appropriate. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["updateVB(pVB, data, x0, y0, x1, y1, ...)"] --> B{"m_vertexBufferTiles && pMap?"}
B -- No --> Z["return 0"]
B -- Yes --> C["Hoist: for each lightIndex in m_numGlobalLights\nRead TheGlobalData->m_terrainLightPos[lightIndex]\nlightRay[lightIndex] = negated position"]
C --> D["Lock vertex buffer\n(WriteLockClass)"]
D --> E["for j = y0 .. y1 (outer row loop)"]
E --> F["for i = x0 .. x1 (inner cell loop)"]
F --> G["Compute UVs, alpha, normals\nfor 4 quad vertices"]
G --> H["doTheLight(vb, lightRay, normal, ...)\n×4 vertices — reads precomputed lightRay"]
H --> F
F -- done --> E
E -- done --> I["Copy memory VB → hardware VB"]
I --> J["return vertex count"]
Reviews (3): Last reviewed commit: "perf(terrain): Hoist global light ray co..." | Re-trigger Greptile
e9e9776 to
38a3192
Compare
Core/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp
Outdated
Show resolved
Hide resolved
|
This is outside the scope of this PR, but may need to be addressed at some point. |
6d6d951 to
18333fb
Compare
I guess this would apply to more global settings, right? and that would require a more generic approach to fix for all overridable settings. |
| assert(x0 >= originX && y0 >= originY && x1>x0 && y1>y0 && x1<=originX+VERTEX_BUFFER_TILE_LENGTH && y1<=originY+VERTEX_BUFFER_TILE_LENGTH); | ||
| #endif | ||
|
|
||
| for (Int lightIndex=0; lightIndex < TheGlobalData->m_numGlobalLights; lightIndex++) |
There was a problem hiding this comment.
I would also add a check that we are smaller than MAX_GLOBAL_LIGHTS for safety.
Int maxLights = min(TheGlobalData->m_numGlobalLights, MAX_GLOBAL_LIGHTS);
for (Int lightIndex=0; lightIndex < maxLights; lightIndex++)
{
// loop gubbins
}etc
There was a problem hiding this comment.
This should be done during / after the INI loading, not throughout the code base imo.
Edit: I'd suggest making a separate issue for it and ignore it for this PR. I can create the issue if needed.
In HeightMapRenderObjClass::updateVB, the light ray directions were recomputed from TheGlobalData->m_terrainLightPos for every terrain quad in the nested i,j loops. These values are constant for the entire update region, so move the computation before the loops.
Eliminates (width * height - 1) redundant recomputations per update tile.