PROWAREtech

articles » current » javascript » three-js » raytracer-example

ThreeJS: Raytracer Example

How to access individual objects on the canvas used by THREE.js.

This code will create a scene and access the individual objects created using the mouse.

Create the HTML file index.html and paste this code into it. Note the comments in the file. This HTML/JavaScript file can be run from this site. Dowload the three.min.js file here: THREEJS.zip

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Raycaster Example</title>
	<style>
		body {
			margin: 0;
			padding: 0;
			height: 100vh;
		}
		canvas {
			display: block;
			width: 100%;
			height: 100vh;
		}
	</style>
</head>
<body>
	<canvas></canvas>
	<script src="/js/three.min.js"></script>
	<script type="text/javascript">

(function () { // NOTE: three dancing balls example

	var canvas = document.getElementsByTagName("canvas")[0];

	// NOTE: create the scene to place objects in
	var scene = new THREE.Scene();
	scene.background = new THREE.Color(0x6699cc); // NOTE: make the background blue for the sky
	scene.matrixWorldAutoUpdate = true;



	// NOTE: the width and height of the parent element; this information is static and should be updated when the browser window is resized
	var size = {
		width: canvas.offsetWidth,
		height: canvas.offsetHeight
	};

	// NOTE: issue these statements when resizing the window
	// camera.aspect = size.width / size.height;
	// camera.updateProjectionMatrix();
	// renderer.setPixelRatio(window.devicePixelRatio);
	// renderer.setSize(size.width, size.height);


	
	// NOTE: create the camera with 53 degree field of view; this is how the scene is viewed by the user
	var camera = new THREE.PerspectiveCamera(53, size.width / size.height, 1, 5000);

	// NOTE: position the camera in space a bit
	camera.position.z = 5;


	var renderer = new THREE.WebGLRenderer({
		canvas: canvas
	});
	renderer.shadowMap.enabled = true;
	renderer.setPixelRatio(window.devicePixelRatio);
	renderer.setSize(size.width, size.height);
	renderer.render(scene, camera);


	// NOTE: create the Raytracer
	var raycaster = new THREE.Raycaster();
	var mouse = new THREE.Vector2();

	
	var sphereGeometry = new THREE.SphereGeometry(1.75, 32, 32);


	// NOTE: create three spheres
	var sphere1 = new THREE.Mesh(sphereGeometry, new THREE.MeshLambertMaterial({ color: 0xeeeeee }));
	sphere1.position.x = sphere1.position.y = 0;
	sphere1.position.z = -50;
	sphere1.receiveShadow = true;
	sphere1.castShadow = true;
	scene.add(sphere1);


	var sphere2 = new THREE.Mesh(sphereGeometry, new THREE.MeshLambertMaterial({ color: 0xeeeeee }));
	sphere2.position.x = sphere2.position.y = 0.5;
	sphere2.position.z = -25;
	sphere2.receiveShadow = true;
	sphere2.castShadow = true;
	scene.add(sphere2);


	var sphere3 = new THREE.Mesh(sphereGeometry, new THREE.MeshLambertMaterial({ color: 0xeeeeee }));
	sphere3.position.x = sphere3.position.y = 0.5;
	sphere3.position.z = -25;
	sphere3.receiveShadow = true;
	sphere3.castShadow = true;
	scene.add(sphere3);



	// NOTE: create the ground
	var plane = new THREE.Mesh(new THREE.PlaneGeometry(1000, 1000), new THREE.MeshLambertMaterial({ color: 0x00FF00 }));
	plane.position.x = 0;
	plane.position.y = 0;
	plane.position.z = -50;
	plane.rotation.x = 4.75;
	plane.receiveShadow = true;
	scene.add(plane);



	var light = new THREE.PointLight(0xffffff, 2);
	light.position.set(0,30,0);
window.light = light;
	light.castShadow = true;
	scene.add(light);

	scene.add(new THREE.AmbientLight(0xffffff, .4));

	var handler = function (element, type, func) {
		if (element.addEventListener) {
			element.addEventListener(type, func, false);
		} else if (window.attachEvent) {
			element.attachEvent("on" + type, func);
		} else {
			element["on" + type] = func;
		}
	};


	// NOTE: this function will set the color to red when hovering over the ball
	handler(window, "mousemove", function (event) {
		event.preventDefault();

		mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
		mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;

		raycaster.setFromCamera(mouse, camera);

		var intersects = raycaster.intersectObjects(scene.children, true);
		for(var i = 0; i < intersects.length; i++) {
			if(intersects[i].object !== plane) {
				intersects[i].object.material.color.set(0xff0000);
				setTimeout(function (obj) {
					obj.material.color.set(0xeeeeee);
				}, 1000, intersects[i].object);
			}
		}
	});



	// NOTE: this function will set the color to blue when the ball is clicked; try not to move the mouse at the same time
	handler(window, "click", function (event) {
		event.preventDefault();

		mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
		mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;

		raycaster.setFromCamera(mouse, camera);

		var intersects = raycaster.intersectObjects(scene.children, true);
		for(var i = 0; i < intersects.length; i++) {
			if(intersects[i].object !== plane) {
				intersects[i].object.material.color.set(0x0000ff);
				setTimeout(function (obj) {
					obj.material.color.set(0xeeeeee);
				}, 1000, intersects[i].object);
			}
		}
	});


	// NOTE: MUST HAVE AN ANIMATE FUNCTION
	var animate = function () {
		var time = Date.now(); // NOTE: this could also be the scroll position

		sphere1.position.x = Math.cos(time / 200 + 10.0);
		sphere1.position.y = Math.sin(time / 1000 + 10.0) + 5;
		sphere1.position.z = Math.sin(time / 200 + 10.0) - 10;

		sphere2.position.x = Math.cos(time / 1000 + 10.0) * 1.2;
		sphere2.position.y = Math.sin(time / 200 + 10.0) * 1.2 + 5;

		sphere3.position.x = Math.cos(time / 1000 + 10.0) * 1.5 + 6;
		sphere3.position.y = Math.sin(time / 1000 + 10.0) * 1.5 + 7;

		requestAnimationFrame(animate);
		renderer.render(scene, camera);
	};
	animate();

})();

	</script>
</body>
</html>

This site uses cookies. Cookies are simple text files stored on the user's computer. They are used for adding features and security to this site. Read the privacy policy.
CLOSE