# [SOLVED] Messed up Normals?

Hello!
My third post now, but I am finally getting out of the noobish phase. I can now successfully generate a mesh from scratch in the form of cubic voxels using 3D Perlin noise (thank you noise.js!). However, the normal vectors for my procedural generation are fairly broken, if you look:

This luckily is still a huge improvement from this:

But even after switching up the vector patterns, they always seem to be wrong in one way or another.

Anyone have experience in procedural mesh generation? I have used many Playcanvas sources, and it seems that the way I am doing it matches themâ€¦ but doesnâ€™t.

Here is the problem child:

``````
var verts = [];
var norms = [];
var uvs = [];
var inds = [];

var blocks = [];
var i = 0;

for(let x = 0; x < 16; x++){
for(let y = 0; y < 16; y++){
for(let z = 0; z < 16; z++){
blocks.push(Math.round(noise.perlin3(x+pos.x+0.3, y+0.3, z+pos.y+0.3)));
}
}
}

for(let x = 0; x < 16; x++){
for(let y = 0; y < 16; y++){
for(let z = 0; z < 16; z++){
var block = blocks[x*256 + y*16 + z];
if(block != 0){
//top face
if(blocks[x*256 + y*16 + z + 16] == 0){
verts.push(x,y,z, x+1,y,z, x+1,y,z+1, x+1,y,z+1, x,y,z+1, x,y,z);
norms.push(0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0);
uvs.push(0,0,1,0,1,1,1,1,0,0,0,0);
inds.push(inds.length,inds.length+1,inds.length+2,inds.length+3,inds.length+4,inds.length+5);
}
//back face
if(blocks[x*256 + y*16 + z + 256] == 0){
verts.push(x,y,z, x+1,y,z, x+1,y-1,z, x+1,y-1,z, x,y-1,z, x,y,z);
norms.push(1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0);
uvs.push(0,0,1,0,1,1,1,1,0,0,0,0);
inds.push(inds.length,inds.length+1,inds.length+2,inds.length+3,inds.length+4,inds.length+5);
}
//right face
if(blocks[x*256 + y*16 + z + 1] == 0){
verts.push(x+1,y,z, x+1,y,z+1, x+1,y-1,z+1, x+1,y-1,z+1, x+1,y-1,z, x+1,y,z);
norms.push(-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0);
uvs.push(0,0,1,0,1,1,1,1,0,0,0,0);
inds.push(inds.length,inds.length+1,inds.length+2,inds.length+3,inds.length+4,inds.length+5);
}
//Front face
if(blocks[x*256 + y*16 + z - 256] == 0){
verts.push(x,y,z+1, x+1,y,z+1, x+1,y-1,z+1, x+1,y-1,z+1, x,y-1,z+1, x,y,z+1);
norms.push(0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1);
uvs.push(0,0,1,0,1,1,1,1,0,0,0,0);
inds.push(inds.length,inds.length+1,inds.length+2,inds.length+3,inds.length+4,inds.length+5);
}
//left face
if(blocks[x*256 + y*16 + z - 1] == 0){
verts.push(x,y,z, x,y,z+1, x,y-1,z+1, x,y-1,z+1, x,y-1,z, x,y,z);
norms.push(-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0);
uvs.push(0,0,1,0,1,1,1,1,0,0,0,0);
inds.push(inds.length,inds.length+1,inds.length+2,inds.length+3,inds.length+4,inds.length+5);
}
//bottom face
if(blocks[x*256 + y*16 + z - 16] == 0){
verts.push(x,y-1,z, x+1,y-1,z, x+1,y-1,z+1, x+1,y-1,z+1, x,y-1,z+1, x,y-1,z);
norms.push(0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0);
uvs.push(0,0,1,0,1,1,1,1,0,0,0,0);
inds.push(inds.length,inds.length+1,inds.length+2,inds.length+3,inds.length+4,inds.length+5);
}
i++;
}
}
}
}
//norms = pc.calculateNormals(verts, inds);
return {verts: verts, norms: norms, uvs: uvs, indicies: inds};

``````

Did I misconnect indicies? pc.calculateNormals does not even work for thisâ€¦ so where did I go wrong?

Project:
https://playcanvas.com/editor/scene/1439135
Find this in game.js.

Thank you.

EDIT:
Just so the code makes more sense:
Verts make the positions for the polygons. Six points for two polygons, branching from the block position. Same for UVs that connect them. Indicies (â€śindsâ€ť) connect the points. Norms are in sets of 3 for xyz vector parts.

EDIT2: I found the issue, just being really bad at placing the points correctly.

1 Like

If you donâ€™t mind posting your solution so this post serves as a helper to future users searching for a similar answer. Many thanks!

1 Like

My solution is not quite complete, apparentlyâ€¦
Although everything is visualized properly, there is a discrepancy. Even though I started with the top faces in development, apparently they are not there at all. If I invert the normals, the faces do not reappear.
From the top:

Beautiful voxels below:

Here is the new code that mostly works:

``````
var verts = [];
var norms = [];
var uvs = [];
var inds = [];

var blocks = [];

for(let x = 0; x < 16; x++){
for(let y = 0; y < 16; y++){
for(let z = 0; z < 16; z++){
blocks.push(Math.round(noise.perlin3(x+pos.x+0.3, y+0.3, z+pos.y+0.3)));
}
}
}

for(let x = 0; x < 16; x++){
for(let y = 0; y < 16; y++){
for(let z = 0; z < 16; z++){
var block = blocks[x*256 + y*16 + z];
if(block != 0){
//Top
if(this.findBlock(pos,x,y+1,z) == 0){
verts.push(x,y,z, x+1,y,z, x+1,y,z+1, x+1,y,z+1, x,y,z+1, x,y,z);
norms.push(0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0);
uvs.push(0,0,1,0,1,1,1,1,0,0,0,0);
inds.push(inds.length,inds.length+1,inds.length+2,inds.length+3,inds.length+4,inds.length+5);
}
//Front
if(this.findBlock(pos,x,y,z-1) == 0){
verts.push(x,y,z, x+1,y,z, x+1,y-1,z, x+1,y-1,z, x,y-1,z, x,y,z);
norms.push(0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1);
uvs.push(0,0,1,0,1,1,1,1,0,0,0,0);
inds.push(inds.length,inds.length+1,inds.length+2,inds.length+3,inds.length+4,inds.length+5);
}
//Right
if(this.findBlock(pos,x+1,y,z) == 0){
verts.push(x+1,y,z, x+1,y,z+1, x+1,y-1,z+1, x+1,y-1,z+1, x+1,y-1,z, x+1,y,z);
norms.push(1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0);
uvs.push(0,0,1,0,1,1,1,1,0,0,0,0);
inds.push(inds.length,inds.length+1,inds.length+2,inds.length+3,inds.length+4,inds.length+5);
}
//Left
if(this.findBlock(pos,x-1,y,z) == 0){
verts.push(x,y,z+1, x,y,z, x,y-1,z, x,y-1,z, x,y-1,z+1, x,y,z+1);
norms.push(-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0);
uvs.push(0,0,1,0,1,1,1,1,0,0,0,0);
inds.push(inds.length,inds.length+1,inds.length+2,inds.length+3,inds.length+4,inds.length+5);
}
//Back
if(this.findBlock(pos,x,y,z+1) == 0){
verts.push(x+1,y,z+1, x,y,z+1, x,y-1,z+1, x,y-1,z+1, x+1,y-1,z+1, x+1,y,z+1);
norms.push(0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1);
uvs.push(0,0,1,0,1,1,1,1,0,0,0,0);
inds.push(inds.length,inds.length+1,inds.length+2,inds.length+3,inds.length+4,inds.length+5);
}
//Bottom
if(this.findBlock(pos,x,y-1,z) == 0){
verts.push(x,y-1,z, x+1,y-1,z, x+1,y-1,z+1, x+1,y-1,z+1, x,y-1,z+1, x,y-1,z);
norms.push(0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0);
uvs.push(0,0,1,0,1,1,1,1,0,0,0,0);
inds.push(inds.length,inds.length+1,inds.length+2,inds.length+3,inds.length+4,inds.length+5);
}
}
}
}
}
//norms = pc.calculateNormals(verts, inds);
return {verts: verts, norms: norms, uvs: uvs, indicies: inds};

``````

Wait, I found the issue. I messed around with Index connections and finally it connected properly! Ignore this! Thank you anyways for being available!

1 Like