GRoutar
GRoutar

Reputation: 1425

Cylinder partially visible WebGL

I am designing a cylinder in WebGL 1.0 (which is based on OpenGL ES 2.0).

It started off as a n-sided polygon (n slices) with m stacks. Its normals are specified as follows:

enter image description here

Even though the polygon/cylinder is being drawn correctly, its faces aren't visible from every angle. They can only be seen from the inside as the following images show:

enter image description here

enter image description here

My goal is to have a fully visible cylinder like the following one (no top/bottom faces required):

enter image description here

Does anyone have any idea on how to fix this? Code below:

//End if stacks = 0
 if (this.stacks <= 0) return;

 this.vertices = []; 
 this.indices = [];
 this.normals = [];

//--- Vertices & Normals ---

 var angle;
 var alpha = 360 / this.slices;
 var zCoord = 0;

 // (N) stacks -> (N + 1) faces -> (faces * this.slices) vertex
 for ( var stackIndex = 0; stackIndex < this.stacks + 1; stackIndex++) {

     //Reset angle for each face of the stack
     angle = 0;

     for ( var sliceIndex = 0; sliceIndex < this.slices; sliceIndex++) {

         this.vertices.push(Math.cos(angle * degToRad)); //X
         this.vertices.push(Math.sin(angle * degToRad)); //Y
         this.vertices.push(zCoord); //Z

         this.normals.push(Math.cos(angle * degToRad)); //X
         this.normals.push(Math.sin(angle * degToRad)); //Y
         this.normals.push(zCoord); //Z

         //Updating angle
         angle = angle + alpha; 
         }
     //Updating z coordinate
     zCoord = zCoord + (1 / this.stacks);
 }   

//--- Indices ---

 var stackInc; stackIndex = 0; sliceIndex = 0;

 for (stackIndex = 0; stackIndex < this.stacks; stackIndex++) {

     stackInc = stackIndex * this.slices;

     for (sliceIndex = 0; sliceIndex < this.slices; sliceIndex++) {

         if (sliceIndex != this.slices - 1) { 
             //T1
             this.indices.push(sliceIndex + stackInc);
             this.indices.push(sliceIndex + stackInc + this.slices);
             this.indices.push(sliceIndex + stackInc + this.slices + 1);

             //T2
             this.indices.push(sliceIndex + stackInc + this.slices + 1); //this.slices
             this.indices.push(sliceIndex + stackInc + 1); //0
             this.indices.push(sliceIndex + stackInc); //int4
             }
        //Handling last face which uses repeated vertices
         else {
             this.indices.push(sliceIndex + stackInc);
             this.indices.push(sliceIndex + stackInc + this.slices);
             this.indices.push(stackInc + this.slices);

             this.indices.push(stackInc + this.slices);
             this.indices.push(stackInc);
             this.indices.push(sliceIndex + stackInc); //int4
             }
         }
     }

Upvotes: 2

Views: 880

Answers (1)

Roman
Roman

Reputation: 6428

Regardless of face normals, WebGL defines the front- and back-face based on the order in which you define the triangle.

Having this triangle:

A-------B
 \     /
  \   /
   \ /
    C

If you add the vertices to the index in order A, B, C (clock wise), and you don't see them, you need to switch the order in A, C, B (counter clock wise).

This is because of this: https://www.opengl.org/wiki/Face_Culling

Upvotes: 3

Related Questions