• <tfoot id='GOMfG'></tfoot>

      <small id='GOMfG'></small><noframes id='GOMfG'>

      1. <legend id='GOMfG'><style id='GOMfG'><dir id='GOMfG'><q id='GOMfG'></q></dir></style></legend>

          <bdo id='GOMfG'></bdo><ul id='GOMfG'></ul>
      2. <i id='GOMfG'><tr id='GOMfG'><dt id='GOMfG'><q id='GOMfG'><span id='GOMfG'><b id='GOMfG'><form id='GOMfG'><ins id='GOMfG'></ins><ul id='GOMfG'></ul><sub id='GOMfG'></sub></form><legend id='GOMfG'></legend><bdo id='GOMfG'><pre id='GOMfG'><center id='GOMfG'></center></pre></bdo></b><th id='GOMfG'></th></span></q></dt></tr></i><div id='GOMfG'><tfoot id='GOMfG'></tfoot><dl id='GOMfG'><fieldset id='GOMfG'></fieldset></dl></div>

        LibGDX 网格高度图法线和灯光

        时间:2023-05-19

            • <bdo id='ZGEkC'></bdo><ul id='ZGEkC'></ul>

              <small id='ZGEkC'></small><noframes id='ZGEkC'>

              • <i id='ZGEkC'><tr id='ZGEkC'><dt id='ZGEkC'><q id='ZGEkC'><span id='ZGEkC'><b id='ZGEkC'><form id='ZGEkC'><ins id='ZGEkC'></ins><ul id='ZGEkC'></ul><sub id='ZGEkC'></sub></form><legend id='ZGEkC'></legend><bdo id='ZGEkC'><pre id='ZGEkC'><center id='ZGEkC'></center></pre></bdo></b><th id='ZGEkC'></th></span></q></dt></tr></i><div id='ZGEkC'><tfoot id='ZGEkC'></tfoot><dl id='ZGEkC'><fieldset id='ZGEkC'></fieldset></dl></div>

              • <legend id='ZGEkC'><style id='ZGEkC'><dir id='ZGEkC'><q id='ZGEkC'></q></dir></style></legend>
                  <tbody id='ZGEkC'></tbody>

                <tfoot id='ZGEkC'></tfoot>
                  本文介绍了LibGDX 网格高度图法线和灯光的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  限时送ChatGPT账号..

                  我正在尝试让网格法线和灯光在 LibGDX 项目中工作.

                  I am trying to get mesh normals and lights working in LibGDX project.

                  我已经有从高度图纹理像素生成的纹理网格.

                  I already have textured mesh generated from heightmap texture pixels.

                  问题是我无法正确点亮法线.我也不是 100% 确定我在 TerrainChunk 类中正确设置了正常顶点.

                  The problem is I cannot get normals lighted up correctly. Also Im not 100% sure I have normal vertices correctly set up in TerrainChunk class.

                  以下是主类代码:

                  package com.me.terrain;
                  
                  import com.badlogic.gdx.Game;
                  import com.badlogic.gdx.Gdx;
                  import com.badlogic.gdx.files.FileHandle;
                  import com.badlogic.gdx.graphics.Color;
                  import com.badlogic.gdx.graphics.GL20;
                  import com.badlogic.gdx.graphics.Mesh;
                  import com.badlogic.gdx.graphics.PerspectiveCamera;
                  import com.badlogic.gdx.graphics.Pixmap;
                  import com.badlogic.gdx.graphics.Texture;
                  import com.badlogic.gdx.graphics.VertexAttribute;
                  import com.badlogic.gdx.graphics.VertexAttributes.Usage;
                  import com.badlogic.gdx.graphics.g3d.utils.CameraInputController;
                  import com.badlogic.gdx.graphics.glutils.ShaderProgram;
                  import com.badlogic.gdx.math.Matrix3;
                  import com.badlogic.gdx.math.Matrix4;
                  import com.badlogic.gdx.math.Vector3;
                  
                  public class Terra extends Game {
                  
                  private PerspectiveCamera camera;
                  private CameraInputController camController;
                  
                  private TerrainChunk chunk;
                  private Mesh mesh;
                  
                  private ShaderProgram shader;
                  private Texture terrainTexture;
                  
                  private final Matrix3 normalMatrix = new Matrix3();
                  
                  private static final float[] lightPosition = { 5, 35, 5 };
                  private static final float[] ambientColor = { 0.2f, 0.2f, 0.2f, 1.0f };
                  private static final float[] diffuseColor = { 0.5f, 0.5f, 0.5f, 1.0f };
                  private static final float[] specularColor = { 0.7f, 0.7f, 0.7f, 1.0f };
                  
                  private static final float[] fogColor = { 0.2f, 0.1f, 0.6f, 1.0f };
                  
                  private Matrix4 model = new Matrix4();
                  private Matrix4 modelView = new Matrix4();
                  
                  private final String vertexShader =
                          "attribute vec4 a_position; 
                  " +
                          "attribute vec3 a_normal; 
                  " +
                          "attribute vec2 a_texCoord; 
                  " +
                          "attribute vec4 a_color; 
                  " +
                  
                          "uniform mat4 u_MVPMatrix; 
                  " +
                          "uniform mat3 u_normalMatrix; 
                  " +
                  
                          "uniform vec3 u_lightPosition; 
                  " +
                  
                          "varying float intensity; 
                  " +
                          "varying vec2 texCoords; 
                  " +
                          "varying vec4 v_color; 
                  " +
                  
                          "void main() { 
                  " +
                          "    vec3 normal = normalize(u_normalMatrix * a_normal); 
                  " +
                          "    vec3 light = normalize(u_lightPosition); 
                  " +
                          "    intensity = max( dot(normal, light) , 0.0); 
                  " +
                  
                          "    v_color = a_color; 
                  " +
                          "    texCoords = a_texCoord; 
                  " +
                  
                          "    gl_Position = u_MVPMatrix * a_position; 
                  " +
                          "}";
                  
                  private final String fragmentShader =
                          "#ifdef GL_ES 
                  " +
                          "precision mediump float; 
                  " +
                          "#endif 
                  " +
                  
                          "uniform vec4 u_ambientColor; 
                  " +
                          "uniform vec4 u_diffuseColor; 
                  " +
                          "uniform vec4 u_specularColor; 
                  " +
                  
                          "uniform sampler2D u_texture; 
                  " +
                          "varying vec2 texCoords; 
                  " +
                          "varying vec4 v_color; 
                  " +
                  
                          "varying float intensity; 
                  " +
                  
                          "void main() { 
                  " +
                          "    gl_FragColor = v_color * intensity * texture2D(u_texture, texCoords); 
                  " +
                          "}";
                  
                  @Override
                  public void create() {
                  
                      // Terrain texture size is 128x128
                      terrainTexture = new Texture(Gdx.files.internal("data/concrete2.png"));
                  
                      // Height map (black/white) texture size is 32x32
                      String heightMapFile = "data/heightmap.png";
                  
                  
                      // position, normal, color, texture
                      int vertexSize = 3 + 3 + 1 + 2;  
                  
                      chunk = new TerrainChunk(32, 32, vertexSize, heightMapFile);
                  
                  
                  
                      mesh = new Mesh(true, chunk.vertices.length / 3, chunk.indices.length,
                              new VertexAttribute(Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE),
                              new VertexAttribute(Usage.Normal, 3, ShaderProgram.NORMAL_ATTRIBUTE),
                              new VertexAttribute(Usage.ColorPacked, 4, ShaderProgram.COLOR_ATTRIBUTE),
                              new VertexAttribute(Usage.TextureCoordinates, 2, ShaderProgram.TEXCOORD_ATTRIBUTE));
                  
                      mesh.setVertices(chunk.vertices);
                      mesh.setIndices(chunk.indices);
                  
                  
                  
                      camera = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
                      camera.position.set(5, 50, 5);
                      camera.direction.set(3, 0, 0).sub(camera.position).nor();
                      camera.near = 0.005f;
                      camera.far = 300;
                      camera.update();
                  
                      camController = new CameraInputController(camera);
                      Gdx.input.setInputProcessor(camController);
                  
                      ShaderProgram.pedantic = false;
                  
                      shader = new ShaderProgram(vertexShader, fragmentShader);
                  
                  }
                  
                  @Override
                  public void render() {
                  
                      Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
                      Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
                      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
                  
                      camController.update();
                      camera.update();
                  
                  
                      // This is wrong?
                      model.setToRotation(new Vector3(0, 1, 0), 45f);
                      modelView.set(camera.view).mul(model);
                  
                  
                      terrainTexture.bind();
                  
                      shader.begin();
                  
                      shader.setUniformMatrix("u_MVPMatrix", camera.combined);
                      shader.setUniformMatrix("u_normalMatrix", normalMatrix.set(modelView).inv().transpose());
                  
                      shader.setUniform3fv("u_lightPosition", lightPosition, 0, 3);
                      shader.setUniform4fv("u_ambientColor", ambientColor, 0, 4);
                      shader.setUniform4fv("u_diffuseColor", diffuseColor, 0, 4);
                      shader.setUniform4fv("u_specularColor", specularColor, 0, 4);
                  
                      shader.setUniformi("u_texture", 0);
                  
                      mesh.render(shader, GL20.GL_TRIANGLES);
                  
                      shader.end();
                  
                  }
                  }
                  

                  TerrainChunk 类代码:

                  final static class TerrainChunk {
                  
                      public final float[] heightMap;
                      public final short width;
                      public final short height;
                      public final float[] vertices;
                      public final short[] indices;
                  
                      public final int vertexSize;
                      private final int positionSize = 3;
                  
                      public TerrainChunk(int width, int height, int vertexSize, String heightMapTexture) {
                  
                          if ((width + 1) * (height + 1) > Short.MAX_VALUE) {
                              throw new IllegalArgumentException(            
                                      "Chunk size too big, (width + 1)*(height+1) must be <= 32767");
                          }
                  
                          this.heightMap = new float[(width + 1) * (height + 1)];
                          this.width = (short) width;
                          this.height = (short) height;
                          this.vertices = new float[heightMap.length * vertexSize];
                          this.indices = new short[width * height * 6];
                          this.vertexSize = vertexSize;
                  
                          buildHeightmap(heightMapTexture);
                  
                          buildIndices();
                          buildVertices();
                  
                          calcNormals(indices, vertices);
                  
                      }
                  
                      public void buildHeightmap(String pathToHeightMap) {
                  
                          FileHandle handle = Gdx.files.internal(pathToHeightMap);
                          Pixmap heightmapImage = new Pixmap(handle);
                          Color color = new Color();
                          int idh = 0;
                  
                          for (int x = 0; x < this.width + 1; x++) {
                              for (int y = 0; y < this.height + 1; y++) {
                                  Color.rgba8888ToColor(color, heightmapImage.getPixel(x, y));
                                  this.heightMap[idh++] = color.r;
                              }
                          }
                      }
                  
                      public void buildVertices() {
                          int heightPitch = height + 1;
                          int widthPitch = width + 1;
                  
                          int idx = 0;
                          int hIdx = 0;
                          int strength = 10; // multiplier for height map
                  
                          float scale = 4f;
                  
                          for (int z = 0; z < heightPitch; z++) {
                              for (int x = 0; x < widthPitch; x++) {
                  
                                  // POSITION
                                  vertices[idx++] = scale * x;
                                  vertices[idx++] = heightMap[hIdx++] * strength;
                                  vertices[idx++] = scale * z;
                  
                                  // NORMAL, skip these for now
                                  idx += 3;
                  
                                  // COLOR
                                  vertices[idx++] = Color.WHITE.toFloatBits();
                  
                                  // TEXTURE
                                  vertices[idx++] = (x / (float) width);
                                  vertices[idx++] = (z / (float) height);
                  
                              }
                          }
                      }
                  
                      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);
                          }
                      }
                  
                      // Gets the index of the first float of a normal for a specific vertex
                      private int getNormalStart(int vertIndex) {
                          return vertIndex * vertexSize + positionSize;
                      }
                  
                      // Gets the index of the first float of a specific vertex
                      private int getPositionStart(int vertIndex) {
                          return vertIndex * vertexSize;
                      }
                  
                      // Adds the provided value to the normal
                      private void addNormal(int vertIndex, float[] verts, float x, float y, float z) {
                  
                          int i = getNormalStart(vertIndex);
                  
                          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) + (y * y)) + (z * z);
                          float num = 1f / (float) Math.sqrt(num2);
                          x *= num;
                          y *= num;
                          z *= num;
                  
                          verts[i] = x;
                          verts[i + 1] = y;
                          verts[i + 2] = z;
                      }
                  
                      /*
                       * 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 / vertexSize); i++) {
                              normalizeNormal(i, verts);
                          }
                      }
                  
                  }
                  

                  我看到的是,当我移动相机时,当我在地形上方时,灯光无法正确显示.当我在地形下时,它们会显示更多,尽管我认为是错误的.

                  What Im seeing is when I move camera the lights dont show correctly when I'm above terrain. They show more when Im under the terrain, though incorrectly even then I think.

                  图片:

                  1. 如下:http://i.imgur.com/TocCLfA.png

                  以上:http://i.imgur.com/fwGhGDT.png

                  推荐答案

                  通过MeshPartBuilder/GL_LINES调试绘制所有正常位置解决了问题.

                  Solved the problem by debugging and drawing all normal positions with MeshPartBuilder / GL_LINES.

                  我发现法线指向地形内部.改变法线方向是解决方案.

                  I found out that the normals were pointing inside the terrain. Changing normal direction was the solution.

                  这篇关于LibGDX 网格高度图法线和灯光的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:将 Admob 添加到 Libgdx 游戏 下一篇:在 Libgdx 中处理屏幕的正确方法

                  相关文章

                  最新文章

                1. <tfoot id='XX9Tt'></tfoot>

                    1. <i id='XX9Tt'><tr id='XX9Tt'><dt id='XX9Tt'><q id='XX9Tt'><span id='XX9Tt'><b id='XX9Tt'><form id='XX9Tt'><ins id='XX9Tt'></ins><ul id='XX9Tt'></ul><sub id='XX9Tt'></sub></form><legend id='XX9Tt'></legend><bdo id='XX9Tt'><pre id='XX9Tt'><center id='XX9Tt'></center></pre></bdo></b><th id='XX9Tt'></th></span></q></dt></tr></i><div id='XX9Tt'><tfoot id='XX9Tt'></tfoot><dl id='XX9Tt'><fieldset id='XX9Tt'></fieldset></dl></div>
                    2. <small id='XX9Tt'></small><noframes id='XX9Tt'>

                      <legend id='XX9Tt'><style id='XX9Tt'><dir id='XX9Tt'><q id='XX9Tt'></q></dir></style></legend>
                        <bdo id='XX9Tt'></bdo><ul id='XX9Tt'></ul>