JSFiddle - React, Tailwind, and code Playground
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.addAttribute( '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'...