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>

PROWAREtech

Hello there! How can I help you today?
Ask any question

PROWAREtech

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