개발/React : React Three Fiber

【React Three Fiber】#04 카메라: StereoCamera

고독한 쵸이 2023. 9. 1. 23:15
반응형

이번 글에서는 일반적으로 잘 사용되지는 않지만, VR/AR개발 등에서 주로 사용되는 StereoCamera에 대해 알아보자.

 

이전 글은 아래를 참고해 주세요.

【React Three Fiber】#03 카메라: Orthographic Camera, OrbitControls

 

【React Three Fiber】#03 카메라: Orthographic Camera, OrbitControls

이번 글에서는 React Three Fiber의 카메라 중 Orthographic Camera, 그리고 카메라를 제어할 수 있는 OrbitControls에 대해 작성해보고자 한다. 이전 글은 아래를 참고해 주세요. 【React Three Fiber】#02 카메라: Pe

solitary-choi.tistory.com

 

서론

이번 포스트에서 소개할 StereoCamera를 포함한 아래 세 카메라의 경우, 이전에 학습한 PerspectiveCamera나 OrthographicCamera와는 다르게 Canvas태그의 프로퍼티를 사용할 수 없기 때문에, three나 다른 라이브러리를 사용할 필요가 있다. (그래서 약간 헤맸다.)

  • StereoCamera
  • CubeCamera
  • ArrayCamera

본인에게는 아직 생소한 카메라들이라, three.js 공식 도큐먼트 예제를 참고로 학습을 진행했다.

 

StereoCamera

스테레오 카메라.

스테레오 비전용 카메라 2대를 붙여, 동시에 2장의 사진을 얻을 수 있게 하는 특수 카메라라고 한다.

 

▼ StereoCamera의 공식 도큐먼트.

https://threejs.org/docs/index.html#api/en/cameras/CubeCamera

 

AnaglyphEffect와 ParallaxBarrier애드온을 사용하여, 실제로 어떤 느낌인지 알아보기로 하자.

 

AnaglyphEffect

▼ Anaglyph(애너글리프)란?

https://ko.wikipedia.org/wiki/애너글리프

 

일단은 박스를 생성한다.

import * as THREE from "three";
import React, { useRef } from "react";
import { useFrame } from "@react-three/fiber";

const Box = () => {
  const boxMeshRef = useRef<THREE.Mesh>(null!);
  useFrame(
    () =>
      (boxMeshRef.current.rotation.x = boxMeshRef.current.rotation.y += 0.001)
  );

  return (
    <mesh ref={boxMeshRef}>
      <boxGeometry />
      <meshStandardMaterial color={0xff12ff} />
    </mesh>
  );
};

그다음, AnnaglyphEffect 애드온을 임포트 하여, Annaglyph 컴포넌트에서 인스턴스를 생성해 준다.

그리고 사이즈를 설정한 후, AnnaglyphEffect를 사용하여 객체를 렌더링 해주자.

import { useThree } from "@react-three/fiber";
import React, { useEffect, useState } from "react";

import { AnaglyphEffect } from "three/examples/jsm/effects/AnaglyphEffect";

const Annaglyph = ({ enabled = false }) => {
  const { gl, scene, camera, size } = useThree();
  const [effect] = useState(() => new AnaglyphEffect(gl));
  useEffect(() => void effect.setSize(size.width, size.height), [size, effect]);

  return useFrame(() => (enabled ? effect : gl).render(scene, camera), 1);
};

전체 코드는 이렇다.

import * as THREE from "three";

import { Canvas, useFrame, useThree } from "@react-three/fiber";
import React, { useEffect, useRef, useState } from "react";

import { AnaglyphEffect } from "three/examples/jsm/effects/AnaglyphEffect";
import { ParallaxBarrierEffect } from "three/examples/jsm/effects/ParallaxBarrierEffect";

const Box = () => {
  const boxMeshRef = useRef<THREE.Mesh>(null!);
  useFrame(
    () =>
      (boxMeshRef.current.rotation.x = boxMeshRef.current.rotation.y += 0.001)
  );

  return (
    <mesh ref={boxMeshRef}>
      <boxGeometry />
      <meshStandardMaterial color={0xff12ff} />
    </mesh>
  );
};

const Annaglyph = ({ enabled = false }) => {
  const { gl, scene, camera, size } = useThree();
  const [effect] = useState(() => new AnaglyphEffect(gl));
  useEffect(() => void effect.setSize(size.width, size.height), [size, effect]);

  return useFrame(() => (enabled ? effect : gl).render(scene, camera), 1);
};

const StereoCamera = () => {
  return (
    <Canvas>
      <Annaglyph enabled={true} />
      <ambientLight />
      <directionalLight color={0xffffff} intensity={1} position={[0, 0, 3]} />
      <Box />
    </Canvas>
  );
};

export default StereoCamera;

그리고 App.tsx에서 StereoCamera를 임포트 한 후, npm start를 실행.

그러면 양쪽에 파랑, 빨강 테두리가 붙어 있는 박스가 렌더링 되는 것을 확인할 수 있다. 

AnnaglyphEffect 애드온을 사용한 결과물

 

ParallaxBarrier

▼ 패럴랙스 배리어(parallax barrier)란?

https://en.wikipedia.org/wiki/Parallax_barrier

 

이번에는 위의 Annaglyph학습에서 사용한 전체 코드에 ParallaxBarrier컴포넌트를 추가해 준다.

단순히 AnnaglyphEffect가 ParallaxBarrierEffect로 변경될 뿐이다.

import { useThree } from "@react-three/fiber";
import React, { useEffect } from "react";

import { ParallaxBarrierEffect } from "three/examples/jsm/effects/ParallaxBarrierEffect";

const ParallaxBarrier = ({ enabled = false }) => {
  const { gl, scene, camera, size } = useThree();
  const [effect] = useState(() => new ParallaxBarrierEffect(gl));
  useEffect(() => void effect.setSize(size.width, size.height), [size, effect]);

  return useFrame(() => (enabled ? effect : gl).render(scene, camera), 1);
};

위에서 선언한 ParallaxBarrier를 호출한 후, npm start를 실행한다.

그러면 아래와 같이, 두 개의 박스가 겹쳐져 있는 듯한 객체가 렌더링 되는 것을 알 수 있다.

ParallaxBarrierEffect 애드온을 사용한 결과물

 

다음 포스트에서는 CubeCamera에 대해 작성할 예정이다.

 

つづく

 

반응형