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