#721 closed enhancement (fixed)
[PATCH] Optimise water renderer
Reported by: | Philip Taylor | Owned by: | philip |
---|---|---|---|
Priority: | Should Have | Milestone: | Alpha 7 |
Component: | Core engine | Keywords: | simple |
Cc: | Rodolphe Ortalo | Patch: |
Description
TerrainRenderer::RenderWater
seems very inefficient: when zoomed out it can take ~8msec/frame even with all the rendering disabled, and it does the rendering with glVertex3f
calls.
Since water very rarely changes, I expect it'd be best to make CPatchRData
store all the vertex data for water over its patch, and only recompute it when the terrain or water parameters change. Store the data in a vertex buffer. Use indexed quads.
As a bonus: If no visible patches have any water (i.e. they're all entirely above the water plane), don't render the reflection/refraction textures.
Attachments (5)
Change History (21)
comment:1 by , 13 years ago
by , 13 years ago
Attachment: | water_ro_r2.patch added |
---|
patch with respect to trunk/ and revision 9001
comment:2 by , 13 years ago
Keywords: | review added |
---|
NB: Also includes a small correction in water_high.vs
vertex shader. It seems to me a typo had slipped in that shader (to be confirmed).
comment:3 by , 13 years ago
Summary: | Optimise water renderer → [PATCH] Optimise water renderer |
---|
by , 13 years ago
Attachment: | water_ro_r2_r9062.patch added |
---|
Patch with respect to trunk and revision 9062
comment:4 by , 13 years ago
New simplified revision 3 for patch and port to latest SVN. Removes tentative checks for eliminating emerged or underwater terrain from the reflection/refraction computation (under the assumption that it would better be done by culling for these).
by , 13 years ago
Attachment: | water_ro_r3_r9066.patch added |
---|
Patch with respect to trunk and revision 9066
comment:5 by , 13 years ago
New revision 4:
- merged simple and fancy vertex buffer struct to avoid complex mangling when switching dynamically between fancy and simple water via the "Enable Water Reflections" in-game option ;
- added a (compiled in and currently unused) parameter that could allow in future to adjust water triangulation level of detail on patch.
by , 13 years ago
Attachment: | water_ro_r4_r9073.patch added |
---|
4th revision with respect to SVN rev9073
comment:6 by , 13 years ago
A few random comments:
- With non-fancy water, the texture doesn't appear to animate (it just scrolls a single frame). Looks like it sets
period = 16.0f
instead ofperiod = 1.6
. SWaterVertex.m_UVs
doesn't need to be stored explicitly. Shaders can do something likegl_TexCoord[0] = gl_Vertex.xz/repeatPeriod
(ifrepeatPeriod
is specified as a uniform) (looks like there's already a TODO for that). Non-shader can passm_Position
toglTexCoordPointer
, and set up the transform in theglMatrixMode(GL_TEXTURE);
section (like howlosTexture.GetTextureMatrix()
is handled) to do the scaling and the y/z component swap automatically.SWaterVertex.m_Color
should probably be aSColor4ub
.- Then
SWaterVertex
is only 20 bytes. If it was specialised for fancy/simple modes then I think it'd only be 16, which would be nice, but probably not worth the complexity now. BuildWaterVertices
should dom_VBWater = 0
after it doesg_VBMan.Release(m_VBWater)
, to avoid double-frees.Emerged
doesn't seem like an intuitive term to me - probably better to use something more explicit likeAboveWater
.- Probably get rid of the per-vertex fresnel effect for simple water - simple water will only be used in the compatibility mode for ~2% of users with very low-end hardware, so make it as simple and fast as possible (even if that makes it look ugly). Then there's no need to store
m_WaterVertexData
- just createm_VBWater
and never update it. m_WaterIndices
should be stored in a vertex buffer (created withGL_ELEMENT_ARRAY_BUFFER
). (There was a noticeable performance improvement when moving other terrain index data to vertex buffers, so it's a nice optimisation.)
comment:7 by , 13 years ago
Keywords: | simple review → simple, review |
---|
comment:8 by , 13 years ago
Cc: | added |
---|---|
Owner: | set to |
comment:9 by , 13 years ago
Milestone: | Alpha 5 → Alpha 6 |
---|
by , 13 years ago
Attachment: | water_ro_r5_r9546.patch added |
---|
Patch with respect to trunk and revision 9546
comment:10 by , 13 years ago
New revision 5 which should adress all the points outlined above in the last ticket comment, except the SWaterVertex.m_Color
conversion to SColor4ub.
The removal of the per-vertex fresnel effect with simple water does not seem noticeable (for me).
Further feedback or testing welcome.
NB: Patch also includes also a small modif to source/lib/sysdep/gfx.cpp
to allow for compilation of r9546 on linux.
comment:11 by , 13 years ago
Status: | new → assigned |
---|
comment:12 by , 13 years ago
Milestone: | Alpha 6 → Alpha 7 |
---|
comment:13 by , 13 years ago
Owner: | changed from | to
---|---|
Status: | assigned → new |
Work is included in or made obsolete by eihrul_'s frakenpatch. See http://lee.fov120.com/0ad-frankenpatch.diff . Ticket will be closed once frankenpatch is reviewed and committed.
comment:14 by , 13 years ago
Type: | task → enhancement |
---|
comment:15 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
(In [9814]) Graphics optimisations and features from eihrul. Add shadow filtering (PCF) option. Fix ugly shadow saturation in old lighting mode. Fix fancy water shader. Fix camera matrix computation. Support scissoring of camera frustum. Optimise vertex skinning. Inline various matrix functions. Support filtering of the list of submitted models before a rendering pass, for more precise culling. Optimise water renderer (fixes #721, based on patch by ortalo). Use scissoring when generating reflection/refraction textures. Skip reflection/refraction texture generation when no water is visible. Render alpha-blended objects differently (fixes #434). Reduce shadow swimming effects.
comment:16 by , 8 years ago
Keywords: | review removed |
---|
Submitting a patch for this issue. It moves water rendering to
CPatchRData
as described.For fancy water, the vertex buffer is computed at build time and used permanently thereafter. For classical water, some initialization data is computed statically but some parts of the vertex buffer are recomputed for each frame (taking account camera position). In both cases, water is later drawn with indexed quads via
glDrawElements
at render time (the terrain renderer iterates over visible patches).Speed improvements seem (very) interesting, but I have not done precise benchmarking.
Additional water-related test methods have been added to
PatchRData
allowing to check if a given patch has any water, is entirely underwater or entirely out of water. (These tests are cheaply computed as a side effect of building the vertex buffer.)As an addition, these checks are incorporated in the renderer main loop in order to avoid computing reflections or refractions when all visible patches are without water as suggested. But 2 additional optimizations are proposed here: not including underwater patches in reflections computation and not including fully emerged patches in refractions computation. The terrain renderer has also been adapted to allow these optimizations.
The perf. effect of these modifications is still rarely seen because the visible patches list sounds pretty over-estimated for the moment but could prove interesting when that list gets more precise.
The patch may not be perfect (includes a few commented-out lines for displaying some internal info.) but I welcome feedback.