Bao Cao Tuan 8

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 94

BÁO CÁO ĐỒ ÁN CHUYÊN NGÀNH

Đề tài: Tìm hiểu thư viện three.js và ứng dụng

Giảng viên hướng dẫn


Phạm Thi Vương

Sinh viên thực hiện


15520787 – Đỗ Thành Thắng
15520203 – Phạm Tuấn Tài
Nội dung báo cáo tuần 9
- Tìm hiểu về cách Loading and Working với Textures
1. Sử dụng textures trong materials
2. Advanced usage of textures
Trong phần trước, chúng ta đã thấy một số cách sử dụng texture cơ bản. Three.js
cũng cung cấp các tùy chọn để sử dụng texture nâng cao hơn. Trong phần này, chúng
ta sẽ xem xét một vài tùy chọn mà Three.js cung cấp.
2.1. Custom UV mapping
Chúng ta sẽ bắt đầu với một cái nhìn sâu hơn về bản đồ UV. Chúng ta đã
giải thích trước đó rằng với ánh xạ UV, bạn có thể chỉ định phần nào của texture
được hiển thị trên một khuôn mặt cụ thể. Khi bạn tạo hình học trong Three.js, các
ánh xạ này cũng sẽ được tạo tự động dựa trên loại hình học bạn đã tạo. Trong hầu
hết các trường hợp,chúng ta không cần phải thay đổi ánh xạ UV mặc định này.
Một cách để hiểu cách hoạt động của ánh xạ UV là xem xét một ví dụ từ Blender.
Ở ví dụ này, bạn thấy hai cửa sổ. Cửa sổ bên trái chứa hình học khối. Cửa
sổ ở phía bên tay phải là ánh xạ UV,là nơi chúng ta đã tải một texture để hiển thị
cách ánh xạ. Trong ví dụ này, chúng ta đã chọn một mặt cho cửa sổ ở phía bên trái
và cửa sổ ở bên phải- mặt bên kia cho thấy bản đồ UV cho mặt này. Như bạn có
thể thấy, mỗi đỉnh của khuôn mặt được đặt ở một trong các góc của ánh xạ UV ở
bên phải (các vòng tròn nhỏ). Điều này có nghĩa là texture hoàn chỉnh sẽ được sử
dụng cho khuôn mặt đó. Tất cả các mặt khác của khối này được ánh xạ theo cùng
một cách, do đó, kết quả sẽ hiển thị một khối lập phương trong đó mỗi mặt hiển
thị texture hoàn chỉnh. Xem 07-uv-maps.html.

Điều này là mặc định cho một khối trong Blender (cũng như trong
Three.js). Hãy thay đổi UV bằng cách chỉ chọn hai phần ba texture.
Nếu bây giờ chúng ta hiển thị điều này trong Three.js, bạn có thể thấy rằng
texture được áp dụng khác nhau.

Tùy chỉnh ánh xạ UV thường được thực hiện từ các chương trình như
Blender, đặc biệt là khi các mô hình trở nên phức tạp hơn. Phần quan trọng nhất
cần nhớ ở đây là ánh xạ UV chạy theo hai chiều, u và v, từ 0 đến 1. Để tùy chỉnh
ánh xạ UV, cần xác định đối với mỗi mặt, phần nào của texture sẽ được hiển thị.
Chúng ta làm điều này bằng cách xác định tọa độ u và v cho mỗi đỉnh tạo nên
khuôn mặt. Bạn có thể sử dụng đoạn mã sau để đặt giá trị u và v:
geom.faceVertexUvs[0][0][0].x = 0.5;

geom.faceVertexUvs[0][0][0].y = 0.7;
geom.faceVertexUvs[0][0][1].x = 0.4;

geom.faceVertexUvs[0][0][1].y = 0.1;

geom.faceVertexUvs[0][0][2].x = 0.4;

geom.faceVertexUvs[0][0][2].y = 0.5;

Đoạn mã này sẽ đặt các thuộc tính uv của mặt đầu tiên thành giá trị
được chỉ định. Hãy nhớ rằng mỗi mặt được xác định bởi ba đỉnh, vì vậy để
đặt tất cả các giá trị uv cho một mặt, chúng ta cần đặt sáu thuộc tính. Nếu bạn
mở 07-uv-maps-Manual.html, ví dụ bạn có thể thấy điều gì xảy ra khi bạn
thay đổi ánh xạ uv theo cách thủ công.

Tiếp theo, chúng ta sẽ xem xét cách texture có thể được lặp lại,cách
được thực hiện bằng một số thủ thuật ánh xạ UV bên trong.

2.2. Repeat wrapping


Khi bạn áp dụng một texture cho hình học được tạo bởi Three.js, Three.js
sẽ áp dụng texture đó một cách tối ưu nhất. Ví dụ, đối với hình khối, điều này có
nghĩa là mỗi bên sẽ hiển thị texture hoàn chỉnh và đối với hình cầu, texture hoàn
chỉnh được bọc xung quanh hình cầu đó. Tuy nhiên, có các tình huống trong đó
bạn không muốn texture trải ra xung quanh một mặt hoàn chỉnh hoặc hình học
hoàn chỉnh, nhưng có texture lặp lại. Three.js cung cấp chức năng chi tiết cho
phép bạn kiểm soát điều này. Ví dụ nơi bạn play xung quanh với các thuộc tính lặp
lại được cung cấp trong ví dụ 08-repeat-wrapping.html.
Trong ví dụ này, bạn có thể đặt thuộc tính điều khiển cách texture lặp lại.
Trước khi thuộc tính này có hiệu ứng mong muốn, bạn cần đảm bảo rằng bạn đã
đặt gói texture thành THREE.RepeatWrapping, như được hiển thị trong đoạn mã
sau:
cube.material.map.wrapS = THREE.RepeatWrapping;

cube.material.map.wrapT = THREE.RepeatWrapping;
Thuộc tính WrapS xác định cách bạn muốn texture hoạt động dọc theo trục
x của nó và thuộc tính WrapT xác định cách texture sẽ hoạt động dọc theo trục y.
Three.js cung cấp hai tùy chọn cho việc này, như sau:
 THREE.RepeatWrapping cho phép texture tự lặp lại.
 THREE.ClampToEdgeWrapping là cài đặt mặc định. Với THREE.
ClampToEdgeWrapping, texture không lặp lại toàn bộ, nhưng chỉ
các pixel ở cạnh được lặp lại.
Nếu bạn tắt tùy chọn menu repeatWrapping, tùy chọn
THREE.ClampToEdgeWrapping được sử dụng, như sau:
Nếu chúng ta sử dụng THREE.RepeatWrapping, chúng ta có thể đặt
thuộc tính lặp lại như trong đoạn mã sau:
cube.material.map.repeat.set(controls.repeatX, controls.repeatY);
Biến repeatX xác định tần suất texture được lặp lại dọc theo trục x của nó
và biến repeatY xác định tương tự cho trục y. Nếu các giá trị này được đặt thành 1,
texture sẽ không lặp lại. Nếu chúng được đặt thành giá trị cao hơn, bạn sẽ thấy
texture sẽ bắt đầu lặp lại. Bạn cũng có thể sử dụng các giá trị nhỏ hơn 1. Trong
trường hợp đó, có thể thấy rằng bạn sẽ phóng to texture. Nếu bạn đặt giá trị lặp lại
thành giá trị âm, texture sẽ được nhân đôi.
Khi bạn thay đổi thuộc tính lặp lại, Three.js sẽ tự động cập nhật texture và
render với cài đặt mới này. Nếu bạn thay đổi từ THREE.RepeatWrapping thành
THREE.ClampToEdgeWrapping, bạn cần cập nhật rõ ràng kết cấu:
cube.material.map.needsUpdate = true;
Cho đến bây giờ, chúng ta chỉ sử dụng hình ảnh tĩnh cho texture. Tuy
nhiên, Three.js cũng có tùy chọn sử dụng canvas HTML5 làm texture.
2.3. Render với canvas và sử dụng như là một texture
2.3.1. Sử dụng canvas làm texture
2.3.2. Sử dụng canvas làm bump map
2.4. Sử dụng đầu ra từ video làm texture
Nội dung báo cáo tuần 8
- Tìm hiểu về animation cơ bản và cách tạo ra animations bằng model.
3. Tìm hiểu animation cơ bản
3.1. Morphing and skeletal animations
Khi tạo animations trong các external programs (ví dụ: Blender), bạn thường có
hai tùy chọn chính để xác định animations:
• Morph targets: Với morph targets, cần xác định một phiên bản biến đổi,
nghĩa là vị trí chính của lưới. Đối với mục tiêu bị biến đổi này, tất cả các vị trí
đỉnh được lưu trữ lại. Tất cả những gì bạn cần để làm chuyển động hình dạng là di
chuyển tất cả các đỉnh từ vị trí này sang vị trí quan trọng khác và lặp lại quá trình
đó. Ảnh chụp màn hình sau đây cho thấy các mục tiêu hình thái khác nhau được
sử dụng để hiển thị biểu cảm khuôn mặt (được cung cấp bởi nền tảng Blender):

• Skeletal animation: Một cách khác là sử dụng skeletal animation. Với


skeletal animation, bạn cần xác định bộ xương, nghĩa là xương của lưới và gắn các
đỉnh vào các xương cụ thể. Bây giờ, bạn di chuyển một xương, bất kỳ xương đã
kết nối nào cũng được di chuyển một cách thích hợp, và các đỉnh kèm theo được
di chuyển và biến dạng dựa trên vị trí, chuyển động và tỉ lệ của xương. Ảnh chụp
màn hình sau đây được cung cấp bởi nền tảng Blender, cho thấy một ví dụ về cách
xương có thể được sử dụng để di chuyển và làm biến dạng một vật thể:

Three.js hỗ trợ cả hai chế độ, nhưng nhìn chung có thể bạn sẽ nhận được kết quả tốt hơn
với các mục tiêu biến đổi. Vấn đề chính với skeletal animation là nhận được export tốt từ
một chương trình 3D như Blender có thể được tạo chuyển động trong Three.js. Dễ dàng
có được một mô hình hoạt động tốt với các mục tiêu hình thái hơn là với xương và da.
Trong phần này, chúng ta sẽ xem xét cả hai tùy chọn và cũng xem xét một vài định dạng
bên ngoài được Three.js hỗ trợ trong đó có thể xác định animations.
3.1.1. Animation with morph targets
Morph targets là cách đơn giản nhất để xác định một animation. Bạn xác
định tất cả các đỉnh cho từng vị trí quan trọng (còn được gọi là khung
chính) và báo lại cho Three.js để di chuyển các đỉnh từ vị trí này sang vị trí
khác. Tuy nhiên, nhược điểm của phương pháp này là đối với các lưới lớn
và hình động lớn, các tập tin mô hình sẽ trở nên rất lớn. Lý do là đối với
mỗi vị trí quan trọng, tất cả các vị trí đỉnh được lặp lại.
Chúng ta sẽ tìm ra cách làm việc với morph targets bằng hai ví dụ. Trong ví
dụ đầu tiên, chúng ta sẽ để Three.js xử lý quá trình chuyển đổi giữa các
khung chính khác nhau (hoặc các mục tiêu hình thái như chúng ta sẽ gọi
chúng từ bây giờ) và trong phần thứ hai, chúng ta sẽ thực hiện việc này một
cách thủ công.
3.1.1.1. Animation with MorphAnimMesh
Lấy ví dụ đàu tiên về first morphing, chúng ta sẽ sử dụng một mô
hình cũng có sẵn từ bản phân phối Three.js – ngựa. Cách duy nhất để
hiểu cách morph-targets là dựa trên sự làm việc của animation bằng
việc mở ví du 10-morph-targets. html lên.
Trong ví dụ này, con ngựa ở phía bên phải là animation và đang chạy, và con ngựa ở phía
bên trái đang đứng yên. Con ngựa thứ hai này (bên trái) được kết xuất từ mô hình cơ bản,
nghĩa là bộ đỉnh ban đầu. Với menu ở góc trên bên phải, bạn có thể duyệt qua tất cả các
mục tiêu hình thái có sẵn và xem các vị trí khác nhau mà ngựa bên trái có thể đảm nhận..
Three.js cung cấp một cách để di chuyển từ vị trí này sang vị trí tiếp theo, nhưng điều
này có nghĩa là chúng ta phải theo dõi thủ công vị trí hiện tại chúng ta đang ở và mục tiêu
chúng ta muốn hướng đến, và khi chúng ta đã đạt được mục tiêu vị trí, lặp lại điều này
cho các vị trí khác. May mắn là Three.js cũng cung cấp một lưới cụ thể, đó là THREE.
MorphAnimMesh, nó lưu lại các thông tin chi tiết cho chúng ta. Trước khi chúng ta tiếp
tục, đây là một ghi chú nhanh về một lưới liên quan đến hoạt hình khác được cung cấp
bởi Three.js có tên là THREE. MorphBlendMesh. Nếu bạn xem qua các đối tượng
được cung cấp bởi Three.js, bạn có thể nhận thấy đối tượng này. Với lưới cụ thể này, bạn
có thể thực hiện khá nhiều điều tương tự bạn có thể làm với
THREE.MorphAnimMesh, và khi bạn nhìn vào mã nguồn, bạn thậm chí có thể thấy
rằng phần lớn nó được sao chép giữa hai đối tượng này. THREE. MorphBlendMesh.
Tuy nhiên,nó dường như không được dùng nữa và không được sử dụng trong bất kỳ ví
dụ chính thức nào của Three.js. Tất cả mọi thứ bạn có thể làm với
THREE.MorhpBlendMesh thì có thể làm đươc với THREE.MorphAnimMesh, vì
vậy, hãy sử dụng THREE.MorphAnimMesh cho loại chức năng này. Đoạn mã sau đây
cho bạn thấy cách tải mô hình và tạo THREE.MorphAnimMesh từ nó:
var loader = new THREE.JSONLoader();
loader.load('../assets/models/horse.js', function (geometry, mat) {
var mat = new THREE.MeshLambertMaterial(
{
morphTargets: true,
vertexColors: THREE.FaceColors
});
var mat2 = new THREE.MeshLambertMaterial(
{color: 0xffffff, vertexColors: THREE.FaceColors});
mesh = new THREE.Mesh(geometry, mat);
mesh.position.x = -100;
frames.push(mesh);
currentMesh = mesh;
morphColorsToFaceColors(geometry);
mesh.geometry.morphTargets.forEach(function (e) {
var geom = new THREE.Geometry();
geom.vertices = e.vertices;
geom.faces = geometry.faces;
var morpMesh = new THREE.Mesh(geom, mat2);
frames.push(morpMesh);
morpMesh.position.x = -100;
});
geometry.computeVertexNormals();
geometry.computeFaceNormals();
geometry.computeMorphNormals();
meshAnim = new THREE.MorphAnimMesh(geometry, mat);
meshAnim.duration = 1000;
meshAnim.position.x = 200;
meshAnim.position.z = 0;
scene.add(meshAnim);
showFrame(0);
}, '../assets/models');
function showFrame(e) {
scene.remove(currentMesh);
scene.add(frames[e]);
currentMesh = frames[e];
console.log(currentMesh);
}
function morphColorsToFaceColors(geometry) {
if (geometry.morphColors && geometry.morphColors.length) {
var colorMap = geometry.morphColors[0];
for (var i = 0; i < colorMap.colors.length; i++) {
geometry.faces[i].color = colorMap.colors[i];
geometry.faces[i].color.offsetHSL(0, 0.3, 0);
}
}
}
Đây là cách tiếp cận tương tự mà chúng ta đã thấy khi tải các mô hình khác. Lần này, mô
hình bên ngoài cũng chứa các mục tiêu hình thái. Thay vì tạo một đối tượng
THREE.Mesh bình thường, chúng ta tạo THREE.MorphAnimMesh. Có một vài điều
bạn cần tính đến khi tải hình ảnh động::
• Đảm bảo rằng vật liệu bạn sử dụng có THREE.morphTargets được đặt thành
true. Nếu nó không được đặt, lưới của bạn sẽ không chuyển động.
• Trước khi tạo THREE.MorphAnimMesh, đảm bảo rằng đã call
computeMorphNormals trên geometry để tất cả the normal vectors cho các mục
tiêu hình thái được tính toán. Điều này là cần thiết cho hiệu ứng ánh sáng và bóng
chính xác..
• Cũng có thể xác định màu sắc cho các khuôn mặt của một mục tiêu hình thái cụ
thể. Đây là tài nguyên có sẵn từ morphColors. Bạn có thể sử dụng điều này để
biến đổi không chỉ hình dạng của hình học, mà cả màu sắc của từng khuôn mặt.
Với phương thức trợ giúp morphColorsToFaceColors, chúng ta chỉ sửa màu của
các mặt thành tập màu đầu tiên trong mảng morphColors.
• Cài đặt mặc định là phát toàn bộ hình động trong một lần. Nếu có nhiều hình động
được xác định cho cùng một hình dạng, bạn có thể sử dụng hàm
parseAnimations() cùng với playAnimation(name,fps) để phát một trong các
hình động được xác định. Chúng ta sẽ sử dụng phương pháp này trong phần cuối
của chương này, nơi chúng ta tải hình ảnh động từ một mô hình MD2..
Tất cả những gì còn lại phải làm là cập nhật hình ảnh động trong vòng lặp render. Đối
với điều này, một lần nữa chúng ta sử dụng THREE.Clock để tính toán delta và sử
dụng nó để cập nhật hình ảnh động, như sau::
function render() {
stats.update();

var delta = clock.getDelta();


webGLRenderer.clear();
if (meshAnim) {
meshAnim.updateAnimation(delta * 1000);
meshAnim.rotation.y += 0.01;
}
// render using requestAnimationFrame
requestAnimationFrame(render);
webGLRenderer.render(scene, camera);
}
Cách tiếp cận này là dễ nhất và cho phép bạn nhanh chóng thiết lập
một hình ảnh động từ một mô hình có các mục tiêu hình thái được
xác định. Một cách tiếp cận khác là thiết lập hình ảnh động theo cách
thủ công như chúng ta hiển thị trong phần tiếp theo.
3.1.1.2. Creating an animation by setting the morphTargetInfluence
property
Chúng ta sẽ tạo một ví dụ rất đơn giản trong đó chúng ta biến hình
khối từ hình này sang hình khác. Lần này, chúng ta sẽ kiểm soát thủ
công mục tiêu mà chúng ta sẽ hướng đến. Bạn có thể tìm thấy ví dụ
trong 11-morph-targets-manually.html. Ảnh chụp màn hình sau
đây cho thấy một hình ảnh tĩnh của ví dụ này:
Trong ví dụ này, chúng ta đã tự tạo hai mục tiêu hình thái cho một khối đơn giản, như
sau:
// create a cube
var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
var cubeMaterial = new THREE.MeshLambertMaterial({morphTargets: true, color:
0xff0000});

// define morphtargets, we'll use the vertices from these geometries


var cubeTarget1 = new THREE.BoxGeometry(2, 10, 2);
var cubeTarget2 = new THREE.BoxGeometry(8, 2, 8);

// define morphtargets and compute the morphnormal


cubeGeometry.morphTargets[0] = {name: 't1', vertices: cubeTarget2.vertices};
cubeGeometry.morphTargets[1] = {name: 't2', vertices: cubeTarget1.vertices};
cubeGeometry.computeMorphNormals();

var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);


Khi bạn mở ví dụ này, bạn sẽ thấy một khối lập phương đơn giản. Với các thanh trượt ở
góc trên bên phải, bạn có thể đặt morphTargetInfluences. Nói cách khác, bạn có thể xác
định khối lượng ban đầu sẽ biến thành khối lập phương được chỉ định là mt1 và mức độ
biến đổi của nó thành mt2. Khi bạn tạo các mục tiêu hình thái của mình bằng tay,
bạn cần tính đến thực tế là mục tiêu hình thái có cùng số đỉnh với hình dạng nguồn. Bạn
có thể đặt ảnh hưởng bằng cách sử dụng thuộc tính morphTargetInfluences của lưới:
var controls = new function () {
this.influence1 = 0.01;
this.influence2 = 0.01;

this.update = function () {
cube.morphTargetInfluences[0] = controls.influence1;
cube.morphTargetInfluences[1] = controls.influence2;
};
};
Lưu ý rằng hình học ban đầu có thể bị ảnh hưởng bởi nhiều mục tiêu
hình thái cùng một lúc. Hai ví dụ này cho thấy các khái niệm quan
trọng nhất đằng sau hoạt hình mục tiêu hình thái. Trong phần tiếp
theo, chúng ta sẽ có một cái nhìn nhanh về hoạt hình bằng cách sử
dụng xương và da.
3.1.2. Animation using bones and skinning
Morph animations thì rất đơn giản. Three.js biết tất cả các vị trí đỉnh đích
và chỉ cần chuyển từng đỉnh từ vị trí này sang vị trí tiếp theo. Đối với
xương và da, nó trở nên phức tạp hơn một chút. Khi bạn sử dụng xương
cho hoạt hình, bạn di chuyển xương và Three.js phải xác định cách dịch
chuyển da theo (một tập hợp các đỉnh) cho phù hợp. Trong ví dụ này,
chúng ta sử dụng một mô hình được xuất từ Blender sang định dạng
Three.js (hand-1.js in the models folder). Đây là mô hình của một bàn
tay, hoàn chỉnh với một bộ xương. Bằng cách di chuyển xương xung
quanh, chúng ta có thể làm động mô hình. Trước tiên hãy xem cách chúng
ta tải mô hình:

var loader = new THREE.JSONLoader();


loader.load('../assets/models/hand-1.js', function (geometry, mat) {
var mat = new THREE.MeshLambertMaterial({color: 0xF0C8C9, skinning:
true});
mesh = new THREE.SkinnedMesh(geometry, mat);
// rotate the complete hand
mesh.rotation.x = 0.5 * Math.PI;
mesh.rotation.z = 0.7 * Math.PI;
// add the mesh
scene.add(mesh);
// and start the animation
tween.start();
}, '../assets/models');
Tải một mô hình cho animation xương không khác với bất kỳ mô hình nào khác. Chúng
ta chỉ xác định tệp mô hình, chứa định nghĩa về đỉnh, mặt và xương, và dựa trên hình
dạng đó, chúng ta tạo ra một lưới. Three.js cũng cung cấp một lưới cụ thể cho hình học
có da như thế này được gọi là THREE.SkinnedMesh. Một điều bạn cần xác định để
đảm bảo mô hình cập nhật được đặt thuộc tính skinning của vật liệu bạn sử dụng thành
true. Nếu không, sẽ không thấy bất kỳ chuyển động xương nào. Điều cuối cùng chúng ta
làm ở đây là đặt thuộc tính useQuaternion của tất cả các xương thành false. Trong ví dụ
này, chúng ta sẽ sử dụng một đối tượng tween để xử lý hình ảnh động. Ví dụ tween này
được định nghĩa như thế này::
var tween = new TWEEN.Tween({pos: -1})
.to({pos: 0}, 3000)
.easing(TWEEN.Easing.Cubic.InOut)
.yoyo(true)
.repeat(Infinity)
.onUpdate(onUpdate);
Với tween, chúng ta chuyển đổi biến pos từ -1 thành 0. Chúng ta cũng đã đặt thuộc tính
yoyo thành true, điều này làm cho hoạt hình chạy ngược lại trong lần chạy tiếp theo. Để
đảm bảo hoạt hình tiếp tục chạy, chúng ta đặt lặp lại thành Infinity. Bạn cũng có thể thấy
rằng chúng ta chỉ định một phương thức onUpdate. Phương pháp này được sử dụng để
định vị xương, và chúng ta sẽ xem xét điều này tiếp theo.
Trước khi di chuyển xương, hãy xem ví dụ 12-bones-manually.html. Ảnh chụp màn
hình sau đây cho thấy một hình ảnh tĩnh của ví dụ này:
Khi mở ví dụ này, bạn sẽ thấy bàn tay tạo ra một chuyển động giống như lấy. Chúng ta
đã làm điều này bằng cách thiết lập xoay z của xương ngón tay trong phương thức
onUpdate được gọi từ tween animation, như sau:
var onUpdate = function () {
var pos = this.pos;

console.log(mesh.skeleton);

// rotate the fingers


mesh.skeleton.bones[5].rotation.set(0, 0, pos);
mesh.skeleton.bones[6].rotation.set(0, 0, pos);
mesh.skeleton.bones[10].rotation.set(0, 0, pos);
mesh.skeleton.bones[11].rotation.set(0, 0, pos);
mesh.skeleton.bones[15].rotation.set(0, 0, pos);
mesh.skeleton.bones[16].rotation.set(0, 0, pos);
mesh.skeleton.bones[20].rotation.set(0, 0, pos);
mesh.skeleton.bones[21].rotation.set(0, 0, pos);

// rotate the wrist


mesh.skeleton.bones[1].rotation.set(pos, 0, 0);
};
Bất cứ khi nào phương thức cập nhật này được gọi, các xương có liên quan sẽ được đặt ở
vị trí pos. Để xác định xương cần di chuyển, đó là một ý tưởng tốt để in thuộc tính mesh.
skeleton ra console. Điều này sẽ liệt kê tất cả các xương và tên.

Three.js cung cấp một trình trợ giúp đơn giản mà bạn có thể sử
dụng để hiển thị
xương của mô hình.
helper = new THREE.SkeletonHelper( mesh );
helper.material.linewidth = 2;
helper.visible = false; scene.add( helper );
The bones are highlighted. You can see an example of this by
enabling the

showHelper property shown in the 12-bones-manually.html example.


Như bạn có thể thấy, làm việc với xương tốn nhiều công sức hơn một chút nhưng linh
hoạt hơn nhiều so với các mục tiêu hình thái cố định. Trong ví dụ này, chúng ta chỉ di
chuyển vòng xoay của xương; bạn cũng có thể di chuyển vị trí hoặc thay đổi quy mô.
Trong phần tiếp theo, chúng ta xem xét tải hình ảnh động từ các mô hình bên ngoài.
Trong phần đó, chúng ta sẽ xem lại ví dụ này, nhưng bây giờ, chúng ta sẽ chạy một hình
ảnh động được xác định trước từ mô hình thay vì tự di chuyển xương xung quanh.

Trong Chapter 8, Creating and Loading Advanced Meshes and Geometries, chúng ta đã
xem xét một số định dạng 3D được Three.js hỗ trợ. Một vài trong số các định dạng cũng
hỗ trợ hình ảnh động. Trong chương này, chúng ta sẽ xem xét các ví dụ sau:
• Blender with the JSON exporter: Chúng ta sẽ bắt đầu với một hình ảnh động
được tạo trong Blender và xuất sang định dạng JSON của Three.js.
• Collada model: Định dạng Collada có hỗ trợ cho hình ảnh động. Trong ví dụ này,
chúng ta sẽ tải một hình ảnh động từ tệp Collada và render nó với Three.js.
• MD2 model: Mô hình MD2 là một định dạng đơn giản được sử dụng trong các
công cụ Quake cũ. Mặc dù định dạng này có lỗi thời 1 tí, nhưng nó vẫn là một
định dạng tốt để lưu trữ hình ảnh động nhân vật.
Chúng ta sẽ bắt đầu với Blender model.

4. Creating animations using external models


4.1. Creating a bones animation using Blender
Để bắt đầu với hình động từ Blender, bạn có thể tải ví dụ chúng ta đã đưa vào thư
mục mô hình. Bạn có thể tìm thấy tệp hand.blend ở đó, nơi bạn có thể tải vào
Blender. Ảnh chụp màn hình sau đây cho thấy một hình ảnh tĩnh của ví dụ này:
Không có thông tin nhiều để đi sâu vào chi tiết về cách tạo hoạt hình trong Blender,
nhưng có một vài điều bạn cần ghi nhớ::
• Mỗi đỉnh từ mô hình của bạn ít nhất phải được gán cho một nhóm đỉnh.
• Tên của các nhóm đỉnh bạn sử dụng trong Blender phải tương ứng với tên của
xương điều khiển nó. Theo cách đó, Three.js có thể xác định các đỉnh cần sửa đổi
khi di chuyển xương.
• Chỉ "action" đầu tiên được xuất. Vì vậy, hãy chắc chắn rằng hình ảnh động bạn
muốn xuất là cái đầu tiên.
• Khi tạo các khung chính, bạn nên chọn tất cả các xương ngay cả khi chúng không
thay đổi.
• Khi xuất mô hình, đảm bảo mô hình ở tư thế nghỉ. Nếu đây không phải là trường
hợp, bạn sẽ thấy một hình ảnh động rất biến dạng.
Để biết thêm thông tin về cách tạo và xuất hình ảnh động từ Blender và lý do cho các
gợi ý đã nói ở trên, bạn có thể xem tài liệu sau đây:
http://devmatrix.wordpress.com/2013/02/27/creating-skeletalanimation-in-
blender-and-exporting-it-to-three-js/.
Khi bạn đã tạo hoạt hình trong Blender, bạn có thể xuất tệp bằng trình xuất Three.js mà
chúng ta đã sử dụng trong chương trước. Khi xuất tệp bằng trình xuất Three.js, bạn phải
đảm bảo rằng các thuộc tính sau được kiểm tra:
Điều này sẽ xuất hình động mà bạn đã chỉ định trong Blender dưới dạng animation khung
xương thay vì animation biến dạng. Với một hình ảnh động của xương, các chuyển động
của xương được xuất ra, mà chúng ta có thể phát lại trong Three.js.
Loading mô hình trong Three.js giống như chúng ta đã làm với ví dụ trước. Tuy nhiên,
bây giờ mô hình đã được tải, chúng ta cũng sẽ tạo một hình ảnh động, như sau:
var loader = new THREE.JSONLoader();
loader.load('../assets/models/hand-2.js', function (model, mat) {
var mat = new THREE.MeshLambertMaterial({color: 0xF0C8C9, skinning:
true});
mesh = new THREE.SkinnedMesh(model, mat);
var animation = new THREE.Animation(mesh, model.animation);
mesh.rotation.x = 0.5 * Math.PI;
mesh.rotation.z = 0.7 * Math.PI;
scene.add(mesh);
helper = new THREE.SkeletonHelper(mesh);
helper.material.linewidth = 2;
helper.visible = false;
scene.add(helper);
// start the animation
animation.play();
}, '../assets/models');
Để chạy animation này, tất cả những gì chúng ta phải làm là tạo một
THREE.Animation và gọi phương thức play trên cái animation này. Trước khi chúng ta
xem animation, chúng ta vẫn cần thực hiện thêm một bước. Trong vòng lặp render,
chúng ta gọi hàm THREE.AnimationHandler. update(clock.getDelta()) để cập nhật
animation, và Three.js sẽ sử dụng xương để đặt mô hình vào đúng vị trí. Kết quả của ví
dụ này (13-animation-from-blender.html) là một bàn tay vẫy.
Ảnh chụp màn hình sau đây cho thấy một hình ảnh tĩnh của ví dụ này:

Ngoài định dạng riêng của Three.js, chúng ta có thể sử dụng một vài định dạng khác để
xác định hình động. Cái đầu tiên chúng ta sẽ xem là tải mô hình Collada.

4.2. Loading an animation from a Collada model


Tải mô hình từ tệp Collada hoạt động theo cách tương tự như đối với các định
dạng khác. Trước tiên, bạn phải include the correct loader JavaScript file:
<script type="text/javascript" src="../libs/ColladaLoader.js"></script>
Tiếp theo, chúng ta tạo một trình tải và sử dụng nó để tải tệp mô hình:
var loader = new THREE.ColladaLoader();
loader.load('../assets/models/monster.dae', function (collada) {
var child = collada.skins[0];
scene.add(child);
var animation = new THREE.Animation(child, child.geometry.animation);
animation.play();
// position the mesh
child.scale.set(0.15, 0.15, 0.15);
child.rotation.x = -0.5 * Math.PI;
child.position.x = -100;
child.position.y = -60;
});
Một tệp Collada có thể chứa nhiều hơn một chế độ đơn lẻ; nó có thể lưu trữ các cảnh
hoàn chỉnh, bao gồm máy ảnh, ánh sáng, hình động, v.v. Một cách tốt để làm việc với mô
hình Collada là in kết quả từ hàm loader.load sang console và xác định thành phần nào
bạn muốn sử dụng. Trong trường hợp này, đã có một THREE.SkinnedMesh trong scene
(child). Để kết xuất và làm động mô hình này, tất cả những gì chúng ta phải làm là thiết
lập animation giống như đã làm cho mô hình dựa trên Blender; ngay cả vòng lặp render
vẫn giữ nguyên. Đây là cách chúng ta kết xuất và làm động mô hình:
function render() {
stats.update();
var delta = clock.getDelta();
THREE.AnimationHandler.update(delta);
// render using requestAnimationFrame
requestAnimationFrame(render);
webGLRenderer.render(scene, camera);
}

Và kết quả cho tệp Collada:


Một ví dụ khác về một mô hình bên ngoài, một mô hình sử dụng các mục tiêu hình thái
là định dạng tệp MD2.

4.3. Animation loaded from a Quake model


Định dạng MD2 được tạo để mô hình các nhân vật từ Quake, một trò chơi tuyệt
vời từ năm 1996. Mặc dù các công cụ mới hơn sử dụng định dạng khác, bạn vẫn
có thể tìm thấy rất nhiều mô hình thú vị ở định dạng MD2. Để sử dụng các tệp ở
định dạng này, trước tiên chúng ta phải chuyển đổi chúng sang định dạng Three.js
JavaScript. Bạn có thể làm điều này trực tuyến bằng cách sử dụng trang web sau:
http://oos.moxiecode.com/js_webgl/md2_converter/
Sau khi chuyển đổi, bạn sẽ nhận được tệp JavaScript ở định dạng Three.js mà bạn có thể
tải và kết xuất bằng MorphAnimMesh. Vì chúng ta đã thấy cách thực hiện điều này
trong các phần trước, nên sẽ bỏ qua mã code nơi mô hình được tải. Đó là cái hay mặc dù
đang xảy ra trong code. Thay vì playing animation complete, chúng ta cung cấp tên của
hình ảnh động cần được phát:
mesh.playAnimation('crattack', 10);
Lý do là một tệp MD2 thường chứa một số hình ảnh động nhân vật khác nhau. Tuy
nhiên, Three.js cung cấp chức năng để xác định các hình ảnh động có sẵn và phát chúng
bằng chức năng playAnimation. Điều đầu tiên chúng ta cần làm là bảo Three.js phân tích
hoạt ảnh:
mesh.parseAnimations();
Điều này dẫn đến một danh sách các tên cho hình ảnh động có thể được phát bằng chức
năng playAnimation. Trong ví dụ, bạn có thể chọn tên của hình ảnh động từ menu ở
góc trên bên phải. Các hình ảnh động có sẵn được xác định như thế này:
mesh.parseAnimations();
// parse the animations and add them to the control
var animLabels = [];
for (var key in mesh.geometry.animations) {
if (key === 'length' || !mesh.geometry.animations.hasOwnProperty(key))
continue;
animLabels.push(key);
}
gui.add(controls, 'animations', animLabels).onChange(function (e) {
mesh.playAnimation(controls.animations, controls.fps);
});
gui.add(controls, 'fps', 1, 20).step(1).onChange(function (e) {
mesh.playAnimation(controls.animations, controls.fps);
});
Bất cứ khi nào một hình động từ menu được chọn, hàm mesh.playAnimation sẽ được
gọi với tên animation được chỉ định. Ví dụ minh họa điều này có thể được tìm thấy trong
15-animation-from-md2.html. Ảnh chụp màn hình sau đây cho chúng ta thấy một hình
ảnh tĩnh của ví dụ này:

 Kế hoạch tuần sau: Tìm hiểu về cách làm việc với Textures
5. Tìm hiểu về animation cơ bản
Ôn lại về render loop, để tạo ra animation chúng ta sẽ render khung hình. Three.js hỗ trợ
việc này bằng hàm requestAnimationFrame.

Với code này ta chỉ cần gọi hàm render() sau khi đã khởi tạo xong một scene. Bên trong
hàm render ta dùng hàm requestAnimationFrame để xác định thời gian render lại scene
đó, thường là 60 lần một giây. Với cách này chúng ta không cần phải quan tâm đến việc
canh thời gian khi nào cần render, và nếu animation không cần phải hiển thị thì CPU hay
GPU cũng sẽ không cần phải xử lý để render ảnh.
1. Animation đơn giản
Đối với cách tiếp cận này, ta sẽ tạo ra animation bằng cách thay đổi độ xoay, thu
phóng, vị trí, material, các đỉnh, ….
Animation trong hình này được tạo với đoạn code sau đặt trước hàm
requestAnimationFrame và chứa trong hàm render
Ở đây chúng ta chỉ thay đổi các thuộc tính của các object trong mỗi render
loop.
2. Tạo Animatio bằng Tween.js
Tween.js là một thư viện javascript hỗ trợ việc xác định thay đổi các thuộc tính
nằm trong khoảng hai giá trị. Tất cả các điểm nằm giữa điểm start và end sẽ được
thư viện này tự động tính toán. Quá trình này gọi là tweening.
Link: https://github.com/sole/tween.js/

Đoạn code trên tạo một tween, tween này thay đổi vị trí của một mesh từ vị trí
hiện tại đến (100, 100, 100) trong vòng 10 giây.
Ta có thể thêm một tween khác xảy ra ngay sau một tween bằng hàm chain().
VD: tween1.chain(tween2);
Bên trong render loop ta thêm vào TWEEN.update();
Sau khi tạo một tween ta sẽ bắt đầu tween này bằng cách gọi hàm start() và có thể
ngừng bằng cách gọi hàm stop().
6. Camera trong three.js
Three.js hỗ trợ nhiều loại control camera, hữu ích và thường được dùng nhất là các
loại FirstPersonControls, FlyControls, RollControls, TrackballControls và
OrbitControls. Ngoài ra còn một số loại control khác ít được sử dụng hơn như:
EditorControls Control này tạo ra để dùng cho three.js
online editor, nằm ở link
https://threejs.org/editor/
OculusControls Control này hỗ trợ việc nhìn xung quanh
khi sử dụng thiết bị Oculus Rift
OrthographicTrackballControls Control này giống với TrackballControls
nhưng dành riêng cho
OrthographicCamera
PointerLockControls Control này cố định con trỏ chuột tại một
vị trí, thường được dùng với một số game
3D đơn giản.
VRControls Control này dùng
PositionSensorVRDevice API để điều
khiển scene. Tìm hiểu thêm tại
https://developer.mozilla.org/en-
US/docs/Web/API/Navigator/getVRDisplays
Ngoài ra thay vì dùng control camera ta cũng có thể tự di chuyển camera bằng cách dùng
hàm lookAt
VD. Camera.lookAt(new Vector3(100, 100, 100));
1. TrackBallControls
Trước khi dùng TrackBallControls cần phải thêm tập tin javascript
<script type="text/javascript" src="../libs/TrackballControls.js"></script>

Ta thêm control vào camera như sau

Để cập nhật vị trí của camera ta làm như sau

Để cập nhật vị trí camera ta cần phải cung cấp thời gian giữa mỗi lần render.
Các cử chỉ có thể sử dụng
Nhấn chuột trái và di chuyển Xoay màn hình
Cuộn chuột Phóng to thu nhỏ
Nhấn chuột phải và di chuyển Di chuyển camera

Ta có thể chỉnh các thuộc tính của control như panSpeed (tốc độ di chuyển
camera), rotateSpeed (tốc độ xoay camera), zoomSpeed (tốc độ thu phóng).
Thuộc tính kiểu boolean noZoom xác định có thể thu phóng camera hay không.
Demo: https://threejs.org/examples/misc_controls_trackball.html

2. FlyControls

Với FlyControls ta có thể điều khiển camera giống như bay qua scene.
Trước khi dùng TrackBallControls cần phải thêm tập tin javascript
<script type="text/javascript" src="../libs/FlyControls.js"> </script>
Sau đó ta thêm control vào camera như sau

Các cử chỉ có thể sử dụng


Nhấn chuột trái hoặc giữa Tiến về phía trước
Nhấn chuột phải Lùi về sau
Di chuột Nhìn xung quanh
W Tiến về trước
S Lùi về sau
A Di chuyển sang trái
D Di chuyển sang phải
R Di chuyển lên trên
F Di chuyển xuống dưới
Các phím điều hướng Di chuyển theo hướng phím điều hướng
G Xoay bên trái
E Xoay bên phải
Demo: https://threejs.org/examples/misc_controls_fly.html

3. FirstPersonControls

Điều khiển camera theo góc nhìn thứ nhất, các phím WASD dùng để di chuyển và chuột
dùng để nhìn xung quanh.
Để khởi tạo FirstPersonControls cũng giống với các control khác, chúng ta chỉ đi vào hai
thuộc tính là lon và lat (tọa độ mà camera lúc mới render)

Các cử chỉ có thể sử dụng


Di chuột Nhìn xung quanh
W Tiến về trước
S Lùi về sau
A Di chuyển sang trái
D Di chuyển sang phải
R Di chuyển lên trên
F Di chuyển xuống dưới
Các phím điều hướng Di chuyển theo hướng phím điều hướng
Q Ngừng di chuyển
Demo: https://threejs.org/examples/misc_controls_pointerlock.html

4. OrbitControls

Control cho phép người dùng xoay quanh quanh quỹ đạo của mục tiêu được chọn.
Khởi tạo OrbitControls

Các thuộc tính


Boolean .autoRotate: Cho phép tự xoay quanh quỹ đạo
Float autoRotateSpeed: Xác định tốc độ xoay
Boolean .enableZoom: Cho phép thu phóng
Float zoomSpeed: Xác định tốc độ thu phóng
Boolean enablePan: Cho phép di chuyển camera
Float panSpeed: Xác định tốc độ di chuyển camera
OrbitControls cũng cần phải update mỗi render loop

Kế hoạch cho tuần tiếp theo


- Tìm hiểu về morphing và skeletal animation
- Tạo animation sử dụng model bên ngoài
Nội dung báo cáo tuần 6
- Tìm hiểu về Particles, Sprites và PointCloud
7. Tìm hiểu về Particle, Sprite và PointCloud
- Với Particles (hạt) chúng ta có thể tạo các object nhỏ để mô phỏng các hiệu ứng
như mưa, tuyết, khói và nhiều hiệu ứng thú vị khác. Trong phần này ta sẽ tìm hiểu
về các chủ đề:
 Tạo và tạo kiểu cho các hạt bằng THREE.SpriteMaterial.
 Cách sử dụng THREE.PointCloud để tạo ra tập hợp các particle
 Cách tạo THREE.PointCloud từ các geometry có sẵn.
 Tạo hiệu ứng chuyển động cho các particle.
 Sử dụng texture để tạo kiểu cho particle

1. Sprite

Để biểu diễn một hạt trong three.js cách đầu tiên là dùng Sprite. Trong three.js sprite
là một mặt phẳng hai chiều luôn hướng mặt về phía camera.
THREE.SpriteMaterial( parameters : Object )

 .color : Color
Màu của material, mặc định là màu trắng.
 .fog : boolean
Thuộc tính xác định material có bị ảnh hưởng bởi sương mù hay không
 .lights : boolean
Thuộc tính xác định material có ảnh hưởng bởi ảnh sáng hay không
 .map : texture
Thuộc tính xác định texture được ánh xạ
 .sizeAttenuation : boolean
Thuộc tính xác định độ lớn của sprite có bị ảnh hưởng bởi khoảng cách so với
camera hay không.
Ảnh bên trái là Sprite với SpriteMaterial mặc định, chúng ta có thể truyển ảnh vào Sprite
bằng cách map SpriteMaterial với một texture.

2. PointCloud
Với THREE.Sprite ta có thể dễ dàng tạo các đối tượng và di chuyển chúng trong scene.
Nhưng ta sẻ gặp vấn đề liên quan đến hiệu năng với số lượng sprite lớn. Vì thế nên
three.js còn cung cấp lớp THREE.PointCloud để quản lý tập hợp các particle.

THREE.PointCloud( geometry : Geometry, material : Material )


 geometry – geometry của một particle trong pointcloud
 material – material ứng với mỗi particle trong pointcloud
THREE.PointCloundMaterial là material mặc định và khuyên dùng cho PointCloud
Đoạn code sau sẽ tạo ra tập hợp 100 điểm để tạo thành một THREE.PointCloud.
PointCloudMaterial( parameters : Object )
parameters - thuộc tính xác định hình dáng của material, gồm các thuộc tính sau.
 .color : Color
Màu của material, mặc định là màu trắng.
 .map : Texture
Map material với một texture.
 .size : Number
Độ lớn của một particle.
 .sizeAttenuation : boolean
Thuộc tính xác định độ lớn của sprite có bị ảnh hưởng bởi khoảng cách so với
camera hay không.
Hình sau là hình PointCloud được tạo từ số lượng lớn particle và mỗi particle sẽ dùng
material hình hoa tuyết.

3. Creating THREE.PointCloud from an advanced geometry


Chúng ta có thể tạo một PointCloud dựa trên một gemoetry phức tạp, ở phần trước ta đã
tìm hiểu về TorusGeometry, phần này thay vì tạo một Torus thông thường ta sẽ tạo một
PointCloud có hình dạng Torus.
Đầu tiên ta sẽ tạo một Sprite từ hình này
Sau đó chúng ta tạo PointClound từ hình dạng ta muốn thêm vào hình
Và ta có sản phẩm

8. Tạo và load Mesh và Geometrie nâng cao

1. Gom nhóm và nhập geometry


Trong phần này, chúng ta sẽ xem xét hai tính năng cơ bản của Three.js: gom nhóm
các objects lại với nhau và hợp nhất nhiều mesh thành một mesh duy nhất. Chúng ta
bắt đầu với việc gom nhóm các objects.
Gom nhóm geometry object
- Khi bạn tạo mesh từ geometries bằng nhiều vật liệu, Three.js tạo một nhóm. Nhiều
bản sao geometries được thêm vào nhóm này, mỗi bản sao với vật liệu cụ thể của
riêng nó. Nhóm này được trả lại, vì vậy nó trông giống như một mesh sử dụng
nhiều vật liệu. Trong thực tế, nhóm này chứa số lượng của một số mesh.
- Tạo nhóm rất dễ dàng. Mỗi lưới bạn có thể tạo để chứa các phần tử con, có thể
được thêm bằng cách sử dụng chức năng thêm. Tác dụng của việc thêm một đối
tượng con vào nhóm là bạn có thể di chuyển, chia tỷ lệ, xoay và dịch đối tượng
cha và tất cả đối tượng con cũng sẽ bị ảnh hưởng. Ảnh chụp màn hình sau đây cho
thấy ví dụ này:

- Trong ví dụ này, bạn có thể sử dụng menu để di chuyển hình cầu và khối lập
phương xung quanh. Nếu kiểm tra tùy chọn xoay, bạn sẽ thấy hai mắt lưới này
xoay quanh tâm của chúng. Tuy nhiên, hai đối tượng này chưa được thêm vào
scene trực tiếp, nhưng đã được thêm vào như một nhóm.
sphere = createMesh(new THREE.SphereGeometry(5, 10, 10));
cube = createMesh(new THREE.BoxGeometry(6, 6, 6));
group = new THREE.Object3D();
group.add(sphere);
group.add(cube);
scene.add(group);
- Trong đoạn code này, chúng ta đã tạo THREE.Object3D. Đây là cơ sở lớp của
THREE.Mesh và THREE.Scene, nhưng bản thân nó không chứa bất cứ thứ gì
hoặc gây ra bất cứ điều gì được đưa ra. Lưu ý rằng trong phiên bản mới nhất của
Three.js, một đối tượng mới gọi là THREE.Group được giới thiệu để hỗ trợ nhóm.
Đối tượng này chính xác là giống như một đối tượng THREE.Object3D và bạn có
thể thay thế THREE.Object3D () trong mã trước đó với THREE.group () cho cùng
hiệu ứng. Trong ví dụ này, sử dụng hàm add để thêm hình cầu và khối lập phương
vào đối tượng này và sau đó chúng ta thêm nó vào scene. Nếu bạn nhìn vào ví dụ,
bạn vẫn có thể di chuyển khối lập phương và khối cầu xung quanh và chia tỉ lệ và
xoay hai đối tượng này. Bạn cũng có thể làm những điều này trong nhóm. Nếu bạn
nhìn vào menu nhóm, bạn sẽ thấy các tùy chọn vị trí và tỷ lệ. Bạn có thể sử dụng
chúng để mở rộng tỉ lệ và di chuyển toàn bộ nhóm xung quanh. Tỉ lệ và vị trí của
các đối tượng trong nhóm này có liên quan đến tỉ lệ và vị trí của chính nhóm đó.
- Tỉ lệ và vị trí rất đơn giản. Chungs ta cần nhớ, mặc dù khi bạn xoay một nhóm, nó
không xoay các đối tượng bên trong nó một cách riêng biệt; nó xoay toàn bộ nhóm
quanh trung tâm của nó (trong ví dụ, bạn xoay toàn bộ nhóm xung quanh trung
tâm của đối tượng nhóm). Trong ví dụ này, chúng tôi đã đặt một mũi tên sử dụng
đối tượng THREE.ArrowHelper ở trung tâm của nhóm để chỉ ra điểm quay:
var arrow = new THREE.ArrowHelper(new THREE.Vector3(0, 1, 0),
group.position, 10, 0x0000ff);
scene.add(arrow);
- Nếu bạn kiểm tra cả hai hộp grouping and rotate , group sẽ xoay. Bạn sẽ nhìn
thấy hình cầu và khối lập phương xoay quanh tâm của nhóm (được biểu thị bằng
mũi tên), như sau:
- Khi sử dụng group, bạn vẫn có thể tham khảo, sửa đổi và định vị trí individual
geometries. Điều duy nhất bạn cần nhớ là tất cả các vị trí, góc quay, và bản dịch
được thực hiện liên quan đến đối tượng cha. Trong phần tiếp theo, chúng ta sẽ xem
xét khi hợp nhất, nơi bạn sẽ kết hợp nhiều geometries riêng biệt và kết thúc bằng
một THREE.Geometry object.
Nhập nhiều mesh thành một mesh

Trong hầu hết các trường hợp, sử dụng groups cho phép bạn dễ dàng thao tác và
quản lý số lượng lớn meshes. Khi bạn xử lý số lượng lớn objects, hiệu suất sẽ trở
thành một vấn đề. Với groups, bạn vẫn làm việc với các đối tượng riêng lẻ mà mỗi đối
tượng cần được xử lý và hiển thị riêng biệt. Với THREE.Geometry.merge (), bạn có
thể merge geometries với nhau và tạo ra một kết hợp. Trong ví dụ sau, bạn có thể thấy
cách thức này hoạt động và hiệu suất cuả nó. Nếu bạn mở ví dụ 02-merging.html, bạn
sẽ thấy một scene với một tập hợp các khối bán trong suốt được phân phối ngẫu
nhiên. Với thanh trượt trong menu, bạn có thể đặt số lượng hình khối bạn muốn trong
scene và vẽ lại scene bằng cách nhấp vào nút vẽ lại. Tùy thuộc vào phần cứng bạn
đang chạy, bạn sẽ thấy sự suy giảm hiệu suất khi số lượng hình khối tăng lên. Trong
trường hợp của chúng ta, như bạn có thể thấy trong ảnh chụp màn hình sau, điều này
xảy ra ở khoảng 4.000 đối tượng, trong đó tốc độ làm mới giảm xuống khoảng 40fps
thay vì 60fps thông thường:
- Như bạn có thể thấy, có một giới hạn nhất định đối với số lượng lưới bạn có thể
thêm vào scene. Thông thường, bạn có thể sẽ không cần nhiều lưới, nhưng khi tạo
các trò chơi cụ thể (ví dụ: một cái gì đó như Minecraft) hoặc nâng cao Trực quan
hóa, bạn có thể cần phải quản lý một số lượng lớn các lưới riêng lẻ. Với
THREE.Geometry.merge(),bạn có thể giải quyết vấn đề này. Trước khi chúng ta
xem code, Hãy chạy ví dụ tương tự, nhưng lần này, với combine box checked.
Với option flagged, chúng ta hợp nhất tất cả các hình khối thành một
THREE.Geometry và thêm vào đó một hình khối để thay thế, như màn hình sau:

- Như bạn có thể thấy, chúng ta có thể dễ dàng render 20.000 khối mà không làm
giảm hiệu suất. Để làm điều này, chúng ta sử dụng một vài dòng mã sau đây:
var geometry = new THREE.Geometry();
for (var i = 0; i < controls.numberOfObjects; i++) {
var cubeMesh = addcube();
cubeMesh.updateMatrix();
geometry.merge(cubeMesh.geometry,cubeMesh.matrix);
}
scene.add(new THREE.Mesh(geometry, cubeMaterial));
- Trong đoạn mã này, hàm addCube () trả về THREE.Mesh. Ở các phiên bản cũ hơn
trong Three.js, chúng ta có thể sử dụng hàm THREE.GeometryUtils.merge để hợp
nhất objects THREE.Mesh vào THREE.Geometry function. Với phiên bản mới
nhất, function này đã bị phản đối vì function THREE.Geometry.merge. Để đảm
bảo merged-in THREE.Geometry object được định vị và xoay một cách chính xác,
chúng ta không chỉ cung cấp THREE.Geometry cho merge function, mà còn vì ma
trận biến đổi. Khi chúng ta thêm ma trận này vào hàm hợp nhất, khối lập phương
chúng ta hợp nhất sẽ được định vị chính xác.
- Chúng tôi làm điều này 20.000 lần và chỉ còn lại một geometries mà chúng tôi
thêm vào scene. Nếu nhìn vào mã code, có lẽ bạn sẽ thấy một vài nhược điểm của
phương pháp này. Vì còn lại một geometries duy nhất, bạn không thể áp dụng một
tài liệu cho từng khối lập phương. Điều này, có thể được giải quyết phần nào bằng
cách sử dụng THREE.MeshFaceMaterial. Tuy nhiên, nhược điểm lớn nhất là bạn
mất kiểm soát đối với các hình khối riêng lẻ. Nếu bạn muốn di chuyển, xoay hoặc
chia tỷ lệ một khối thì bạn không thể (trừ khi bạn tìm kiếm mặt chính xác, đỉnh và
định vị chúng riêng lẻ).
- Với cách tiếp cận nhóm và hợp nhất, bạn có thể tạo ra geometries lớn và phức tạp
bằng cách sử dụng các geometries cơ bản được cung cấp bởi Three.js. Nếu bạn
muốn tạo geometries tiên tiến hơn, sau đó sử dụng phương pháp lập trình được
cung cấp bởi Three.js không phải lúc nào cũng là lựa chọn tốt nhất và dễ nhất.
Three.js, may mắn là nó cung cấp một vài các tùy chọn khác để tạo geometries.
Trong phần tiếp theo, chúng ta sẽ xem cách có thể load geometries và lưới từ các
nguồn bên ngoài.
2. Load geometry từ resource ngoài

Three.js có thể đọc một số file định dạng 3D và import geometries and meshes
trong những files đó. Bảng sau đây cho thấy các định dạng fle được hỗ trợ
bởi Three.js:
Lưu và load Three.js với format JSON
Bạn có thể sử dụng định dạng JSON của Three.js cho hai kịch bản khác nhau
trong Three.js. Có thể sử dụng nó để lưu và load một THREE.Mesh hoặc sử dụng
nó để lưu và load complete scene.
a. Lưu và load THREE.Mesh
 Kịch bản Để thể hiện việc lưu và load, một ví dụ đơn giản dựa trên
THREE.TorusKnotGeometry. Với ví dụ này, bạn có thể tạo một nút hình
xuyến, giống như chúng ta đã làm trong Chapter 5, Learning to Work with
Geometries và sử dụng nút save từ Menu Save & Load, bạn có thể lưu hình
học hiện tại. Ví dụ này, chúng ta lưu sử dụng API lưu trữ cục bộ HTML5. API
này cho phép chúng ta dễ dàng lưu trữ liên tục thông tin trong trình duyệt của
khách hàng và truy xuất nó sau đó (ngay cả sau khi trình duyệt đã bị tắt và khởi
động lại).
 Chúng ta xem ví dụ 03-load-save-json-object.html.
 Exporting JSON từ Three.js rất dễ dàng và không yêu cầu phải có bất kỳ thư
viện bổ sung nào. Điều duy nhất bạn cần làm để xuất THREE.Mesh Ở dạng
JSON là như sau:
 var result = knot.toJSON();
localStorage.setItem("json", JSON.stringify(result));
 Trước khi lưu, chúng ta sẽ chuyển đổi kết quả từ hàm toJSON, JavaScript
object, đến một chuỗi bằng cách sử dụng hàm JSON.opesify. Điều này dẫn đến
một chuỗi JSON trông giống như thế này (hầu hết các đỉnh và mặt đều bị bỏ
lại):

{
"metadata": {
"version": 4.3,
"type": "Object",
"generator": "ObjectExporter"
},
"geometries": [{
"uuid": "53E1B290-3EF3-4574-BD68-E65DFC618BA7",
"type": "TorusKnotGeometry",
"radius": 10,
"tube": 1,
"radialSegments": 64,
"tubularSegments": 8,
"p": 2,
"q": 3,
"heightScale": 1
}],
...
}
 Như bạn có thể thấy, Three.js lưu tất cả thông tin về THREE.Mesh. Để lưu
thông tin này sử dụng HTML5 local storage API, tất cả những gì chúng ta phải
làm là gọi hàm localStorage.setItem. Đối số đầu tiên là key value (json) mà sau
này chúng ta có thể sử dụng để lấy thông tin đã truyền vào làm đối số thứ hai.
 Load THREE.Mesh back into Three.js cũng chỉ cần một vài dòng mã, như sau:
var json = localStorage.getItem("json");
if (json) {
var loadedGeometry = JSON.parse(json);
var loader = new THREE.ObjectLoader();
loadedMesh = loader.parse(loadedGeometry);
loadedMesh.position.x -= 50;
scene.add(loadedMesh);
}
 Ở đây, chúng ta sẽ nhận JSON từ bộ nhớ cục bộ bằng cách sử dụng tên mà
chúng ta đã lưu(json trong trường hợp này). Đối với điều này, chúng ta sử
dụng hàm localStorage.getItem được cung cấp bởi API lưu trữ cục bộ HTML5.
Tiếp theo, chúng ta cần chuyển đổi chuỗi trở lại thành JavaScript object
(JSON.parse) và chuyển đổi JSON object trở lại THREE.Mesh. Three.js cung
cấp helper object có tên THREE.ObjectLoader, mà bạn có thể sử dụng để
chuyển đổi JSON đến THREE.Mesh. Trong ví dụ này, chúng ta sử dụng parse
method trên trình load để phân tích trực tiếp một chuỗi JSON. Trình load về
cũng cung cấp một hàm load, trong đó bạn có thể chuyển URL sang một tệp có
chứa định nghĩa JSON.
 Như bạn có thể thấy, chúng ta chỉ lưu THREE.Mesh. Nếu bạn muốn lưu scene
hoàn chỉnh, bao gồm đèn và máy ảnh, bạn có thể sử dụng
THREE.SceneExporter
b. Lưu và load một scene
Nếu bạn muốn lưu complete scene, bạn sử dụng cách tiếp cận giống như chúng
ta đã thấy trong phần trước cho geometry.
 Trong ví dụ này, bạn có ba tùy chọn: exportScene, clearScene và importscene.
Với exportScene, trạng thái hiện tại của scene sẽ được lưu trong bộ nhớ cục bộ
của trình duyệt. Để kiểm tra import function, bạn có thể xóa scene bằng cách
nhấp vào nút ClearScene và load nó từ bộ nhớ cục bộ với nút importscene.
Code làm tất cả điều này rất đơn giản, nhưng trước khi bạn có thể sử dụng nó,
bạn phải import trình xuất và trình load yêu cầu từ bản phân phối Three.js
(look at the examples/js/exporters and examples/js/loaders directories):
 <script type="text/javascript" src="../libs/SceneLoader.js">
</script>
<script type="text/javascript" src="../libs/SceneExporter.js">
</script>
 Với các cách import JavaScript trong trang, bạn có thể xuất scene với mã sau:
 var exporter = new THREE.SceneExporter();
var sceneJson = JSON.stringify(exporter.parse(scene));
localStorage.setItem('scene', sceneJson);
 Cách tiếp cận này hoàn toàn giống như cách chúng ta đã sử dụng trong phần
trước, chỉ có lần này, chúng ta sử dụng THREE.SceneExporter () để export
scene hoàn chỉnh. kết quả JSON trông như thế này:
{
"metadata": {
"formatVersion": 3.2,
"type": "scene",
"generatedBy": "SceneExporter",
"objects": 5,
"geometries": 3,
"materials": 3,
"textures": 0
},
"urlBaseType": "relativeToScene", "objects": {
"Object_78B22F27-C5D8-46BF-A539-A42207DDDCA8": {
"geometry": "Geometry_5",
"material": "Material_1",
"position": [15, 0, 0],
"rotation": [-1.5707963267948966, 0, 0],
"scale": [1, 1, 1],
"visible": true
}
... // removed all the other objects for legibility
},
"geometries": {
"Geometry_8235FC68-64F0-45E9-917F-5981B082D5BC": {
"type": "cube",
"width": 4,
"height": 4,
"depth": 4,
"widthSegments": 1,
"heightSegments": 1,
"depthSegments": 1
}
... // removed all the other objects for legibility
}
... other scene information like textures
 Khi bạn load lại JSON này, Three.js chỉ tạo lại các đối tượng chính xác như chúng
đã được export. Loading a scene được thực hiện như thế này:
 var json = (localStorage.getItem('scene'));
var sceneLoader = new THREE.SceneLoader();
sceneLoader.parse(JSON.parse(json), function(e) {
scene = e.scene;
}, '.');
 Đối số cuối cùng được truyền vào trình load ('.') làm sai URL tương đối. Ví dụ,
nếu bạn có materials sử dụng textures(ví dụ: ảnh bên ngoài), chúng sẽ lấy ra bằng
URL tương đối này. Trong ví dụ này, chúng ta không sử dụng textures, Chỉ cần
pass tới thư mục hiện tại. Giống như với THREE.ObjectLoader, bạn cũng có thể
load một JSON chạy từ một URL bằng cách sử dụng chức năng load.
 Có nhiều chương trình 3D khác nhau mà bạn có thể sử dụng để tạo các lưới phức
tạp. Một mã nguồn mở phổ biến là Blender (www.blender.org). Three.js có thể
export cho Blender (và cho Maya và 3D Studio Max) xuất trực tiếp sang định dạng
JSON của Three.js. Trong phần tiếp theo, sẽ hướng dẫn bạn cách để Blender được
giới thiệu sử dụng trình xuất này và chỉ cho bạn cách bạn có thể xuất một model
phức tạp trong Blender và hiển thị nó trong Three.js.
Làm việc với Blender
Trước khi bắt đầu với configuration, chúng ta sẽ hiển thị kết quả rằng chúng tôi sẽ
hướng tới mục đích. Trong ảnh chụp màn hình sau, bạn có thể thấy một model
Blender đơn giản được export với plugin Three.js và được import trong Three.js với
THREE.JSONLoader:

\
a. Cài đặt the Three.js exporter trong Blender
 Để có được Blender để xuất các model Three.js, trước tiên chúng ta cần thêm
trình xuất Three.js to Blender. Các bước sau đây dành cho Mac OS X nhưng
khá giống nhau trên Windows và Linux. Bạn có thể load xuống Blender từ
www.blender.org và làm theo các hướng dẫn cài đặt flatform-specifc. Sau khi
cài đặt, bạn có thể thêm Plugin Three.js. Đầu tiên, định vị thư mục addons từ
bản cài đặt Blender của bạn sử dụng cửa sổ terminal:

 Tiếp theo, bạn cần lấy bản distribution Three.js và giải nén nó. Trong bản này,
bạn có thể tìm tới thư mục sau: utils / export / blender / 2.65 / scripts / addons /.
Trong thư mục này, có một thư mục con duy nhất có tên io_ mesh_threejs. Sao
chép thư mục này vào thư mục addons của bản cài đặt Blender.
 Bây giờ, tất cả những gì chúng ta cần làm là khởi động Blender và kích hoạt
trình xuất. Trong Blender, mở Blender User Preferences (File | User
Preferences). Trong cửa sổ mở, chọn tab Addons và trong hộp tìm kiếm, nhập
three. Màn hình sẽ xuất hiện:
 Ở đây, plugin Three.js được tìm thấy, nhưng nó vẫn bị vô hiệu hóa. Kiểm tra
small checkbox bên phải và Three.js exporter sẽ được bật. Kiểm tra cuối cùng
để xem mọi thứ có hoạt động chính xác không, mở File | Export menu option,
sẽ thấy Three.js được liệt kê dưới dạng tùy chọn xuất.

 Với plugin được cài đặt, chúng ta có thể load model đầu tiên.
b. Load và xuất một model từ Blender
 Như ví dụ, chúng ta đã thêm một model Blender đơn giản có tên
misc_ouch01.blend trong thư mục assets/models , bạn có thể tìm thấy trong các
nguồn cho cuốn sách này. Trong Phần này, chúng ta sẽ load xuống model này
và hiển thị các bước tối thiểu cần thiết để xuất model này thành Three.js.
 Đầu tiên, chúng ta cần load model này trong Blender. Sử dụng File | Open và
điều hướng đến thư mục chứa misc_ouch01.blend file. Chọn file này và click
Open. Một màn hình trông giống như thế này:
 Việc xuất model này sang định dạng Three.js JSON khá đơn giản. Từ File
menu, open Export | Three.js, nhập tên của file export và chọn Export Three.js.
Điều này sẽ tạo ra một file JSON được hiểu theo định dạng Three.js. Một phần
nội dung của contents này được hiển thị:
{
"metadata" :
{
"formatVersion" : 3.1,
"generatedBy" : "Blender 2.7 Exporter",
"vertices" : 208,
"faces" : 124,
"normals" : 115,
"colors" : 0, "uvs" : [270,151],
"materials" : 1,
"morphTargets" : 0,
"bones" : 0
},
...
 Material này xác định texture, misc_ouch01_col.jpg, for mapDiffuse property.
Vì vậy, bên cạnh việc xuất model , chúng ta cũng cần đảm bảo texture file
cũng có sẵn cho Three.js. May mắn thay, chúng ta có thể lưu texture này trực
tiếp từ Blender.
 Trong Blender, mở chế độ xem UV / Image Editor. Bạn có thể chọn chế độ
xem này từ menu the dropdown.

 Đảm bảo texture bạn muốn xuất được chọn, misc_ouch_01_col.jpg (bạn có thể
chọn một trường hợp khác bằng biểu tượng hình ảnh nhỏ). Tiếp theo, nhấp vào
Menu Image và sử dụng tùy chọn menu Save as Image để lưu hình ảnh. Lưu nó
trong cùng thư mục nơi bạn đã lưu model bằng cách sử dụng tên được chỉ định
trong JSON export file. Chúng ta sẽ load model vào Three.js.
 Đoạn code để load model này vào Three.js:
var loader = new THREE.JSONLoader();
loader.load('../assets/models/misc_chair01.js', function (geometry,
mat) {
mesh = new THREE.Mesh(geometry, mat[0]);
mesh.scale.x = 15;
mesh.scale.y = 15;
mesh.scale.z = 15;
scene.add(mesh);
}, '../assets/models/');
 Chúng ta đã thấy JSONLoader trước đây, nhưng lần này, chúng ta sử dụng
hàm load thay vì hàm parse. Trong chức năng này,chúng ta chỉ định URL
muốn load (trỏ đến tệp JSON đã xuất), mọt cáo callback được gọi khi đối
tượng được load, và location, ../assets/models/, nơi có thể tìm thấy texture (liên
quan đến trang). Callback này có hai tham số: geometry và mat. Tham số
geometry chứa model và tham số mat chứa một mảng vật liệu các đối tượng.
Chúng ta biết rằng chỉ có một material, vì vậy khi tạo ra THREE.MESH.
chúng trực tiếp tham khảo material đó.
 Sử dụng Three.js exporter không phải là cách duy nhất để load các model từ
Blender vào Three.js. Three.js hiểu một số định dạng file 3D và Blender có thể
xuất trong một vài định dạng Tuy nhiên, sử dụng định dạng Three.js rất dễ
dàng và nếu mọi thứ đi sai, chúng thường được tìm thấy nhanh chóng.
 Trong phần sau, chúng ta sẽ xem xét một vài định dạng mà Three.js hỗ trợ và
cũng hiển thị một ví dụ dựa trên Blender cho các định dạng OBJ và MTL.

Nhập từ format file 3D

Ở đầu chương này, chúng ta đã liệt kê một số định dạng được hỗ trợ
bởi Three.js. Trong phần này, chúng ta sẽ nhanh chóng đi qua một vài ví dụ cho
những định dạng đó. Lưu ý rằng đối với tất cả các định dạng này, cần phải có một
JavaScript bổ sung. Bạn có thể find tất cả các files này trong bản phân phối
Three.js trong các example/js/thư mục loaders.
a. The OBJ and MTL formats
 OBJ và MTL là các định dạng đồng hành và thường được sử dụng cùng nhau.
File OBJ định nghĩa geometry và file MTL định nghĩa cho material được sử
dụng. Cả OBJ và MTL là các định dạng dựa trên văn bản. Một phần của OBJ
file trông như thế này:
v -0.032442 0.010796 0.025935
v -0.028519 0.013697 0.026201
v -0.029086 0.014533 0.021409
usemtl Material
s1
f 2731 2735 2736 2732
f 2732 2736 3043 3044
 MTL file định nghĩa materials:
newmtl Material
Ns 56.862745
Ka 0.000000 0.000000 0.000000
Kd 0.360725 0.227524 0.127497
Ks 0.010000 0.010000 0.010000
Ni 1.000000
d 1.000000
illum 2
 Các định dạng OBJ và MTL của Three.js được hiểu rõ và cũng được hỗ trợ
bằng Blender. Vì vậy, để thay thế, bạn có thể chọn xuất các model từ Blender
trong định dạng OBJ / MTL thay vì định dạng Three.js JSON. Three.js có hai
bộ load khác nhau bạn có thể sử dụng. Nếu bạn chỉ muốn load geometry, bạn
có thể sử dụng OBJLoader. Chúng ta đã sử dụng trình load này cho ví dụ của
mình.

 Để import cái này vào Three.js, bạn phải thêm JavaScript OBJLoader:
<script type="text/javascript" src="../libs/OBJLoader.js">
</script>
 Import model:
var loader = new THREE.OBJLoader();
loader.load('../assets/models/pinecone.obj', function (loadedMesh) {
var material = new THREE.MeshLambertMaterial({color: 0x5C3A21});
// loadedMesh is a group of meshes. For
// each mesh set the material, and compute the information
// three.js needs for rendering.
loadedMesh.children.forEach(function (child) {
child.material = material;
child.geometry.computeFaceNormals();
child.geometry.computeVertexNormals();
});
mesh = loadedMesh;
loadedMesh.scale.set(100, 100, 100);
loadedMesh.rotation.x = -0.3;
scene.add(loadedMesh);
});
 Trong đoạn code này, chúng ta sử dụng OBJLoader để tải mô hình từ một
URL. Một khi mô hình là đã tải, callback mà chúng ta cung cấp được gọi và
thêm mô hình vào scene.
 Ví dụ tiếp theo (07-load-obj-mtl.html) sử dụng OBJMTLLoader để tải một mô
hình và trực tiếp assign material.

 Đầu tiên, chúng ta cần thêm bộ correct loaders vào page:


<script type="text/javascript" src="../libs/OBJLoader.js">
</script>
<script type="text/javascript" src="../libs/MTLLoader.js">
</script>
<script type="text/javascript" src="../libs/OBJMTLLoader.js">
</script>
 Chúng ta có thể load model từ OBJ và MTL files:
var loader = new THREE.OBJMTLLoader();
loader.load('../assets/models/butterfly.obj', '../assets/
models/butterfly.mtl', function(object) {
// configure the wings
var wing2 = object.children[5].children[0];
var wing1 = object.children[4].children[0];
wing1.material.opacity = 0.6;
wing1.material.transparent = true;
wing1.material.depthTest = false;
wing1.material.side = THREE.DoubleSide;
wing2.material.opacity = 0.6;
wing2.material.depthTest = false;
wing2.material.transparent = true;
wing2.material.side = THREE.DoubleSide;
object.scale.set(140, 140, 140);
mesh = object;
scene.add(mesh);
mesh.rotation.x = 0.2;
mesh.rotation.y = -1.3;
});
 Điều đầu tiên cần đề cập trước khi xem code là nếu bạn nhận được OBJ file,
một MTL file và các files texture cần thiết, bạn sẽ phải kiểm tra MTL file liên
quan như thế nào đến texture. Chúng nên được tham chiếu đến MTL file và
không phải là đường link tuyệt đối. Bản thân code không khác với cách mà
chúng ta đã thấy trong Three. ObjLoader . Chúng ta chỉ định vị trí của OBJ fle,
vị trí của MTL fle và chức năng gọi khi mô hình được load. Mô hình chúng ta
sử dụng làm ví dụ trong trường hợp này là một mô hình phức tạp. Vì vậy,
chúng ta đặt một số thuộc tính cụ thể trong callback để fix một số vấn đề
rendering, như sau:
 Độ mờ trong các tệp nguồn được đặt không chính xác. Vì vậy, để khắc
phục điều đó, chúng ta đặt thuộc tính độ mờ và độ trong suốt.
 Theo mặc định, Three.js chỉ hiển thị một mặt của đối tượng. Vì chúng ta
nhìn vào cánh từ hai phía, chúng ta cần đặt thuộc tính bên là
Three.DoubleSide value.
 Đôi cánh gây ra một số đồ tạo tác không mong muốn khi chúng cần
được render chồng lên nhau. Chúng ta sửa lỗi đó bằng cách đặt thuộc
tính heightTest thành false. Điều này có tác động nhẹ đến hiệu suất
nhưng thường có thể giải quyết một số tạo tác.
 Nhưng, như bạn có thể thấy, bạn có thể dễ dàng load các mô hình phức tạp trực
tiếp vào Three.js và render chúng trong thời gian thực trong trình duyệt của
bạn. Bạn có thể cần phải điều chỉnh một số thuộc tính của material.
b. Load một Collada model
 Các mô hình Collada (phần mở rộng là .dae) là một định dạng rất phổ biến
để định nghĩa scene và model (và animations, như chúng ta sẽ thấy trong
chương sau). Trong một model Collada, nó không chỉ là geometry được
định nghĩa, mà còn là material. nó thậm chí có thể làm mờ các nguồn
sáng.
 Để tải các mô hình Collada, bạn phải thực hiện khá nhiều bước tương tự
như đối với OBJ và các mô hình MTL. Bắt đầu bằng cách including
correct loader:
<script type="text/javascript" src="../libs/ColladaLoader.js">
</script>
 Trong ví dụ này, chúng ta sẽ tải mô hình sau:

 Nó khá đơn giản:

var mesh;
loader.load("../assets/models/dae/Truck_dae.dae", function
(result) {
mesh = result.scene.children[0].children[0].clone();
mesh.scale.set(4, 4, 4);
scene.add(mesh);
});
 Sự khác biệt chính ở đây là kết quả của đối tượng được trả về
callback . Kết quả object có cấu trúc sau:
var result = {
scene: scene,
morphs: morphs,
skins: skins,
animations: animData,
dae: {
...
}
};
 Như bạn có thể thấy, đối với hầu hết các mô hình phức tạp, bao gồm
cả material, bạn thường phải thực hiện một số bước bổ sung để có
được kết quả mong muốn. Bằng cách nhìn kỹ vào các tài liệu được
xác nhận (sử dụng console.log ()) hoặc thay thế chúng bằng test
material, vấn đề thường dễ dàng nhận ra.
c. Load STL, CTM, VTK, AWD, Assimp, VRML và Babylon models
 Chúng ta sẽ nhanh chóng lướt qua các định dạng này vì tất cả chúng
đều theo cùng một Nguyên tắc:
1. including [NameOfFormat] Loader.js trong trang web của bạn.
2. use [NameOfFormat] Loader.load () để tải URL.
3. Kiểm tra định dạng phản hồi cho callback trông như thế nào và
render kết quả.
 Chúng ta đã include một ví dụ cho tất cả các định dạng này:
 Nếu bạn xem mã nguồn cho các ví dụ này, bạn có thể thấy rằng đối
với một số, chúng ta cần thay đổi một số thuộc tính material hoặc
thực hiện một số tỷ lệ trước khi model được hiển thị chính xác. Lý
do chúng ta cần làm điều này là vì cách mô hình được tạo ra trong
ứng dụng bên ngoài của nó, mang lại cho nó các kích thước khác
nhau và grouping hơn chúng ta thường sử dụng trong Three.js.

Kế hoạch cho tuần tiếp theo


Tìm hiểu về Animation cơ bản trong three.js
Nội dung báo cáo tuần 5
- Tìm hiểu về các geometry cơ bản
- Tìm hiểu về các geometry nâng cáo và cách tạo geometry mới bằng binary
operation.
9. Geometry cơ bản
Three.js cung cấp cho ta nhiều geometry, đầu tiên ta sẽ tìm hiểu về các geometry cơ bản.
Geometry cơ bản được chia làm 2 loại: 2 chiều và 3 chiều.
1. Two-dimensional geometries
THREE.PlaneGeometry
PlaneGeometry dùng để tạo object có hình dạng mặt phẳng hình chữ nhật.

THREE.PlaneGeometry (width : Float, height : Float, widthSegments : Integer,


heightSegments : Integer)
 width: Chiều rộng của mặt phẳng. Giá trị mặt định là 1.
 height: Chiều dài của mặt phẳng. Giá trị mặt định là 1.
 widthSegments – Số phần được chia theo chiều rộng của mặt phẳng.
 heightSegments - widthSegments – Số phần được chia theo chiều rộng của mặt
phẳng.

THREE.CircleGeometry
Dùng để tạo mặt phẳng có hình tròn, hình này được tạo bởi nhiều hình tam giác cùng
hướng về tâm.
THREE.CircleGeometry(radius : Float, segments : Integer, thetaStart : Float,
thetaLength : Float)
 radius - bán kính của hình tròn
 segments - Số mặt phẳng tam giác dùng để tạo hình tròn.
 thetaStart - Góc bắt đầu để vẻ hình tròn
 thetaLength – Giá trị xác định bao nhiêu phần của hình tròn có thể được nhìn thấy.
(giá trị từ 0 – 2PI)

THREE.RingGeometry
Dùng để tạo một hình vòng.
RingGeometry có các thuộc tính khá giống với Circle geometry
THREE.RingGeometry(innerRadius : Float, outerRadius : Float,
thetaSegments : Integer, phiSegments : Integer, thetaStart : Float, thetaLength : Float)
 innerRadius – Xác định bán kính của hình tròn bên trong vòng được tạo.
 outerRadius – Xác định khoảng cách từ tâm vòng đến phía ngoài.
 thetaSegments – xác định số phần tạo thành phía ngoài vòng tròn, chỉ số này càng
lớn vòng tròn sẽ càng tròn.
 phiSegments – xác định số mặt tạo thành bề mặt của vòng.
 thetaStart – góc bắt đầu của vòng tròn.
 thetaLength – chỉ số xác định độ mở của vòng tròn.
THREE.ShapeGeometry
Dùng để tạo hình dạng tùy chỉnh dựa trên tập hợp các hình được truyền vào.
THREE.ShapeGeometry(shapes : Array, curveSegments : Integer)
 shapes – chuỗi các hình ảnh kiểu THREE.Shape.
 curveSegments – số lượng segment mỗi hình.
Trước khi tạo một ShapeGeometry chúng ta phải có các Shape. Ví dụ với hình trên ta tạo
như sau.

2. Three-dimensional geometries
THREE.BoxGeometry
Dùng để tạo một hình hộp đơn giản dựa vào chiều rộng, chiều dài, chiều sâu.
THRRE.BoxGeometry(width : Float, height : Float, depth : Float,
widthSegments : Integer, heightSegments : Integer, depthSegments : Integer)
 width – rộng, song song với trục x.
 height – chiều dài, song song với trục y.
 depth – chiều sâu, song song với trục z.
 widthSegments/heightSegments/depthSegments – số segment để tạo thành các mặt
phẳng tương ứng.

THREE.SphereGeometry
Dùng để tạo geometry có dạng hình cầu.
THREE.SphereGeometry(radius : Float, widthSegments : Integer,
heightSegments : Integer, phiStart : Float, phiLength : Float, thetaStart : Float,
thetaLength : Float)
 Radius – bán kính của hình cầu.
 widthSegments – số lượng segment theo chiều ngang.
 heightSegments – số lượng segment theo chiều dọc.
 phiStart – xác định góc bắt đầu theo chiều ngang của hình cầu.
 phiLength – xác định góc độ mở theo chiều ngang của hình cầu.
 thetaStart – xác định góc bắt đầu theo chiều dọc của hình cầu.
 thetaLength – xác định góc độ mở theo chiều dọc của hình cầu.

THREE.CylinderGeometry (Hình trụ)


Dùng để tạo hình có dạng hình trụ.
THREE.CylinderGeometry(radiusTop : Float, radiusBottom : Float, height : Float,
radialSegments : Integer, heightSegments : Integer, openEnded : Boolean,
thetaStart : Float, thetaLength : Float)
 radiusTop - bán kính của mặt trên hình trụ.
 radiusBottom – bán kình mặt dưới hình trụ.
 Height – khoảng cách giữa 2 mặt hình trụ.
 radialSegments – số segment tạo quanh hình trụ theo chiều ngang, chỉ số này càng
lớn hình trụ càng tròn.
heightSegments – số segment tạo quanh hình trụ theo chiều dọc.
 openEnded – giá trị boolean xác định hai mặt của hình trụ có đóng hay không.
 thetaStart – góc bắt đầu của hình trụ.
 thetaLength – góc độ mở rộng của hình trụ.
Chú ý: khi bán kính của mặt trên và mặt dưới trái dấu sẽ tạo thành hình dạng giống đồng
hồ cát.

THREE.TorusGeometry
Dùng để tạo hình có dạng torus.
THREE.TorusGeometry(radius : Float, tube : Float, radialSegments : Integer,
tubularSegments : Integer, arc : Float)
 radius – khoảng cách tính từ tâm tròn ở giữa đến giữa các ống của torus.
 tube – bán kính của các ống.
 radialSegments – xác định số segment được dùng dọc theo chiều dài các ống.
 tubularSegments – xác định số segment theo chiều rộng của các ống.
 arc – xác định mức được vẻ của torus (giống thetalength).

THREE.TorusKnotGeometry
Dùng để tạo ra hình có dạng các torus bị thắt nút.
THREE.TorusKnotGeometry(radius : Float, tube : Float, tubularSegments : Integer,
radialSegments : Integer, p : Integer, q : Integer)
 radius – bán kinh của các torus.
 tube - bán kính của các ống.
 tubularSegments/ radialSegments: tương tự như TorusGeometry.
 p — Xác định số vòng các torus cuốn quanh trục tọa độ.
 q — Xác định số vòng các torus tự cuốn quanh nó.
Chú ý: nếu p = q, hình ảnh sẽ có dạng một torus bình thường.

THREE.PolyhedronGeometry
Dùng để tạo các khối đa diện đều
 vertices — Tập hợp các điểm dưới dạng [1,1,1, -1,-1,-1, ... ]
 indices — Tập hợp các chỉ số tạo thành bề mặt của khối đa diện có dạng [0,1,2,
2,3,0, ... ]
 radius — Bán kính của hình đa diện.
 detail — Độ chi tiết của các mặt, nếu tăng chỉ số này sẽ có thêm nhiều mặt.
Dưới đây là các đa diện có sẵn của three.js, chúng ta có thể dùng chúng thay vì tạo
một PolyhedronGeometry tùy chỉnh. Các đa diện có sẵn không có vertices và indices.
VD: Nếu muốn tạo một hình chóp tam giác ta tạo một đối tượng kiểu
THREE.Tetrahedron.
10.Geometries nâng cao và Binary Operation

1. Các Geometry nâng cao

THREE.ConvexGeometry
Với THREE.ConvexGeometry, chúng ta có thể tạo một convex hull (bao lồi) bao quanh
tập hợp các điểm được truyền vào.
Hình trên là một ConvexGeometry được tạo từ 20 điểm.
Do THREE.ConvexGeometry không chứa trong thư viện three.js chuẩn nên chúng ta sẽ
thêm file js để dùng được geometry này.
<script src="../libs/ConvexGeometry.js"></script>

THREE.ConvexGeometry( points : Array )


 points – tập hợp các điểm kiểu THREE.Vector3D.

THREE.LatheGeometry
Dùng để tạo hình có dạng giống chiếc lọ.
THREE.LatheGeometry(points : Array, segments : Integer, phiStart : Float,
phiLength : Float)
 points – các điểm cơ bản để tạo thành một LatheGeometry.
 segments – số lượng segment dùng để tạo hình, các nhiều segment hình càng tròn
hơn.
 phiStart – Góc độ bắt đầu vẻ của hình. (Hình được vẻ từ các điểm cơ bản)
 phiLength – Xác định độ mở của hình.

THREE.TubeGeometry
Dùng để tạo hình có dạng ống.
THREE.TubeGeometry(path : Curve, tubularSegments : Integer, radius : Float,
radialSegments : Integer, closed : Boolean)
 path — thuộc tính có kiểu THREE.SplineCurve3 dùng để xác định hình dạng.
 tubularSegments – số lượng segment tạo nên ống
 radius – bán kính của ống.
 radialSegments – số segment bao quanh ống.
 closed – thuộc tính kiểu boolean, xác định các điểm đầu và các điểm cuối của ống
có nối với nhau không.

Tạo hình bằng phương pháp extruding


Extruding là việc biến hình hai chiều thành ba chiều bằng cách kéo hình để có thêm độ
sâu. Ví dụ một PlaneGeometry có thể được kéo thành BoxGeometry. Để làm việc này ta
sẽ sử dụng ExtrudeGeometry.
THREE.ExtrudeGeometry

THREE.ExtrudeGeometry(shapes : Array, options : Object)


 shapes – tập hợp các hình kiểu THREE.Shape được truyền vào
 options – đối tượng chứa các tham số sau

 depth – độ sâu được kéo của ảnh 2D.


 curveSegments – số lượng segment được dùng để tạo thành đường cong của
hình.
 steps – số lượng segment theo độ sâu được kéo của hình.

THREE.TextGeometry
Lớp này dùng để tạo chữ 2D và chữ 3D.
THREE.TextGeometry(text : String, options : Object)
 text - văn bản sẽ được hiển thị.
 options — Object that can contains the following parameters.
TextGeometry có các thuộc tính giống với ExtrudeGeometry nhưng có thêm font và
size.
 font — an instance of THREE.Font.
 size — Float. Size of the text. Default is 100.

2. Sử binary operation để kết hợp các geometry.

Tạo có thể kết hợp các geometry để tạo thành một geometry mới. Để làm được điều này
ta sẽ sử dụng thư viện có tên là ThreeBSP. Thư viện này có thể được download tại
https://github.com/skalnik/ThreeBSP.

Thư viên này được viết bằng CoffeeScript, vì vậy chúng ta phải cài đặt coffeescript trước
khi sử dụng bằng lệnh: “npm install -global coffeescript”
Sau đó thêm thư viện ThreeBSP vào file HTML.
<script type="text/coffeescript" src="../libs/ThreeBSP.coffee"></script>

Các hàm của ThreeBSP


intersect: hàm này dùng để tạo geometry mới dựa trên phần chung của hai geometry.
union: hàm này dùng để kết hợp hai geometry.
subtract: hàm này dùng để tạo geometry dựa vào một geometry sau khi đã loại bỏ phần
chung so với geometry còn lại.
ThreeBSP (geo: Geometry)

Kế hoạch tuần tiếp theo


Tìm hiểu particles, Sprites, and the Point Cloud, Geometry grouping and merging.
Nội dung báo cáo tuần 3
 Các vấn đề liên quan đến scene.
 Camera trong three.js.
 Ánh sáng trong three.js..
 Material cơ bản trong three.js.
I. SCENE
Định nghĩa: Scene cho phép xác định những thứ sẽ được render, ta có thể đặc object,
light, camera vào scene.
Các hàm và thuộc tính thường dùng
this .add(obj: Object3D) : Thêm object vào scene.
this .remove(obj: Object3D): Xóa object khỏi scene.
Object3D .getObjectByName(name: String): Trả về object đầu tiên có tên trùng với name.
Object3D .children: Chuỗi các object chứa trong scene.
Fog .fog: thuộc tính cho phép điều chỉnh sương mù xuất hiện trong toàn bộ scene.
Material .overrideMaterial: thuộc tính bắt buộc tất cả các object chứa trong scene sử
dụng cùng một material.

II. CAMERA
Perspective camera:
 Định nghĩa: Loại camera này mô phỏng cách mắt con người nhìn.
 Góc nhìn của Perspective camera

Float .fov: field of view, đây là thuộc tính xác định góc độ giữa 2 mặt trái và phải.
Float .near: Xác định khoảng cách gần nhất mà camera có thể render.
Float .far: Xác định khoảng cách xa nhất mà camera có thể render.
Orthographic Camera
 Định nghĩa: Kích thước của các object qua camera này sẽ không bị ảnh hưởng bởi
khoảng cách

 Góc nhìn của Orthographic camera

Bốn tham số đầu tiên là các thuộc tính left, right, top, bot xác định 4 biên của
orthographic camera. Tiếp theo là near và far tương tự perspective camera.
Thuộc tính và hàm chung thường dùng của camera
 LookAt

null .LookAt(target: Vector3): Hướng camera về vị trí tùy chọn.


 updateProjectMatrix
null .updateProjectionMatrix(): Hàm này phải được gọi sau khi thay đổi thuộc tính
của camera.
 zoom
number .zoom: Dùng để thu phóng camera.
11.LIGHT
AmbientLight
 Định nghĩa: Loại ánh sáng này chiếu toàn bộ tất cả các object chứa trong scene.
Không thể tạo bóng, định hướng, đặt ví trí với AmbientLight.
 Các thuộc tính thường dùng
Integer .color: Màu sắc của ánh sáng.
Float .intensity: Cường độ của ánh sáng.

PointLight
 Định nghĩa: Ánh sáng soi từ một điểm đến mọi phía xung quanh
 Các thuộc tính thường dùng
Integer .color: Màu sắc của ánh sáng.
Float .intensity: Cường của độ ánh sáng.
Number .distance: Tầm tối đa của PointLight, càng xa tâm, cường độ ánh sáng tại vị
trí đó càng giảm.

SpotLight
 Định nghĩa: Ánh sáng soi hình nón từ một điểm va hướng đến một hướng theo
một góc độ xác định.
 Các thuộc tính thường dùng
Integer .color: Màu sắc của ánh sáng.
Float .intensity: Cường của độ ánh sáng.
number .distance: Tầm tối đa của ánh sáng, càng xa tâm, cường độ ánh sáng tại vị trí
đó càng giảm.
Radians .angle: Góc độ chiếu của Spotlight, tối đa là π/2

Float .penumbra: Tỉ lệ cường độ của phần penumbra so với ánh sáng, giá trị từ
khoảng 0-1
DirectionalLight
 Định nghĩa: Là ánh sáng dưới dạng các tia sáng song song soi về một hướng,
DirectionalLight không thể rotate.
 Các thuộc tính thường dùng
Integer .color: Màu sắc của ánh sáng.
Float .intensity: Cường của độ ánh sáng.
Boolean .castShadow: Cho phép ánh sáng này có thể tạo bóng.
DirectionalLightShadow .shadow: Dùng để tùy chỉnh bóng cho ánh sáng.
HemisphereLight
 Định nghĩa: Ánh sáng từ phía trên của scene, giảm dần khi chiếu xuống. Ánh
sáng này không thể tạo bóng.
 Các thuộc tính thường dùng
Float .color: Màu sắc ánh sáng từ bầu trời.
Float .groundColor: Màu sắc ánh sáng dưới mặt đất.
Float .intensity: Cường của độ ánh sáng.
RectAreaLight
 Định nghĩa: Ánh sáng chiếu thông qua một mặt phẳng chữ nhật.
 Các thuộc tính thường dùng
Integer .color: Màu sắc của ánh sáng.
Float .intensity: Cường của độ ánh sáng.
Float .width: Chiều rộng của ánh sáng.
Float .height: Chiều dài của ánh sáng.

12.MATERIAL
Mesh được tạo thành từ material và geometry. Geometry có thể được xem là khung
của object còn material là lớp bao của khung đó.
Các loại material có các thuộc tính chung, ta có thể chia các thuộc tính này thành ba
loại
• Basic properties: Các thuộc tính này thường được dùng nhất.
VD: ID, Name, opacity, visible, …
• Blending properties: Các thuộc tính này xác định cách material phối màu với
background.
• Advanced properties: Một vài thuộc tính quyết định cách WebGL render object.
Hầu hết trước hợp ta sẽ không dùng các thuộc tính này.
Basic properties

Thuộc tính Kiểu Mô tả

Thuộc tính dùng để xác định material. Được tự


Id Integer
tạo ra khi tạo material, bắt đầu từ 0 và tăng dần

name String Dùng để gán tên cho material và gọi ở nơi khác

opacity Float Độ trong suốt của material

transparent Boolean Cho phép material trong suốt


visible Boolean Xác định có thể nhìn thấy material hay không

side Integer Xác định mặt để render material

Đối với một vài thay đổi thuộc tính của


material, three.js cần được thông báo. Nếu
needsUpdate Boolean thuộc tính này bằng true, three.js sẽ thay đổi
thuộc tính mới và giữ nguyên các thuộc tính
không thay đổi dựa vào cache.
MeshBasicMaterial
Material cơ bản để tô màu cho geometry, material này không ảnh hưởng bởi ánh
sáng

 Thuộc tính liên quan

Thuộc tính Thuộc tính Mô tả

color Color Màu của material

wireframe Boolean Render material dưới dạng wireframe

wireframelinewidth Float Độ lớn của mỗi wire trong wireframe

Xác định hình dáng tại các đầu của mỗi


wireframelinecap String
wire
MeshDepthMaterial
Material thay đổi màu sắc dựa trên chiều sâu, càng xa camera thì màu của material
càng tối.

 Thuộc tính liên quan: wireframe và wireframelinewidth

MeshNormalMaterial
Material ánh xạ vector với màu RGB.
MeshLambertMaterial
Material không có có độ bóng

 Các thuộc tính liên quan: emissive, wrapAround, …

MeshLambertMaterial
Material với bề mặt có độ bóng
 Các thuộc tính liên quan

Thuộc tính Kiểu Description

Màu sắc ánh sáng do material này phát ra, mặc định
emissive Color
là màu đen

specular Color Màu điểm shiny của material

shininess Float Mức độ sáng của điểm shiny

Nếu thuộc tính này bằng true, three.js sẽ render cho


metal Boolean
material này trông giống với kim loại
13.Kế hoạch tuần tiếp theo
 Tìm hiểu và các material nâng cao
 Tìm hiểu về geometry trong three.js

14.Tài liệu tham khảo


[1]Tài liệu chính thức thư viện three.js - https://threejs.org/docs/
[2] Learning Three.js - the JavaScript 3D Library for WebGL (Second Edition) -
Jos Dirksen
[3] Source code sample - https://github.com/josdirksen/learning-threejs
Nội dung báo cáo tuần 2
- Các thành phần(object) chính để tạo nên 1 web 3d.
- Demo Web3D đơn giản sử dụng three.js.

1. Giới thiệu thành phần chính để tạo nên 1 Web3D


- Scene: Cho phép bạn thiết lập những gì và nơi sẽ được hiển thị bởi three.js. Đây
là nơi bạn đặt các objects, lights and cameras.
- Camera: Lớp cơ sở trừu tượng của cameras. Lớp này phải luôn được kế thừa khi
bạn xây dựng camera mới.
- Renderer: render các cảnh, các đối tượng, …
- Object: Là đối tượng đồ họa có thể add vào scene.
VD: THREE.Mesh object được tạo nên từ sự kết hợp của geometry và material
● Geometry: Tập hợp các đỉnh tạo thành bề mặt.
● Material: Là lớp phủ bề mặt của geometry, có thể là màu sắc hoặc texture.

2. Demo Web3D đơn giản sử dụng three.js


a. Import thư viện three.js
- Copy file three.js hoặc three.min.js trong thư mục build từ
https://github.com/mrdoob/three.js/
Chú ý: nên đưa thư viện này vào thư mục js.
b. File html:

c. Tạo scene
- Để có thể hiển thị bất kỳ thứ gì với thư viện three.js. Cần có 3 thứ: Scene,
Camera và Renderer.

- Ở đoạn code trên, chúng ta thiết lập scene, camera và renderer.


- Thư viện three.js hỗ trợ nhiều kiểu camera. Ở đây chúng ta sử dụng
PerspectiveCamera.
Các tham số của PerspectiveCamera
● Field of View: là phạm vi của cảnh được nhìn thấy trên màn hình tại
một thời điểm. Giá trị được đo bằng độ.
● Tỷ lệ khung hình (aspect ratio): Thường sử dụng tỷ số chiều
rộng/chiều cao.
● Hai thuộc tính tiếp theo là near và far: các vật thể có vị trí nằm
ngoài khoảng near-far sẽ không được hiển thị.
- Renderer: Ngoài WebGLRenderer mà chúng ta sử dụng ở đây, three.js còn
đi kèm với một số khác, nhưng chỉ thường sử dụng cho trình duyệt cũ hơn
hoặc cho những trình duyệt không có hỗ trợ WebGL.

- Tiếp theo chúng ta sẽ tạo mesh, cụ thể là một khối lập phương

● Đầu tiên chúng ta sẽ tạo một BoxGeometry. Đây là một đối tượng chứa tất cả
các điểm (đỉnh) và các mặt của khối.
● Tạo material cho geometry đã tạo.
● Kết hợp material và geometry tạo thành mesh. Sau đó thêm mesh này vào
scene.
d. Làm cho khối lập phương chuyển động

- Tạo một vòng lặp animate và viết code xử lý sự thay đổi của các đối tượng trên
một frame.

- Render lại scene và camera.

Nội dung báo cáo tuần 1


- Tổng quan thư viện three.js
- Cấu trúc cơ bản
- Định hướng đồ án
1. TỔNG QUAN
- Three.js là một thư viện JavaScript nguồn mở được sử dụng để tạo và hiển thị đồ
họa 3D trên trình duyệt web.
- Three.js giúp sử dụng JavaScript như một phần của trang web mà không cần dựa
vào các plugin trình duyệt . Đó là nhờ có sự ra đời của WebGL.
2. LỊCH SỬ
- Three.js được phát hành lần đầu bởi Ricardo Cabello trên GitHub vào tháng 4 năm
2010. Source code này ban đầu được viết bằng ActionScript vào đầu những năm 2000,
sau đó được chuyển sang JavaScript vào năm 2009 vì Cabello cho rằng hai điểm mạnh để
chuyển sang JavaScript là không phải biên dịch mã trước mỗi lần chạy và độc lập nền
tảng.
- Sau đó Branislav Ulicny tham gia three.js vào năm 2010 sau khi đã đăng một số
bản demo WebGL trên trang web của ông. Những đóng góp chính của ông thường liên
quan đến materials, shaders và post-processing.
- Không lâu sau khi ra Firefox ra mắt WebGL 1.0, Joshua Koo tham gia vào three.js
và đóng góp các phần liên quan đến hình học.
- Hiện nay three.js đã có hơn 1000 contributor và gần 50 ngàn sao trên github.
https://github.com/mrdoob/three.js/
3. TÍNH NĂNG
- Three.js bao gồm các tính năng:
· Effect
· Scenes
· Cameras
· Animation.
· Lights
· Materials
· Shaders
· Objects
· Geometry
· Data loaders
· Virtual reality
- Three.js chạy trên mọi trình duyệt hỗ trợ WebGL 1.0

You might also like