Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Normal calculation with ever changing vertices

Discussion in 'General Graphics' started by itisMarcii_, Apr 23, 2023.

  1. itisMarcii_

    itisMarcii_

    Joined:
    Apr 5, 2022
    Posts:
    107
    Hey, I have a question to normal calculations :)

    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 :)

    Ps: Hopefully I explained it reasonable ^^
     
  2. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    549
    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
    Code (CSharp):
    1. float3 dx = pos(xGrid + 1, yGrid) - pos(xGrid - 1, yGrid);
    2. float3 dz = pos(xGrid, yGrid + 1) - pos(xGrid, yGrid - 1);
    3. 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
    Code (CSharp):
    1. float3 dx = float3(2, height[xGrid + 1, yGrid] - height[xGrid - 1, yGrid], 0);
    2. float3 dz = float3(0, height[xGrid, yGrid + 1] - height[xGrid, yGrid - 1], 2);
    3. float3 normal = normalize(cross(dx, dz));
     
    Last edited: Apr 23, 2023
    itisMarcii_ likes this.
  3. itisMarcii_

    itisMarcii_

    Joined:
    Apr 5, 2022
    Posts:
    107

    Thanks, exactly what i needed :)
     
  4. itisMarcii_

    itisMarcii_

    Joined:
    Apr 5, 2022
    Posts:
    107
    Question: What do i with the vertices on the edges? Since their vertex partners are missing.
     
  5. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    549
    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.
     
    Last edited: Apr 23, 2023
    itisMarcii_ likes this.