JSFiddle - React, Tailwind, and code Playground

by mmansion

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">

varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vViewPosition;

void main() {

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

	vUv = uv;
	vNormal = normalize( normalMatrix * normal );
	vViewPosition = -mvPosition.xyz;

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

}

</script>

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

uniform sampler2D texture;
uniform sampler2D texture2;

varying vec2 vUv;
varying vec3 vNormal;
varying vec3 vViewPosition;

void main() {

	vec4 tColor = texture2D( texture, vUv );
	vec4 tColor2 = texture2D( texture2, vUv );

	// 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;

	gl_FragColor = vec4( mix( tColor.rgb, tColor2.rgb, tColor2.a ), 1.0 ) * dotProduct;

}

</script>

CSS

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

JavaScript

// three.js Custom ShaderMaterial with Multiple Textures

var mesh, renderer, scene, camera, controls;

init();
animate();

function init() {

	// info
	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.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( 200, 0, 200 );

	// controls
	controls = new THREE.OrbitControls( camera, renderer.domElement );

	// no lights in this example; fake them in the shader
	
	// cube geometry
	var geometry = new THREE.BoxGeometry( 70, 70, 70 );

	// texture
	var texture = new THREE.Texture( generateTexture( ) );
	texture.needsUpdate = true; // important
	var texture2 = new THREE.Texture( generateTexture2( ) ); // texture background is transparent
	texture2.needsUpdate = true; // important

	// uniforms
	var uniforms = {
		texture: { type: "t", value: texture },
		texture2: { type: "t", value: texture2 }
	};

	// material
	var material = new THREE.ShaderMaterial({
		uniforms        : uniforms,
		vertexShader    : document.getElementById( 'vertex_shader' ).textContent,
		fragmentShader  : document.getElementById( 'fragment_shader' ).textContent
	});
    
	// cube
	mesh = new THREE.Mesh( geometry, material );
	scene.add( mesh );

}

function animate() {

	requestAnimationFrame( animate );

    mesh.rotation.x += 0.001;
    mesh.rotation.y += 0.002;
    mesh.rotation.z +=...