Wawa Sensei logo

Render Target

Starter pack

जब हम React Three Fiber का उपयोग करते हैं, हम बस एक Canvas कॉम्पोनेंट जोड़ते हैं और अपनी 3D सीन उसमें रखते हैं, और यह स्क्रीन पर रेंडर हो जाएगा।

यदि आपके पास Three.js का कुछ अनुभव है, तो आप जानते हैं कि हमें पहले एक WebGLRenderer बनाना पड़ता है और फिर renderer.render(scene, camera) कॉल करना पड़ता है अपनी सीन को स्क्रीन पर रेंडर करने के लिए।

सौभाग्य से, React Three Fiber यह सब हमारे लिए पृष्ठभूमि में करता है, लेकिन अधिक उन्नत उपयोग मामलों के लिए यह जानना महत्वपूर्ण है कि यह कैसे काम करता है।

renderer का काम 3D सीन को प्रोसेस करना है ताकि हम स्क्रीन पर 2D इमेज देख सकें।

डिफ़ॉल्ट रूप से, renderer का आउटपुट Canvas कॉम्पोनेंट में सेट होता है और स्क्रीन पर प्रदर्शित होता है, लेकिन हम इसे एक टेक्सचर (एक WebGLRenderTarget के माध्यम से) में भी आउटपुट कर सकते हैं।

फिलहाल यह थोड़ा सैद्धांतिक हो सकता है, चलिए देखते हैं कि यह वास्तविकता में कैसे काम करता है और हम इसे किस प्रकार के रचनात्मक तरीकों में उपयोग कर सकते हैं।

Security Camera

समझने के लिए कि Render Targets कैसे काम करते हैं और हम इनके साथ क्या कर सकते हैं, मैंने एक 3D सीन तैयार किया है जिसमें शामिल हैं:

  • एक लिविंग रूम 3D मॉडल एलेक्स सफायन CC-BY के द्वारा Poly Pizza
  • एक Ready Player Me अवतार (जैसा कि हम पोर्टफोलियो लेसन में उपयोग करते हैं) जो टीवी पर SpongeBob Squarepants देख रहा है
  • एक 2D रिमोट कंट्रोल जिसमें कई बटन हैं

टीवी देखता हुआ 3D अवतार

लक्ष्य एक सर्विलांस सिस्टम बनाना है जिसमें सीन को security camera के दृष्टिकोण से टीवी पर रेंडर किया जाए।

दृश्य को एक टेक्सचर पर रेंडर करना

हमारे वर्तमान दृश्य को टेक्सचर पर रेंडर करने के लिए, हमें एक Render Target बनाना होगा।

Drei लाइब्रेरी के धन्यवाद, हम useFBO हुक का उपयोग करके आसानी से एक Render Target बना सकते हैं:

// ...
import { useFBO } from "@react-three/drei";

export const Experience = () => {
  const cornerRenderTarget = useFBO();
  // ...
};

यदि आप जानना चाहते हैं कि एक Render Target को प्रारंभ से कैसे बनाया जाए, तो आप useFBO हुक का सोर्स कोड यहाँ देख सकते हैं। यह एक अच्छा तरीका है कि आप समझ सकें कि चीज़ें अंदर से कैसे काम करती हैं।

अब जब हमारे पास एक Render Target है, हमें अपने renderer को बताना होगा कि हमारे scene को हमारे camera का उपयोग करके रेंडर करना है।

ये सभी ऑब्जेक्ट्स हमारी React Three Fiber एप्लिकेशन की root state में उपलब्ध हैं। यह वही ऑब्जेक्ट है जो useThree हुक द्वारा लौटाया जाता है।

gl प्रॉपर्टी renderer है।

लेकिन, क्योंकि हम टीवी पर जो हो रहा है उसे वास्तविक समय में दिखाना चाहते हैं, हम इस प्रक्रिया को प्रत्येक फ्रेम पर useFrame हुक का उपयोग करके करेंगे।

कॉलबैक फ़ंक्शन में root state शामिल होती है, ताकि हम सीधे इसमें से अपने वेरिएबल्स को एक्सेस कर सकें:

// ...
import { useFrame } from "@react-three/fiber";

export const Experience = () => {
  // ...
  useFrame(({ gl, camera, scene }) => {
    gl.setRenderTarget(cornerRenderTarget);
    gl.render(scene, camera);
    gl.setRenderTarget(null);
  });
  // ...
};

यहां हम जो कर रहे हैं वह है:

  • Render Target को renderer आउटपुट के रूप में सेट करना
  • camera का उपयोग करके scene को रेंडर करना और क्योंकि renderer आउटपुट Render Target पर सेट है, यह दृश्य को उस पर रेंडर करेगा
  • renderer आउटपुट को null पर सेट करना ताकि दृश्य को फिर से कैनवास पर रेंडर किया जा सके

अब जब हमारे पास हमारा Render Target है, हमें इसे टीवी पर दिखाने की जरूरत है। आइए वर्तमान में वीडियो रेंडर करने वाले material को एक रेफरेंस जोड़ें:

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

export const Experience = () => {
  // ...
  const tvMaterial = useRef();
  // ...
  return (
    <>
      {/* ... */}
      <group position-y={-0.5}>
        <group>
          <Sky />
          <Avatar rotation-y={Math.PI} scale={0.45} position-z={0.34} />
          <Gltf src="models/Room.glb" scale={0.3} rotation-y={-Math.PI / 2} />
          <mesh position-x={0.055} position-y={0.48} position-z={-0.601}>
            <planeGeometry args={[0.63, 0.44]} />
            <meshBasicMaterial ref={tvMaterial} />
          </mesh>
        </group>
      </group>
      {/* ... */}
    </>
  );
};

और फिर, हम useFrame हुक का उपयोग कर material की map प्रॉपर्टी को हमारे Render Target के साथ अपडेट कर सकते हैं:

// ...
export const Experience = () => {
  // ...
  useFrame(({ gl, camera, scene }) => {
    // ...
    tvMaterial.current.map = cornerRenderTarget.texture;
  });
  // ...
};

3D अवतार टीवी पर सुरक्षा कैमरे का दृश्य देख रहा है

अब हम टीवी पर सुरक्षा कैमरा दृश्य देख सकते हैं, लेकिन सुरक्षा कैमरे के दृश्य में टीवी स्क्रीन खाली है।

इसका कारण यह है कि जब हम दृश्य को Render Target पर रेंडर करते हैं, तो हमारी स्क्रीन खाली रहती है।

इन्सेप्शन प्रभाव

टीवी स्क्रीन के अंदर सुरक्षा कैमरा दृश्य को देखने के लिए 🤯, हमें:

  • एक और रेंडर टारगेट बनाना होगा (हम इसे bufferRenderTarget नाम देंगे)
  • सीन को इस पर रेंडर करना होगा
  • इसे टीवी स्क्रीन material से संलग्न करना होगा
  • सीन को corderRenderTarget पर रेंडर करना होगा
  • इसे टीवी material से संलग्न करना होगा
// ...
export const Experience = () => {
  const bufferRenderTarget = useFBO();

  // ...
  useFrame(({ gl, camera, scene }) => {
    gl.setRenderTarget(bufferRenderTarget);
    gl.render(scene, camera);
    tvMaterial.current.map = bufferRenderTarget.texture;
    gl.setRenderTarget(cornerRenderTarget);
    gl.render(scene, camera);
    gl.setRenderTarget(null);
    tvMaterial.current.map = cornerRenderTarget.texture;
  });
  // ...
};

यह डरावना लग सकता है लेकिन वास्तव में यह बहुत सरल है। बस हर कदम पर क्या हो रहा है इसके बारे में सोचें।

अब हमारी सीन टीवी स्क्रीन के अंदर अनंत रूप से रेंडर हो रही है!

हालांकि यह सबसे यथार्थवादी प्रभाव है जिसे हम बना सकते हैं, यह सबसे रचनात्मक नहीं है। आइए inception प्रभाव को हटा दें और बजाय स्क्रीन पर Spongebob Squarepants दिखाएं:

End of lesson preview

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