Shader 전환

Starter pack

이 강의에서는 셰이더를 사용하여 전환 효과를 만드는 방법을 배워봅니다.

첫 번째로 만들 효과는 화면 전환 효과입니다:

전환 효과에 대한 완전한 제어가 가능하며, 지속 시간, 이징 함수 및 셰이더 자체를 변경할 수 있습니다.

두 번째로 만들 효과는 모델 전환 효과입니다:

모델이 사라질 때 흰색으로 녹아내리고 색상이 바뀌며, 반대의 경우도 마찬가지입니다.

시작 패키지

이 강의에서 사용할 모든 3D 모델은 Ergoni의 작품으로, Creative Commons Attribution에 따라 라이선스가 부여되었습니다:

시작 패키지에서 사용되는 패키지는 다음과 같습니다:

사용된 폰트는 Google FontsKanitRubik Doodle Shadow입니다.

컴포넌트는 자유롭게 조정하여 원하는 대로 설정하실 수 있습니다.

Leva 컨트롤을 오른쪽 상단에서 조작하여 색상을 조정할 수 있습니다. 원하는 색상을 찾았으면, App.jsxLeva 컴포넌트에 hidden 속성을 추가하세요:

// ...

function App() {
  // ...
  return (
    <>
      <Leva hidden />
      {/* ... */}
    </>
  );
}

// ...

화면 전환

화면 전환 효과를 만들면서 시작해 봅시다. 우리는 전환 효과를 처리할 ScreenTransition이라는 컴포넌트를 만들 것입니다.

components 폴더에 ScreenTransition.jsx라는 새 파일을 만듭니다:

export const ScreenTransition = ({ transition, color }) => {
  return (
    <mesh>
      <planeGeometry args={[2, 2]} />
      <meshBasicMaterial color={color} />
    </mesh>
  );
};

이 컴포넌트에서는 화면 전체를 덮을 색상의 plane을 만들고 있습니다. 이 plane을 사용하여 화면 간 전환을 수행할 것입니다.

우리의 컴포넌트는 두 개의 props를 받습니다:

  • transition: 컴포넌트가 전환 효과를 표시해야 하는지 여부를 결정하는 boolean 값
  • color: 전환 효과의 주요 색상

App.jsxScreenTransition 컴포넌트를 추가합시다:

// ...
import { ScreenTransition } from "./components/ScreenTransition";

function App() {
  // ...
  return (
    <>
      {/* ... */}
      <Canvas camera={{ position: [0, 1.8, 5], fov: 42 }}>
        <color attach="background" args={[backgroundColor]} />
        <fog attach="fog" args={[backgroundColor, 5, 12]} />
        <ScreenTransition transition color="#a5b4fc" />
        <Suspense>
          <Experience />
        </Suspense>
      </Canvas>
    </>
  );
}

export default App;

현재는 transition prop에 true를 전달하여 전환 효과를 강제로 표시하도록 하고 있습니다. 나중에 전환 효과를 제어하는 로직을 추가할 것입니다.

색상을 원하는 대로 조정하세요. 색상을 변경하면, 웹 사이트가 로드될 때 색상이 깜빡이는 것을 방지하기 위해 index.css 파일의 색상도 업데이트하세요:

// ...

html {
  background-color: #a5b4fc;
}

장면 가운데의 plane

plane가 장면의 정중앙에 위치해 있습니다.

전체 화면을 덮는 평면

우리의 평면이 화면 전체를 덮기를 원합니다. viewport 크기를 사용하여 카메라를 바라보게 만들 수 있지만, 우리는 또한 그것이 모든 것 위에 위치하기를 원합니다.

이를 달성하기 위해 Drei는 모든 것 위에 자식을 렌더링하는 Hud 컴포넌트를 제공합니다. Hud 컴포넌트에 고정 카메라를 추가하여 평면과 완벽하게 정렬되도록 할 수 있습니다:

import { Hud, OrthographicCamera } from "@react-three/drei";

export const ScreenTransition = ({ transition, color }) => {
  return (
    <Hud>
      <OrthographicCamera
        makeDefault
        top={1}
        right={1}
        bottom={-1}
        left={-1}
        near={0}
        far={1}
      />
      <mesh>
        <planeGeometry args={[2, 2]} />
        <meshBasicMaterial color={color} />
      </mesh>
    </Hud>
  );
};

OrthographicCamera를 사용하여 카메라와 평면 사이의 거리와 상관없이 쉽게 전체 화면을 덮을 수 있습니다.

평면이 화면 전체를 덮고 있음

평면이 이제 화면 전체를 덮고 있습니다.

전환 논리

커스텀 셰이더를 만들기 전에 마지막으로 UI.jsx에서 전환 상태를 정의해 봅시다:

// ...
import { atom } from "jotai";

export const transitionAtom = atom(true);
// ...

웹사이트가 로드된 후 페이드 아웃 효과를 시작하기 위해 초기 값을 true로 설정합니다.

이 상태를 사용하여 전환 효과를 제어할 것입니다.

여전히 UI.jsx에서 전환 효과의 지속 시간과 지연을 제어할 두 개의 상수를 정의하겠습니다:

// ...
export const TRANSITION_DELAY = 0.8;
export const TRANSITION_DURATION = 3.2;
// ...

이제 setScreen 함수 호출을 전환 효과를 처리할 새로운 함수로 교체해 봅시다:

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

export const UI = () => {
  // ...
  const [transition, setTransition] = useAtom(transitionAtom);
  const timeout = useRef();

  // ...
  const transitionToScreen = (newScreen) => {
    setTransition(true);
    clearTimeout(timeout.current);
    timeout.current = setTimeout(() => {
      setScreen(newScreen);
      setTransition(false);
    }, TRANSITION_DURATION * 1000 + TRANSITION_DELAY * 1000);
  };
  // ...
};

직접 새로운 화면을 설정하는 대신, transition 상태를 true로 설정하고 setTimeout을 사용하여 전환 효과가 끝난 후 (전환 효과의 지속 시간과 지연의 합) 새로운 화면을 설정합니다.

이제 함수가 준비되었으니, UI 컴포넌트에서 setScreen 호출을 찾아 transitionToScreen으로 교체하세요.

에서 메뉴로:

<motion.button
  onClick={() => transitionToScreen("menu")}
  // ...
>

그리고 메뉴에서 으로:

<motion.button
onClick={() => transitionToScreen("home")}
// ...
>
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.