Jump to content
  • Advertisement
Alex Gomez Cortes

OpenGL Problem with Gerstner waves in vertex shader

Recommended Posts

Hello everyone!

I am working in a openGL framework lately, and I found a problem when implementing Gerstner waves. The problem is that when I calculate the waves through the CPU, it works really good, but when i copy and paste the code to the vertex shader(with some changes, uniforms, etc) the waves become weird af.

I am going to post some pictures so you can get a better idea about what is going on.

 

CPU waves: 

olas_cpu.PNG.5aeabb4f85970ab39f9f6a9ac5cc4187.PNG

 

GPU waves: 

570815670_Capturaolas.thumb.PNG.adae8eb48ad7e0e736d0850d63bb877f.PNG

 

Code comparison:

2080527730_comparacioncodigo.thumb.PNG.f2be0a81e8a0b29c283b18923962f404.PNG

k->wave direction w-> frequency A-> amplitude of the wave   L-> distance between crests

 

If someone knows what is going on, please tell me.

Thank you in advance!

Share this post


Link to post
Share on other sites
Advertisement

Hola Alex,

First, I would recommend getting familiar with a GPU debugger, my favourite one being RenderDoc. It allows you to debug the execution of shaders on individual vertices or pixels. 

I had a quick look at your shader code. You are modifying all components of pos, including w and that might explain the error. In theory you should modify the xz components with the horizontal displacement formula, y the component with the vertical formula (assuming y points vertically in your world space), and leave w to 1. k should be a 2D normalized vector, not a vec4, and the wave phase should be given by dot(k, in_Position.xz) + offset.  

I have worked on waves simulation for many years so please let me know if you have any questions related to it.

 

Share this post


Link to post
Share on other sites

I had a quick look at your code, but the first thing you have to know is that the vertex shader works per vertex whereas doing it on the CPU you have vision over all vertices.

olas seems to become the L uniform in your shader. Do you update L for every vertex as it seems it should from your CPU version ? olas is an array, so L might remain an array (thus removing the need to update the uniform for every vertex). Then to know which vertex is currently processed, you can use gl_VertexID and access it threw L[gl_VertexID] for example.

Also note that uniforms have limitations in their size (this is important if your grid is big and you use array of uniforms as I suggested).

If you don't want to use array of uniforms and if olas is constant, then use olas as a vertex attribute.

Share this post


Link to post
Share on other sites
10 hours ago, Reitano said:

Hola Alex,

First, I would recommend getting familiar with a GPU debugger, my favourite one being RenderDoc. It allows you to debug the execution of shaders on individual vertices or pixels. 

I had a quick look at your shader code. You are modifying all components of pos, including w and that might explain the error. In theory you should modify the xz components with the horizontal displacement formula, y the component with the vertical formula (assuming y points vertically in your world space), and leave w to 1. k should be a 2D normalized vector, not a vec4, and the wave phase should be given by dot(k, in_Position.xz) + offset.  

I have worked on waves simulation for many years so please let me know if you have any questions related to it.

 

@Reitano  Thanks for your answer!

The problem was what you said, I was multiplying the w component.

But I have two questions:

Why should the vector k be 2D? If I want to make a wave that moves along z axis I can't then.

What is the offset of the wave? 

Thank you!

9 hours ago, _Silence_ said:

I had a quick look at your code, but the first thing you have to know is that the vertex shader works per vertex whereas doing it on the CPU you have vision over all vertices.

olas seems to become the L uniform in your shader. Do you update L for every vertex as it seems it should from your CPU version ? olas is an array, so L might remain an array (thus removing the need to update the uniform for every vertex). Then to know which vertex is currently processed, you can use gl_VertexID and access it threw L[gl_VertexID] for example.

Also note that uniforms have limitations in their size (this is important if your grid is big and you use array of uniforms as I suggested).

If you don't want to use array of uniforms and if olas is constant, then use olas as a vertex attribute.

@_Silence_ First of all thanks for your answer!

olas is not the L uniform. L, k, w, speed, A are the attributes of the waves, so what I do is: when I call the draw function, I make a foor loop where in every iteration i pass to the shader olas.w, olas.k, etc. as uniforms.

I'll read about passing arrays to the shader because right now only the last wave is being rendered, the previous no, so I think I can pass several arrays (one array of w components, another one of L components, etc) and iterate inside the vertex shader applying the formulas with the right variables.

 

Thank you very much!

Share this post


Link to post
Share on other sites

Where do you use temp_vertices array in shader??? Seems you use the same index so either pass another attribute to vertex shader with this temp array (if its static - if not youll have to update this buffer..)

Share this post


Link to post
Share on other sites
Posted (edited)
5 hours ago, _WeirdCat_ said:

Where do you use temp_vertices array in shader??? Seems you use the same index so either pass another attribute to vertex shader with this temp array (if its static - if not youll have to update this buffer..)

@_WeirdCat_ Hello and thanks for your reply!

 

I dont need temp_vertices in the shader. When I calculate the waves through the cpu I need temp_vertices[] because I need to know the difference between the initial position and the new position after applying the formulas. As you can see, vertices[] is being modified every frame, so every frame I need to reset it with temp_vertices[] (it has the initial positions) in order to recalculate the difference between points again.

In the shader, I dont need temp_vertices[] because vertices[] is not being modified, I just pass vertices[] to the shader and it acts like temp_vertices[] and pos acts as vertices[].

Thanks for your reply!

Edited by Alex Gomez Cortes

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!