Partial Vertex Shader Animation


I’ve been searching for a better way to realize vertex animation of a single part in the mesh.
My mesh consists of a ground and grass blades (all in one mesh). It’s not an option to render the grass and ground separately, because I need to save draw calles where possible. The shader use Array Textures for the different textures.

On the basis of this, I do conditional branching (IF in shaders) on the texure array stack index in the shader like this:

// apply tranformations if texture id is 19 or 30
if(inTexCoord.y > 0.5 && (inTexCoord.z == 19.0 || inTexCoord.z == 30.0))
    gl_Position = animateGrass(modelSpacePos);  

Has anyone an idea to get vertex animation for some texture IDs without conditional branching? I built the vertex buffers on my own on the CPU side. Maybe I can use an additional Buffer to “mark” the vertieces that needs to be animated?



1 draw call + branching versus 2 draw calls? I think 2 draw calls will win as both shaders can do less work. Also, ground and grass are so totally different things. One needs to be opaque and the other needs to likely be semi-transparent.

I think your optimization strategy is going in the wrong direction.

Edit: Note: this presumes you are batching the grass already.

I use AlphaDiscardThreshold to make the grass “transparent”. Two draw calls means that I have to attach a second spatial to the scene which leads to additional scene graph traversal/updates and higher CPU usage. I need to save as much as possible CPU power, because it is required for other purposes. Do you know another way?

Not my experience on Mac with AMD hardware - draw calls kills performance like nothing else (but from what I understand that is very different between drivers / cards). In this case though I would do what pspeed suggests.

One more spatial in your scene will cost less than a nanosecond.

Extra code in your shader will cost some amount per vertex.

One more draw call is not going to break you. As it stands, you are burdening your terrain rendering with a bunch of stuff it doesn’t need (alpha discard, vertex animation, etc.)… that’s nearly guaranteed to cost you more than one more draw call.

hm I should mention that I have not one mesh of this type but rather 1000~1500 meshes. So instead of 1500 draw calls, if have 3000 :confused:

Please explain your scene in greater detail.

What are these 1500 meshes, and what are you are doing that is requiring so much CPU usage?

IMHO - It sounds to me like you need to group these meshes by texture into single meshes and create a dynamic mesh to build them at run-time.

my world consists of mesh (1000-1500) tiles that extends indefinitely in every (x,z) direction, depending on the players position. The meshes are dynamically generated at run-time. The meshes contains opaque textures and “transparent” grass blades. I need the CPU power for generating these meshes, calculating other game logik stuff, AI and moving models around. I think grouping these meshes with the GeometryBatchFactory make fast tile handling impossible?

I hate to say this but you should look into how block worlds are created the entire thing is just one mesh usually. in your situation it is even simpler your just making a flat plane. Atlas your textures for the ground and have it as only one mesh adjust texture cords as needed. finding the location of one quad is easy math because each quad will be the same width. Do the same for the grass but as a separate mesh you could even animate the grass dynamically. So only with what you have told me it sounds like you only need 2 meshes.

Yeah, that’s too many tiles.

You are generating the tiles, you say… so make just them bigger. Doubling their size shouldn’t affect generation much (and anyway that’s a time sink in another thread I hope) but would cut your object count to 1/4. 250 to 375 objects… which if you moved grass out becomes 500 to 750 objects. That sounds like a way better performance improvement than trying to sandwich all logic into shaders that don’t really need it.

Right now you incur extra cost per vertex and extra cost per fragment (having discard active in a shader can affect parallelization of the pipelines).

If I have one big mesh, how can I achieve walking in each direction? I move the world around the player but I cannot move the one-big-mesh or can I? How do I extend/shrink the mesh? currently I move all tiles around the player and attach/detach new/old tiles.

And what about updating this one big mesh? I cannot modify a buffer which is currently rendered. This mesh must have huge buffers so I think updating it would take a long time (more than a few frames)

Did I say use one big mesh? No.

I think I specifically said make bigger meshes. If your mesh is 16x16 then make it 32x32 and separate opaque from transparent and you will have half as many objects as you do now.

But since you didn’t read my reply you might actually want to read it.

sry for clicking on the wrong reply button…

bigger meshes are also not an option because it took too much time to generate it. I cannot really optimize the way the meshes are generated.

The concept i was describing doesnt move the mesh at all it would recreate your vertex buffers for cords and textures based on camera movement. The actual mesh could remain at (0, 0, 0) the only thing i don’t understand is how you are storing world data? Is it a tile map or just procedurally generated? Both would work though.

Think you could give a image of what you are going for?

I seriously doubt that, for one thing. We don’t know how you are generating your meshes but I bet good money that it can be done faster. But either way, that’s a ‘one time’ cost versus the per-vertex-per-frame and per-pixel-per-frame and per-object-per-frame costs you are incurring now. Even if making a 2x bigger tile cost 4x more (which I seriously doubt) it would be worth it since you do it extremely rarely compared to all of your other per-frame costs.

Edit: unless you are doing your generation on the main thread in which case… don’t do that.

Edit 2: and for the record, I do know a little bit about terrain generation both just for paging:

As well as terrain you can edit in real time (block world):

1 Like

How do you handle the tiles in mythruna? Are there 16^3 or 32^3 tiles which are stacked vertically? How are they rendered? I downloaded your game and it looks like your grass is rendered separately to the rest of the world. Looks all nice :smile:

32x32x32 tiles.

Every texture is a separate material right now. No atlas at all.