Skip to main content
added 197 characters in body
Source Link

I have a mesh that is generated using the marching cubes algorithm that is drawn using gl.drawArrays(), however the whole mesh isn't rendered, only part of it. I checked if the count I was specifiying in my gl.drawArrays() method was equal to the number of triangles, it was, and I checked if the mesh data was valid, and it was. So I am out of ideas on what to do. My meshes are split into 16x16 chunks. Here is what the issue looks like:  

For a 1x1 mesh, it didn't even render, even though the 1x1 mesh data looks correct. If it helps, the vertex data where every 3 entries is an x, y, z position looked like this:

[1, 0.5, 0, 0, 0.5, 0, 1, 0.5, 1, 1, 0.5, 1, 0, 0.5, 0, 0, 0.5, 1]

Partly Rendered Chunks

I have a mesh that is generated using the marching cubes algorithm that is drawn using gl.drawArrays(), however the whole mesh isn't rendered, only part of it. I checked if the count I was specifiying in my gl.drawArrays() method was equal to the number of triangles, it was, and I checked if the mesh data was valid, and it was. So I am out of ideas on what to do. My meshes are split into 16x16 chunks. Here is what the issue looks like:  Partly Rendered Chunks

I have a mesh that is generated using the marching cubes algorithm that is drawn using gl.drawArrays(), however the whole mesh isn't rendered, only part of it. I checked if the count I was specifiying in my gl.drawArrays() method was equal to the number of triangles, it was, and I checked if the mesh data was valid, and it was. So I am out of ideas on what to do. My meshes are split into 16x16 chunks. Here is what the issue looks like:

For a 1x1 mesh, it didn't even render, even though the 1x1 mesh data looks correct. If it helps, the vertex data where every 3 entries is an x, y, z position looked like this:

[1, 0.5, 0, 0, 0.5, 0, 1, 0.5, 1, 1, 0.5, 1, 0, 0.5, 0, 0, 0.5, 1]

Partly Rendered Chunks

Source Link

gl.drawArrays() not rendering whole mesh

I have a mesh that is generated using the marching cubes algorithm that is drawn using gl.drawArrays(), however the whole mesh isn't rendered, only part of it. I checked if the count I was specifiying in my gl.drawArrays() method was equal to the number of triangles, it was, and I checked if the mesh data was valid, and it was. So I am out of ideas on what to do. My meshes are split into 16x16 chunks. Here is what the issue looks like: Partly Rendered Chunks

Have you guys ever had meshes being partially rendered, if so, any ideas on how to solve it? If it helps, here is the chunk class:

function Chunk(chunkX, chunkY, cameraMatrix) {
  this.chunkX = chunkX;
  this.chunkY = chunkY;
  this.cameraMatrix = cameraMatrix;
  this.positionData = [];
  this.textureIdData = [];
  this.uvData = [];
  this.normalData = [];

  const chunkSizePlusOne = chunkSize + 1;
  const full = -1;
  const empty = 1;
  const totallyInside = 255;
  const totallyOutside = 0;
  const edgeIntersectionsSize = 16;
  const surface = 0;
  const chunkXPosition = chunkSize * chunkX;
  const chunkYPosition = chunkSize * chunkY;

  this.build = function () {
    const normalsOfTrianglesAdjacentToVertex = {};
    const vertexNormals = {};
    const perlinValues = [];

    for (let y = 0; y < chunkSizePlusOne; y++) {
      for (let x = 0; x < chunkSizePlusOne; x++) {
        const trueX = x + chunkXPosition;
        const trueY = y + chunkYPosition;

        perlinValues[y * chunkSizePlusOne + x] = perlin(trueX, trueY);
      };
    };

    for (let y = 0; y < chunkSize; y++) {
      for (let x = 0; x < chunkSize; x++) {
        const trueX = x + chunkXPosition;
        const trueY = y + chunkYPosition;

        for (let z = 0; z < worldHeight; z++) {
          const cubePositions = [
            [trueX, trueY, z],
            [trueX + 1, trueY, z],
            [trueX + 1, trueY + 1, z],
            [trueX, trueY + 1, z],
            [trueX, trueY, z + 1],
            [trueX + 1, trueY, z + 1],
            [trueX + 1, trueY + 1, z + 1],
            [trueX, trueY + 1, z + 1]
          ];
          const cubeScalarField = [];
          let lookupIndexOrrer = 1;
          let lookupIndex = 0;

          for (let cubePosition of cubePositions) {
            const [cubeX, cubeY, cubeZ] = cubePosition;
            const perlinValuesIndex = chunkSizePlusOne * (cubeY - chunkYPosition) + (cubeX - chunkXPosition);
            const height = worldHeight * perlinValues[perlinValuesIndex];

            if (cubeZ <= height) {
              cubeScalarField.push(full);

              lookupIndex |= lookupIndexOrrer;
            } else {
              cubeScalarField.push(empty);
            };

            lookupIndexOrrer <<= 1;
          };

          if (lookupIndex != totallyInside && lookupIndex != totallyOutside) {
            const edgeIntersections = triangulationTable[lookupIndex];
            
            for (let i = 0; i < edgeIntersectionsSize; i += 3) {
              const edgeIntersectionAtI = edgeIntersections[i];

              if (edgeIntersectionAtI !== -1) {
                const triangleEdgeIntersections = [
                  edgeIntersectionAtI,
                  edgeIntersections[i + 1],
                  edgeIntersections[i + 2]
                ];
                const xArray = [];
                const yArray = [];
                const zArray = [];

                for (let edgeIntersection of triangleEdgeIntersections) {
                  const [vertex1, vertex2] = verticesByEdge[edgeIntersection];
                  const [x1, y1, z1] = cubePositions[vertex1];
                  const [x2, y2, z2] = cubePositions[vertex2];
                  const vertex1Value = cubeScalarField[vertex1];
                  const vertex2Value = cubeScalarField[vertex2];
                  const vertex2Bias = (surface - vertex1Value) / (vertex2Value - vertex1Value);
                  const vertex1Bias = 1 - vertex2Bias;
                  const interpolatedX = x1 * vertex1Bias + x2 * vertex2Bias;
                  const interpolatedY = y1 * vertex1Bias + y2 * vertex2Bias;
                  const interpolatedZ = z1 * vertex1Bias + z2 * vertex2Bias;

                  xArray.push(interpolatedX);
                  yArray.push(interpolatedY);
                  zArray.push(interpolatedZ);

                  // push in order of actual webgl coordinates
                  this.positionData.push(interpolatedX);
                  this.positionData.push(interpolatedZ);
                  this.positionData.push(interpolatedY);
                };

                this.textureIdData.push(textureId(zArray));

                const uvData2D = uv(xArray, yArray);
                // parameters in order of webgl coordinates
                const normalOfTriangle = triangleNormal(xArray, zArray, yArray);

                for (let i = 0; i < numberOfTriangleVertices; i++) {
                  for (let j = 0; j < 2; j++) {
                    this.uvData.push(uvData2D[i][j]);
                  };

                  // in order of webgl coordinates
                  const vertexCoordinate = [xArray[i], zArray[i], yArray[i]];

                  if (normalsOfTrianglesAdjacentToVertex[vertexCoordinate]) {
                    normalsOfTrianglesAdjacentToVertex[vertexCoordinate].push(normalOfTriangle);
                  } else {
                    normalsOfTrianglesAdjacentToVertex[vertexCoordinate] = [normalOfTriangle];
                  };
                };  
              };
            };
          };
        };
      };
    };

    for (let vertex of Object.keys(normalsOfTrianglesAdjacentToVertex)) {
      vertexNormals[vertex] = meanOfVector3Ds(normalsOfTrianglesAdjacentToVertex[vertex]);
    };

    const positionData = this.positionData;
    const positionDataLength = positionData.length;

    for (let i = 0; i < positionDataLength; i += 3) {
      const vertex = [positionData[i], positionData[i + 1], positionData[i + 2]];
      this.normalData.push(...vertexNormals[vertex]);
    };
  };
  this.render = function () {
    gl.useProgram(program);

    const positionBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.positionData), gl.DYNAMIC_DRAW);
  
    gl.enableVertexAttribArray(positionLocation);
    gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);

    const textureIdBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, textureIdBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.textureIdData), gl.DYNAMIC_DRAW);

    gl.enableVertexAttribArray(textureIdLocation);
    gl.vertexAttribPointer(textureIdLocation, 1, gl.FLOAT, false, 0, 0);
  
    const uvBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, uvBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.uvData), gl.DYNAMIC_DRAW);
  
    gl.enableVertexAttribArray(uvLocation);
    gl.vertexAttribPointer(uvLocation, 2, gl.FLOAT, false, 0, 0);
  
    const normalBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.normalData), gl.DYNAMIC_DRAW);
  
    gl.enableVertexAttribArray(normalLocation);
    gl.vertexAttribPointer(normalLocation, 3, gl.FLOAT, false, 0, 0); 

    gl.uniformMatrix4fv(matrixLocation, false, this.cameraMatrix);

    gl.drawArrays(gl.TRIANGLES, 0, this.textureIdData.length);
  };
};