# GridBoxGeometry

**URL:** <https://discourse.threejs.org/t/gridboxgeometry/1420>\
**Category:** Resources\
**Tags:** buffergeometry, geometry\
**Created:** [December 17, 2017, 10:49pm UTC](https://discourse.threejs.org/t/gridboxgeometry/1420 "2017-12-17T22:49:36Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [December 17, 2017, 10:49pm UTC](https://discourse.threejs.org/t/gridboxgeometry/1420/1 "2017-12-17T22:49:36Z")

</div>

This question was asked many times on SO, but there hasn’t been any appropriate and simple solution so far. I can’t say though that mine is just what we need, but anyway, here it is. Based on the method `.toGrid()` from this showcase [Grids of Waves (shaders)](https://discourse.threejs.org/t/grids-of-waves-shaders/1168).

![GridBoxGeometry](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/1X/a3f02ff735abdc86ef87cd3d5c25581e686a6c78.png)

[https://jsfiddle.net/prisoner849/8hqy99jj/](https://jsfiddle.net/prisoner849/8hqy99jj/)

**`GridBoxGeometry`**. Takes two parameters.  
The first one `geometry` is of the type `THREE.BoxBufferGeometry`.  
The second one `independent` is optional boolean. Default value is `false`. If set to `true`, the resulting geometry will have a cloned copy of the buffer attribute `position` from the first parameter, otherwise, it shares this attribute.

_Criticism is very welcomed._

```
  function GridBoxGeometry(geometry, independent) {
    if (!(geometry instanceof THREE.BoxBufferGeometry)) {
      console.log("GridBoxGeometry: the parameter 'geometry' has to be of the type THREE.BoxBufferGeometry");
      return geometry;
    }
    independent = independent !== undefined ? independent : false;

    let newGeometry = new THREE.BoxBufferGeometry();
    let position = geometry.attributes.position;
    newGeometry.attributes.position = independent === false ? position : position.clone();

    let segmentsX = geometry.parameters.widthSegments || 1;
    let segmentsY = geometry.parameters.heightSegments || 1;
    let segmentsZ = geometry.parameters.depthSegments || 1;

    let startIndex = 0;
    let indexSide1 = indexSide(segmentsZ, segmentsY, startIndex);
    startIndex += (segmentsZ + 1) * (segmentsY + 1);
    let indexSide2 = indexSide(segmentsZ, segmentsY, startIndex);
    startIndex += (segmentsZ + 1) * (segmentsY + 1);
    let indexSide3 = indexSide(segmentsX, segmentsZ, startIndex);
    startIndex += (segmentsX + 1) * (segmentsZ + 1);
    let indexSide4 = indexSide(segmentsX, segmentsZ, startIndex);
    startIndex += (segmentsX + 1) * (segmentsZ + 1);
    let indexSide5 = indexSide(segmentsX, segmentsY, startIndex);
    startIndex += (segmentsX + 1) * (segmentsY + 1);
    let indexSide6 = indexSide(segmentsX, segmentsY, startIndex);

    let fullIndices = [];
    fullIndices = fullIndices.concat(indexSide1);
    fullIndices = fullIndices.concat(indexSide2);
    fullIndices = fullIndices.concat(indexSide3);
    fullIndices = fullIndices.concat(indexSide4);
    fullIndices = fullIndices.concat(indexSide5);
    fullIndices = fullIndices.concat(indexSide6);

    newGeometry.setIndex(fullIndices);

    function indexSide(x, y, shift) {
      let indices = [];
      for (let i = 0; i < y + 1; i++) {
        let index11 = 0;
        let index12 = 0;
        for (let j = 0; j < x; j++) {
          index11 = (x + 1) * i + j;
          index12 = index11 + 1;
          let index21 = index11;
          let index22 = index11 + (x + 1);
          indices.push(shift + index11, shift + index12);
          if (index22 < ((x + 1) * (y + 1) - 1)) {
            indices.push(shift + index21, shift + index22);
          }
        }
        if ((index12 + x + 1) <= ((x + 1) * (y + 1) - 1)) {
          indices.push(shift + index12, shift + index12 + x + 1);
        }
      }
      return indices;
    }
    return newGeometry;
  };
```

---

<div class="post-metadata">

**Author:** ![hofk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hofk/32/44944_2.png) [@hofk](https://discourse.threejs.org/u/hofk)\
**Post date:** [March 7, 2018, 7:17pm UTC](https://discourse.threejs.org/t/gridboxgeometry/1420/2 "2018-03-07T19:17:46Z")

</div>

Another way to get a GridBox.

Uses THREEg addon [https://discourse.threejs.org/t/addon-to-create-special-extended-geometries/1855/3](https://discourse.threejs.org/t/addon-to-create-special-extended-geometries/1855/3)

Try it on [http://sandboxthreeg.threejs.hofk.de/gridBoxTHREEg.html](http://sandboxthreeg.threejs.hofk.de/gridBoxTHREEg.html)  
 ![20180307-2003-59694](https://cdck-file-uploads-canada1.s3.dualstack.ca-central-1.amazonaws.com/flex035/uploads/threejs/original/2X/4/41035c9bf556a2e7fa6f5b2bb47b108cffdcd03a.png)

Add  
**waffleDeep: function( t ){ return 0.02 },**  
to parameters0 and you get

![20180307-2028-51891](https://cdck-file-uploads-canada1.s3.dualstack.ca-central-1.amazonaws.com/flex035/uploads/threejs/original/2X/3/33c69a1df12c023eca125842e0818defd2ce5819.png)

```
<!DOCTYPE html>
<!-- ***example MagicBox - THREEg -***
/**
 * @author hofk / http://threejs.hofk.de/
*/
-->
<html lang="de">
<head>
	<title> Magic Box </title>
	<meta charset="utf-8" />
</head>
<body bgcolor="#cccccc " >
</body>
<script src="three.min.90.js"></script>
<script src="OrbitControls.js"></script>
<script src="THREEx.WindowResize.js"></script>
<script src="THREEg.js"></script>
<script>
'use strict'
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 2000 );
camera.position.set( 1, 2, 3);
var renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xefefef, 1 );
var container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
THREEx.WindowResize( renderer, camera );
var controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableZoom = true;
var light1 = new THREE.PointLight();
light1.position.set( -2, 2, 4 );
scene.add( light1 ); 
var light2 = new THREE.PointLight();
light2.position.set( -6, -3, -6 );
scene.add( light2 );
var clock = new THREE.Clock( true );
var time;
var side = THREE.DoubleSide; // material
var materials = [ // material index:
	new THREE.MeshBasicMaterial( { transparent: true, opacity: 0.45, side: side } ),	// 0 transparent
	new THREE.MeshPhongMaterial( { color: 0xff0000, emissive: 0xff0000, side: side } ), // 1 red	
	new THREE.MeshPhongMaterial( { color: 0x444444, emissive: 0x333333, side: side } )	// 2 grey	
];
var parameters0 = {
	sides: [7,7,7,7],
	materials: [2, 2, 2, 2, 2, 2],	
	radius: function( t ){ return 0 },
	widthSegments: 8,
	heightSegments: 8,
	depthSegments: 8,
	explode: function( t ){ return 0.01 },
}
var geometry0 = new THREE.BufferGeometry();
geometry0.createMagicBox = THREEg.createMagicBox;
geometry0.createMagicBox( parameters0 );
var mesh0 = new THREE.Mesh( geometry0, materials );
scene.add( mesh0 );
var parameters1 = {
	sides: [7,7,7,7],
	materials: [1, 1, 1, 1, 1, 1],	
	radius: function( t ){ return 0 },
	widthSegments: 8,
	heightSegments: 8,
	depthSegments: 8,	
}
var geometry1 = new THREE.BufferGeometry();
geometry1.createMagicBox = THREEg.createMagicBox;
geometry1.createMagicBox( parameters1 );
var mesh1 = new THREE.Mesh( geometry1, materials );
scene.add( mesh1 );
animate();
function animate( ) {	
	requestAnimationFrame( animate );
	time = clock.getElapsedTime( );	
	geometry0.morphVerticesMagicBox( time );
	geometry1.morphVerticesMagicBox( time );
	renderer.render( scene, camera );
	controls.update( );	
}
</script>
</html>

```

* * *

A dynamic example of this  
[http://sandboxthreeg.threejs.hofk.de/dynamicGridBoxTHREEg.html](http://sandboxthreeg.threejs.hofk.de/dynamicGridBoxTHREEg.html)

---

<div class="post-metadata">

**Author:** ![deepansh96](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/deepansh96/32/24870_2.png) [@deepansh96](https://discourse.threejs.org/u/deepansh96)\
**Post date:** [March 10, 2022, 11:38am UTC](https://discourse.threejs.org/t/gridboxgeometry/1420/3 "2022-03-10T11:38:17Z")

</div>

Thank you so much!!  
I wanted to implement a grid but without the ugly diagonal triangles that come with `wireframe: true`.

I just made a plane using your method and everything worked smoothly.

However I faced an issue. Writing it here for others facing a similar issue.  
I wanted to create a 2d grid using this method, and then inject some custom shader logic into the `LineBasicMaterial` that is being used.

I was trying to use `uv` attribute but it was not working by default.

Turns out that you need to clone the `uv` coordinates from our original geometry and assign it as an attribute to this new geometry that is made using `GridBoxGeometry` method.
