JSFiddle - React, Tailwind, and code Playground

by sagar Bhanushali

HTML

<script src="http://threejs.org/build/three.min.js"></script>
<script src="http://threejs.org/examples/js/controls/OrbitControls.js"></script>

<script id="vertex_shader" type="x-shader/x-vertex">

attribute float distance;

varying float vDistance;
varying vec3 vNormal;
varying vec3 vViewPosition;

void main() {

	vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );

	vDistance = distance;
	vNormal = normalize( normalMatrix * normal );
	vViewPosition = - mvPosition.xyz;

	gl_Position = projectionMatrix * mvPosition;

}

</script>

<script id="fragment_shader" type="x-shader/x-fragment">

uniform float fraction;

varying float vDistance;
varying vec3 vNormal;
varying vec3 vViewPosition;

void main() {

	if ( vDistance > fraction ) discard;

	vec3 color = vec3( 0.25, 0.5, 1.0 );

	// hack in a fake pointlight at camera location, plus ambient
	vec3 normal = normalize( vNormal );
	vec3 lightDir = normalize( vViewPosition );

	float dotProduct = max( dot( normal, lightDir ), 0.0 ) + 0.2;

	// trick to make the clipped ends appear solid
	gl_FragColor = ( gl_FrontFacing ) ? vec4( color * dotProduct, 1.0 ) : vec4( color, 1.0 );

}

</script>

CSS

body {
	background-color: #000;
	margin: 0px;
	overflow: hidden;
}

JavaScript

var renderer, scene, camera;

var t = 0;

init();
animate();

function init() {

	// info
	var info = document.createElement( 'div' );
	info.style.position = 'absolute';
	info.style.top = '30px';
	info.style.width = '100%';
	info.style.textAlign = 'center';
	info.style.color = '#fff';
	info.style.fontWeight = 'bold';
	info.style.backgroundColor = 'transparent';
	info.style.zIndex = '1';
	info.style.fontFamily = 'Monospace';
	info.innerHTML = 'Drag mouse to rotate camera; scroll to zoom';
	document.body.appendChild( info );

	// renderer
	renderer = new THREE.WebGLRenderer();
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );
	document.body.appendChild( renderer.domElement );

	// scene
	scene = new THREE.Scene();
	
	// camera
	camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 );
	camera.position.set( 15, 20, 30 );

	// controls
	controls = new THREE.OrbitControls( camera, renderer.domElement );
	controls.minDistance = 20;
	controls.maxDistance = 50;

	// geometry
	var geometry = new THREE.BoxBufferGeometry( 2, 20, 2, 1, 128, 1 );

	// new attribute
	var numVertices = geometry.attributes.position.count;
	var distance = new Float32Array( numVertices * 1 ); // 1 value per vertex
	geometry.setAttribute( 'distance', new THREE.BufferAttribute( distance, 1 ) );

	// populate attribute
	for ( var i = 0, l = numVertices; i < l; i ++ ) {

		// set new attribute
		distance[ i ] = ( geometry.attributes.position.getY( i ) + 10 ) / 20;

		// wiggle geometry a bit while we're at it
		var x = geometry.attributes.position.getX( i )
		var y = geometry.attributes.position.getY( i );
		geometry.attributes.position.setX( i, x + 2 * Math.sin( y ) );

	}

	// uniforms
	var uniforms = {
		"fraction" : { value: 0 }
	};

	// material
	var material = new THREE.ShaderMaterial( {
		uniforms        : uniforms,
		vertexShader    : document.getElementById( 'vertex_shader'...