three.js ~ Sphere Impostor Example

2016-14-03

HTML

<script src="http://threejs.org/build/three.js"></script>
<script src="http://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script id="shader-vs" type="x-shader/x-vertex">
// Inherits from Phong Shading in ThreeJS, allows compatibility with chunks
#define PHONG

// Normalize diagonal matrix (1)
const mat4 D = mat4(
    vec4(1.0, 0.0, 0.0, 0.0),
    vec4(0.0, 1.0, 0.0, 0.0),
    vec4(0.0, 0.0, 1.0, 0.0),
    vec4(0.0, 0.0, 0.0, -1.0)
);

// Create transpose method (not built-in OpenGL ES Shading Language)
highp mat4 transpose(in highp mat4 inMatrix) {
    highp vec4 i0 = inMatrix[0];
    highp vec4 i1 = inMatrix[1];
    highp vec4 i2 = inMatrix[2];
    highp vec4 i3 = inMatrix[3];

    highp mat4 outMatrix = mat4(
        vec4(i0.x, i1.x, i2.x, i3.x),
        vec4(i0.y, i1.y, i2.y, i3.y),
        vec4(i0.z, i1.z, i2.z, i3.z),
        vec4(i0.w, i1.w, i2.w, i3.w)
    );

    return outMatrix;
}

#include <common>
#include <color_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>

attribute float radius;

uniform vec4 viewport;
uniform mat4 modelViewMatrixInverse;

varying mat4 MTInverse;
varying mat4 VPInverse;
varying vec4 centernormclip;

// Near, far, width and height
varying float n, f, w, h;
varying float projMatrix11;
varying float projMatrix22;

// Compatibility with threejs chunks
varying vec3 vViewPosition;

void main() {
    // Chunck to color vertex with vertex color attribute
    #include <color_vertex>

    // Chunck to compute position in world space
    #include <begin_vertex>
    #include <project_vertex>
    #include <logdepthbuf_vertex>
    #include <clipping_planes_vertex>

    vViewPosition = - mvPosition.xyz;

    // Computing T matrix with u,v,w and c as quadratic surface parameters (2)
    mat4 T = mat4(
        // Three following vectors represents u, v, w axis of the quadric
        vec4(radius,        0.0,           0.0,           0.0),
        vec4(0.0,           radius,        0.0,     ...

JavaScript

var camera, scene, directionalLight, renderer, geometry, material, mesh, gl;

var WIDTH = window.innerWidth - 20;
var HEIGHT = window.innerHeight - 20;

var controls;
var impostorMaterial;

createImpostorMaterial();
init();
animate();

function init() {
    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera(50, WIDTH / HEIGHT, 2, 20);
    camera.position.z = 5;
    camera.position.y = 0;
    
    var ambient = new THREE.AmbientLight( 0x404040 );
    scene.add(ambient);
    
    directionalLight = new THREE.DirectionalLight( 0xffffff, 1.0 );
		directionalLight.position.set( 0, 3, 3 );
		scene.add( directionalLight );
    
    scene.add(camera);
    
    // controls
    controls = new THREE.OrbitControls( camera );

		geometry = createBufferGeometry();
    mesh = new THREE.Points(geometry, impostorMaterial);
    scene.add(mesh);
    
    var mesh2 = new THREE.Mesh(
    	new THREE.SphereGeometry( 1, 32, 32 ),
      new THREE.MeshPhongMaterial( { color: 0xdddddd, specular: 0x009900, shininess: 30 } )
    );
    mesh2.position.x = 2;
    scene.add(mesh2);
    
    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(WIDTH, HEIGHT);
    
    nearClippingPlane = new THREE.Plane(new THREE.Vector3(0.0, 0.0, -1.0), 0.0);
    farClippingPlane = new THREE.Plane(new THREE.Vector3(0.0, 0.0, 1.0), 0.0);
    //renderer.clippingPlanes = [nearClippingPlane, farClippingPlane];

    document.body.appendChild(renderer.domElement);
}

var previousTime;

function animate() {
  	requestAnimationFrame(animate);
    
    var now = Date.now();
    if (isNaN(previousTime)) {
    	previousTime = Date.now();
    }
    var time = (now - previousTime) * 0.0005;
    previousTime = now;
    
    var x = directionalLight.position.x;
    var z = directionalLight.position.z;
  	directionalLight.position.x = x * Math.cos(time) - z * Math.sin(time);
  	directionalLight.position.z = z * Math.cos(time) + x * Math.sin(time);
    
    render();
}

function...