libgdx - GLGS - 创建让物体波动的顶点着色器

libgdx - GLGS - Create vertex shader which let objects wave

我有一些 Mesh-像扁平矩形的对象:

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});
}

我的任务是创建一个顶点着色器,让这样的对象以某种方式波动。

我的想法: 首先,我为顶点着色器提供了一个 uniform 变量,该变量每秒从 0 变为 1,反之亦然:

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

矩形对象的每个顶点都有一个 Normal 向量,就像您在上面的 generateMesh 方法中看到的那样。我可以在顶点着色器中访问和使用这个向量:

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;
}

我预计对象每秒都会发生变化,它以某种方式发生了变化,但我也每次都操纵相机位置。如果 Normal 向量的值都为 0,则视图位置也会来回移动。

我也试过:

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

但更糟...

那么如何在不改变整个视角的情况下改变顶点的位置呢?

感谢您的帮助!

好久不见了。只想关闭已解决的问题。

问题出在generateMesh函数上,特别是在NORMAL XYZ值上:

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});
}