Chào các bạn, trong thời gian vừa rồi, mình có một task liên quan đến việc sử dụng thư viện Model-viewer để hiển thị AR model trong ứng dụng Next.js. Trong quá trình tìm hiểu và sử dụng thư viện này có rất nhiều điều thú vị, đồng thời cũng gặp một số vấn đề liên quan đến việc tích hợp thư viện này với Next.js nên mình viết bài blog lần này với 2 mục đích. Một là để chia sẻ với mọi người về thư viện thú vị này, hai là cá nhân mình cũng note lại những thứ hay ho trong khi làm. Không dài dòng nữa, chúng ta cùng bắt đầu thôi.

I. Giới thiệu

Trong thời đại công nghệ số, đồ họa 3D đang trở thành xu hướng phổ biến, tạo ra những trải nghiệm tương tác hấp dẫn trên web. Để đáp ứng xu hướng này, Google đã giới thiệu thư viện Model-viewer - một công cụ mạnh mẽ giúp hiển thị và tương tác với các mô hình 3D trên nền tảng web. Với Model-viewer, nhà phát triển có thể dễ dàng tạo ra những trang web độc đáo, tương tác và thậm chí hỗ trợ chế độ thực tế tăng cường (AR) trên nhiều trình duyệt và thiết bị khác nhau.

Model-viewer là một thư viện web component dựa trên tiêu chuẩn Web Components của W3C, cho phép nhà phát triển dễ dàng hiển thị và tương tác với các mô hình 3D trên web. Được xây dựng trên ngôn ngữ HTML, CSS và JavaScript, Model-viewer mang đến những giá trị mặc định về chất lượng và hiệu suất để đảm bảo trải nghiệm tốt nhất cho người dùng.

Khi các tiêu chuẩn và API mới xuất hiện, Model-viewer sẽ được cải tiến để tận dụng những tiến bộ này. Nếu có thể, sẽ hỗ trợ các phương pháp thay thế và polyfills để mang lại trải nghiệm phát triển mượt mà.

2.Tính năng và lợi ích của Model-viewer

2.1 Hiệu suất và chất lượng

Model-viewer tập trung vào việc cung cấp những giá trị mặc định xuất sắc để đảm bảo chất lượng hiển thị và hiệu suất tối ưu. Với việc tận dụng tiêu chuẩn WebGL và công nghệ GPU rendering, Model-viewer đảm bảo rằng mô hình 3D sẽ được hiển thị một cách mượt mà và hấp dẫn cho người dùng. Ngoài ra, thư viện cũng hỗ trợ việc tải và xử lý mô hình 3D một cách thông minh, giúp giảm bớt thời gian tải và tăng cường hiệu suất trang web.

2.2 Hỗ trợ đa nền tảng

Model-viewer được thiết kế để hoạt động trên nhiều trình duyệt và thiết bị khác nhau. Điều này đảm bảo rằng mô hình 3D của bạn có thể được trình diễn một cách tốt nhất trên các nền tảng khác nhau, từ máy tính để bàn đến điện thoại di động. Thư viện hỗ trợ trình duyệt phổ biến như Google Chrome, Mozilla Firefox, Safari và Microsoft Edge, đồng thời cung cấp tích hợp tốt với các hệ điều hành di động như Android và iOS.

2.3 Tích hợp AR dễ dàng

Một trong những tính năng nổi bật của Model-viewer là khả năng hỗ trợ chế độ thực tế tăng cường (AR). Với AR, người dùng có thể trải nghiệm mô hình 3D trong không gian thực tế, tạo ra những trải nghiệm tương tác ấn tượng. Model Viewer hỗ trợ AR trên cả các thiết bị Android và iOS thông qua việc tích hợp các tiêu chuẩn như WebXR Device API, Scene Viewer và Quick Look. Điều này cho phép người dùng khám phá và tương tác với mô hình 3D một cách chân thực và độc đáo.

3. Hướng dẫn sử dụng <model-viewer> với HTML

Để sử dụng Model-viewer, đầu tiên bạn cần nhúng thư viện vào trang web của mình bằng cách thêm mã HTML và JavaScript tương ứng. Sau đó, bạn có thể tạo một thẻ <model-viewer> và cấu hình các thuộc tính để hiển thị mô hình 3D.

<!-- Import component -->
<script type="module" src="https://ajax.googleapis.com/ajax/libs/model-viewer/3.1.1/model-viewer.min.js"></script>

<!-- Sử dụng như một phần tử HTML -->
<model-viewer alt="Neil Armstrong's Spacesuit from the Smithsonian Digitization Programs Office and National Air and Space Museum" src="shared-assets/models/NeilArmstrong.glb" ar environment-image="shared-assets/environments/moon_1k.hdr" poster="shared-assets/models/NeilArmstrong.webp" shadow-intensity="1" camera-controls touch-action="pan-y"></model-viewer>

4. Tích hợp vào ứng dụng Next.js

Sau đây mình sẽ demo cho các bạn cách tích hợp và sử dụng Model-viewer trong ứng dụng Next.js.

Đầu tiên, các bạn khởi tạo ứng dụng Next.js bằng câu lệnh:

npx create-next-app@latest

Bản Next.js hiện tại mình đang dùng là 13.4.3.

Tiếp theo, sau khi các bạn đã khởi tạo xong source code, thì chúng ta sẽ cài thư viện Model-viewer

# install peer dependency ThreeJS
yarn add three 
# install package
yarn add @google/model-viewer

Note: từ bản Model-viewer 3.1.0, model-viewer sử dụng three.js như một peer dependency, nên khi các bạn install Model-viewer thì hãy install luôn cả thư viện này nhé. Nếu bạn nào muốn sử dụng Model-viewer thôi thì có thể tải bản 3.1.0 trở về trước. Phiên bản Model-viewer mình đang dùng là bản 3.1.1.

Ok, vậy là các bước set-up của chúng ta đã xong, tiếp đến chúng tao sẽ tạo 1 component sử dụng component Model-viewer này. Các bạn khởi tạo component Model.tsx

// app/components/Model.tsx

"use client";

import "@google/model-viewer";

const Model = () => {
  return (
    <div id="card">
      <model-viewer
        src="Astronaut.glb"
        ios-src=""
        poster="https://cdn.glitch.com/36cb8393-65c6-408d-a538-055ada20431b%2Fposter-astronaut.png?v=1599079951717"
        alt="A 3D model of an astronaut"
        shadow-intensity="1"
        camera-controls
        auto-rotate
        ar
      ></model-viewer>
    </div>
  );
};

export default Model;

Trước khi đi sâu vào giải thích các thuộc tính mà mình sử dụng, mình sẽ chia sẻ 1 issue mà chắc chắn các bạn sẽ gặp phải.

Khi import và sử dụng thư viện, chúng ta sẽ gặp lỗi liên quan đến Typescript.

Property 'model-viewer' does not exist on type 'JSX.IntrinsicElements'.

Nguyên nhân là do thư viện Model-viewer hiện tại chỉ hỗ trợ thẻ HTML và theo một cách chính thống, chưa có tài liệu nào trên trang chủ của nó nói về việc hỗ trợ React, và cụ thể hơn nữa là TypeScript.

Sau một thời gian mày mò, mình đã tìm ra một cách để sửa được vấn đề này. Đó là khai báo type cho nó. Các bạn tạo file model-viewer.d.ts như sau:

// app/@types/model-viewer.d.ts

import { ModelViewerElement } from "@google/model-viewer";

export declare global {
  namespace JSX {
    interface IntrinsicElements {
      "model-viewer": React.DetailedHTMLProps<Partial<ModelViewerElement>>;
    }
  }
}

Với việc khai báo type trên, chúng ta đã giải quyết được vấn đề import rồi ^^:

Giờ mình sẽ giải thích các thuộc tính quan trọng trong Model-viewer mà mình đã sử dụng:

  • src: Đường dẫn đến mô hình 3D. Bạn có thể chỉ định đường dẫn tương đối hoặc tuyệt đối. Ở đây mình đã sử dụng đường dẫn đến 1 file model mình đã tải về trong thư mục public. Hiện tại model-viewer chỉ hỗ trợ model có định dạng glTF/GLB.
  • ios-src: Đường dẫn đến mô hình 3D dành cho thiết bị iOS. ios-src thường không cần thiết. Tuy nhiên, mô hình USDZ sẽ được sử dụng trên các thiết bị hỗ trợ iOS 12+ thông qua AR Quick Look trên trình duyệt Safari. Với thuộc tính này, thư viện sẽ tạo một USDZ ngay khi người dùng nhấn nút AR. Điều này có nghĩa là các thay đổi thông qua API scene-graph sẽ được phản ánh trong Quick Look. Tuy nhiên, việc tạo USDZ không hoàn hảo, ví dụ như không hỗ trợ hoạt hình, vì vậy trong một số trường hợp, cung cấp ios-src có thể mang lại kết quả tốt hơn.
  • ar: Thuộc tính này kích hoạt chế độ AR. Khi được thiết lập, nút kích hoạt AR sẽ xuất hiện và người dùng có thể bật chế độ AR nếu thiết bị của họ hỗ trợ.
  • camera-controls: Cho phép người dùng điều khiển camera để xoay và di chuyển trong mô hình 3D.
  • auto-rotate: Tự động quay mô hình 3D khi ở chế độ xem phẳng trước khi vào chế độ AR.
  • poster: Đường dẫn đến hình ảnh sẽ hiển thị trước khi mô hình 3D load thành công.
  • shadow-intensity: Điều chỉnh độ mờ của bóng. Đặt giá trị là 0 để tắt hoàn toàn bóng.
  • alt: ĐỪNG QUÊN THUỘC TÍNH ALT. Nếu bạn develop ứng dụng trên web, sẽ có các vấn đề trong việc load, trải nghiệm nội dung. Giống như trong hình ảnh, các thuộc tính alt cũng có mặt trong model-viewer, vì vậy bạn có thể thêm một mô tả thay thế.

Ngoài ra, còn có rất nhiều các thuộc tính khác cũng có sẵn để tùy chỉnh hiển thị và tương tác của mô hình 3D, như camera, màu sắc, ánh sáng, và nhiều hơn nữa.

Tiếp đến chúng ta sẽ import file Model.tsx vào page.tsx để hiển thị component này ở trang chủ.

// app/page.tsx

import Model from "./components/Model";

export default function Home() {
  return <Model />;
}

IV. Thành quả

Và đây là kết quả sau khi implement đoạn code trên:

  • Web:

Và đây vẫn chưa phải là phần hay nhất, hãy kết nối thiết bị di động của bạn cùng mạng với máy tính và truy cập thông qua private network:

  • Mobile:

Ta có thể thấy thư viện này hỗ trợ AR tuyệt vời thế nào!

V. Xử lý với Animation Model

Ở trên mình mới demo 1 model 3D tĩnh, vậy còn đối với model 3D động thì sao. Tất nhiên là Model-viewer cũng hỗ trợ phần animation này khá tốt. Nó cung cấp các tính năng mạnh mẽ để điều khiển và hiển thị các hoạt động động của mô hình 3D.

Để demo với các Animation Model, mình sẽ sử dụng model khác và sử dụng các thuộc tính liên quan đến animation:

  • animation-name: Chọn một hoạt động để phát theo tên. Nếu không chỉ định tên hoạt động, Model-viewer luôn chọn hoạt động đầu tiên mà nó tìm thấy trong mô hình.
  • auto-play: Một hoạt động sẽ tự động bắt đầu phát khi thuộc tính này được thiết lập . Nếu không chỉ định tên hoạt động, sẽ phát hoạt động đầu tiên.

Như vậy mình sẽ thêm 2 thuộc tính này vào file Model.tsx:

"use client";

import "@google/model-viewer";

const Model = () => {
  return (
    <div id="card">
      <model-viewer
        autoplay // <- add
        animation-name="run" // <- add
        src="/Rampaging T-Rex.glb" // <- thay đổi file model
        ios-src=""
        poster="https://cdn.glitch.com/36cb8393-65c6-408d-a538-055ada20431b%2Fposter-astronaut.png?v=1599079951717"
        alt="A 3D model of an astronaut"
        shadow-intensity="1"
        camera-controls
        auto-rotate
        ar
      ></model-viewer>
    </div>
  );
};

export default Model;

Mình có 1 model hình khủng long T-Rex, và mình sẽ thay đổi animation-name của nó:

  • animation-name="run"
  • animation-name="bite"

Rất hay phải không nào!!!

Ở chế độ xem AR, model hiển thị rất chân thật với từng cử chỉ. Các bạn muốn xem thử thì hãy tự mình vọc thư viện này và tận hưởng độ chân thực nhé :D

VI. Kết luận

Mình hy vọng rằng bài blog này đã cung cấp cho bạn cái nhìn tổng quan về thư viện Model Viewer của Google và khả năng của nó trong việc hiển thị và tương tác với đồ họa 3D trên web cũng như thiết bị di động. Với Model Viewer, bạn có thể tạo ra những trang web độc đáo và hấp dẫn, đồng thời hỗ trợ chế độ thực tế tăng cường để mang đến trải nghiệm tuyệt vời cho người dùng. Bài viết của mình mới trình bày được sơ sài những tính năng cơ bản của thư viện, còn rất nhiều điều thú vị đang chờ đón bạn khám phá đấy. Các bạn có thể truy cập vào trang chủ https://modelviewer.dev/ để khám phá nhé. Ngoài ra, các bạn cũng có thể tham khảo code hoặc lấy file glb ở đây nhé. Hẹn gặp lại các bạn trong các bài blog tiếp theo.