Theatre.js

Starter pack

Theatre.js là một thư viện animation javascript cho phép chúng ta tạo ra những trải nghiệm điện ảnh với Three.jsReact Three Fiber.

Điểm nổi bật của nó so với các thư viện animation khác mà chúng ta đã sử dụng trước đó là nó đi kèm với một giao diện studio UI cho phép chúng ta tạo và chỉnh sửa các animations một cách trực quan.

Từ việc animating các đối tượng Three.js trực tiếp trong không gian 3D đến việc tạo ra các sequenc phức tạp với nhiều transitionseasing functions, Theatre.js có đầy đủ mọi thứ chúng ta cần để tạo ra các chuyển cảnh 3D tuyệt vời.

Trong bài học này, chúng ta sẽ tạo một trang web cho một thị trấn trung cổ tưởng tượng. Chúng ta sẽ sử dụng mô hình Medieval Fantasy Book đẹp mắt này của Pixel.

Animation là một phần của mô hình, chúng tôi để nó ở chế độ tự động phát để thêm sức sống vào cảnh.

Tôi cũng đã chuẩn bị giao diện với TailwindCSSFramer Motion để chuyển đổi giữa các phần khác nhau của trang web.

Sẵn sàng trở thành Steven Spielberg tiếp theo của web chưa? Hãy bắt đầu nào!

Cài đặt

Để thêm Theatre.js vào dự án của chúng ta, chạy lệnh sau trong terminal:

yarn add @theatre/core@0.5 @theatre/studio@0.5 @theatre/r3f@0.5

Sau đó, trong mã của chúng ta, cần lấy sheet mà chúng ta sẽ làm việc cho dự án. Trong App.jsx:

// ...
import { getProject } from "@theatre/core";

const project = getProject("MedievalTown");
const mainSheet = project.sheet("Main");

// ...

Tên dự án cần phải độc nhất để tránh xung đột với các dự án khác. Vì Theatre.js sử dụng localStorage để lưu dữ liệu animation và chúng ta thường sử dụng cùng một url và cổng trình duyệt trong quá trình phát triển, điều quan trọng là sử dụng một tên độc nhất.

Sheet được dùng để animate một hoặc nhiều đối tượng trong cảnh. Chúng ta sẽ chỉ sử dụng một sheet cho dự án này. Bạn nên xem xét việc sử dụng nhiều sheet nếu muốn animate các đối tượng khác nhau một cách độc lập. Trong trường hợp của chúng ta, tất cả các animations đều có ý nghĩa nằm trong cùng một sheet.

Cuối cùng chúng ta cần bao bọc tất cả các thành phần sẽ được animate trong <SheetProvider>:

// ...
import { SheetProvider } from "@theatre/r3f";
// ...

function App() {
  // ...
  return (
    <>
      <UI
        currentScreen={currentScreen}
        onScreenChange={setTargetScreen}
        isAnimating={currentScreen !== targetScreen}
      />
      <Canvas camera={{ position: [5, 5, 10], fov: 30, near: 1 }} shadows>
        <SoftShadows />
        <SheetProvider sheet={mainSheet}>
          <Experience />
        </SheetProvider>
      </Canvas>
    </>
  );
}

export default App;

Giờ là lúc thêm trình chỉnh sửa trực quan vào dự án của chúng ta.

Theatre.js Studio

Để thêm Theatre.js Studio vào dự án, chúng ta cần import và khởi tạo nó:

// ...
import extension from "@theatre/r3f/dist/extension";
import studio from "@theatre/studio";

studio.initialize();
studio.extend(extension);

// ...

Khá đơn giản đúng không? Bây giờ nếu bạn chạy dự án, bạn sẽ thấy giao diện Theatre.js Studio trên màn hình:

Theatre.js Studio UI

Editable

Để một đối tượng có thể editable với Theatre.js và tương tác với nó trong studio, chúng ta cần import component editable. Trong Experience.jsx:

// ...
import { editable as e } from "@theatre/r3f";
// ...

Chúng ta sử dụng editable as e để phù hợp với tài liệu chính thức. Đây là một cách viết ngắn gọn giúp mã của chúng ta trở nên ngắn hơn.

Sau đó, chúng ta cần tiền tố phần tử JSX của đối tượng mà chúng ta muốn làm cho có thể chỉnh sửa với e và xác định prop theatreKey:

// ...

export const Experience = () => {
  return (
    <>
      <e.directionalLight
        theatreKey="SunLight"
        position={[3, 3, 3]}
        intensity={0.2}
        castShadow
        shadow-bias={-0.001}
        shadow-mapSize-width={2048}
        shadow-mapSize-height={2048}
      />
      <e.group theatreKey="MedievalFantasyBook">
        <MedievalFantasyBook scale={0.1} envMapIntensity={0.3} />
      </e.group>
      <Environment preset="dawn" background blur={4} />
    </>
  );
};

Chúng ta đã làm cho directional lightMedieval Fantasy Book có thể chỉnh sửa. Hãy tải lại trang và xem điều gì xảy ra:

Editable objects in Theatre.js Studio

Các đối tượng của chúng ta xuất hiện dưới tab Main trong outline panel

Điều Khiển

Giờ đây chúng ta đã sẵn sàng chơi với studio.

Panel Đề cương

Panel đề cương là nơi chúng ta có thể tìm thấy tất cả các đối tượng có thể chỉnh sửa trong cảnh của mình. Chúng ta có thể chọn một đối tượng bằng cách nhấp vào tên của nó. Khi đã được chọn, chúng ta có thể chỉnh sửa các thuộc tính của nó trong panel chi tiết.

Panel Chi Tiết

Panel chi tiết liệt kê tất cả các thuộc tính có thể chỉnh sửa của đối tượng được chọn. Chúng ta có thể chỉnh sửa giá trị của một thuộc tính bằng cách kéo giá trị của nó hoặc bằng cách nhấp vào và nhập một giá trị mới.

Panel Chi Tiết trong Theatre.js Studio

Nhấp chuột vào tên prop và nhấp vào Sequence để làm cho nó có sẵn trong trình chỉnh sửa trình tự. Nếu nó đã có trong timeline của trình chỉnh sửa trình tự, Make static sẽ loại bỏ nó.

Prop Sequence trong Theatre.js Studio

Sau khi nhấp, trình chỉnh sửa trình tự sẽ xuất hiện ở phía dưới màn hình.

Trình Chỉnh Sửa Trình Tự

Trình chỉnh sửa trình tự là nơi chúng ta có thể tạo và chỉnh sửa các hoạt hình. Chúng ta có thể thêm một keyframe bằng cách nhấp vào biểu tượng losange của một prop trong panel chi tiết hoặc bằng cách nhấp vào biểu tượng losange của một prop trong trình chỉnh sửa trình tự.

Dưới đây là các phím tắt phổ biến nhất để điều hướng trong trình chỉnh sửa trình tự:

  • Shift + Left Mouse để chọn nhiều keyframe
  • Left Mouse trên đầu phát để di chuyển nó. (Trong khi giữ nút chuột trái, đặt con trỏ trên một keyframe để gắn chặt vào nó)
  • Ctrl + Mouse Wheel để phóng to và thu nhỏ
  • Mouse Wheel để cuộn lên và xuống
  • Mouse Wheel + Shift để cuộn trái và phải
  • Left Click trên các mũi tên trái/phải của một prop để di chuyển đến keyframe trước/sau
  • Left Click trên biểu tượng losange của một prop để thêm/xóa một keyframe
  • Left Click trên biểu tượng đường cong của một prop để bật/tắt trình chỉnh sửa đường cong
  • Left Click trên đường giữa hai keyframe để chọn một thiết lập trước đường cong hoặc tinh chỉnh đường cong
  • Left Click và kéo trên đường giữa hai keyframe để di chuyển toàn bộ nhóm và các keyframe tiếp theo

Hãy thử tạo hoạt hình cho vị trí x của quyển sách:

  • Chúng ta tạo một keyframe ở đầu của timeline
  • Chúng ta di chuyển đầu phát đến vị trí kết thúc dự kiến
  • Chúng ta thay đổi giá trị x bằng cách kéo giá trị trên panel chi tiết
  • Nó tự động tạo một keyframe tại vị trí hiện tại của đầu phát
  • Chúng ta đặt đầu phát đến đầu của timeline và nhấn Space để phát hoạt hình

Đây là một hoạt hình rất đơn giản nhưng là một khởi đầu tốt.

Việc chỉnh sửa các giá trị bằng thanh trượt không thực sự tiện lợi. Chúng ta có thể sử dụng snapshot view để di chuyển các đối tượng trong không gian 3D và thấy sự thay đổi trong thời gian thực.

Chế độ xem Snapshot

Chế độ xem Snapshot là một cách biểu diễn cảnh với các điều khiển bổ sung để di chuyển các đối tượng trong không gian 3D. Chúng ta có thể kích hoạt nó bằng cách nhấp vào biểu tượng camera trong bảng điều khiển outline.

Chế độ xem Snapshot trong Theatre.js Studio

Chúng ta có thể thấy lưới, các điều khiển khác nhau và cách hiển thị cảnh. Có một lỗi ở góc trên bên phải. Nó được dự định là bản xem trước của cảnh nhưng hiện tại chưa hoạt động.

Chúng ta cần cập nhật cấu hình renderer trên thành phần Canvas để làm cho nó hoạt động:

// ...

function App() {
  // ...

  return (
    <>
      {/* ... */}
      <Canvas
        camera={{ position: [5, 5, 10], fov: 30, near: 1 }}
        shadows
        gl={{
          preserveDrawingBuffer: true,
        }}
      >
        {/* ... */}
      </Canvas>
    </>
  );
}

export default App;

Bây giờ chúng ta có thể thấy bản xem trước của cảnh trong chế độ xem snapshot từ góc nhìn của camera.

Dưới đây là một số phím tắt hữu ích để điều hướng trong chế độ xem snapshot:

  • Left Click để chọn một đối tượng
  • Shift + Left Mouse hoặc Right Mouse để di chuyển camera
  • Alt + Left Mouse để xoay camera
  • Mouse Wheel để phóng to và thu nhỏ

Hãy nhấp vào ánh sáng và điều chỉnh vị trí của nó để xem trước trong thời gian thực sự di chuyển của bóng nó tạo ra.

Chung

Điều này có thể hữu ích khi biết, ở khắp mọi nơi trong studio:

  • Ctrl + Z hoặc Cmd + Z để hoàn tác
  • Ctrl + Shift + Z hoặc Cmd + Shift + Z để làm lại

Thị trấn trung cổ

Chúng ta đã đề cập đến những điều cơ bản, bây giờ là lúc xây dựng các chuỗi hoạt ảnh khi chúng ta chuyển đổi giữa các phần khác nhau của trang web.

Chúng ta sẽ học dần dần, có thể mất thời gian để quen với studio nhưng nó đáng giá. Kết quả sẽ rất tuyệt vời.

Chuỗi

Dự án của chúng ta sẽ có 3 chuỗi:

  • Giới thiệu khi trải nghiệm bắt đầu đến phần Home
  • Chuyển tiếp đến phần Castle
  • Chuyển tiếp đến phần Windmill

Cách dễ nhất để sử dụng Theatre.js là chơi chuỗi theo cách tuyến tính và tạm dừng khi chúng ta muốn.

Ví dụ bằng cách theo thứ tự này: Giới thiệu -> Home -> Castle -> Windmill

Nhưng, chúng ta là những người thích thử thách và muốn học nhiều hơn nên chúng ta sẽ làm mọi thứ khác biệt.

Phần Home sẽ là trạng thái mặc định của trang web. Các phần CastleWindmill sẽ có thể truy cập từ phần Home mà không cần phải đi qua phần khác. (Windmill cho Castle và ngược lại)

Đáng tiếc là, hiện tại, Theatre.js không hỗ trợ nhiều chuỗi cho mỗi sheet. Chúng ta vẫn có thể dùng một cách giải quyết bằng cách thêm tất cả các chuyển đổi của chúng ta vào một chuỗi duy nhất và sau đó sử dụng API để chơi các chuyển đổi phù hợp vào đúng thời điểm.

Camera và mục tiêu của camera

Thành phần chính của chuyển đổi của chúng ta sẽ là hoạt ảnh Camera. Chúng ta sẽ thực hiện hoạt ảnh cho position của nó và nơi nó đang nhìn.

Hiện tại, chúng ta đang sử dụng camera được tạo tự động bởi thành phần Canvas. Chúng ta cần tạo camera của riêng mình để có thể thực hiện hoạt ảnh cho nó:

// ...
import { PerspectiveCamera } from "@theatre/r3f";

function App() {
  // ...

  return (
    <>
      {/* ... */}
      <Canvas
        camera={{ position: [5, 5, 10], fov: 30, near: 1 }}
        shadows
        gl={{
          preserveDrawingBuffer: true,
        }}
      >
        <SoftShadows />
        <SheetProvider sheet={mainSheet}>
          <PerspectiveCamera
            position={[5, 5, 10]}
            fov={30}
            near={1}
            makeDefault
            theatreKey="Camera"
          />
          <Experience />
        </SheetProvider>
      </Canvas>
    </>
  );
}

// ...

Lưu ý rằng PerspectiveCamera được nhập từ Theatre.js chứ không phải từ Drei library. Đây là lý do tại sao chúng ta không cần thêm thành phần editable.

Điều này tốt cho vị trí camera, nhưng đối với mục tiêu camera, chúng ta sẽ sử dụng một mesh chỉ nhìn thấy trong studio. Bằng cách này, chúng ta có thể thực hiện hoạt ảnh cho vị trí của nó và camera sẽ nhìn vào nó. (Dễ hơn nhiều so với việc thực hiện hoạt ảnh cho rotation của camera)

// ...
import { useRef } from "react";

// ...

function App() {
  // ...
  const cameraTargetRef = useRef();
  return (
    <>
      {/* ... */}
      <Canvas
        camera={{ position: [5, 5, 10], fov: 30, near: 1 }}
        shadows
        gl={{
          preserveDrawingBuffer: true,
        }}
      >
        <SoftShadows />
        <SheetProvider sheet={mainSheet}>
          <PerspectiveCamera
            position={[5, 5, 10]}
            fov={30}
            near={1}
            makeDefault
            theatreKey="Camera"
            lookAt={cameraTargetRef}
          />
          <e.mesh
            theatreKey="Camera Target"
            visible="editor"
            ref={cameraTargetRef}
          >
            <octahedronBufferGeometry args={[0.1, 0]} />
            <meshPhongMaterial color="yellow" />
          </e.mesh>
          <Experience />
        </SheetProvider>
      </Canvas>
    </>
  );
}

Bây giờ chúng ta có thể quyết định chính xác vị trí của camera, nơi nó đang nhìn và thực hiện hoạt ảnh cho nó.

Cristopher Nolan

Chúng ta sẽ tạo ra 3 chuyển cảnh:

  • Home: Vị trí bắt đầu đến phần Home
  • Castle: Phần Home đến phần Castle
  • Windmill: Phần Home đến phần Windmill

Trước tiên, hãy bỏ cuốn sách trong dòng thời gian đi, chúng ta không cần nó nữa.

Nhấp vào MedievalFantasyBook trong bảng điều hướng, mở rộng bảng chi tiết, nhấp chuột phải vào x, hoặc props nếu bạn đã tạo keyframe cho các thuộc tính khác, và nhấp vào Make static (hoặc Make all static).

Bây giờ, đối với CameraCamera Target, mở bảng chi tiết, nhấp chuột phải vào positionSequence all.

Đã đến lúc đội mũ giám đốc của bạn, chúng ta sẽ tạo chuỗi Home. Bạn có quyền chọn vị trí bạn thích. Điều quan trọng nhất là điểm bắt đầu và kết thúc.

Hãy thử chơi với nhiều keyframe.

Đây là những gì tôi đã tạo ra:

Thời lượng tôi chọn là 5 giây.

Bây giờ, chúng ta tạo tiếp chuỗi thứ hai. Nhưng hãy nhớ, chúng ta không sử dụng phương pháp tuyến tính và các chuỗi trong một sheet đơn lẻ không tồn tại...

Những gì chúng ta sẽ làm là sao chép lại các keyframe cuối cùng ở giây thứ 6 trên dòng thời gian để làm điểm bắt đầu cho chuỗi thứ hai.

Theo cách tiếp cận của tôi, điều đó sẽ rất dễ dàng. Ngay cả khi bạn muốn thay đổi nó sau này, bạn cũng có thể dễ dàng thực hiện.

Di chuyển playhead đến nơi bạn muốn dán các keyframe. (Để tránh nó can thiệp vào những gì chúng ta sẽ làm)

Nhấn Shift và chọn keyframe Main. Nó sẽ tự động chọn tất cả các phần con của nó.

Sau đó, Nhấp chuột phải hoặc sử dụng tổ hợp sao chép yêu thích của bạn, và Copy.

Di chuyển con trỏ của bạn trên playhead, Nhấp chuột phảiPaste.

Thật kỳ diệu! Chúng ta đã có điểm bắt đầu cho chuỗi thứ hai.

Bây giờ tạo chuỗi thứ hai, và lặp lại quy trình cho chuỗi thứ ba.

Phát chuyển cảnh

Bây giờ, bạn đã sẵn sàng dòng thời gian của mình, đã đến lúc phát chuyển cảnh đúng lúc.

Hãy định nghĩa một biến toàn cục dưới mainSheet. Nó sẽ là một map của tất cả các chuyển cảnh của chúng ta. Đối với mỗi khóa (tên phần), chúng ta sẽ có một mảng hai giá trị: vị trí bắt đầu và kết thúc của chuyển cảnh.

// ...

const transitions = {
  Home: [0, 5],
  Castle: [6, 12 + 16 / 30],
  Windmill: [14, 18 + 5 / 30],
};

// ...

Đây là các giá trị của tôi. Để tìm giá trị của bạn, hãy vào sequence editor và xem vị trí của playhead khi bạn muốn bắt đầu và kết thúc chuyển cảnh.

18s05f nghĩa là 18 giây và 5 frame. 30 frame = 1 giây (đối với Theatre.js), đó là lý do chúng ta chia cho 30.

Dự án khởi đầu đã chứa các trạng thái cho currentScreentargetScreen.

targetScreen được cập nhật khi chúng ta nhấp vào nút trong UI. currentScreen được cập nhật khi sequence kết thúc.

Chúng ta sẽ sử dụng hook useEffect để phát chuyển cảnh đúng khi targetScreen thay đổi:

import { useEffect } from "react";
// ...

function App() {
  // ...
  useEffect(() => {
    project.ready.then(() => {
      if (currentScreen === targetScreen) {
        return;
      }
      const reverse = targetScreen === "Home" && currentScreen !== "Intro";
      const transition = transitions[reverse ? currentScreen : targetScreen];
      if (!transition) {
        return;
      }

      mainSheet.sequence
        .play({
          range: transition,
          direction: reverse ? "reverse" : "normal",
          rate: reverse ? 2 : 1,
        })
        .then(() => {
          setCurrentScreen(targetScreen);
        });
    });
  }, [targetScreen]);

  // ...
}

export default App;

Hãy phân tích từng phần:

  • Chúng ta chờ cho dự án được tải bởi Theatre.js
  • Nếu targetScreen giống với currentScreen, chúng ta không làm gì cả
  • Nếu chúng ta chuyển đến phần home từ một phần khác không phải intro, chúng ta phát chuyển cảnh ngược lại
  • Chúng ta phát chuyển cảnh
  • Ngược lại, chúng ta phát chuyển cảnh với tốc độ 2x

Chúng ta có một chút lỗi nhỏ vì chúng ta đang ở chế độ strict mode. useEffect của chúng ta được gọi hai lần. Hãy tạo một ref boolean để không kích hoạt lại hiệu ứng:

function App() {
  // ...

  const isSetup = useRef(false);

  useEffect(() => {
    project.ready.then(() => {
      if (currentScreen === targetScreen) {
        return;
      }
      if (isSetup.current && currentScreen === "Intro") {
        // Chế độ strict trong phát triển sẽ kích hoạt useEffect hai lần, vì vậy chúng ta cần kiểm tra xem nó đã được thiết lập chưa
        return;
      }
      isSetup.current = true;
      // ...
    });
  }, [targetScreen]);
  // ...
}
// ...

Bắt đầu trông rất chuyên nghiệp phải không?

Lấy Nét Tự Động

Để tạo ra một hiệu ứng điện ảnh, chúng ta sẽ thêm hiệu ứng độ sâu trường ảnh vào camera. Chúng ta sẽ sử dụng hiệu ứng xử lý hậu kỳ lấy nét tự động.

Trước tiên, hãy cài đặt các phụ thuộc cần thiết:

yarn add @react-three/postprocessing

Sau đó, hãy thêm thành phần Autofocus vào trong Experience của chúng ta:

// ...
import { Autofocus, EffectComposer } from "@react-three/postprocessing";
export const Experience = () => {
  return (
    <>
      {/* ... */}
      <EffectComposer>
        <Autofocus
          smoothTime={0.1}
          debug={0.04}
          focusRange={0.002}
          bokehScale={8}
        />
      </EffectComposer>
    </>
  );
};

Với debug chúng ta có thể thấy nơi mà camera đang lấy nét.

Hãy tạo một mục tiêu cho camera để lấy nét. Chúng ta sẽ sử dụng một mesh chỉ hiển thị trong studio và sao chép vị trí của nó vào mục tiêu lấy nét tự động ở mỗi frame:

// ...
import { useFrame } from "@react-three/fiber";
import { useRef } from "react";
import { Vector3 } from "three";
export const Experience = () => {
  const focusTargetRef = useRef(new Vector3(0, 0, 0));

  const focusTargetVisualizerRef = useRef();

  useFrame(() => {
    if (focusTargetVisualizerRef.current) {
      focusTargetRef.current.copy(focusTargetVisualizerRef.current.position);
    }
  });

  return (
    <>
      {/* ... */}
      <e.mesh
        theatreKey="FocusTarget"
        ref={focusTargetVisualizerRef}
        visible="editor"
      >
        <sphereBufferGeometry args={[0.01, 8, 8]} />
        <meshBasicMaterial color="red" wireframe />
      </e.mesh>
      <EffectComposer>
        <Autofocus
          target={focusTargetRef.current}
          smoothTime={0.1}
          debug={0.04}
          focusRange={0.002}
          bokehScale={8}
        />
      </EffectComposer>
    </>
  );
};

Bây giờ chúng ta có khả năng điều chỉnh vị trí lấy nét một cách độc lập.

Nhiệm vụ của bạn là tạo hoạt cảnh cho vị trí FocusTarget trong trình chỉnh sửa chuỗi để tạo ra một vẻ điện ảnh.

Khi hệ thống của chúng ta đã được thiết lập sẵn, bạn chỉ cần tích hợp nó vào các hoạt cảnh hiện tại.

Chuẩn bị cho sản xuất

Khi chúng ta đã hài lòng với các hoạt ảnh của mình, đó là lúc chuẩn bị dự án để đưa vào sản xuất. Điều này có nghĩa là:

  • Lưu lại dữ liệu hoạt ảnh để tránh mất nếu chúng ta mất bộ nhớ địa phương hoặc ghi đè khóa dự án của mình từ một dự án khác.
  • Không hiển thị studio trên trang web cuối cùng.

Lưu/tải dữ liệu hoạt ảnh

Trên outline panel, nhấp vào tên dự án. Trong trường hợp này, đó là MedievalTown. Sau đó, trong details panel, nhấp vào Export MedievalTown to JSON.

Nó sẽ tải xuống một tập tin JSON chứa tất cả dữ liệu hoạt ảnh. Chúng ta có thể đặt tập tin vào thư mục src/assets.

Chúng ta muốn phân biệt khi nào chúng ta đang ở chế độ phát triển hay sản xuất để chỉ tải dữ liệu hoạt ảnh khi ở chế độ sản xuất. Nhờ vậy, ta vẫn có thể chỉnh sửa hoạt ảnh trong quá trình phát triển.

Chúng ta có thể lấy thông tin này từ environment:

export const isProd = import.meta.env.MODE === "production";

Nếu bạn không sử dụng Vite, bạn có thể sử dụng process.env.NODE_ENV === "production" thay thế.

Hãy tải dữ liệu hoạt ảnh vào dự án. Trong App.jsx:

// ...
import projectState from "./assets/MedievalTown.theatre-project-state.json";

// ...
const project = getProject(
  "MedievalTown",
  isProd
    ? {
        state: projectState,
      }
    : undefined
);
// ...

Kết xuất điều kiện của Theatre.js

Để không hiển thị studio trên trang web cuối cùng, chúng ta sẽ đặt việc khởi tạo studio trong một điều kiện:

// ...

if (!isProd) {
  studio.initialize();
  studio.extend(extension);
}

// ...

Chúng ta cũng muốn ẩn debug của Autofocus. Chúng ta có thể đặt điều kiện này trong Experience.jsx:

// ...
import { isProd } từ "../App";

export const Experience = () => {
  // ...

  return (
    <>
      {/* ... */}
      <EffectComposer>
        <Autofocus
          target={focusTargetRef.current}
          smoothTime={0.1}
          debug={isProd ? undefined : 0.04}
          focusRange={0.002}
          bokehScale={8}
        />
      </EffectComposer>
    </>
  );
};

Giờ là lúc kiểm tra dự án trong chế độ sản xuất. Để thực hiện, chạy yarn build và sau đó yarn preview.

Chia sẻ kết quả của bạn trên cộng đồng Discord! Tôi tò mò muốn xem bạn đã làm được gì! 🎥

Kết luận

Chúng ta đã học cách sử dụng Theatre.js để tạo ra các chuyển cảnh 3D tuyệt vời, cách sử dụng studio để tạo và chỉnh sửa hoạt hình một cách trực quan, và cách chuẩn bị dự án cho sản xuất.

Tôi khuyên bạn nên xem qua tài liệu chính thức để khám phá tất cả các tính năng của Theatre.js mà chúng ta chưa đề cập trong bài học này.

Điều còn lại là thực hành. Bạn càng sử dụng nhiều, bạn càng cảm thấy thoải mái hơn với nó.

Three.js logoReact logo

React Three Fiber: The Ultimate Guide to 3D Web Development

✨ You have reached the end of the preview ✨

Go to the next level with Three.js and React Three Fiber!

Get full access to this lesson and the complete course when you enroll:

  • 🔓 Full lesson videos with no limits
  • 💻 Access to the final source code
  • 🎓 Course progress tracking & completion
  • 💬 Invite to our private Discord community
Unlock the Full Course – Just $85

One-time payment. Lifetime updates included.