提交 16ee65ef 编写于 作者: M Mr.doob

Added basic raytracing renderer.

上级 c9a32068
/**
* @author mrdoob / http://mrdoob.com/
*/
THREE.RaytracingRenderer = function ( parameters ) {
console.log( 'THREE.RaytracingRenderer', THREE.REVISION );
parameters = parameters || {};
var canvas = document.createElement( 'canvas' );
var context = canvas.getContext( '2d', {
alpha: parameters.alpha === true
} );
var canvasWidth, canvasHeight;
var canvasWidthHalf, canvasHeightHalf;
var clearColor = new THREE.Color( 0x000000 );
var blockX = 0;
var blockY = 0;
var blockSize = 64;
var canvasBlock = document.createElement( 'canvas' );
canvasBlock.width = blockSize;
canvasBlock.height = blockSize;
var contextBlock = canvasBlock.getContext( '2d', {
alpha: parameters.alpha === true
} );
var imagedata = contextBlock.getImageData( 0, 0, blockSize, blockSize );
var data = imagedata.data;
var viewMatrix = new THREE.Matrix4();
var viewProjectionMatrix = new THREE.Matrix4();
var origin = new THREE.Vector3();
var direction = new THREE.Vector3();
var raycaster = new THREE.Raycaster( origin, direction );
var objects;
this.domElement = canvas;
this.autoClear = true;
this.setClearColor = function ( color, alpha ) {
clearColor.set( color );
};
this.setSize = function ( width, height ) {
canvas.width = width;
canvas.height = height;
canvasWidth = canvas.width;
canvasHeight = canvas.height;
canvasWidthHalf = Math.floor( canvasWidth / 2 );
canvasHeightHalf = Math.floor( canvasHeight / 2 );
context.fillStyle = 'white';
};
this.setSize( canvas.width, canvas.height );
this.clear = function () {
};
var renderBlock = function () {
for ( var i = 0, l = data.length; i < l; i += 4 ) {
data[ i ] = 0;
data[ i + 1 ] = 0;
data[ i + 2 ] = 0;
}
var index = 0;
for ( var y = 0; y < blockSize; y ++ ) {
for ( var x = 0; x < blockSize; x ++ ) {
direction.set( x + blockX - canvasWidthHalf, y + blockY - canvasHeightHalf, - 500 );
direction.normalize();
var intersections = raycaster.intersectObjects( objects, true );
if ( intersections.length > 0 ) {
var intersection = intersections[ 0 ];
var object = intersection.object;
var material = object.material;
var face = intersection.face;
var color;
if ( material.vertexColors === THREE.NoColors ) {
color = material.color;
} else if ( material.vertexColors === THREE.FaceColors ) {
color = face.color;
}
data[ index ] = color.r * 255;
data[ index + 1 ] = color.g * 255;
data[ index + 2 ] = color.b * 255;
}
index += 4;
}
}
context.putImageData( imagedata, blockX, blockY );
blockX += blockSize;
if ( blockX >= canvasWidth ) {
blockX = 0;
blockY += blockSize;
if ( blockY >= canvasHeight ) return;
}
context.fillRect( blockX, blockY, blockSize, blockSize );
requestAnimationFrame( renderBlock );
};
this.render = function ( scene, camera ) {
if ( this.autoClear === true ) this.clear();
origin.copy( camera.position );
objects = scene.children;
renderBlock();
}
};
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js - raytracing renderer</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 {
font-family: Monospace;
color: #ffffff;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="../build/three.min.js"></script>
<script src="js/controls/TrackballControls.js"></script>
<script src="js/renderers/RaytracingRenderer.js"></script>
<script>
var container;
var camera, controls, scene, renderer;
var torus, cube;
var start = Date.now();
init();
render();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
var info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = '<a href="http://threejs.org" target="_blank">three.js<a/> - raytracing renderer';
container.appendChild( info );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 600;
controls = new THREE.TrackballControls( camera );
scene = new THREE.Scene();
var geometry = new THREE.TorusKnotGeometry( 150 );
for ( var i = 0, j = geometry.faces.length; i < j; i ++ ) {
geometry.faces[ i ].color.setHex( Math.random() * 0xffffff );
}
torus = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: 0x0000ff, vertexColors: THREE.FaceColors } ) );
scene.add( torus );
// Plane
var geometry = new THREE.BoxGeometry( 200, 200, 200 );
for ( var i = 0, j = geometry.faces.length; i < j; i ++ ) {
geometry.faces[ i ].color.setHex( Math.random() * 0xffffff );
}
cube = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: 0x00ff00, vertexColors: THREE.FaceColors } ) );
scene.add( cube );
renderer = new THREE.RaytracingRenderer();
renderer.setClearColor( 0xf0f0f0 );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//
function render() {
var timer = Date.now() - start;
torus.position.y = Math.sin( timer * 0.002 ) * 150;
torus.rotation.x = timer * 0.0003;
torus.rotation.z = timer * 0.0002;
cube.rotation.x = timer * 0.0002;
cube.rotation.z = timer * 0.0003;
controls.update();
renderer.render( scene, camera );
}
</script>
</body>
</html>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册