Developer Manual


A geometry is one of the building blocks for a 3D object: it defines it shape.

In WebGL, everything that is rendered on screen is a triangle, so geometries represent that.

Geometries contain their data in javascript typed arrays, which are essentially more performant versions of standard javascript arrays that can only contain numbers.

Each of these arrays is called an attribute.

A geometry contains the 3D coordinates for all the points that make it, which are stored in its position attribute.

It may also contain an index: when the geometry contains points that are used in several of its triangles, we can choose to index these points to avoid having the same point stored multiple times in the position attribute.

If the geometry doesn’t contain an index, the WebGL renderer assumes that every 3 consecutive points should be drawn as a triangle.

Attributes can also affect other parameters than position:

  • they can store UV coordinates, which are passed as a varying to the fragment shader, mapping a point in the geometry to a point on the texture or material that will be applied to the geometry
  • they can also store normals, a normal being a vector that is perpendicular to the geometry at a certain point
  • they can also store colors, so that each point has its own color

Attributes can only be read by the vertex shader. In order to access them in the fragment shader, they must be passed to it as a varying. A varying is declared in both the vertex and fragment shaders’ declarations (before the main() function), and is conventionally prefixed with the letter v.


varying vec3 vPosition

void main(){

// assign the attribute to the varying

vPosition = position;




varying vec3 vPosition

void main(){

// do something with the varying

gl_FragColor.r = fract( vPosition.x );



Geometry types

There are two types of geometries:

  • procedural geometries are entirely generated by code. Basic shapes such as cubes, spheres, curves are usually procedurally generated, as it is more efficient in terms of resources to create it on the user’s device instead of having them download the geometry – a procedural geometry defined in a few lines of code can create a geometry with millions of points very quickly, whereas loading the same pre-created geometry from a server would take significant time and bandwidth
  • model geometries, created in a 3D modelling software then exported to a WeGL compatible format ( ideally GLTF/GLB, though FBX and OBJ are also supported)

Watch out


THREE.js Geometry documentation