<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<style>
body {
margin: 0;
overflow: hidden;
cursor: move;
}
</style>
</HEAD>
<BODY>
<div id="three-container"></div>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.min.js"></script>
<script type="text/javascript" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/175711/THREE.OrbitControls.js"></script>
<script>
var mContainer;
var mCamera, mRenderer;
var mControls;
var mScene;
var mParticleCount = 100000; // <-- change this number!
var mParticleSystem;
var mTime = 0.0;
var mTimeStep = (1/60);
var mDuration = 120;
window.onload = function () {
init();
};
function init() {
initTHREE();
initControls();
initParticleSystem();
requestAnimationFrame(tick);
window.addEventListener('resize', resize, false);
}
function initTHREE() {
mRenderer = new THREE.WebGLRenderer({antialias: true});
mRenderer.setSize(window.innerWidth, window.innerHeight);
mContainer = document.getElementById('three-container');
mContainer.appendChild(mRenderer.domElement);
mCamera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 5000);
mCamera.position.set(0, 0, 800);
mScene = new THREE.Scene();
var light;
light = new THREE.PointLight(0xffffff, 4, 1000, 2);
light.position.set(0, 300, 0);
mScene.add(light);
}
function initControls() {
mControls = new THREE.OrbitControls(mCamera, mRenderer.domElement);
}
function initParticleSystem() {
var prefabGeometry = new THREE.PlaneGeometry(3, 3);
var bufferGeometry = new THREE.BAS.PrefabBufferGeometry(prefabGeometry, mParticleCount);
bufferGeometry.computeVertexNormals();
// generate additional geometry data
var aOffset = bufferGeometry.createAttribute('aOffset', 1);
var aPivot = bufferGeometry.createAttribute('aPivot', 3);
var aAxisAngle = bufferGeometry.createAttribute('aAxisAngle', 4);
var aColor = bufferGeometry.createAttribute('color', 3);
var i, j, offset;
// buffer time offset
var delay;
for (i = 0, offset = 0; i < mParticleCount; i++) {
delay = i / mParticleCount * mDuration;
for (j = 0; j < prefabGeometry.vertices.length; j++) {
aOffset.array[offset++] = delay;
}
}
// buffer pivot
var pivot = new THREE.Vector3();
for (i = 0, offset = 0; i < mParticleCount; i++) {
pivot.x = THREE.Math.randFloat(0, 2);
pivot.y = THREE.Math.randFloat(0, 2);
pivot.z = THREE.Math.randFloat(0, 2);
for (j = 0; j < prefabGeometry.vertices.length; j++) {
aPivot.array[offset++] = pivot.x;
aPivot.array[offset++] = pivot.y;
aPivot.array[offset++] = pivot.z;
}
}
// buffer axis angle
var axis = new THREE.Vector3();
var angle = 0;
for (i = 0, offset = 0; i < mParticleCount; i++) {
axis.x = THREE.Math.randFloatSpread(2);
axis.y = THREE.Math.randFloatSpread(2);
axis.z = THREE.Math.randFloatSpread(2);
axis.normalize();
angle = Math.PI * THREE.Math.randInt(24, 32);
for (j = 0; j < prefabGeometry.vertices.length; j++) {
aAxisAngle.array[offset++] = axis.x;
aAxisAngle.array[offset++] = axis.y;
aAxisAngle.array[offset++] = axis.z;
aAxisAngle.array[offset++] = angle;
}
}
// buffer color
var color = new THREE.Color();
var h, s, l;
for (i = 0, offset = 0; i < mParticleCount; i++) {
h = i / mParticleCount;
s = THREE.Math.randFloat(0.5, 0.75);
l = THREE.Math.randFloat(0.25, 0.5);
color.setHSL(h, s, l);
for (j = 0; j < prefabGeometry.vertices.length; j++) {
aColor.array[offset++] = color.r;
aColor.array[offset++] = color.g;
aColor.array[offset++] = color.b;
}
}
// buffer spline (uniform)
var pathArray = [];
var radiusArray = [];
var length = 14;
var x, y, z;
// first point
pathArray.push(-1000, 0, 0);
radiusArray.push(2);
for (i = 1; i < length - 1; i++) {
x = -100 * (length * 0.5) + 100 * i;
y = THREE.Math.randFloat(50, 300) * (i % 2 ? 1 : -1);
z = THREE.Math.randFloatSpread(300);
pathArray.push(
x,
y,
z
);
radiusArray.push(
THREE.Math.randFloat(1, 32)
);
}
// last point
pathArray.push(1000, 0, 0);
radiusArray.push(2);
var material = new THREE.BAS.PhongAnimationMaterial(
// custom parameters & THREE.MeshPhongMaterial parameters
{
vertexColors: THREE.VertexColors,
shading: THREE.FlatShading,
side: THREE.DoubleSide,
defines: {
PATH_LENGTH:pathArray.length / 3
},
uniforms: {
uTime: {type: 'f', value: 0},
uDuration: {type: 'f', value: mDuration},
uPath: {type: 'fv', value: pathArray},
uRadius: {type: 'fv1', value: radiusArray},
uRoundness: {type: 'v2', value: new THREE.Vector2(4, 4)}
},
shaderFunctions: [
THREE.BAS.ShaderChunk['quaternion_rotation'],
THREE.BAS.ShaderChunk['catmull-rom']
],
shaderParameters: [
'uniform float uTime;',
'uniform float uDuration;',
'uniform vec3 uPath[PATH_LENGTH];',
'uniform float uRadius[PATH_LENGTH];',
'uniform vec2 uRoundness;',
'attribute float aOffset;',
'attribute vec3 aPivot;',
'attribute vec4 aAxisAngle;'
],
shaderVertexInit: [
'float tProgress = mod((uTime + aOffset), uDuration) / uDuration;',
'float angle = aAxisAngle.w * tProgress;',
'vec4 tQuat = quatFromAxisAngle(aAxisAngle.xyz, angle);'
],
shaderTransformNormal: [
'objectNormal = rotateVector(tQuat, objectNormal);'
],
shaderTransformPosition: [
'float tMax = float(PATH_LENGTH - 1);',
'float tPoint = tMax * tProgress;',
'float tIndex = floor(tPoint);',
'float tWeight = tPoint - tIndex;',
'int i0 = int(max(0.0, tIndex - 1.0));',
'int i1 = int(tIndex);',
'int i2 = int(min(tIndex + 1.0, tMax));',
'int i3 = int(min(tIndex + 2.0, tMax));',
'vec3 p0 = uPath[i0];',
'vec3 p1 = uPath[i1];',
'vec3 p2 = uPath[i2];',
'vec3 p3 = uPath[i3];',
'float radius = catmullRom(uRadius[i0], uRadius[i1], uRadius[i2], uRadius[i3], tWeight);',
'transformed += aPivot * radius;',
'transformed = rotateVector(tQuat, transformed);',
'transformed += catmullRom(p0, p1, p2, p3, uRoundness, tWeight);'
]
},
// THREE.MeshPhongMaterial uniforms
{
shininess: 16,
specular: 0xffd700
}
);
mParticleSystem = new THREE.Mesh(bufferGeometry, material);
// because the bounding box of the particle system does not reflect its on-screen size
// set this to false to prevent the whole thing from disappearing on certain angles
mParticleSystem.frustumCulled = false;
mScene.add(mParticleSystem);
}
function tick() {
update();
render();
mTime += mTimeStep;
mTime %= mDuration;
requestAnimationFrame(tick);
}
function update() {
mControls.update();
mParticleSystem.material.uniforms['uTime'].value = mTime;
}
function render() {
mRenderer.render(mScene, mCamera);
}
function resize() {
mCamera.aspect = window.innerWidth / window.innerHeight;
mCamera.updateProjectionMatrix();
mRenderer.setSize(window.innerWidth, window.innerHeight);
}
////////////////////
// three.bas
////////////////////
THREE.BAS = {};
THREE.BAS.ShaderChunk = {};
THREE.BAS.ShaderChunk["animation_time"] = "float tDelay = aAnimation.x;\nfloat tDuration = aAnimat
评论0