Mục tiêu của bài này là giới thiệu ngắn gọn về three.js. Chúng tôi sẽ bắt đầu bằng cách thiết lập một scene (cảnh), với một spinning cube (khối quay).
Cấu trúc của trang web với three.js
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script src="js/three.js"></script>
<script>
// Our Javascript will go here.
</script>
</body>
</html>
Tạo khung cảnh cảnh Scene
Để thực sự có thể hiển thị bất cứ thứ gì với three.js, chúng tôi cần ba thứ: cảnh (Scene), máy ảnh (Camera) và trình kết xuất (Renderer), để chúng tôi có thể kết xuất ra một khung cảnh
//Khai báo khung cảnh three
const scene = new THREE.Scene();ư
//Camera
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
//Render ra DOM
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
Hãy dành một chút thời gian để giải thích những gì đang xảy ra ở đây. Bây giờ chúng tôi đã thiết lập cảnh, máy ảnh của chúng tôi và trình kết xuất.
Có một vài máy ảnh khác nhau trong three.js. Bây giờ, hãy sử dụng PerspectiveCamera .
PerspectiveCamera
Thuộc tính đầu tiên là trường xem . fov là phạm vi của cảnh được nhìn thấy trên màn hình tại bất kỳ thời điểm nào. Giá trị tính bằng độ.
Cái thứ hai là tỷ lệ khung hình . Bạn hầu như luôn muốn sử dụng chiều rộng của phần tử chia cho chiều cao, nếu không bạn sẽ nhận được kết quả tương tự như khi bạn phát các bộ phim cũ trên TV màn hình rộng - hình ảnh trông bị méo.
Hai thuộc tính tiếp theo là mặt phẳng cắt gần và xa . Điều đó có nghĩa là các đối tượng ở xa máy ảnh hơn giá trị của xa hoặc gần hơn gần sẽ không được hiển thị. Bạn không phải lo lắng về điều này bây giờ, nhưng bạn có thể sử dụng giá trị khác trong ứng dụng của mình để có được hiệu suất tốt hơn.
Tiếp theo là trình kết xuất. Đây là nơi điều kỳ diệu xảy ra. Ngoài WebGLRenderer mà chúng tôi sử dụng ở đây, three.js đi kèm với một số trình duyệt khác, thường được sử dụng làm dự phòng cho người dùng có trình duyệt cũ hơn hoặc cho những người không có hỗ trợ WebGL vì một số lý do.
Ngoài việc tạo phiên bản trình kết xuất, chúng tôi cũng cần đặt kích thước mà chúng tôi muốn nó hiển thị ứng dụng của chúng tôi. Bạn nên sử dụng chiều rộng và chiều cao của khu vực mà chúng tôi muốn điền vào ứng dụng của mình - trong trường hợp này là chiều rộng và chiều cao của cửa sổ trình duyệt. Đối với các ứng dụng chuyên sâu về hiệu suất, bạn cũng có thể cung cấp các giá trị setSize nhỏ hơn, như window.innerWidth / 2 và window.innerHeight / 2 , điều này sẽ làm cho ứng dụng hiển thị ở kích thước một phần tư.
Nếu bạn muốn giữ nguyên kích thước của ứng dụng nhưng hiển thị nó ở độ phân giải thấp hơn, bạn có thể làm như vậy bằng cách gọi setSize với false là updateStyle (đối số thứ ba). Ví dụ: setSize (window.innerWidth / 2, window.innerHeight / 2, false) sẽ hiển thị ứng dụng của bạn ở độ phân giải một nửa, miễn là <canvas> của bạn có 100% chiều rộng và chiều cao.
Cuối cùng nhưng không kém phần quan trọng, chúng tôi thêm phần tử trình kết xuất vào tài liệu HTML của mình. Đây là phần tử <canvas> mà trình kết xuất sử dụng để hiển thị cảnh cho chúng tôi.
“Tất cả đều tốt, nhưng khối lập phương mà bạn đã hứa ở đâu?” Hãy thêm nó ngay bây giờ.
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
Để tạo một khối lập phương, chúng ta cần một BoxGeometry . Đây là một đối tượng chứa tất cả các điểm ( đỉnh ) và tô ( mặt ) của khối lập phương. Chúng tôi sẽ khám phá điều này nhiều hơn trong tương lai.
Ngoài hình học, chúng ta cần một vật liệu để tô màu cho nó. Three.js đi kèm với một số vật liệu, nhưng chúng ta sẽ gắn bó với MeshBasicMaterial. Tất cả các vật liệu có một đối tượng của các thuộc tính sẽ được áp dụng cho chúng. Để giữ cho mọi thứ rất đơn giản, chúng tôi chỉ cung cấp một thuộc tính màu 0×00ff00 , là màu xanh lá cây. Điều này hoạt động giống như cách mà màu sắc hoạt động trong CSS hoặc Photoshop ( màu hex ).
Điều thứ ba chúng ta cần là Mesh (một tấm lưới) . Mesh là một đối tượng lấy một hình học và áp dụng vật liệu cho nó, sau đó chúng ta có thể chèn vào cảnh của mình và di chuyển tự do xung quanh.
Theo mặc định, khi chúng ta gọi scene.add () , thứ chúng ta thêm vào sẽ được thêm vào tọa độ (0,0,0) . Điều này sẽ làm cho cả máy ảnh và khối vuông ở bên trong nhau. Để tránh điều này, chúng tôi chỉ cần di chuyển máy ảnh ra ngoài một chút.
Render khung cảnh
Nếu bạn đã sao chép mã từ bên trên vào tệp HTML mà tôi đã tạo trước đó, bạn sẽ không thể nhìn thấy bất kỳ thứ gì. Điều này là do chúng tôi chưa thực sự hiển thị bất cứ thứ gì. Để làm được điều đó, chúng ta cần cái được gọi là vòng lặp render hoặc animate .
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
animate();
Điều này sẽ tạo ra một vòng lặp khiến trình kết xuất vẽ cảnh mỗi khi màn hình được làm mới (trên màn hình thông thường, điều này có nghĩa là 60 lần mỗi giây). Nếu bạn chưa quen với việc viết trò chơi trên trình duyệt, bạn có thể nói “tại sao chúng ta không tạo một setInterval?” Vấn đề là - chúng tôi có thể, nhưng requestAnimationFrame có một số lợi thế. Có lẽ điều quan trọng nhất là nó tạm dừng khi người dùng điều hướng đến tab trình duyệt khác, do đó không lãng phí sức mạnh xử lý quý giá và tuổi thọ pin của họ.
Tạo chuyển động cho khối lập phương
Nếu bạn chèn tất cả mã ở trên vào tệp bạn đã tạo trước khi tôi bắt đầu, bạn sẽ thấy một hộp màu xanh lục. Hãy làm cho tất cả thú vị hơn một chút bằng cách xoay nó.
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
Điều này sẽ được chạy mọi khung hình (thường là 60 lần mỗi giây) và tạo cho khối lập phương một hoạt ảnh xoay đẹp mắt. Về cơ bản, bất cứ thứ gì bạn muốn di chuyển hoặc thay đổi trong khi ứng dụng đang chạy đều phải trải qua vòng lặp hoạt ảnh. Bạn dĩ nhiên có thể gọi các chức năng khác từ đó, vì vậy mà bạn không kết thúc với một Animate chức năng đó là hàng trăm dòng.
Thêm phần sau ngay trên lệnh gọi renderer.render trong hàm animate của bạn :
Kết quả
Vậy là chung ta đã tạo được một khung cảnh cơ bản với three.js
Mong các bạn xem tiếp bài 3