I am having performance problems when drawing lots of grass zoomed out
in an RTS like tropico.
Here is some background …
1) The grass is already very low poly. Basically a blade of grass is 2
triangles (4 since it is dual-sided).
2) When fully zoomed out I believe I’m drawing 8-1000000 blades of
3) The world is divided into square zones. 16x16=256 of them.
4) Static objects including grass is rendered in a single call to
glDrawElements for each zone.
5) I use some simple math to determine if a particular zone is in view
and thus drawn.
6) This works well when I’m zoomed in but performance drags when I’m
zoomed out and
have to draw too many zones.
7) My grass is built up from individual blades into clumps and then
multiple clumps into patches.
Here is an idea swimming in my head …
1) When zoomed in, we obviously draw the grass in its dense glory. That
is draw all the blades.
2) When zoomed out, it is probably OK to draw the grass much more
3) Currently, the idea is to have less blades per clump of grass.
To achieve this …
1) Sort the elements (blades of grass) so that we draw in the following
way. See example below.
2) Start with blade1, clump1, patch 1 (1,1,1) then blade (2,1,1),
3) Then onto the next patch and so on.
4) Now for high LOD (zoomed in) we draw more elements in
5) For low (LOD) we simply draw less elements
What do u guys think of this scheme?
Please log in or register to post a reply.
You should try drawing the grass as alpha-tested billboards with a
texture that contains several blades of grass, when the grass is far
away. You’ll have far fewer polygons and it should perform much
1) billboards may not work very well with my orbiting camera system
and procedurally generated grass.
2) would really like to avoid the transitioning artifacts when switching
billboard and actual 3D when zooming in and out.
Search google, I cannot remember the URL but a guy has published his
code for a really, really, really good grass system.
It works by having multiple levels for each voxel.
1) Long range textured quad
2) Medium range single billboard
3) Short range multiple billboards
4) Close range full 3d
The use of multiple billboards instead of a single billboard makes the
transition between medium and close range really smooth.
Wish I could point you straight at the code
#Stainless - you meant Kevin Boulanger’s work?
His work is good and pretty realistic, indeed - I’ve written
implementation based on his paper in 2010 - my video is here
[media]http://www.youtube.com/watch?v=2J_Tuf2Ghdg[/media](post-recorded application, after presentation at GA 2010)
I also worked on another “new solution” last year (it is merely the same
as the last one), that should be more realistic - mainly focused on
including more types of plants (using maps), as the current
implementation still suffers from being too artificial (1), more
realistic animation (as the previous still sucks a bit) (2), and higher
resolution meshes, and heavy optimizations (3). And most important
making some editing tool for this-like stuff (which is work-in-progress
since as editor for our own game engine).
Note. For actual understanding, you need to know that our engine is
designed as open-world game engine, that uses rectangular cells
similarly like Creation engine in Skyrim does.
(1) Seems like quite easy to solve, and it actually is - you add plant
models to plant-slot in single cell, where the engine reserves you 8
(also possible 16, 32 or 64) possible slots for different plants. You
probably have the idea now - we use separate bits in integer texture map
as mask for plants distribution. Note that we actually use just 8 (due
to performance). The plants are also scaled on Y axis, where the scale
is defined as bilinearly interpolated value of the texture. Easy to code
and bloody effective.
(2) Quite a challange, as this one is subjective. We actually use
something new, that we call “wind maps” that are artist created
(hopefully some (realtime) navier-stokes in future :P) and say in which
direction (standart xyz vector) the wind flows for each cell. It’s cheap
trick to know the direction of wind, but it looks pretty nice. Then,
some simple vertex shader and harmonic functions come into place.
(3) In shown demonstration, the grass plates are in grid optimization
scheme - which is still a little slower than currently working
quad-tree. Though just a few percents in performance. It actually is a
little faster (even with the more trickery added - like wind maps and
more layers of plants). Even though I think that Kevin Boulanger’s great
idea on how-to-LOD-that-grass is giving the largest boost to this tech.
I hope this can help a bit in implementation of good grass system (not
that my one is good - it still needs a lot of work).
Thanks for pointing out Kevin’s paper. His volume rendering idea looks
I can render each patch of grass as a single textured cube. 5 small
textures per patch.
It also seems reasonable to have similar patches share textures. These
decent when zoomed out. Thanks again, guys.
Yes that’s the one.
Good luck with real time wind effects, I have been trying for years to
write a physically based cloud generation system for planets. The maths
involved in atmospheric physics is very time consuming and doing it in
shaders requires a lot of texture swapping. Yuck.
I am wondering if the wind effects mean you cannot do any short cuts
based on instancing?
The last time I played with a grass system I had all my cells organised
as batches and was able to instance many of them.
Do you modify the verts based on the wind in the shader?
Just for informatino - Right now I don’t have much time, but I’ll find
an hour or two to quickly build small demo of this to show…
Okay, so here it is:http://www.otte.cz/GrassDM.rar
Linux + Windows binary, I tested it just on AMD gpus (but it should look
also on NVidia, if it supports GLSL version 330). Some extensions are
needed (including ARB_draw_instanced of course). I just put it quickly
together (dropped out LOD as I didn’t have time to generate textures for
it, also windmap is just quickly made, along with grass blades map(s) +
mesh). It’s far from perfect (well whole data were built in 1 hour or so
+ I had to think off some shader constants and actually put it together)
- it is just proof-of-concept.
Feel free to try and/or ask about anything.
Note, it needs ODE libraries and OpenAL libraries (+ OpenGL and system
libraries - WinAPI on Win32 and XLib ob Linux). You can grab needed ODE
dll here -
or build it from source -
OpenAL installer is here -
Also forgot to say - you actually see windmap direction generated sine
waves (without turbulence), the important is shader code in
data/shaders/grass.glsl (it’s not commented, but I think you can easily
figure out what is what).
crashes on my XP laptop
Unhandled exception at 0x00000000 in msvc.exe: 0xC0000005: Access
violation reading location 0x00000000.
it’s on the call to …
mainret = WinMain(
#endif /* WPRFLAG */
StartupInfo.dwFlags & STARTF_USESHOWWINDOW
Looks like my Nvidia card does not support some extensions
Error: GL_ARB_shader_objects and GL_ARB_shading_language_100 not
Error: GL_ARB_tessellation_shader not supported
Error: GL_ARB_vertex_array_object not supported
Error: GL_ARB_framebuffer_object not supportedError:
GL_ARB_draw_instanced not supported
I write shaders all the time on this machine, but never use the ARB
Huh… sounds strange that you don’t have ARB_shader_objects +
ARB_shading_language (maybe just few procedures are missing), but
ARB_draw_instanced is needed here (it was also known as
EXT_draw_instanced), maybe installing new drivers would help this
(ARB_vertex_array_object and ARB_framebuffer_object and
ARB_tessellation_shader are not needed in this one - it just tests for
The drivers are up to date as I do a lot of OpenGLES 2.0 code and the IT
guy is paranoid about drivers being up to date.
This is why I hate PC development, I have a really rotten 2gig 64 bit
desktop that I dropped a £15 graphic card into, and it runs on that.
Though the machine is so slow it might as well be steam powered.
This dual core 32 bit laptop cannot run it because the graphics card
doesn’t support some of the extensions.
Btw. may I ask what GPU (+ configuration) do you have on notebook?
NVidia Quadro NVS 135M