0

I have some Mesh-Objects like a flat rectangle:

private void generateMesh(float xshift_mesh, float yshift_mesh, float zshift_mesh, float size_mesh) {
    float size = size_mesh/2; 
    mesh = new Mesh(true, 4, 6, VertexAttribute.Position(), VertexAttribute.ColorUnpacked(), VertexAttribute.TexCoords(0), VertexAttribute.Normal());
    mesh.setVertices(new float[] 
    // Position XYZ       Color RGBA  Texture Coordinates UV   Normal XYZ
    //|-,-,-,|            |-,-,-,-,|  |-,-,|                   |-,-,-|
    {
        -size+xshift_mesh, -size+yshift_mesh, zshift_mesh,  1, 1, 1, 1,     0, 1,    0, 0, -1,
        size+xshift_mesh, -size+yshift_mesh, zshift_mesh,   1, 1, 1, 1,     1, 1,    0, 0, 1,
        size+xshift_mesh,  size+yshift_mesh, zshift_mesh,   1, 1, 1, 1,     1, 0,    0, 0, 1,
        -size+xshift_mesh,  size+yshift_mesh, zshift_mesh,  1, 1, 1, 1,     0, 0,    0, 0, -1
        });
        mesh.setIndices(new short[] {0, 1, 2,2, 3, 0});
}

My task is to create a vertex shader which let such an object wave in some way.

My idea: First I deliver the vertex shader a uniform variable which changes every second from 0 to 1 and vice versa:

Date endDate = new Date();
float numSeconds = (float)((endDate.getTime() - startDate.getTime()) / 1000);
float even = (numSeconds % 2);
...

shader.setUniformMatrix("u_worldView", cam.combined);//WVP-Matrix
shader.setUniformi("u_texture", 0);
shader.setUniformf("u_even", even);

Each vertex of the rectangle object has an Normal vector, like you in see above in the generateMesh method. I can access and use this vector inside the vertex shader:

uniform float u_even;
uniform mat4 u_worldView;
attribute vec4 a_color;
attribute vec4 a_position;
attribute vec2 a_texCoord0;
attribute vec4 a_normal;

varying vec4 v_color;
varying vec2 v_texCoords;

void main() {
    v_color = a_color;
    v_texCoords = a_texCoord0;
    if(u_even > 0.5)  gl_Position = u_worldView * a_position + a_normal;
    else gl_Position = u_worldView * a_position - a_normal;
}

I expected that the object would change every second, which it does in some way, but I also manipulate the camera position everytime. The view position also goes back and forth if the values of the Normal vector are all 0.

I have also tried:

if(u_even > 0.5)  gl_Position = u_worldView * (a_position + a_normal);
else gl_Position = u_worldView * (a_position - a_normal);

But its even worse...

So how can I change the position of a vertex without changing the whole point of view?

I appreciate your help!

goulashsoup
  • 2,639
  • 2
  • 34
  • 60
  • What is the value of `size` you're passing into this method? Am I correct that you want this object to snap back and forth, inverting itself? When I hear the word "wave", I think of smooth motion back and forth, not snapping back and forth like your code seems to be written for. – Tenfour04 Jan 19 '17 at 18:45
  • @Tenfour04 `mesh_size` is the size of the rectangle. The XYZ coordinates of the vertices get calculated by `size = mesh_size/2` so the rectangle will have the size `mesh_size`. The implementation is just a first approach. I first want to fix the camera issue before finding a better way to change the vertices of the rectangle... – goulashsoup Jan 19 '17 at 19:26
  • I was asking what specific number did you pass in for that parameter when testing this. What I'm getting at is that your method accepts an arbitrary `size` attribute that's used for the positions of the vertices, but is not used for the normals, so they could be orders of magnitude different. BTW, you definitely need those parentheses you used in your second try. – Tenfour04 Jan 19 '17 at 19:30
  • @Tenfour04 Ok thx. I call the method with following parameters: `generateMesh(1.5f, 1.0f, 0.0f, 1.0f);`. To my knowledge a normal vector should have the size 1 so it should be independent of the rectangle size... Or not? – goulashsoup Jan 19 '17 at 19:42
  • That's true, but then you should be passing some kind of amplitude to the shader to multiply it by. But in this case, you are in the same range of magnitude, so it wouldn't be causing your issue. I don't see any issues with the code you posted, except for those missing parentheses. The problem lies elsewhere. If `a_normal` is 0, and `u_even` is the only shader input that's changing, it doesn't make sense that there would be any motion on screen at all. – Tenfour04 Jan 19 '17 at 19:45
  • @Tenfour04 A classmate found the issue in the the `NORMAL` values... – goulashsoup Jul 18 '18 at 19:13

1 Answers1

0

It's been a while. Just want to closing the question as resolved.

The problem lied in the generateMesh function, specifically in the NORMAL XYZ values:

private void generateMesh(float xshift_mesh, float yshift_mesh, float zshift_mesh, float size_mesh) {
    if(size_mesh < 0) {
        return; 
    }
    float size = size_mesh/2; 
    mesh = new Mesh(true, 4, 6, VertexAttribute.Position(), VertexAttribute.ColorUnpacked(), VertexAttribute.TexCoords(0), VertexAttribute.Normal());
    mesh.setVertices(new float[] 
      //<------------ Position XYZ ------------------------>   <-Color RGBA->   <Texture Coordinates UV>   <Normal XYZ>
      //|               -,                  -,           -,|   |-, -, -, -, |   | -, -, |                  |-, -, -|
    {   
        -size+xshift_mesh,  -size+yshift_mesh, zshift_mesh,     1, 1, 1, 1,       0, 1,                     0, 0, 1,
         size+xshift_mesh,  -size+yshift_mesh, zshift_mesh,     1, 1, 1, 1,       1, 1,                     0, 0, 1,
         size+xshift_mesh,   size+yshift_mesh, zshift_mesh,     1, 1, 1, 1,       1, 0,                     0, 0, -1,
        -size+xshift_mesh,   size+yshift_mesh, zshift_mesh,     1, 1, 1, 1,       0, 0,                     0, 0, -1
    });
    mesh.setIndices(new short[] {0, 1, 2,2, 3, 0});
}
goulashsoup
  • 2,639
  • 2
  • 34
  • 60