Bắt đầu với Three.js

Giới thiệu

Tôi đã sử dụng Three.js cho một số thử nghiệm của mình và thư viện này thực sự rất hiệu quả trong việc giúp bạn giải quyết những vấn đề phiền toái khi bắt đầu sử dụng 3D trong trình duyệt. Với công cụ này, bạn có thể tạo máy ảnh, đối tượng, ánh sáng, chất liệu và nhiều nội dung khác. Ngoài ra, bạn có thể chọn trình kết xuất, tức là bạn có thể quyết định xem có muốn vẽ cảnh bằng canvas, WebGL hay SVG của HTML 5 hay không. Và vì đây là nguồn mở nên bạn thậm chí có thể tham gia vào dự án này. Nhưng ngay bây giờ, tôi sẽ tập trung vào những gì tôi đã học được bằng cách sử dụng nó làm công cụ và giới thiệu cho bạn một số kiến thức cơ bản.

Mặc dù Three.js rất tuyệt vời, nhưng đôi khi bạn có thể gặp khó khăn. Thông thường, bạn sẽ cần dành khá nhiều thời gian cho các ví dụ, kỹ thuật đảo ngược và (trong trường hợp của tôi chắc chắn) tìm kiếm chức năng cụ thể và thỉnh thoảng hỏi qua GitHub. Nhân tiện, nếu bạn có câu hỏi, tôi nhận thấy Mr. doobAlteredQualia cực kỳ hữu ích!

1. Khái niệm cơ bản

Tôi sẽ giả định rằng bạn có ít nhất là kiến thức cơ bản về 3D và có trình độ sử dụng JavaScript hợp lý. Nếu không, bạn nên tìm hiểu một chút trước khi thử và chơi với nội dung này, vì nó có thể gây nhầm lẫn.

Trong thế giới 3D, chúng ta sẽ có một số thành phần sau đây. Tôi sẽ hướng dẫn bạn quy trình tạo các thành phần này:

  1. Một cảnh
  2. Trình kết xuất
  3. Máy ảnh
  4. Một hoặc hai đối tượng (có chất liệu)

Tất nhiên, bạn có thể làm một số việc thú vị và tôi hy vọng bạn sẽ tiếp tục làm như vậy và bắt đầu thử nghiệm với 3D trong trình duyệt.

2. Hỗ trợ

Xin lưu ý nhanh về tính năng hỗ trợ trong trình duyệt. Theo kinh nghiệm của tôi, trình duyệt Chrome của Google là trình duyệt tốt nhất để làm việc về trình kết xuất được hỗ trợ và tốc độ của công cụ JavaScript cơ bản. Chrome hỗ trợ Canvas, WebGL và SVG với tốc độ cực nhanh. Firefox đứng ở vị trí thứ hai, với sự ra đời của phiên bản 4. Công cụ JavaScript của trình duyệt này có vẻ chậm hơn một chút so với Chrome, nhưng lại hỗ trợ rất tốt các công nghệ kết xuất. Opera và Safari đang trong quá trình thêm tính năng hỗ trợ WebGL, nhưng các phiên bản hiện tại của chúng chỉ hỗ trợ canvas. Internet Explorer (phiên bản 9 trở lên) chỉ hỗ trợ kết xuất canvas và tôi chưa nghe thấy bất kỳ thông tin nào về việc Microsoft dự định thêm các tính năng WebGL.

3. Thiết lập cảnh

Tôi sẽ giả định rằng bạn đã chọn một trình duyệt hỗ trợ tất cả các công nghệ kết xuất và bạn muốn kết xuất bằng canvas hoặc WebGL, vì đây là các lựa chọn tiêu chuẩn hơn. Canvas được hỗ trợ rộng rãi hơn WebGL, nhưng đáng chú ý là WebGL chạy trên GPU của thẻ đồ hoạ, nghĩa là CPU có thể tập trung vào các tác vụ không kết xuất khác như mọi hoạt động tương tác vật lý hoặc người dùng mà bạn đang cố gắng thực hiện.

Bất kể trình kết xuất bạn chọn là gì, bạn cũng cần lưu ý rằng JavaScript sẽ cần được tối ưu hoá để đạt hiệu suất cao. 3D không phải là một tác vụ nhẹ nhàng đối với trình duyệt (và thật tuyệt vời khi bạn có thể làm được điều này), vì vậy, hãy cẩn thận tìm hiểu xem có nút thắt cổ chai nào trong mã của bạn hay không và xoá chúng nếu có thể!

Như vậy, giả sử bạn đã tải xuống và đưa three.js vào tệp HTML, bạn sẽ thiết lập cảnh như thế nào? Chẳng hạn như:

// set the scene size
var WIDTH = 400,
HEIGHT = 300;

// set some camera attributes
var VIEW_ANGLE = 45,
ASPECT = WIDTH / HEIGHT,
NEAR = 0.1,
FAR = 10000;

// get the DOM element to attach to
// - assume we've got jQuery to hand
var $container = $('#container');

// create a WebGL renderer, camera
// and a scene
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.PerspectiveCamera(
                VIEW_ANGLE,
                ASPECT,
                NEAR,
                FAR );

var scene = new THREE.Scene();

// the camera starts at 0,0,0 so pull it back
camera.position.z = 300;

// start the renderer
renderer.setSize(WIDTH, HEIGHT);

// attach the render-supplied DOM element
$container.append(renderer.domElement);

Thật sự không quá khó!

4. Tạo lưới

Vì vậy, chúng ta có một cảnh, một máy ảnh và một trình kết xuất (tôi đã chọn một trình kết xuất WebGL trong mã mẫu) nhưng chúng ta không có gì để vẽ. Three.js thực sự hỗ trợ việc tải một số loại tệp chuẩn khác nhau. Điều này rất hữu ích nếu bạn đang xuất mô hình từ Blender, Maya, Cinema4D hoặc bất kỳ ứng dụng nào khác. Để đơn giản hoá mọi thứ (việc này là để bắt đầu!) Tôi sẽ nói về các đối tượng gốc. Đối tượng gốc là các lưới hình học, tương đối cơ bản như hình cầu, mặt phẳng, hình lập phương và hình trụ. Three.js cho phép bạn dễ dàng tạo các loại hình ảnh gốc sau:

// set up the sphere vars
var radius = 50, segments = 16, rings = 16;

// create a new mesh with sphere geometry -
// we will cover the sphereMaterial next!
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(radius,
segments,
rings),

sphereMaterial);

// add the sphere to the scene
scene.add(sphere);

Tất cả đều ổn, nhưng còn chất liệu cho quả cầu thì sao? Trong mã, chúng ta đã sử dụng biến sphereMaterial nhưng chưa xác định biến này. Trước tiên, chúng ta cần nói chi tiết hơn về chất liệu.

5. Vật liệu

Không nghi ngờ gì nữa, đây là một trong những phần hữu ích nhất của Three.js. Công cụ này cung cấp cho bạn một số chất liệu phổ biến (và rất hữu ích) để áp dụng cho lưới:

  1. "Cơ bản" – chỉ có nghĩa là kết xuất "không chiếu sáng"
  2. Lambert
  3. Phong

Còn nhiều tính năng khác, nhưng để đơn giản, tôi sẽ để bạn tự khám phá những tính năng đó. Đặc biệt, trong trường hợp WebGL, những tài liệu này có thể là cứu cánh. Tại sao? Vì trong WebGL, bạn phải viết chương trình đổ bóng cho mọi nội dung được kết xuất. Chương trình đổ bóng là một chủ đề rất lớn, nhưng tóm lại, chương trình này được viết bằng GLSL (Ngôn ngữ chương trình đổ bóng OpenGL), cho GPU biết giao diện của một đối tượng. Điều này có nghĩa là bạn cần mô phỏng toán học của ánh sáng, phản chiếu, v.v. Việc này có thể trở nên rất phức tạp rất nhanh. Nhờ Three.js, bạn không cần phải làm việc này nếu không muốn vì thư viện này sẽ giúp bạn trừu tượng hoá việc đó. Tuy nhiên, nếu muốn viết chương trình đổ bóng, bạn cũng có thể thực hiện việc đó bằng MeshShaderMaterial, vì vậy, đây là một chế độ thiết lập linh hoạt.

Tuy nhiên, hiện tại, hãy áp dụng một chất liệu lambert cho hình cầu:

// create the sphere's material
var sphereMaterial = new THREE.MeshLambertMaterial(
{
// a gorgeous red.
color: 0xCC0000
});

Ngoài ra, bạn cũng có thể chỉ định các thuộc tính khác khi tạo chất liệu ngoài màu sắc, chẳng hạn như bản đồ làm mượt hoặc bản đồ môi trường. Bạn nên tham khảo trang Wiki để biết các thuộc tính mà bạn có thể đặt trên chất liệu và trên thực tế là mọi đối tượng mà công cụ cung cấp cho bạn. Ngoài ra, threejs.org cũng mới ra mắt, cung cấp một chế độ xem hấp dẫn hơn về API.

6. Đèn!

Nếu kết xuất cảnh ngay bây giờ, bạn sẽ thấy một vòng tròn màu đỏ. Mặc dù chúng ta đã áp dụng chất liệu Lambert nhưng không có ánh sáng nào trong cảnh, vì vậy theo mặc định, Three.js sẽ quay lại ánh sáng môi trường xung quanh đầy đủ, giống như màu phẳng. Hãy khắc phục vấn đề đó bằng một điểm sáng đơn giản:

// create a point light
var pointLight = new THREE.PointLight( 0xFFFFFF );

// set its position
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;

// add to the scene
scene.add(pointLight);

7. Kết xuất

Bây giờ, chúng ta đã thiết lập mọi thứ để kết xuất. Nhưng chúng ta thực sự cần phải tiếp tục và làm điều đó:

// draw!
renderer.render(scene, camera);

Tuy nhiên, có thể bạn sẽ muốn kết xuất nhiều lần, vì vậy, nếu định lặp lại, bạn thực sự nên sử dụng requestAnimationFrame; đây là cách thông minh nhất để xử lý ảnh động trong trình duyệt. Tính năng này chưa được hỗ trợ đầy đủ, vì vậy, bạn nên xem shim của Paul Irish.

8. Các thuộc tính đối tượng phổ biến

Nếu dành thời gian xem qua mã cho Three.js, bạn sẽ thấy nhiều đối tượng "kế thừa" từ Object3D. Đây là một đối tượng cơ sở chứa một số thuộc tính rất hữu ích, chẳng hạn như thông tin về vị trí, xoaytỷ lệ. Cụ thể, Sphere là một Mesh kế thừa từ Object3D, trong đó thêm các thuộc tính riêng: geometry (hình học) và materials (chất liệu). Tại sao tôi đề cập đến những điều này? Bạn sẽ không muốn chỉ có một hình cầu trên màn hình mà không làm gì cả. Vì vậy, bạn nên tìm hiểu các thuộc tính này vì chúng cho phép bạn thao tác nhanh các chi tiết cơ bản của lưới và chất liệu.

// sphere geometry
sphere.geometry

// which contains the vertices and faces
sphere.geometry.vertices // an array
sphere.geometry.faces // also an array

// its position
sphere.position // has x, y and z properties
sphere.rotation // same
sphere.scale // ... same

9. Dirty Little Secrets

Tôi chỉ muốn nhanh chóng chỉ ra một điểm cần lưu ý về Three.js, đó là nếu bạn sửa đổi, ví dụ: các đỉnh của một lưới, bạn sẽ nhận thấy trong vòng lặp kết xuất không có gì thay đổi. Tại sao? Lý do là Three.js (theo như tôi có thể biết) lưu dữ liệu của một lưới vào bộ nhớ đệm dưới dạng một hoạt động tối ưu hoá. Việc bạn cần làm là gắn cờ cho Three.js biết rằng có gì đó đã thay đổi để có thể tính toán lại mọi thứ cần thiết. Bạn có thể thực hiện việc này bằng cách sau:

// changes to the vertices
sphere.geometry.__dirtyVertices = true;

// changes to the normals
sphere.geometry.__dirtyNormals = true;

Xin nhắc lại rằng còn nhiều cách khác, nhưng hai cách này là hữu ích nhất mà tôi tìm thấy. Rõ ràng là bạn chỉ nên gắn cờ những nội dung đã thay đổi để tránh tính toán không cần thiết.

Kết luận

Tôi hy vọng bạn thấy phần giới thiệu ngắn gọn về Three.js này hữu ích. Không có gì bằng việc tự mình thực hiện và thử nghiệm. Tôi thực sự khuyên bạn nên làm như vậy. Việc chạy 3D gốc trong trình duyệt rất thú vị và việc sử dụng một công cụ như Three.js sẽ giúp bạn giải quyết được nhiều vấn đề đau đầu và có thể tạo ra một số nội dung thực sự thú vị. Để giúp bạn một chút, tôi đã gói mã nguồn trong bài viết về lớp học lập trình này để bạn có thể sử dụng làm tài liệu tham khảo. Nếu bạn thích bài viết này, hãy cho tôi biết qua Twitter. Tôi luôn sẵn sàng chào đón bạn!