Cập nhật tháng 10/2026. Phiên bản three.js mới nhất trên npm lúc viết bài là 0.186.1 (bản r186). Hãy kiểm tra lại phiên bản trước khi dùng mã mẫu.
Bài này dành cho ai: người làm web đã quen HTML, CSS, JavaScript cơ bản, đang được khách hoặc sếp hỏi “làm trang có hiệu ứng 3D được không?”.
Bạn sẽ nắm được gì: bốn thành phần tối thiểu của một cảnh three.js, đoạn mã dựng khối 3D đầu tiên, cách cho canvas co giãn đúng tỉ lệ, cách giữ trang nhẹ trên điện thoại, và góc nhìn khi nào 3D đáng tiền với website doanh nghiệp.
Thời gian đọc: khoảng 8 phút, thực hành thêm 20–30 phút.
Quan điểm của bài này khá thẳng: với website doanh nghiệp, 3D là gia vị chứ không phải món chính. Một khối 3D đặt đúng chỗ khiến khách dừng lại vài giây và hiểu sản phẩm nhanh hơn. Đặt sai chỗ, nó làm trang chậm và khách thoát sớm.

1. three.js là gì và vì sao người làm web nên biết
three.js là thư viện JavaScript mã nguồn mở giúp vẽ đồ hoạ 3D trong trình duyệt. Bên dưới, nó dùng WebGL, nhưng gói các lệnh đồ hoạ dài dòng thành khái niệm dễ hiểu: cảnh, máy quay, vật thể, ánh sáng.
Ngoài WebGLRenderer quen thuộc, tài liệu hiện có thêm WebGPURenderer, ưu tiên WebGPU và tự lùi về WebGL 2. Cảnh đầu tiên cứ dùng WebGLRenderer cho dễ theo ví dụ.
2. Bốn thứ tối thiểu của một cảnh 3D
Hướng dẫn chính thức nói gọn: muốn hiển thị bất cứ thứ gì, bạn cần cảnh, máy quay và bộ dựng hình. Nếu dùng vật liệu có phản chiếu ánh sáng, bạn cần thêm đèn, nếu không vật thể sẽ đen thui.
Scene (cảnh)
Sân khấu chứa mọi thứ: vật thể, đèn, nền. Bạn thêm đồ vào bằng scene.add().
Camera (máy quay)
PerspectiveCamera nhìn giống mắt người: góc nhìn, tỉ lệ khung, mặt cắt gần và xa.
Renderer (bộ dựng hình)
Vẽ cảnh nhìn từ máy quay lên thẻ canvas, mỗi lần gọi render() là một khung hình.
Light (ánh sáng)
HemisphereLight chiếu sáng nền dịu, DirectionalLight giống ánh nắng, tạo mặt sáng mặt tối cho vật thể.
Vật thể trong cảnh gọi là Mesh, ghép từ hình khối (geometry, ví dụ BoxGeometry) và vật liệu (material, ví dụ MeshStandardMaterial).
3. Dựng khối 3D đầu tiên trong một section
Website doanh nghiệp thường chỉ cần 3D trong một khung, không phải toàn màn hình. Trong HTML, đặt một thẻ canvas có id pdl-3d, dùng CSS cho nó rộng 100%, cao khoảng 360px, display: block. Không có công cụ build thì khai báo import map trỏ tới CDN, ghim đúng phiên bản:
{ “imports”: { “three”: “https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js” } }
</script>
<script type=”module” src=”/js/canh-3d.js”></script>
Tệp canh-3d.js dựng cảnh, đèn và một khối hộp:
const canvas = document.querySelector(‘#pdl-3d’);
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true });
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, 2, 0.1, 100);
camera.position.set(0, 1, 5);
scene.add(new THREE.HemisphereLight(0xffffff, 0x445566, 1.5));
const sun = new THREE.DirectionalLight(0xffffff, 2);
sun.position.set(3, 4, 5);
scene.add(sun);
const box = new THREE.Mesh(
new THREE.BoxGeometry(1.5, 1.5, 1.5),
new THREE.MeshStandardMaterial({ color: 0x193059, roughness: 0.4 })
);
scene.add(box);
Cuối cùng là vòng lặp render. Tài liệu WebGLRenderer khuyên luôn dùng setAnimationLoop thay vì tự gọi requestAnimationFrame. Hàm nhận tham số thời gian tính bằng mili giây, dùng để xoay khối đều nhau trên mọi máy:
resize();
box.rotation.y = time / 2000;
renderer.render(scene, camera);
}
renderer.setAnimationLoop(loop);
Mở trang qua một máy chủ cục bộ (ví dụ npx serve .), bạn sẽ thấy khối hộp màu xanh navy xoay chậm.
4. Responsive: canvas có hai kích thước
Theo bài Responsive Design trong manual, canvas có kích thước hiển thị (do CSS quyết định) và kích thước bộ đệm vẽ (số điểm ảnh thật). Nếu chỉ đổi CSS, hình bị kéo méo hoặc mờ. Cách làm gọn: để CSS lo kích thước hiển thị, còn mỗi khung hình kiểm tra và cập nhật bộ đệm vẽ cùng tỉ lệ máy quay:
const ratio = Math.min(window.devicePixelRatio, 2);
const width = Math.floor(canvas.clientWidth * ratio);
const height = Math.floor(canvas.clientHeight * ratio);
if (canvas.width !== width || canvas.height !== height) {
renderer.setSize(width, height, false);
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
}
Tham số false cuối setSize báo three.js đừng ghi đè CSS. Manual khuyên tự tính theo devicePixelRatio như trên thay vì dùng setPixelRatio. Việc giới hạn tỉ lệ ở mức 2 là lựa chọn của chúng tôi: điện thoại có màn hình tỉ lệ 3 sẽ phải vẽ gấp 9 lần số điểm ảnh.

5. Giữ trang nhẹ trên điện thoại
- Dừng vẽ khi không ai nhìn:
setAnimationLoopdựa trênrequestAnimationFramenên tự tạm dừng khi người dùng chuyển tab. Nhưng khi canvas đã cuộn khỏi màn hình thì vòng lặp vẫn chạy. Dùng Intersection Observer gọirenderer.setAnimationLoop(null)khi canvas khuất và gắn lạiloopkhi nó hiện ra. - Tôn trọng người tắt chuyển động: nếu
matchMedia('(prefers-reduced-motion: reduce)')trả về true, chỉ vẽ một khung hình tĩnh. - Cảnh đứng yên thì vẽ theo yêu cầu: bài Rendering on Demand chỉ cách chỉ gọi
render()khi có thay đổi, ví dụ người dùng xoay mô hình, thay vì vẽ liên tục 60 lần mỗi giây. - Mô hình và ảnh vân bề mặt gọn: mô hình dùng định dạng glTF, ảnh vân nén nhỏ.
Nguyên tắc nén ảnh cho web vẫn đúng với ảnh vân bề mặt; bạn có thể xem lại bài tìm hiểu định dạng ảnh WebP.
6. Khi nào nên, khi nào không nên dùng 3D cho website doanh nghiệp
Nên dùng khi
Khách cần xoay, lật để hiểu sản phẩm (đồ nội thất, bao bì, linh kiện); hình khối là câu chuyện thương hiệu; trang chiến dịch cần gây ấn tượng.
Không nên dùng khi
3D chỉ để “trông hiện đại”; khách chủ yếu vào bằng điện thoại cấu hình thấp qua quảng cáo; nội dung là không gian có sẵn, chụp 360 độ rẻ và thật hơn.
Ví dụ minh hoạ: một xưởng in bao bì ở Bình Dương muốn khách xem hộp giấy từ mọi góc trước khi đặt in. Một khối hộp three.js dán ảnh mặt in, cho xoay bằng tay, đặt trong trang sản phẩm là hợp lý: khách hiểu nhanh, trang vẫn nhẹ. Ngược lại, một khách sạn muốn khách “đi thử” sảnh và phòng thì dựng 3D từ đầu tốn kém mà kém thật, nên chọn tour thực tế ảo 360.

7. Bài học áp dụng ngay
- Bắt đầu bằng câu hỏi “3D giúp khách hiểu điều gì?” Không trả lời được trong một câu thì bỏ.
- Đặt 3D trong một khung có kích thước rõ, đừng phủ cả trang; chữ và nút liên hệ luôn là HTML.
- Ghim phiên bản three.js, nâng cấp có chủ đích.
- Đo trên điện thoại tầm trung thật, không chỉ trên máy làm việc của lập trình viên.
8. Thuật ngữ cần biết
- WebGL: giao diện lập trình giúp trình duyệt vẽ đồ hoạ 2D, 3D tăng tốc bằng card đồ hoạ trong thẻ canvas. Nguồn: MDN WebGL API.
- Render loop (vòng lặp render): hàm được gọi lặp lại mỗi lần màn hình làm mới để vẽ khung hình mới. Nguồn: three.js WebGLRenderer.
- Device pixel ratio: tỉ lệ giữa điểm ảnh vật lý và điểm ảnh CSS của màn hình. Nguồn: MDN devicePixelRatio.
- Import map: khai báo cho trình duyệt biết tên module như
threetrỏ tới tệp nào. Nguồn: MDN importmap.
9. Tìm hiểu thêm
- three.js manual: Creating a scene và Installation: cài đặt bằng npm, Vite hoặc CDN.
- Responsive Design và Rendering on Demand: hai bài nên đọc trước khi đưa 3D lên trang thật.
- MDN Intersection Observer API và prefers-reduced-motion.
10. Câu hỏi thường gặp
Có chèn three.js vào trang WordPress được không?
Được. Cách gọn là đặt thẻ canvas trong một khối HTML, nạp import map và tệp module ở trang cần dùng, không nạp toàn site. Nếu trình dựng trang chặn mã HTML hoặc script, nhờ người quản trị kỹ thuật thêm qua theme con.
3D có làm hại SEO không?
Canvas không chứa chữ để công cụ tìm kiếm đọc, nên nội dung quan trọng phải nằm trong HTML. Ảnh hưởng thật nằm ở tốc độ: thư viện và mô hình nặng tải sớm sẽ làm trang chậm, vì vậy hãy tải 3D sau nội dung chính.
Đọc tiếp
- Bài sau trong chuyên mục Lập trình & Thiết kế: Core Web Vitals cho chủ doanh nghiệp: hiểu LCP, INP, CLS và tự đo website
- Nên đọc cùng: Làm chủ CSS Specificity
PDL Digital đào tạo và đồng hành cùng đội ngũ làm web của doanh nghiệp, từ nền tảng HTML, CSS, JavaScript đến ứng dụng AI vào quy trình thiết kế và lập trình. Xem trang đào tạo để chọn khoá phù hợp.

