JSFiddle - React, Tailwind, and code Playground

by Natcher86

HTML

<script src="https://rawgit.com/mrdoob/three.js/master/build/three.min.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/master/examples/js/loaders/GLTFLoader.js"></script>
<script type="x-shader/x-vertex" id="vertex-shader">

  varying vec3 vNormal;
  varying vec3 vPosition;
  varying vec3 vLight;

  vec4 lightPosition = vec4( -30., 30., -20., 1. );

  void main() {

    // vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
    // gl_Position = projectionMatrix * mvPosition;

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

    vec4 modelViewPosition = modelViewMatrix * mvPosition;
    gl_Position = projectionMatrix * modelViewPosition;

    vNormal = normalMatrix * normal;
    vPosition = mvPosition.xyz;
    vLight = ( viewMatrix * lightPosition ).xyz;

  }

</script>

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

  varying vec3 vNormal;
  varying vec3 vPosition;
  varying vec3 vLight;

  void main() {

    vec3 ambient = vec3( .1 );
    vec3 n = normalize( vNormal );
    vec3 s = normalize( vLight - vPosition );

    vec3 color = vec3( .95 );
    vec3 diffuse = color * max( 0.0, dot( n, s ) ) * vec3( 1. );

    vec3 r = - reflect( vLight, n );
    r = normalize( r );
    vec3 v = - vPosition.xyz;
    v = normalize( v );
    float shininess = 10.;

    float rm = 1. - max( 0., dot( n, v ) );
    vec3 rim = vec3( pow( rm, 2. ) );

    vec3 specular;
    if( shininess != 0.0 ) {
      specular = vec3( 1. ) * vec3( 1. ) * pow( max( 0.0, dot( r, v ) ), shininess );
    } else {
      specular = vec3( 0. );
    }
    specular = vec3( 0.);
    rim = vec3( 0. );

		gl_FragColor = vec4( rim + ambient + diffuse + specular, 1. );

  }

</script>

JavaScript

var camera, scene, renderer;

var mesh;
var material;
var amount = parseInt( window.location.search.substr( 1 ) ) || 20;
var count = Math.pow( amount, 3 );
var dummy = new THREE.Object3D();

init();
animate();

function init() {

  camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 100 );
  camera.position.set( amount * 0.9, amount * 0.9, amount * 0.9 );
  camera.lookAt( 0, 0, 0 );

  scene = new THREE.Scene();
  

	material = new THREE.ShaderMaterial({
    vertexShader: document.getElementById( 'vertex-shader' ).textContent,
    fragmentShader: document.getElementById( 'fragment-shader' ).textContent,
    flatShading: false,
    transparent: true
  });

  var loader = new THREE.GLTFLoader();
  loader.load( 'https://assets.codepen.io/1137/model_1.glb', function ( gltf ) {
      
    geometry = gltf.scene.children[0].geometry;

    // material = new THREE.MeshNormalMaterial();

    mesh = new THREE.InstancedMesh( geometry, material, count );
    //mesh.instanceMatrix.setUsage( THREE.DynamicDrawUsage ); // will be updated every frame
    scene.add( mesh );

  } );

  //

  renderer = new THREE.WebGLRenderer( { antialias: true } );
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.setSize( window.innerWidth, window.innerHeight );
  document.body.appendChild( renderer.domElement );

  //

  window.addEventListener( 'resize', onWindowResize, false );

}

function onWindowResize() {

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize( window.innerWidth, window.innerHeight );

}

//

function animate() {

  requestAnimationFrame( animate );

  render();

}

function render() {

  if ( mesh ) {

    var time = Date.now() * 0.001;

    //mesh.rotation.x = Math.sin( time / 4 );
    //mesh.rotation.y = Math.sin( time / 2 );

    var i = 0;
    var offset = ( amount - 1 ) / 2;

    for ( var x = 0; x < amount; x ++ ) {

      for ( var y = 0; y < amount; y ++ ) {

...