Normal calculation with ever changing vertices

Hey, I have a question to normal calculations :slight_smile:

I am currently working on an ocean surface and decided that I compute the vertex displacement on the Compute Shader (so that I can recall the information if needed) and at the same time send the displacement on my Material Shader and render my mesh visually accordingly.

So the mesh gets initialized with my triangle calculations and the vertex arrangement set up at the beginning.

On my Material Shader I call the SV_VertexID to select my vertex position from my StructureBuffer that holds the vertices.

Each update I calculate the vertex displacement and store them in the StructureBuffer which holds the vertices.

Now since I calculate each update my new vertex positions, my normals are obviously always different. I have not much experience with the whole normals and lightning stuff. And for performance reasons I wanted to calculate the normals on the vertex shader.

Question:

How would I calculate my normals in the best way?

Thanks :slight_smile:

Ps: Hopefully I explained it reasonable ^^

You get the normal by calculating the partial derivatives in x and z direction and then taking the cross product of that.

So something along the lines of

float3 dx = pos(xGrid + 1, yGrid) - pos(xGrid - 1, yGrid);
float3 dz = pos(xGrid, yGrid + 1) - pos(xGrid, yGrid - 1);
float3 normal = normalize(cross(dx, dz));

where pos returns the 3d position at the grid coordinate (xGrid, yGrid) for the current vertex.

Or more optimally

float3 dx = float3(2, height[xGrid + 1, yGrid] - height[xGrid - 1, yGrid], 0);
float3 dz = float3(0, height[xGrid, yGrid + 1] - height[xGrid, yGrid - 1], 2);
float3 normal = normalize(cross(dx, dz));
1 Like

Thanks, exactly what i needed :slight_smile:

Question: What do i with the vertices on the edges? Since their vertex partners are missing.

What I used above is called “central differences” since I used both the right and left neighbor. On the edges, you could use so called forward and backward differences, which uses the center vertex and either the left or right neighbor. Assuming your grid is at least 2 x 2 vertices large, you will always have either a left or right neighbor.

https://en.wikipedia.org/wiki/Finite_difference

Alternatively, if you water is tilable (like FFT water), you can just use the vertex height from the other side.

1 Like