Wawa Sensei logo

Shader transitions

Starter pack

इस पाठ में हम shaders का उपयोग करके transitions बनाना सीखेंगे।

पहला प्रभाव जो हम बनाएंगे वह एक स्क्रीन transition प्रभाव है:

हमारे पास transition प्रभाव पर पूरा नियंत्रण होगा, हम अवधि, easing function, और shader को बदल सकते हैं।

दूसरा प्रभाव जो हम बनाएंगे वह एक मॉडल transition प्रभाव है:

मॉडल को fading out करने पर यह dissolve हो जाता है और रंग सफेद में धुल जाते हैं, fading in के समय इसके विपरीत होता है।

Starter pack

Ergoni द्वारा और Creative Commons Attribution के तहत लाइसेंस प्राप्त ये सभी 3D मॉडल इस पाठ में उपयोग होंगे:

Starter pack में निम्नलिखित पैकेजों का उपयोग किया गया है:

  • स्टाइलिंग के लिए Tailwind CSS
  • एनिमेशन के लिए Framer Motion
  • कंपोनेंट्स के बीच साझा state को प्रबंधित करने के लिए Jotai library

दो फ़ॉन्ट जो उपयोग किए गए हैं वो हैं Kanit और Rubik Doodle Shadow, दोनों Google Fonts से हैं।

कृपया अपनी पसंदानुसार किसी भी कंपोनेंट को समायोजित करने के लिए स्वतंत्र महसूस करें।

आप Leva कंट्रोल्स का उपयोग करके रंगों को समायोजित कर सकते हैं जो ऊपर दाईं ओर हैं। एक बार जब आपको पसंद आने वाले रंग मिल जाएं, तो App.jsx में Leva कंपोनेंट में 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>
  );
};

इस घटक में, हम एक प्लेन बना रहे हैं जिसका रंग पूरे स्क्रीन को कवर करेगा। हम इस प्लेन का उपयोग स्क्रीन के बीच संक्रमण करने के लिए करेंगे।

हमारे घटक में दो props हैं:

  • transition: एक boolean जो बताता है कि घटक को संक्रमण प्रभाव प्रदर्शित करना चाहिए या नहीं
  • color: संक्रमण प्रभाव का मुख्य रंग

आइए ScreenTransition घटक को App.jsx में जोड़ें:

// ...
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 in middle of the scene

प्लेन सीन के बीच में है।

Fullscreen plane

हम चाहते हैं कि हमारा plane पूरे स्क्रीन को कवर करे। हम viewport आयामों का उपयोग कर सकते हैं और इसे कैमरे की ओर घुमा सकते हैं, लेकिन हम इसे सब कुछ के ऊपर भी रखना चाहते हैं।

इसको हासिल करने के लिए, Drei एक Hud कॉम्पोनेन्ट प्रदान करता है जो अपने बच्चों को सब कुछ के ऊपर रेंडर करेगा। हम निश्चित रूप से यह सुनिश्चित करने के लिए Hud कॉम्पोनेन्ट में एक स्थिर कैमरा जोड़ सकते हैं कि यह हमारे plane के साथ पूरी तरह से संरेखित हो:

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 का उपयोग करते हैं ताकि जिस दूरी पर भी कैमरा और plane के बीच हो, पूरे स्क्रीन को आसानी से कवर किया जा सके।

Plane covering the entire screen

plane अब पूरे स्क्रीन को कवर कर रहा है।

ट्रांज़िशन लॉजिक

हमारा कस्टम shader बनाने से पहले, UI.jsx में एक transition state को परिभाषित करते हैं:

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

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

हम शुरुआती मूल्य को true पर सेट करते हैं ताकि वेबसाइट लोड होने के बाद एक fade-out प्रभाव से शुरू हो सके।

हम इस state का उपयोग ट्रांज़िशन प्रभाव को नियंत्रित करने के लिए करेंगे।

अभी भी UI.jsx में, हम दो constants को परिभाषित करेंगे जो ट्रांज़िशन प्रभाव की अवधि और विलंब को नियंत्रित करेंगे:

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

अब हम setScreen function call को एक नए function से बदलेंगे जो ट्रांज़िशन प्रभाव को संभालेगा:

// ...
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 state को true पर सेट करते हैं और setTimeout का उपयोग करते हैं ताकि ट्रांज़िशन प्रभाव के बाद नया स्क्रीन सेट किया जा सके (ट्रांज़िशन प्रभाव की अवधि प्लस विलंब)

अब हमारा function तैयार है, UI component में setScreen कॉल्स को खोजें और उन्हें transitionToScreen से बदल दें।

home से menu की ओर:

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

और menu से home की ओर:

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

End of lesson preview

To get access to the entire lesson, you need to purchase the course.