6. 형태가 바뀌는 이미지패널(1)

훈나무·2022년 7월 6일
0

개인적으로 이 파트를 진행 할 때, 조금 어려움이 있었고, 그 것을 공유하고 싶습니다.

Points 생성하기


먼저 2와 같은 과정을 반복합니다. 하지만 이번엔 구 형태로 만들 것 이기 때문에, sphereGeometry 를 이용해서 구 형태의 points 들을 생성해줍니다

<points>
    <sphereGeometry ref={ref} args={[1, 8, 8]} />
    <pointsMaterial size={0.1} vertexColors color={"yellow"} transparent depthWrite={false} />
</points>

이렇게 하면 다음과 같은 형태의 구가 생성 될 것입니다.

우리는 여기서 각 vertex 에 plane 형태의 mesh 를 붙여주고, 거기에 이미지를 넣어주면 완성입니다.

PlaneMesh 붙여주기


먼저 저희는 저런 점이 필요가 없기 때문에 pointsMaterial 을 다음과 같이 변경해 줍니다.

<meshBasicMaterial transparent />

다음으로는 vertex 들의 position 값을 가져와서 그 position 에 planeMesh 를 생성해서 붙여 넣어주면 됩니다.

저는 position들을 담는 배열을 만들고 그 배열을 map을 돌면서 planeMesh 를 리턴해 주었습니다

먼저 useEffect 로 positions 배열을 만들어 줍니다

useEffect(() => {
    var tempP = Array.from(ref.current.attributes.position.array);
    var newP = [];
    for (let i = 0; i < tempP.length; i += 3) {
      const temp = [tempP[i], tempP[i + 1], tempP[i + 2]];
      newP.push(temp);
    }
    setPlanePositions(newP);

  }, [ref.current]);

다음으로는 return 부분에서 plane을 하나하나씩 리턴해 주면 됩니다

{planePositions.map((arr, i) => (
    <mesh ref={(item) => (planeRefs.current[i] = item)} key={i} position={[arr[0], arr[1], arr[2]]}>
      <planeGeometry args={[0.3, 0.3]} />
      <meshBasicMaterial map={textures[i % 5]} side={THREE.DoubleSide} />
    </mesh>
  ))}

이미지 패널들이 전부 평면으로 서있어서 뭔가 조금 부자연스럽다…. 다음에는 모든 이미지 패널들이 가운데를 바라보도록 해보겠습니다!

전체 코드


import { OrbitControls, useTexture } from "@react-three/drei";
import React, { useEffect, useRef, useState } from "react";
import * as THREE from "three";
import img01 from "../images/01.jpg";
import img02 from "../images/02.jpg";
import img03 from "../images/03.jpg";
import img04 from "../images/04.jpg";
import img05 from "../images/05.jpg";

export default function NewThree() {
  const ref = useRef(null);
  const planeRefs = useRef([]);
  const texture01 = useTexture(img01);
  const texture02 = useTexture(img02);
  const texture03 = useTexture(img03);
  const texture04 = useTexture(img04);
  const texture05 = useTexture(img05);
  const textures = [texture01, texture02, texture03, texture04, texture05];

  const [planePositions, setPlanePositions] = useState([]);

  useEffect(() => {
    var tempP = Array.from(ref.current.attributes.position.array);
    var newP = [];
    for (let i = 0; i < tempP.length; i += 3) {
      const temp = [tempP[i], tempP[i + 1], tempP[i + 2]];
      newP.push(temp);
    }
    setPlanePositions(newP);
  }, []);

  return (
    <>
      <OrbitControls />

      <points>
        <sphereGeometry ref={ref} args={[1, 8, 8]} />
        <meshBasicMaterial transparent />
      </points>

      {planePositions.map((arr, i) => (
        <mesh key={i} position={[arr[0], arr[1], arr[2]]}>
          <planeGeometry args={[0.3, 0.3]} />
          <meshBasicMaterial map={textures[i % 5]} side={THREE.DoubleSide} />
        </mesh>
      ))}
    </>
  );
}
profile
프론트엔드 개발자 입니다

0개의 댓글

관련 채용 정보