Skip to content

Instantly share code, notes, and snippets.

@roymacdonald
Created July 8, 2015 22:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roymacdonald/dd6ba30c770558ad3e90 to your computer and use it in GitHub Desktop.
Save roymacdonald/dd6ba30c770558ad3e90 to your computer and use it in GitHub Desktop.
Level of detail mesh max vertices test for three.js. just download file and run on browser. It will download the needed libs
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - materials - wireframe</title>
<meta charset="utf-8">
<style>
body {
background:#000;
color:#fff;
padding:0;
margin:0;
overflow:hidden;
font-family:georgia;
text-align:center;
}
#log { position:absolute; top:50px; text-align:left; display:block; background:#000 }
</style>
</head>
<body>
<pre id="log"></pre>
<button onclick="incRes()">Increase Resolution</button>
<button onclick="decRes()">Decrease Resolution</button>
<script src="http://threejs.org/build/three.min.js"></script>
<script src="http://threejs.org/examples/js/controls/TrackballControls.js"></script>
<script src="http://threejs.org/examples/js/libs/stats.min.js"></script>
<script id="vertexShader" type="x-shader/x-vertex">
uniform vec2 uTileOffset;
uniform float uScale;
void main() {
vec3 vPosition = uScale * position + vec3(uTileOffset, 0.0);
gl_Position = projectionMatrix * modelViewMatrix * vec4(vPosition, 1.0);
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
void main() {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
</script>
<script>
// Terrain is an extension of Object3D and thus can be added directly to the stage
var Terrain = function( worldWidth, levels, resolution ) {
THREE.Object3D.call( this );
this.worldWidth = ( worldWidth !== undefined ) ? worldWidth : 1024;
this.levels = ( levels !== undefined ) ? levels : 6;
this.resolution = ( resolution !== undefined ) ? resolution : 128;
this.numTiles =0;
this.tileGeometry = new THREE.PlaneGeometry( 1, 1, this.resolution, this.resolution );
var m = new THREE.Matrix4();
m.makeTranslation( 0.5, 0.5, 0 );
this.tileGeometry.applyMatrix( m );
var initialScale = this.worldWidth / Math.pow( 2, levels );
this.createTile( -initialScale, -initialScale, initialScale );
this.createTile( -initialScale, 0, initialScale );
this.createTile( 0, 0, initialScale);
this.createTile( 0, -initialScale, initialScale );
for ( var scale = initialScale; scale < worldWidth; scale *= 2 ) {
this.createTile( -2 * scale, -2 * scale, scale );
this.createTile( -2 * scale, -scale, scale);
this.createTile( -2 * scale, 0, scale);
this.createTile( -2 * scale, scale, scale);
this.createTile( -scale, -2 * scale, scale);
// 2 tiles 'missing' here are in previous layer
this.createTile( -scale, scale, scale);
this.createTile( 0, -2 * scale, scale);
// 2 tiles 'missing' here are in previous layer
this.createTile( 0, scale, scale);
this.createTile( scale, -2 * scale, scale);
this.createTile( scale, -scale, scale);
this.createTile( scale, 0, scale);
this.createTile( scale, scale, scale);
}
};
Terrain.prototype = Object.create( THREE.Object3D.prototype );
Terrain.prototype.createTile = function ( x, y, scale ) {
var terrainMaterial = this.createTerrainMaterial( new THREE.Vector2( x, y ),
scale
);
var plane = new THREE.Mesh( this.tileGeometry, terrainMaterial );
this.add( plane );
this.numTiles++;
};
Terrain.prototype.createTerrainMaterial = function(offset, scale ) {
return new THREE.ShaderMaterial( {
uniforms: {
uTileOffset: { type: "v2", value: offset },
uScale: { type: "f", value: scale }
},
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
transparent: true,
wireframe: true
} );
};
var camera, controls, scene, renderer, stats;
var terrain;
var resolution = 64;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 800;
controls = new THREE.TrackballControls( camera );
scene = new THREE.Scene();
buildLOD();
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.zIndex = 100;
document.body.appendChild( stats.domElement );
window.addEventListener( 'resize', onWindowResize, false );
}
function log( text ) {
var e = document.getElementById( "log" );
e.innerHTML = text + "<br/>" + e.innerHTML;
}
function buildLOD(){
scene.remove(terrain);
terrain = new Terrain( 1024, 4, resolution );
scene.add( terrain );
log("Tile resolution: " + resolution + "<br/>"+
"Tile Num Vertices: " + terrain.tileGeometry.vertices.length + "<br/>"+
"Tile instances: " + terrain.numTiles + "<br/>");
}
function incRes() {
resolution *=2;
buildLOD();
}
function decRes() {
resolution /=2;
if(resolution < 2){
resolution = 2;
}
buildLOD();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
stats.update();
controls.update();
renderer.render( scene, camera );
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment