JSFiddle - React, Tailwind, and code Playground

by YouTingKuo

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

#define NVERTS 4

varying vec3 vNormal;
varying vec3 vViewPosition;

void main() {

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

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

#define NVERTS 4

uniform vec3 color;

uniform vec3 lightColor;
uniform float lightIntensity;
uniform vec3 lightverts[ NVERTS ];	// in local space
uniform mat4 lightMatrixWorld;

varying vec3 vNormal;				// in camera space
varying vec3 vViewPosition;			// in camera space

void main() {

	vec3 normal = normalize( vNormal );

	vec4 lPosition[ NVERTS ];

	vec3 lVector[ NVERTS ];

	// stub in some ambient reflectance

	vec3 ambient = color * vec3( 0.2 );

	// direction vectors from point to area light corners

	for( int i = 0; i < NVERTS; i ++ ) {

		lPosition[ i ] = viewMatrix * lightMatrixWorld * vec4( lightverts[ i ], 1.0 ); // in camera space

		lVector[ i ] = normalize( lPosition[ i ].xyz + vViewPosition.xyz ); // dir from vertex to areaLight

	}

	// bail if the point is on the wrong side of the light... there must be a better way...

	float tmp = dot( lVector[ 0 ], cross( ( lPosition[ 2 ] - lPosition[ 0 ] ).xyz, ( lPosition[ 1 ] - lPosition[ 0 ] ).xyz ) );

	if ( tmp > 0.0 ) {

		gl_FragColor = vec4( ambient, 1.0 );
		return;

	}

	// vector irradiance at point

	vec3 lightVec = vec3( 0.0 );

	for( int i = 0; i < NVERTS; i ++ ) {

		vec3 v0 = lVector[ i ];
		vec3 v1 = lVector[ int( mod( float( i + 1 ), float( NVERTS ) ) ) ]; // ugh...

		lightVec += acos( dot( v0, v1 ) ) * normalize( cross( v0, v1 ) );

	}

	// irradiance factor at point

	float factor = max( dot( lightVec, normal ), 0.0 ) / ( 2.0...

CSS

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

JavaScript

// Area Light Shader for three.js r.58

// WestLangley

var renderer, scene, camera, controls;
var areaLight, material, mesh;
var t = 0, delta = 0.004;

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 );
	renderer.physicallyBasedShading = true;
	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( 150, 50, 150 );

	// controls
	controls = new THREE.OrbitControls( camera );

	// axes
	scene.add( new THREE.AxisHelper( 200 ) );

	// area light
	var lightColor = 0xffffff;
	var lightIntensity = 1;

	var geometry = new THREE.PlaneGeometry( 100, 50 );

	var material = new THREE.MeshBasicMaterial( { 
        color: lightColor, transparent: true, opacity: 0.7, side: THREE.FrontSide } );

	areaLight = new THREE.Mesh( geometry, material );
    
 	areaLight.position.set( 0, 25, -25 );
	areaLight.rotation.set( 0, 0, 0 );
	areaLight.scale.set( 1, 1, 1 );
	scene.add( areaLight );

    // wireframe hack
    areaLight.add( new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { wireframe: true } ) ) );

	// areaLight verts
	var vertices = areaLight.geometry.vertices;
	var verts = [];
	verts.push( vertices[ 0 ] );
	verts.push( vertices[ 1 ] );
	verts.push( vertices[ 3 ] ); // swap 2 & 3; must be in clockwise order; they are not
	verts.push( vertices[ 2 ] );

	// uniforms
	var...