在LibGDX平面着色 [英] Flat shading in LibGDX

查看:156
本文介绍了在LibGDX平面着色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前工作的一个简单的游戏,我想我的地势要平坦着色。我目前的地形如下所示:

正如你所看到的颜色混合toghether根据顶点的颜色。

我会为我的最终产品类似于以下喜爱:

所以我想知道我怎样才能做到这一点?有哪些步骤,从洛德着色去平阴影?

下面是我如何去创造我给我的网格顶点:

 公共TerrainChunk(){
    buildHeightmap();
    buildIndices();
    buildVertices();
    calcNormals(指数,顶点);

}

公共无效buildHeightmap(){...}

私人无效buildIndices(){
    INT IDX = 0;
    短节距=(短)(宽度+ 1);
    短的i1 = 0;
    短I2 = 1;
    短I3 =(短)(1 +间距);
    短I4 =间距;

    短行= 0;

    对于(INT Z = 0; Z<高度; Z ++){
        为(中间体X = 0 X  - 其中;宽度; X ++){
            指数[IDX +] = I1;
            指数[IDX +] = I2;
            指数[IDX +] = I3;

            指数[IDX +] = I3;
            指数[IDX +] = 6-14;
            指数[IDX +] = I1;

            I1 ++;
            I2 ++;
            I3 ++;
            I4 ++;
        }

        行+ =间距;
        I1 =行;
        I2 =(短)(行+ 1);
        I3 =(短)(I2 +间距);
        I4 =(短)(行+间距);
    }
}

公共无效buildVertices(){
    INT heightPitch =身高+ 1;
    INT widthPitch =宽度+ 1;
    INT IDX = 0;

    为(中间体X = 0 X  - 其中; widthPitch; X ++){
        对于(INT Z = 0; Z< heightPitch; Z ++){

            // 位置
            顶点[IDX +] =规模* X;
            顶点[IDX +] =(浮点)Math.pow(1 + chunkDepths [X] [Z],强度));
            顶点[IDX +] =规模* Z;

            //师范大学,跳过这些现在
            IDX + = 3;

            // 颜色
            顶点[IDX +] =的getColor(;

            // 质地
            顶点[IDX +] =(X /(浮点)宽);
            顶点[IDX +] =(Z /(浮点)高度);

        }
    }
}

/ *
 *计算法线
 * /
私人无效calcNormals(简称[]指数,浮动[]绿党){

    的for(int i = 0; I< indices.length; I + = 3){
        INT I1 = getPositionStart(指数[I]);
        INT I2 = getPositionStart(指数为[I + 1]);
        INT的i3 = getPositionStart(指数为[I + 2]);

        // P1
        浮X1 =绿党[I1]
        浮Y1 =绿党[I1 + 1];
        浮Z1 =绿党[I1 + 2];

        // P2
        浮X2 =绿党[12];
        浮Y2 =绿党[I2 + 1];
        浮Z2 =绿党[I2 + 2];

        // P3
        浮X3 =绿党[I3]
        浮Y3 =绿党[酷睿i3 + 1];
        浮Z3 =绿党[酷睿i3 + 2];

        // U = P3  -  P1
        浮UX = X3  -  X1;
        浮UY = Y3  -  Y1;
        浮UZ = Z3  -  Z1;

        // V =​​ P2  -  P1
        浮VX = X2  -  X1;
        浮VY = Y2  -  Y1;
        浮VZ = Z2  -  Z1;

        // N =交(V,U)
        浮动NX =((VY * UZ) - (VZ * UY));
        浮动NY =((VZ * UX) - (VX * UZ));
        浮动NZ =((VX * UY) - (VY * UX));

        //正常化(N)
        浮动NUM2 =((NX * NX)+(纽约州*纽约州))+(NZ * NZ);
        浮NUM = 1F /(浮动)的Math.sqrt(NUM2);
        NX * = NUM​​;
        纽约* = NUM​​;
        新西兰* = NUM​​;

        addNormal(指数为[I]​​中,绿党,NX,NY,NZ);
        addNormal(指数为[I + 1],绿党,NX,NY,NZ);
        addNormal(指数为[1 + 2],绿党,NX,NY,NZ);
    }

    的for(int i = 0;我≤(verts.length / VERTEX_SIZE);我++){
        normalizeNormal(我,绿党);
    }
}

//将提供的值正常
私人无效addNormal(INT vertIndex,浮法[]绿党,浮动的x,浮Y,
        浮Z){

    INT I = getNormalStart(vertIndex);

    浮RX =(浮子)((X * Math.cos(180)) - (γ* Math.sin(180)));
    浮RY =(浮子)((X * Math.sin(180))+(γ* Math.cos(180)));
    X = RX;
    Y = RY;
    绿党[I] + = X;
    绿党[I + 1] + = Y;
    绿党[I + 2] + = Z;
}

/ *
 *正常化法线
 * /
私人无效normalizeNormal(INT vertIndex,浮法[]绿党){

    INT I = getNormalStart(vertIndex);

    浮法X =绿党[I]
    浮动Y =绿党[I + 1];
    浮Z =绿党[I + 2];

    浮动NUM2 =((X * X)+(Z * Z))+(Y * Y);
    浮NUM =(浮动)的Math.sqrt(NUM2);
    X * = NUM​​;
    Y * = NUM​​;
    Z * = NUM​​;

    绿党[I] = X;
    绿党[I + 1] = Y;
    绿党[1 + 2] = Z;
}


//获取一个正常的第一条浮法的指数为特定的顶点
私人诠释getNormalStart(INT vertIndex){
    返回vertIndex * VERTEX_SIZE + 3;
}

//获取特定顶点的第一个浮动的索引
私人诠释getPositionStart(INT vertIndex){
    返回vertIndex * VERTEX_SIZE;
}
 

解决方案

在最后,我改变了我的建网完全的方式。现在我建网了三角形。下面是它看起来像现在:。 这还不是很完善,因为没有对角的颜色,但我很高兴与一般的样子。

下面是我做到了。 我做了一个新的类来保存我的变量

 私人Vector3类型corner1;
私人Vector3类型corner2;
私人Vector3类型corner3;
私人Vector3类型corner4;
私人Vector3类型leftNormal;
私人Vector3类型rightNormal;
私人色颜色1;
私人色颜色2;
私人色彩COLOR3;
私人色彩color4;
私人Vector2 texturePos;
 

和吸引他们,像这样:

  //左三角
VertexInfo V1 =新VertexInfo();
VertexInfo V2 =新VertexInfo();
VertexInfo V3 =新VertexInfo();

// 直角三角形
VertexInfo V4 =新VertexInfo();
VertexInfo V5 =新VertexInfo();
VertexInfo V6 =新VertexInfo();

v1.setPos(cell.getCorner1()).setNor(cell.getLeftNormal()).setCol(cell.getColor1()).setUV(cell.getTexturePos());
v2.setPos(cell.getCorner4()).setNor(cell.getLeftNormal()).setCol(cell.getColor1()).setUV(cell.getTexturePos());
v3.setPos(cell.getCorner2()).setNor(cell.getLeftNormal()).setCol(cell.getColor1()).setUV(cell.getTexturePos());

v4.setPos(cell.getCorner3()).setNor(cell.getRightNormal()).setCol(cell.getColor3()).setUV(cell.getTexturePos());
v5.setPos(cell.getCorner2()).setNor(cell.getRightNormal()).setCol(cell.getColor3()).setUV(cell.getTexturePos());
v6.setPos(cell.getCorner4()).setNor(cell.getRightNormal()).setCol(cell.getColor3()).setUV(cell.getTexturePos());

meshBuilder.triangle(V1,V2,V3);
meshBuilder.triangle(V4,V5,V6);
 

我计算三角形的面法线像这样:

 私人Vector3类型calcNormal(Vector3类型P1,P2 Vector3类型,Vector3类型P3){

    // U = P3  -  P1
    浮UX = p3.x  -  p1.x;
    浮UY = p3.y  -  p1.y;
    浮UZ = p3.z  -  p1.z;

    // V =​​ P2  -  P1
    浮VX = p2.x  -  p1.x;
    浮VY = p2.y  -  p1.y;
    浮VZ = p2.z  -  p1.z;

    // N =交(V,U)
    浮动NX =((VY * UZ) - (VZ * UY));
    浮动NY =((VZ * UX) - (VX * UZ));
    浮动NZ =((VX * UY) - (VY * UX));

    // //正常化(N)
    浮动NUM2 =((NX * NX)+(纽约州*纽约州))+(NZ * NZ);
    浮NUM = 1F /(浮动)的Math.sqrt(NUM2);
    NX * = NUM​​;
    纽约* = NUM​​;
    新西兰* = NUM​​;

    返回新的Vector3类型(NX,NY,NZ);
}
 

I am currently working on a simple game and I would like to my terrain to be flat shaded. My terrain currently looks like the following:

As you can see the colours blend toghether depending on the vertice colours.

I would love for my end product to resemble the following:

So I was wondering how can I achieve this? What are the steps to go from gouraud shading to flat shading?

Here is how I go about creating the vertices I give to my mesh:

public TerrainChunk() {
    buildHeightmap();
    buildIndices();
    buildVertices();
    calcNormals(indices, vertices);

}   

public void buildHeightmap() {...}

private void buildIndices() {
    int idx = 0;
    short pitch = (short) (width + 1);
    short i1 = 0;
    short i2 = 1;
    short i3 = (short) (1 + pitch);
    short i4 = pitch;

    short row = 0;

    for (int z = 0; z < height; z++) {
        for (int x = 0; x < width; x++) {
            indices[idx++] = i1;
            indices[idx++] = i2;
            indices[idx++] = i3;

            indices[idx++] = i3;
            indices[idx++] = i4;
            indices[idx++] = i1;

            i1++;
            i2++;
            i3++;
            i4++;
        }

        row += pitch;
        i1 = row;
        i2 = (short) (row + 1);
        i3 = (short) (i2 + pitch);
        i4 = (short) (row + pitch);
    }
}

public void buildVertices() {
    int heightPitch = height + 1;
    int widthPitch = width + 1;
    int idx = 0;

    for (int x = 0; x < widthPitch; x++) {
        for (int z = 0; z < heightPitch; z++) {

            // POSITION
            vertices[idx++] = scale * x;
            vertices[idx++] = (float)Math.pow(1 + chunkDepths[x][z], strength));
            vertices[idx++] = scale * z;

            // NORMAL, skip these for now
            idx += 3;

            // COLOR
            vertices[idx++] = getColor(;

            // TEXTURE
            vertices[idx++] = (x / (float) width);
            vertices[idx++] = (z / (float) height);

        }
    }
}

/*
 * Calculates the normals
 */
private void calcNormals(short[] indices, float[] verts) {

    for (int i = 0; i < indices.length; i += 3) {
        int i1 = getPositionStart(indices[i]);
        int i2 = getPositionStart(indices[i + 1]);
        int i3 = getPositionStart(indices[i + 2]);

        // p1
        float x1 = verts[i1];
        float y1 = verts[i1 + 1];
        float z1 = verts[i1 + 2];

        // p2
        float x2 = verts[i2];
        float y2 = verts[i2 + 1];
        float z2 = verts[i2 + 2];

        // p3
        float x3 = verts[i3];
        float y3 = verts[i3 + 1];
        float z3 = verts[i3 + 2];

        // u = p3 - p1
        float ux = x3 - x1;
        float uy = y3 - y1;
        float uz = z3 - z1;

        // v = p2 - p1
        float vx = x2 - x1;
        float vy = y2 - y1;
        float vz = z2 - z1;

        // n = cross(v, u)
        float nx = ((vy * uz) - (vz * uy));
        float ny = ((vz * ux) - (vx * uz));
        float nz = ((vx * uy) - (vy * ux));

        // normalize(n)
        float num2 = ((nx * nx) + (ny * ny)) + (nz * nz);
        float num = 1f / (float) Math.sqrt(num2);
        nx *= num;
        ny *= num;
        nz *= num;

        addNormal(indices[i], verts, nx,ny, nz);
        addNormal(indices[i + 1], verts, nx, ny, nz);
        addNormal(indices[i + 2], verts, nx, ny, nz);
    }

    for (int i = 0; i < (verts.length / VERTEX_SIZE); i++) {
        normalizeNormal(i, verts);
    }
}

// Adds the provided value to the normal
private void addNormal(int vertIndex, float[] verts, float x, float y,
        float z) {

    int i = getNormalStart(vertIndex);

    float rx = (float) ((x * Math.cos(180)) - (y * Math.sin(180)));
    float ry = (float) ((x * Math.sin(180)) + (y * Math.cos(180)));
    x = rx;
    y = ry;
    verts[i] += x;
    verts[i + 1] += y;
    verts[i + 2] += z;
}

/*
 * Normalizes normals
 */
private void normalizeNormal(int vertIndex, float[] verts) {

    int i = getNormalStart(vertIndex);

    float x = verts[i];
    float y = verts[i+1];
    float z = verts[i+2];

    float num2 = ((x * x) + (z * z)) + (y * y);
    float num = (float) Math.sqrt(num2);
    x *= num;
    y *= num;
    z *= num;

    verts[i] = x;
    verts[i + 1] = y;
    verts[i + 2] = z;
}


// Gets the index of the first float of a normal for a specific vertex
private int getNormalStart(int vertIndex) {
    return vertIndex * VERTEX_SIZE + 3;
}

// Gets the index of the first float of a specific vertex
private int getPositionStart(int vertIndex) {
    return vertIndex * VERTEX_SIZE;
}

解决方案

In the end I changed the way I build the Mesh entirely. Now I build the mesh out of triangles. Here's what it looks like now: . it's not yet perfect as there are no diagonal colours but I'm happy with the general look.

Here is how I did it. I made a new class to hold my variables

private Vector3 corner1;
private Vector3 corner2;
private Vector3 corner3;
private Vector3 corner4;
private Vector3 leftNormal;
private Vector3 rightNormal;
private Color color1;
private Color color2;
private Color color3;
private Color color4;
private Vector2 texturePos;

and draw them like so:

// left triangle
VertexInfo v1 = new VertexInfo();
VertexInfo v2 = new VertexInfo();
VertexInfo v3 = new VertexInfo();

// right triangle
VertexInfo v4 = new VertexInfo();
VertexInfo v5 = new VertexInfo();
VertexInfo v6 = new VertexInfo();

v1.setPos(cell.getCorner1()).setNor(cell.getLeftNormal()).setCol(cell.getColor1()).setUV(cell.getTexturePos());
v2.setPos(cell.getCorner4()).setNor(cell.getLeftNormal()).setCol(cell.getColor1()).setUV(cell.getTexturePos());
v3.setPos(cell.getCorner2()).setNor(cell.getLeftNormal()).setCol(cell.getColor1()).setUV(cell.getTexturePos());

v4.setPos(cell.getCorner3()).setNor(cell.getRightNormal()).setCol(cell.getColor3()).setUV(cell.getTexturePos());
v5.setPos(cell.getCorner2()).setNor(cell.getRightNormal()).setCol(cell.getColor3()).setUV(cell.getTexturePos());
v6.setPos(cell.getCorner4()).setNor(cell.getRightNormal()).setCol(cell.getColor3()).setUV(cell.getTexturePos());

meshBuilder.triangle(v1, v2, v3);
meshBuilder.triangle(v4, v5, v6);

I calculate the face normals of the triangles like so:

private Vector3 calcNormal(Vector3 p1, Vector3 p2, Vector3 p3) {

    // u = p3 - p1
    float ux = p3.x - p1.x;
    float uy = p3.y - p1.y;
    float uz = p3.z - p1.z;

    // v = p2 - p1
    float vx = p2.x - p1.x;
    float vy = p2.y - p1.y;
    float vz = p2.z - p1.z;

    // n = cross(v, u)
    float nx = ((vy * uz) - (vz * uy));
    float ny = ((vz * ux) - (vx * uz));
    float nz = ((vx * uy) - (vy * ux));

    // // normalize(n)
    float num2 = ((nx * nx) + (ny * ny)) + (nz * nz);
    float num = 1f / (float) Math.sqrt(num2);
    nx *= num;
    ny *= num;
    nz *= num;

    return new Vector3(nx, ny, nz);
}

这篇关于在LibGDX平面着色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆