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à nó thực sự tuyệt vời trong việc loại bỏ những cơn đau đầu khi sử dụng mô hình 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, đèn, vật liệu, v.v. và có lựa chọn trình kết xuất, tức là bạn có thể quyết định xem bạn muốn vẽ cảnh của mình bằng canvas, WebGL hoặc SVG của HTML 5. Vì đây là mã nguồn mở, nên bạn thậm chí có thể tham gia vào dự án. Nhưng bây giờ tôi sẽ tập trung vào những gì tôi đã học được bằng cách chơi với nó như một công cụ, đồng thời nói với bạn về một số kiến thức cơ bản.

Đối với sự tuyệt vời của Three.js, có thể đôi khi bạn sẽ 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à đôi khi đặt câu hỏi qua GitHub. Nếu bạn cần hỏi, nhân tiện, tôi thấy Mr. doobAlteredQualia cực kỳ hữu ích!

1. Thông tin cơ bản

Tôi sẽ giả định rằng bạn đã có ít nhất kiến thức về 3D và thành thạo ở mức hợp lý với JavaScript. Nếu không, có thể 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ể khiến bạn hơi nhầm lẫn.

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

  1. Cảnh
  2. Trình kết xuất
  3. Một camera
  4. Một hoặc hai vật thể (có chất liệu)

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

2. Hỗ trợ

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

3. Đặt bối 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 hình ảnh và bạn muốn kết xuất bằng canvas hoặc WebGL, vì đây là những 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à WebP chạy trên GPU của thẻ đồ hoạ, tức là CPU của bạn có thể tập trung vào các tác vụ không kết xuất khác như tác vụ vật lý hoặc tương tác với 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, bạn nên lưu ý rằng JavaScript sẽ cần được tối ưu hoá cho hiệu suất. 3D không phải là một tác vụ nhẹ đối với trình duyệt (và thật tuyệt vời là có thể), vì vậy, hãy cẩn thận tìm hiểu vị trí bất kỳ nút thắt cổ chai nào trong mã của bạn và loại bỏ chúng nếu có thể!

Vì vậy, giả sử bạn đã tải xuống và bao gồm 3.js trong tệp HTML, bạn sẽ thiết lập một 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);

Cũng không quá phức tạp!

4. Tạo lưới

Vì vậy, chúng tôi có một cảnh, một máy ảnh và một trình kết xuất đồ hoạ (tôi đã chọn sử dụng WebGL trong mã mẫu) nhưng chúng tôi không có gì để vẽ. Three.js thực sự hỗ trợ việc tải một số loại tệp tiêu chuẩn khác nhau. Điều này sẽ tuyệt vời nếu bạn xuất các mô hình từ Blender, Maya, rạp chiếu phim 4D hoặc bất cứ loại tệp nào khác. Để cho mọi thứ đơn giản (sau cùng, đây là việc bắt đầu!) Tôi sẽ nói về dữ liệu nguyên thuỷ. Nguyên bản là các lưới hình học, các lưới 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 dữ liệu gốc này:

// 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);

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

5. Vật liệu

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

  1. "Basic" (Cơ bản) – chỉ có nghĩa là chế độ này hiển thị "không sáng"
  2. Lambert
  3. Phong

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

Tuy nhiên, bây giờ hãy áp dụng vậ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ần chỉ ra rằng có các thuộc tính khác mà bạn có thể chỉ định khi tạo chất liệu ngoài màu sắc, chẳng hạn như làm mượt hoặc bản đồ môi trường. Bạn nên tham khảo trang Wiki để biết nhiều thuộc tính mà bạn có thể đặt trên các tài liệu và thực tế là mọi đối tượng mà công cụ cung cấp cho bạn. Ngoài ra, threejs.org đã xuất hiện gần đây, cung cấp chế độ xem API hấp dẫn hơn.

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 tôi đã áp dụng vật liệu Lambert nhưng không có ánh sáng trong cảnh, vì vậy, theo mặc định, Three.js sẽ chuyển về ánh sáng xung quanh đầy đủ, tương tự như màu phẳng. Hãy cùng khắc phục vấn đề này bằng một điểm ánh 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

Giờ đây, chúng ta thực sự đã thiết lập xong mọi thứ để hiển thị. Nhưng chúng tôi 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 sắp thực hiện một vòng lặp, bạn 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 qua đảo của Paul Ireland.

8. 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à đố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ề position (vị trí), rotation (Xoay) và scale (tỷ lệ). Cụ thể, hình cầu của chúng ta là một Lưới kế thừa từ Object3D, đồng thời thêm các thuộc tính riêng: hình họcchất liệu. Tại sao tôi đề cập đến những tính năng này? Ít có khả năng bạn sẽ muốn chỉ có một hình cầu trên màn hình mà không có tác dụng gì, và các thuộc tính này nên được kiểm tra vì chúng cho phép bạn thao tác nhanh chóng các chi tiết cơ bản của lưới và vậ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. Những bí mật nhỏ bẩn

Tôi chỉ muốn nhanh chóng chỉ ra một khái niệm nhanh cho Three.js, đó là nếu bạn sửa đổi các đỉnh của lưới, chẳng hạn như 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? Vì Three.js (theo như tôi có thể biết) sẽ lưu dữ liệu vào bộ nhớ đệm cho một lưới dưới dạng tối ưu hoá. Việc bạn thực sự cần làm là gắn cờ cho Three.js rằng có gì đó đã thay đổi để ứng dụng có thể tính toán lại bất kỳ điều gì cần làm. Bạn thực hiện việc này như sau:

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

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

Tôi xin nhắc lại rằng vẫn còn nhiều tính năng khác, nhưng tôi thấy hai báo cáo đó hữu ích nhất. Rõ ràng là bạn chỉ nên gắn cờ những nội dung đã thay đổi để tránh các phép tính 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 này về Three.js hữu ích. Thực tế, chẳng có gì giống như việc bạn phải làm sạch tay mình và thử một việc gì đó cả, và tôi không thể giới thiệu nó đủ cao. Việc chạy mô hình 3D nguyên 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 tránh được nhiều khó khăn cũng như có thể tạo ra một số nội dung thú vị. Để giúp bạn hiểu rõ hơn, tôi đã tổng kết mã nguồn trong bài viết này trong phòng thí nghiệm để bạn có thể tham khảo. Nếu bạn thích tính năng này thì hãy cho tôi biết qua Twitter, chào bạn nhé!