"Dynamically" changing the terrain's resolution. How to do it?

Hi all outstanding forum members !

Once again I’m asking you help.
I promise you I’ll give back to the community if one day I write something worth sharing.

Here is the context :
I’m playing with the terrain’s vert shader but I’m still not getting the big picture. Any link to any documentation is welcome (yes, I’ve read the wiki. Pardon my stupidity in case I missed something.).

What I’m achieving right now :
I’ve modified the terrain’s vert shader to make a shockwave effect. It’s just about computing a distance, a couple of ratios, a sine and some clamping, then changing the gl_Position.y.
The result is really cool but … it could be nicer.
My terrain is low poly, which is good enough for my game as the difference in level per unit of terrain is low. Said in another way : I don’t need many polygons as the terrain is pretty flat.

The problem is that with that new shockwave effect, one can clearly see the terrain is low poly. My sines look like spikes, not like sines. Using a higher poly terrain 100% of the time would be a complete waste of resources. Switching my low poly terrain to a high poly terrain when the shockwave is happening would be a quick & dirty solution but it sounds wrong and too dirty to me. It might also make too much data flow from/to the GPU. Manually changing the mesh using the CPU would have the same (bad) effect on performance I think.

I think the solution is to subdivide my polygons where the deformation is at the GPU level.

Is that a good way to do it ?
If so, how would you do that ? From what I understand the concept of “tesselation” might be the thing I need, but … it seems this tesselation can only be done after the vert shader in the rendering pipeline so I have no idea on how to do it with jME.
How would you do it ?

Any link to any documentation more or less related to the subject is welcome.

Best regards,


Maybe that would be done with only shaders, like for water waves, by displacing pixels, or changing normals?

Please paste you current modified shader

Its not a problem that the tessellation shader gets executed after the vertex shader.
All you have to do is to use the vertex shader as passtrough stage and deform your terrain in the tessellation evaluation shader after it has been tessellated.
In the tessellation control shader stage you can set the required tessellation levels depending on your calculations.

If you can live with only GL4+ support, then yes, it should be a working solution for your problem

EDIT: I pressed edit in place of reply so my last post is gone …
well, I was thanking zzuegg and methusalah.

Ok I’m home now. When I make the shockwave a bit faster the eye can’t see the “sharp edges” so I think it’s going to stay this way for this game. (but that won’t stop me from playing with the water shader as I see so much interest in this shader for my game)

I’ve simplified the algorithm so the clamp is no longer needed and made it a bit more readable for this post. See that as my first small contribution (mhh sorry, hack). Please comment and improve it if you will/can.

At the top of the terrain’s vert, add that :

uniform float m_ShockWavePct;
uniform vec2 m_InitialShockWavePos;
const float twoPi = 6.283185307;
const float    pi = 3.141592359;

And, at the end of the main(), add :

vec2 initPosToCurrVert = texCoord - m_InitialShockWavePos;
vec2 dirToCurrVert = normalize(initPosToCurrVert);
vec2 waveCoord = m_InitialShockWavePos + (dirToCurrVert * m_ShockWavePct);
float distToWaveCoord = distance(waveCoord, texCoord);
float distToInitPos = distance(texCoord, m_InitialShockWavePos);
gl_Position.y -= (1.0 / distToWaveCoord) * m_InitialShockWavePos * (1.0 - m_ShockWavePct);

Where ShockWavePct is a float between [0.0, 1.0] and represents the “progress” of the shockwave.
and InitialShockWavePos is the position where the shockwave starts.

1 Like

Can you show a screenshot? Just to maybe understand a bit more what do you mean by sharp edges.

1 Like

Sure. Here is the screenshot :

You can clearly see it’s “low poly”, but that’s only because you’re looking at a motionless screenshot.
In fact I’ve now made the “animation” a lot faster and … It’s looking so good :smile:

As I said about in my previous self-deleted post I’ll forget about tesselation for a moment but now I’m going to dive into the water shader :smile:

thanks guys.


The displacement is huge ! I was thinking about a less important effect.

Can you show how you trigger the effect? I’m not very comfortable with shaders.

1 Like

Yes I guess it needs less displacement. I’ll add an amplitude.

For now the result looks like that :


Great video :slight_smile: But I was talking about the call (and param if any) inside the code.

Oh, sorry …

Once again I’m at work so you’ll have to imagine the code.

SHOCKWAVE is defined whenever ShockWavePct is defined. I recall adding “SHOCKWAVE : ShockWavePct” somewhere in the j3md. I’ll give you the exact modifications I did to Material { … } and TheThingIDontRemember { … } tonight if you will.

So to trigger the effect I only have to set ShockWavePct :


When the effect is done you just have to clear the parameter :
for example :

if (currentProgress >= 1f) {

That’s all…
As usual my ears are all open if you have something better.