提交 8c8ce25f 编写于 作者: M Mr.doob

Merge pull request #5892 from daoshengmu/softwareDrawLine

SoftwareRenderer draw lines
......@@ -40,7 +40,10 @@ THREE.SoftwareRenderer = function ( parameters ) {
var blockShift = 3;
var blockSize = 1 << blockShift;
var maxZVal = ( 1 << 24 ); // Note: You want to size this so you don't get overflows.
var lineMode = false;
var lookVector = new THREE.Vector3( 0, 0, 1 );
var crossVector = new THREE.Vector3();
var rectx1 = Infinity, recty1 = Infinity;
var rectx2 = 0, recty2 = 0;
......@@ -141,6 +144,7 @@ THREE.SoftwareRenderer = function ( parameters ) {
};
// TODO: Check why autoClear can't be false.
this.render = function ( scene, camera ) {
if ( this.autoClear === true ) this.clear();
......@@ -252,6 +256,18 @@ THREE.SoftwareRenderer = function ( parameters ) {
}
} else if ( element instanceof THREE.RenderableLine ) {
var shader = getMaterialShader( material );
drawLine(
element.v1.positionScreen,
element.v2.positionScreen,
element.vertexColors[0],
element.vertexColors[1],
shader,
material
);
}
}
......@@ -288,6 +304,53 @@ THREE.SoftwareRenderer = function ( parameters ) {
};
function setSize( width, height ) {
canvasWBlocks = Math.floor( width / blockSize );
canvasHBlocks = Math.floor( height / blockSize );
canvasWidth = canvasWBlocks * blockSize;
canvasHeight = canvasHBlocks * blockSize;
var fixScale = 1 << subpixelBits;
viewportXScale = fixScale * canvasWidth / 2;
viewportYScale = -fixScale * canvasHeight / 2;
viewportZScale = maxZVal / 2;
viewportXOffs = fixScale * canvasWidth / 2 + 0.5;
viewportYOffs = fixScale * canvasHeight / 2 + 0.5;
viewportZOffs = maxZVal / 2 + 0.5;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
context.fillStyle = clearColor.getStyle();
context.fillRect( 0, 0, canvasWidth, canvasHeight );
imagedata = context.getImageData( 0, 0, canvasWidth, canvasHeight );
data = imagedata.data;
zbuffer = new Int32Array( data.length / 4 );
numBlocks = canvasWBlocks * canvasHBlocks;
blockMaxZ = new Int32Array( numBlocks );
blockFlags = new Uint8Array( numBlocks );
for ( var i = 0, l = zbuffer.length; i < l; i ++ ) {
zbuffer[ i ] = maxZVal;
}
for ( var i = 0; i < numBlocks; i ++ ) {
blockFlags[ i ] = BLOCK_ISCLEAR;
}
cleanColorBuffer();
}
function cleanColorBuffer() {
var size = canvasWidth * canvasHeight * 4;
......@@ -462,9 +525,9 @@ THREE.SoftwareRenderer = function ( parameters ) {
material.addEventListener( 'update', onMaterialUpdate );
if ( material instanceof THREE.MeshBasicMaterial ||
material instanceof THREE.MeshLambertMaterial ||
material instanceof THREE.MeshPhongMaterial ||
material instanceof THREE.SpriteMaterial ) {
material instanceof THREE.MeshLambertMaterial ||
material instanceof THREE.MeshPhongMaterial ||
material instanceof THREE.SpriteMaterial ) {
if ( material instanceof THREE.MeshLambertMaterial ) {
......@@ -537,6 +600,19 @@ THREE.SoftwareRenderer = function ( parameters ) {
}
} else if ( material instanceof THREE.LineBasicMaterial ) {
var string = [
'var colorOffset = offset * 4;',
'buffer[ colorOffset ] = material.color.r * (color1.r+color2.r) * 0.5 * 255;',
'buffer[ colorOffset + 1 ] = material.color.g * (color1.g+color2.g) * 0.5 * 255;',
'buffer[ colorOffset + 2 ] = material.color.b * (color1.b+color2.b) * 0.5 * 255;',
'buffer[ colorOffset + 3 ] = 255;',
'depthBuf[ offset ] = depth;'
].join('\n');
shader = new Function( 'buffer, depthBuf, offset, depth, color1, color2, material', string );
} else {
var string = [
......@@ -548,7 +624,7 @@ THREE.SoftwareRenderer = function ( parameters ) {
'depthBuf[ offset ] = depth;'
].join( '\n' );
shader = new Function( 'buffer, depthBuf, offset, depth, u, v', string );
shader = new Function( 'buffer, depthBuf, offset, depth, u, v, n, face, material', string );
}
......@@ -765,7 +841,6 @@ THREE.SoftwareRenderer = function ( parameters ) {
// Loop through blocks
var linestep = canvasWidth - q;
var scale = 1.0 / ( c1 + c2 + c3 );
var cb1 = c1;
var cb2 = c2;
......@@ -1118,7 +1193,117 @@ THREE.SoftwareRenderer = function ( parameters ) {
}
}
// When drawing line, the blockShiftShift has to be zero. In order to clean pixel
// Using color1 and color2 to interpolation pixel color
// LineWidth is according to material.linewidth
function drawLine( v1, v2, color1, color2, shader, material ) {
// While the line mode is enable, blockSize has to be changed to 0.
if ( !lineMode ) {
lineMode = true;
blockShift = 0;
blockSize = 1 << blockShift;
setSize( canvas.width, canvas.height );
}
// TODO: Implement per-pixel z-clipping
if ( v1.z < -1 || v1.z > 1 || v2.z < -1 || v2.z > 1 ) return;
var halfLineWidth = Math.floor( (material.linewidth-1) * 0.5 );
// https://gist.github.com/2486101
// explanation: http://pouet.net/topic.php?which=8760&page=1
// 28.4 fixed-point coordinates
var x1 = (v1.x * viewportXScale + viewportXOffs) | 0;
var x2 = (v2.x * viewportXScale + viewportXOffs) | 0;
var y1 = (v1.y * viewportYScale + viewportYOffs) | 0;
var y2 = (v2.y * viewportYScale + viewportYOffs) | 0;
var z1 = (v1.z * viewportZScale + viewportZOffs) | 0;
var z2 = (v2.z * viewportZScale + viewportZOffs) | 0;
// Deltas
var dx12 = x1 - x2, dy12 = y1 - y2, dz12 = z1 - z2;
// Bounding rectangle
var minx = Math.max( ( Math.min( x1, x2 ) + subpixelBias ) >> subpixelBits, 0 );
var maxx = Math.min( ( Math.max( x1, x2 ) + subpixelBias ) >> subpixelBits, canvasWidth );
var miny = Math.max( ( Math.min( y1, y2 ) + subpixelBias ) >> subpixelBits, 0 );
var maxy = Math.min( ( Math.max( y1, y2 ) + subpixelBias ) >> subpixelBits, canvasHeight );
var minz = Math.max( ( Math.min( z1, z2 ) + subpixelBias ) >> subpixelBits, 0 );
var maxz = Math.min( ( Math.max( z1, z2 ) + subpixelBias ) >> subpixelBits, 0 );
rectx1 = Math.min( minx, rectx1 );
rectx2 = Math.max( maxx, rectx2 );
recty1 = Math.min( miny, recty1 );
recty2 = Math.max( maxy, recty2 );
// Get the line's unit vector and cross vector
var length = Math.sqrt((dy12 * dy12) + (dx12 * dx12));
var unitX = (dx12 / length);
var unitY = (dy12 / length);
var unitZ = (dz12 / length);
var pixelX, pixelY, pixelZ;
var pX, pY, pZ;
crossVector.set( unitX, unitY, unitZ );
crossVector.cross( lookVector );
crossVector.normalize();
while (length > 0) {
// Get this pixel.
pixelX = (x2 + length * unitX);
pixelY = (y2 + length * unitY);
pixelZ = (z2 + length * unitZ);
pixelX = (pixelX + subpixelBias) >> subpixelBits;
pixelY = (pixelY + subpixelBias) >> subpixelBits;
pZ = (pixelZ + subpixelBias) >> subpixelBits;
// Draw line with line width
for ( var i = -halfLineWidth; i <= halfLineWidth; ++i ) {
// Compute the line pixels.
// Get the pixels on the vector that crosses to the line vector
pX = Math.floor((pixelX + crossVector.x * i));
pY = Math.floor((pixelY + crossVector.y * i));
// if pixel is over the rect. Continue
if ( rectx1 >= pX || rectx2 <= pX || recty1 >= pY
|| recty2 <= pY )
continue;
// Find this pixel at which block
var blockX = pX >> blockShift;
var blockY = pY >> blockShift;
var blockId = blockX + blockY * canvasWBlocks;
// Compare the pixel depth width z block.
if ( blockMaxZ[ blockId ] < minz ) continue;
blockMaxZ[ blockId ] = Math.min( blockMaxZ[ blockId ], maxz );
var bflags = blockFlags[ blockId ];
if ( bflags & BLOCK_NEEDCLEAR ) clearBlock( blockX, blockY );
blockFlags[ blockId ] = bflags & ~( BLOCK_ISCLEAR | BLOCK_NEEDCLEAR );
// draw pixel
var offset = pX + pY * canvasWidth;
if ( pZ < zbuffer[ offset ] ) {
shader( data, zbuffer, offset, pZ, color1, color2, material );
}
}
--length;
}
}
function clearBlock( blockX, blockY ) {
var zoffset = blockX * blockSize + blockY * blockSize * canvasWidth;
......
......@@ -145,19 +145,22 @@
// SPRITES
var texture = THREE.ImageUtils.loadTexture( 'textures/sprite.png' );
var material = new THREE.SpriteMaterial( { map: texture, transparent: true } );
THREE.ImageUtils.loadTexture( 'textures/sprite.png', null, function ( texture ) {
for ( var i = 0; i < 50; i ++ ) {
var material = new THREE.SpriteMaterial( { map: texture, transparent: true } );
var sprite = new THREE.Sprite( material );
sprite.position.x = Math.random() * 1000 - 500;
sprite.position.y = Math.random() * 1000 - 500;
sprite.position.z = Math.random() * 1000 - 500;
sprite.scale.set( 64, 64, 1 );
scene.add( sprite );
for ( var i = 0; i < 50; i ++ ) {
}
var sprite = new THREE.Sprite( material );
sprite.position.x = Math.random() * 1000 - 500;
sprite.position.y = Math.random() * 1000 - 500;
sprite.position.z = Math.random() * 1000 - 500;
sprite.scale.set( 64, 64, 1 );
scene.add( sprite );
}
} );
for ( var i = 0; i < 50; i ++ ) {
......
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js software - lines - cubes - colors</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background-color: #000000;
margin: 0px;
overflow: hidden;
}
a {
color:#0078ff;
}
#info {
position: absolute;
top: 10px; width: 100%;
color: #ffffff;
padding: 5px;
font-family: Monospace;
font-size: 13px;
text-align: center;
z-index:100;
}
a {
color: orange;
text-decoration: none;
}
a:hover {
color: #0080ff;
}
</style>
</head>
<body>
<div id="info">
<a href="http://threejs.org" target="_blank">three.js</a> - color lines Software demo
[<a href="http://en.wikipedia.org/wiki/Hilbert_curve">Hilbert curve</a> thanks to <a href="http://www.openprocessing.org/visuals/?visualID=15599">Thomas Diewald</a>]
</div>
<script src="../build/three.min.js"></script>
<script src="js/geometries/hilbert3D.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/renderers/Projector.js"></script>
<script src="js/renderers/SoftwareRenderer.js"></script>
<script>
var mouseX = 0, mouseY = 0,
windowHalfX = window.innerWidth / 2,
windowHalfY = window.innerHeight / 2,
camera, scene, renderer, material;
init();
animate();
function init() {
var i, container;
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 33, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 700;
scene = new THREE.Scene();
renderer = new THREE.SoftwareRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
var geometry = new THREE.Geometry(),
geometry2 = new THREE.Geometry(),
geometry3 = new THREE.Geometry(),
points = hilbert3D( new THREE.Vector3( 0,0,0 ), 200.0, 2, 0, 1, 2, 3, 4, 5, 6, 7 ),
colors = [], colors2 = [], colors3 = [];
for ( i = 0; i < points.length; i ++ ) {
geometry.vertices.push( points[ i ] );
colors[ i ] = new THREE.Color( 0xffffff );
colors[ i ].setHSL( 0.6, 1.0, Math.max( 0, ( 200 - points[ i ].x ) / 400 ) * 0.5 + 0.5 );
colors2[ i ] = new THREE.Color( 0xffffff );
colors2[ i ].setHSL( 0.3, 1.0, Math.max( 0, ( 200 + points[ i ].x ) / 400 ) * 0.5 );
colors3[ i ] = new THREE.Color( 0xffffff );
colors3[ i ].setHSL( i / points.length, 1.0, 0.5 );
}
geometry2.vertices = geometry3.vertices = geometry.vertices;
geometry.colors = colors;
geometry2.colors = colors2;
geometry3.colors = colors3;
// lines
material = new THREE.LineBasicMaterial( { color: 0xffffff, opacity: 1, linewidth: 3, vertexColors: THREE.VertexColors } );
var line, p, scale = 0.3, d = 225;
var parameters = [
[ material, scale*1.5, [-d,0,0], geometry ],
[ material, scale*1.5, [0,0,0], geometry2 ],
[ material, scale*1.5, [d,0,0], geometry3 ]
];
for ( i = 0; i < parameters.length; ++i ) {
p = parameters[ i ];
line = new THREE.Line( p[ 3 ], p[ 0 ] );
line.scale.x = line.scale.y = line.scale.z = p[ 1 ];
line.position.x = p[ 2 ][ 0 ];
line.position.y = p[ 2 ][ 1 ];
line.position.z = p[ 2 ][ 2 ];
scene.add( line );
}
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = event.clientX - windowHalfX;
mouseY = event.clientY - windowHalfY;
}
function onDocumentTouchStart( event ) {
if ( event.touches.length > 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
mouseY = event.touches[ 0 ].pageY - windowHalfY;
}
}
function onDocumentTouchMove( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
mouseY = event.touches[ 0 ].pageY - windowHalfY;
}
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
camera.position.x += ( mouseX - camera.position.x ) * .05;
camera.position.y += ( - mouseY + 200 - camera.position.y ) * .05;
camera.lookAt( scene.position );
var time = Date.now() * 0.0005;
for ( var i = 0; i < scene.children.length; i ++ ) {
var object = scene.children[ i ];
if ( object instanceof THREE.Line ) object.rotation.y = time * ( i % 2 ? 1 : -1 );
}
renderer.render( scene, camera );
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js software - lines - cubes</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background-color: #000000;
margin: 0px;
overflow: hidden;
}
a {
color:#0078ff;
}
#info {
position: absolute;
top: 10px; width: 100%;
color: #ffffff;
padding: 5px;
font-family: Monospace;
font-size: 13px;
text-align: center;
z-index:100;
}
a {
color: orange;
text-decoration: none;
}
a:hover {
color: #0080ff;
}
</style>
</head>
<body>
<div id="info">
<a href="http://threejs.org" target="_blank">three.js</a> - lines WebGL demo
[<a href="http://en.wikipedia.org/wiki/Hilbert_curve">Hilbert curve</a> thanks to <a href="http://www.openprocessing.org/visuals/?visualID=15599">Thomas Diewald</a>]
</div>
<script src="../build/three.min.js"></script>
<script src="js/geometries/hilbert3D.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/renderers/Projector.js"></script>
<script src="js/renderers/SoftwareRenderer.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var mouseX = 0, mouseY = 0,
windowHalfX = window.innerWidth / 2,
windowHalfY = window.innerHeight / 2,
camera, scene, renderer;
init();
animate();
function init() {
var i, material, container;
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 33, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 700;
scene = new THREE.Scene();
renderer = new THREE.SoftwareRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
var geometry = new THREE.Geometry(),
points = hilbert3D( new THREE.Vector3( 0,0,0 ), 200.0, 4, 0, 1, 2, 3, 4, 5, 6, 7 );
for ( i = 0; i < points.length; i ++ ) {
geometry.vertices.push( points[i] );
}
// lines
var line, p, scale = 0.3, d = 125, c1 = 0x553300, c2 = 0x555555, c3 = 0x992800,
g1 = geometry,
m1 = new THREE.LineBasicMaterial( { color: c1, opacity: 1, blending: THREE.AdditiveBlending, transparent: true } ),
m2 = new THREE.LineBasicMaterial( { color: c2, opacity: 1, blending: THREE.AdditiveBlending, transparent: true } ),
m3 = new THREE.LineBasicMaterial( { color: c3, opacity: 1, blending: THREE.AdditiveBlending, transparent: true } ),
parameters = [ [ m3, scale*0.5, [0,0,0], g1 ], [ m2, scale*0.5, [d, 0, 0], g1 ],
[ m2, scale*0.5, [-d, 0, 0], g1 ], [ m2, scale*0.5, [0,d,0], g1 ],
[ m2, scale*0.5, [d, d, 0], g1 ], [ m2, scale*0.5, [-d, d, 0], g1 ],
[ m2, scale*0.5, [0,-d,0], g1 ], [ m2, scale*0.5, [d, -d, 0], g1 ],
[ m2, scale*0.5, [-d, -d, 0], g1 ], [ m1, scale*0.5, [2*d, 0, 0], g1 ],
[ m1, scale*0.5, [-2*d, 0, 0], g1 ], [ m1, scale*0.5, [2*d, d, 0], g1 ],
[ m1, scale*0.5, [-2*d, d, 0], g1 ], [ m1, scale*0.5, [2*d, -d, 0], g1 ],
[ m1, scale*0.5, [-2*d, -d, 0], g1 ]];
for ( i = 0; i < parameters.length; i ++ ) {
p = parameters[ i ];
line = new THREE.Line( p[ 3 ], p[ 0 ] );
line.scale.x = line.scale.y = line.scale.z = p[ 1 ];
line.position.x = p[ 2 ][ 0 ];
line.position.y = p[ 2 ][ 1 ];
line.position.z = p[ 2 ][ 2 ];
scene.add( line );
}
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove(event) {
mouseX = event.clientX - windowHalfX;
mouseY = event.clientY - windowHalfY;
}
function onDocumentTouchStart( event ) {
if ( event.touches.length > 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
mouseY = event.touches[ 0 ].pageY - windowHalfY;
}
}
function onDocumentTouchMove( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
mouseY = event.touches[ 0 ].pageY - windowHalfY;
}
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
camera.position.x += ( mouseX - camera.position.x ) * .05;
camera.position.y += ( - mouseY + 200 - camera.position.y ) * .05;
camera.lookAt( scene.position );
var time = Date.now() * 0.0015;
for ( var i = 0; i < scene.children.length; i ++ ) {
var object = scene.children[ i ];
if ( object instanceof THREE.Line ) object.rotation.y = time * ( i % 2 ? 1 : -1 );
}
renderer.render( scene, camera );
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js software - lines - spheres</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background-color: #000;
margin: 0px;
overflow: hidden;
}
a {
color:#0078ff;
}
#info {
position: absolute;
top: 10px; width: 100%;
color: #ffffff;
padding: 5px;
font-family: Monospace;
font-size: 13px;
text-align: center;
z-index:100;
}
a {
color: #ff0080;
text-decoration: none;
}
a:hover {
color: #0080ff;
}
</style>
</head>
<body>
<div id="info">
<a href="http://threejs.org" target="_blank">three.js</a> - lines Software demo
</div>
<script src="../build/three.min.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/renderers/Projector.js"></script>
<script src="js/renderers/SoftwareRenderer.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var SCREEN_WIDTH = window.innerWidth,
SCREEN_HEIGHT = window.innerHeight,
r = 450,
mouseX = 0, mouseY = 0,
windowHalfX = window.innerWidth / 2,
windowHalfY = window.innerHeight / 2,
camera, scene, renderer;
init();
animate();
function init() {
var container;
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 80, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 3000 );
camera.position.z = 1000;
scene = new THREE.Scene();
var i, line, vertex1, vertex2, material, p,
parameters = [ [ 0.25, 0xff7700, 1, 2 ], [ 0.5, 0xff9900, 1, 1 ],
[ 0.75, 0xffaa00, 0.75, 1 ], [ 1, 0xffaa00, 0.5, 1 ],
[ 1.25, 0x000833, 0.8, 1 ], [ 3.0, 0xaaaaaa, 0.75, 2 ],
[ 3.5, 0xffffff, 0.5, 1 ], [ 4.5, 0xffffff, 0.25, 1 ],
[ 5.5, 0xffffff, 0.125, 1 ] ];
var geometry = createGeometry();
for( i = 0; i < parameters.length; ++ i ) {
p = parameters[ i ];
material = new THREE.LineBasicMaterial( { color: p[ 1 ], opacity: p[ 2 ], linewidth: p[ 3 ] } );
line = new THREE.LineSegments( geometry, material );
line.scale.x = line.scale.y = line.scale.z = p[ 0 ];
line.originalScale = p[ 0 ];
line.rotation.y = Math.random() * Math.PI;
line.updateMatrix();
scene.add( line );
}
renderer = new THREE.SoftwareRenderer();
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
container.appendChild( renderer.domElement );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
window.addEventListener( 'resize', onWindowResize, false );
}
function createGeometry() {
var geometry = new THREE.Geometry();
for ( i = 0; i < 1500; i ++ ) {
var vertex1 = new THREE.Vector3();
vertex1.x = Math.random() * 2 - 1;
vertex1.y = Math.random() * 2 - 1;
vertex1.z = Math.random() * 2 - 1;
vertex1.normalize();
vertex1.multiplyScalar( r );
vertex2 = vertex1.clone();
vertex2.multiplyScalar( Math.random() * 0.09 + 1 );
geometry.vertices.push( vertex1 );
geometry.vertices.push( vertex2 );
}
return geometry;
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = event.clientX - windowHalfX;
mouseY = event.clientY - windowHalfY;
}
function onDocumentTouchStart( event ) {
if ( event.touches.length > 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
mouseY = event.touches[ 0 ].pageY - windowHalfY;
}
}
function onDocumentTouchMove( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
mouseY = event.touches[ 0 ].pageY - windowHalfY;
}
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
camera.position.y += ( - mouseY + 200 - camera.position.y ) * .05;
camera.lookAt( scene.position );
renderer.render( scene, camera );
var time = Date.now() * 0.0001;
for ( var i = 0; i < scene.children.length; i ++ ) {
var object = scene.children[ i ];
if ( object instanceof THREE.Line ) {
object.rotation.y = time * ( i < 4 ? ( i + 1 ) : - ( i + 1 ) );
if ( i < 5 ) object.scale.x = object.scale.y = object.scale.z = object.originalScale * (i/5+1) * (1 + 0.5 * Math.sin( 7*time ) );
}
}
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js software - lines - splines</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background-color: #000000;
margin: 0px;
overflow: hidden;
}
a {
color:#0078ff;
}
#info {
position: absolute;
top: 10px; width: 100%;
color: #ffffff;
padding: 5px;
font-family: Monospace;
font-size: 13px;
text-align: center;
z-index:100;
}
a {
color: orange;
text-decoration: none;
}
a:hover {
color: #0080ff;
}
</style>
</head>
<body>
<div id="info">
<a href="http://threejs.org" target="_blank">three.js</a> - splines Software demo
[<a href="http://en.wikipedia.org/wiki/Hilbert_curve">Hilbert curve</a> thanks to <a href="http://www.openprocessing.org/visuals/?visualID=15599">Thomas Diewald</a>]
</div>
<script src="../build/three.min.js"></script>
<script src="js/geometries/hilbert3D.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/renderers/Projector.js"></script>
<script src="js/renderers/SoftwareRenderer.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var mouseX = 0, mouseY = 0,
windowHalfX = window.innerWidth / 2,
windowHalfY = window.innerHeight / 2,
camera, scene, renderer, material;
init();
animate();
function init() {
var i, n_sub, container;
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 33, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 700;
scene = new THREE.Scene();
renderer = new THREE.SoftwareRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
var geometry = new THREE.Geometry(),
geometry2 = new THREE.Geometry(),
geometry3 = new THREE.Geometry(),
points = hilbert3D( new THREE.Vector3( 0,0,0 ), 200.0, 1, 0, 1, 2, 3, 4, 5, 6, 7 ),
colors = [], colors2 = [], colors3 = [];
n_sub = 6;
var position, index;
var spline = new THREE.Spline( points );
for ( i = 0; i < points.length * n_sub; i ++ ) {
index = i / ( points.length * n_sub );
position = spline.getPoint( index );
geometry.vertices[ i ] = new THREE.Vector3( position.x, position.y, position.z );
colors[ i ] = new THREE.Color( 0xffffff );
colors[ i ].setHSL( 0.6, 1.0, Math.max( 0, - position.x / 200 ) + 0.5 );
colors2[ i ] = new THREE.Color( 0xffffff );
colors2[ i ].setHSL( 0.9, 1.0, Math.max( 0, - position.y / 200 ) + 0.5 );
colors3[ i ] = new THREE.Color( 0xffffff );
colors3[ i ].setHSL( i / ( points.length * n_sub ), 1.0, 0.5 );
}
geometry2.vertices = geometry3.vertices = geometry.vertices;
geometry.colors = colors;
geometry2.colors = colors2;
geometry3.colors = colors3;
// lines
material = new THREE.LineBasicMaterial( { color: 0xffffff, opacity: 1, linewidth: 3, vertexColors: THREE.VertexColors } );
var line, p, scale = 0.3, d = 225;
var parameters = [
[ material, scale*1.5, [-d,0,0], geometry ],
[ material, scale*1.5, [0,0,0], geometry2 ],
[ material, scale*1.5, [d,0,0], geometry3 ]
];
for ( i = 0; i < parameters.length; ++ i ) {
p = parameters[ i ];
line = new THREE.Line( p[ 3 ], p[ 0 ] );
line.scale.x = line.scale.y = line.scale.z = p[ 1 ];
line.position.x = p[ 2 ][ 0 ];
line.position.y = p[ 2 ][ 1 ];
line.position.z = p[ 2 ][ 2 ];
scene.add( line );
}
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = event.clientX - windowHalfX;
mouseY = event.clientY - windowHalfY;
}
function onDocumentTouchStart( event ) {
if ( event.touches.length > 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
mouseY = event.touches[ 0 ].pageY - windowHalfY;
}
}
function onDocumentTouchMove( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
mouseY = event.touches[ 0 ].pageY - windowHalfY;
}
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
camera.position.x += ( mouseX - camera.position.x ) * .05;
camera.position.y += ( - mouseY + 200 - camera.position.y ) * .05;
camera.lookAt( scene.position );
var time = Date.now() * 0.0005;
for ( var i = 0; i < scene.children.length; i ++ ) {
var object = scene.children[ i ];
if ( object instanceof THREE.Line ) {
object.rotation.y = time * ( i % 2 ? 1 : -1 );
}
}
renderer.render( scene, camera );
}
</script>
</body>
</html>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册