React와three가 있는 3D 프로그램 경관을 구축합니다.js!

43517 단어 reactjavascript
이제 자바스크립트로 재미있는 일을 많이 할 수 있습니다. 그 중 하나는 브라우저에서 3D로 물건을 구축하는 것입니다.이 강좌에서 React withththree를 사용하여 3차원 경관을 구축하는 방법을 보여 드리겠습니다.js.
이것은 세 사람의 강좌다.js 초보자, 많은 유사한 강좌는 브라우저에서 회전 상자를 만드는 방법만 가르쳐 주지만, 우리는 React를 사용하여 실제 경관을 만들고 정확한 조명, 카메라 등을 설정할 것입니다!
자바스크립트 ES6+, React, 웹 팩, npm 또는 yarn을 사용하는 기본 지식을 습득했다고 가정합니다. (이 강좌에서 yarn을 사용할 것입니다. 최근에 npm에서 전환했습니다.)

1. 입안


우리는 세 개를 사용할 것이다.js는 3D JavaScript 라이브러리(https://threejs.org)와reactthreefiber(https://github.com/react-spring/react-three-fiber와 함께 훌륭한'조율기'입니다. 이것은 우리에게 중용 가능한 구성 요소를 제공하여 우리의 세계를 더욱 쉽게 하고 삼자의 동일한 성능을 유지할 수 있도록 합니다.제시
create react 앱으로 새 응용 프로그램을 초기화합니다.$ npx create-react-app 3d-landscape그리고 나서 우리는 세 개와 세 개의 react 광섬유 패키지를 설치할 것이다.$ yarn add three react-three-fiber/src 폴더에서 index를 제외한 모든 파일을 삭제합니다.css와 인덱스.js.
이제/src에서 다음 폴더와 파일을 만듭니다.
src
|--components
|  |--Controls
|  |  |--index.js
|  |--Scene
|  |  |--Lights
|  |  |  |--index.js
|  |  |--Terrain
|  |  |  |--index.js
|  |  index.js
index.css
index.js
Visual Studio 코드의react 코드 세그먼트 확장을 사용하고 있습니다. 사용하시기 바랍니다.JS 파일에'rafce'를 입력하고enter를 누르면react 구성 요소가 설정되어 있음을 알 수 있습니다!내가 사용하는 다른 확장자는 eslint와prettier이다.
현재 이 강좌의 중점은 CSS가 아니기 때문에 제 CSS를 메인 색인에 복사하기만 하면 됩니다./src 폴더의 css 파일입니다.
@import url("https://fonts.googleapis.com/css?family=News+Cycle&display=swap");
:root {
  font-size: 20px;
}

html,
body {
  margin: 0;
  padding: 0;
  background: #070712;
  color: #606063;
  overflow: hidden;
  font-family: "News Cycle", sans-serif;
}

#root {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}

canvas,
.canvas > div {
  z-index: 1;
}

.loading {
  padding: 10px;
  transform: translate3d(-50%, -50%, 0);
}

2. 캔버스 설치


다음으로, 우리는 색인 안에 화포를 설치할 것이다.src 폴더의 js 파일입니다.
너는 항상 네 세 개의 캔버스에 있는 모든 것을 넣을 캔버스를 정의해야 한다.안의 js 장면.우리도 그곳에서 카메라를 설명하고 크기와 위치를 정의할 수 있다.서스펜스를 사용하면 장면 불러오기가 완료될 때까지 기다렸다가 애니메이션을 표시하거나 화면을 불러옵니다.
import React, { Suspense } from "react";
import ReactDOM from "react-dom";
import { Canvas, Dom } from "react-three-fiber";
import "./index.css";

function App() {
  return (
      <Canvas camera={{ zoom: 40, position: [0, 0, 500] }}>
        <Suspense
          fallback={<Dom center className="loading" children="Loading..." />}
        >
        </Suspense>
      </Canvas>
  );
}

const root = document.getElementById("root");
ReactDOM.render(<App />, root);

3. 장면 만들기


다음에 우리는 장면의 모든 구성 요소(지형과 불빛)의 받침대로 장면 구성 요소를 만들 것이다.
import React from "react";
import Lights from './Lights';
import Terrain from "./Terrain";

const Scene = () => (
  <>
    <Lights />
    <Terrain />
  </>
);

export default Scene;
그리고 장면을 메인 색인에 포함시켜야 합니다.js 파일을 서스펜스 구성 요소에 배치합니다.

4. 조명 추가


우리의 색인에 있습니다./lights 폴더의 js 파일을 그룹화합니다.
  • 가짜 구면등 1개
  • 1개의 환경광
  • 평행등 1개
  • 2개의 포인트 라이트
  • 만약 네가 세 가지 방면의 기초 지식을 배우고 싶다면.우선, 나는 https://threejsfundamentals.org/의 일부 또는 전체 장절을 읽는 것을 건의한다
    import React from "react";
    
    export default () => {
      const FakeSphere = () => (
        <mesh>
          <sphereBufferGeometry attach="geometry" args={[0.7, 30, 30]} />
          <meshBasicMaterial attach="material" color={0xfff1ef} />
        </mesh>
      );
    
      return (
        <group>
          <FakeSphere />
          <ambientLight position={[0, 4, 0]} intensity={0.3} />
          <directionalLight intensity={0.5} position={[0, 0, 0]} color={0xffffff} />
          <pointLight
            intensity={1.9}
            position={[-6, 3, -6]}
            color={0xffcc77}
          />
          <pointLight
            intensity={1.9}
            position={[6, 3, 6]}
            color={0xffcc77}
            />
        </group>
      );
    };
    
    
    React 세 가지 섬유는 우리에게 사용하기 쉬운 성분을 제공하는데, 우리는 이 성분들을 한데 조합하여 그 특성을 부여할 수 있다.현재 캔버스에 렌더링된 검은색 화면을 볼 수 있습니다. (잠시 후에 제작할 지형 구성 요소를 주석해 주십시오.)그것은 우리의 빛이 비출 것이 없기 때문이다.만약 어떤 안내원이 우리에게 등불의 위치를 알려준다면 이것은 매우 유익할 것이라고 상상해 보세요.셋째js 실제로 조명 조수가 있어요!우리가 그것들을 설정합시다.
    useRef () 를 사용하여 조명을 조명 보조 대상에 연결해야 합니다.reactthree fiber는 useResource 연결을 제공합니다. 이 연결은ref를 만들고 다음 프레임이 사용될 때 구성 요소를 다시 렌더링합니다.
    import React from "react";
    import { useResource } from "react-three-fiber";
    
    export default () => {
      const FakeSphere = () => (
        <mesh>
          <sphereBufferGeometry attach="geometry" args={[0.7, 250, 250]} />
          <meshBasicMaterial attach="material" color={0xfff1ef} />
        </mesh>
      );
    
      const [ref, pLight1] = useResource();
      const [ref2, pLight2] = useResource();
    
      return (
        <group>
          <FakeSphere />
          <ambientLight ref={ref2} position={[0, 4, 0]} intensity={0.3} />
    
          <directionalLight intensity={0.5} position={[0, 0, 0]} color={0xffffff} />
    
          <pointLight
            ref={ref}
            intensity={1}
            position={[-6, 3, -6]}
            color={0xffcc77}
          >
            {pLight1 && <pointLightHelper args={[pLight1]} />}
          </pointLight>
    
          <pointLight
            ref={ref2}
            intensity={1}
            position={[6, 3, 6]}
            color={0xffcc77}
          >
            {pLight2 && <pointLightHelper args={[pLight2]} />}
          </pointLight>
        </group>
      );
    };
    
    

    등불은 여전히 밝을 것이 없지만, 우리는 지금 그것들의 위치를 볼 수 있다.

    5, 컨트롤 추가


    메인 인덱스로 돌아가겠습니다.js 파일과 카메라 컨트롤을 설정합니다.
    import Controls from "./components/Controls";
    import Scene from './components/Scene';
    
    function App() {
      return (
          <Canvas camera={{ zoom: 40, position: [0, 0, 500] }}>
            <Suspense
              fallback={<Dom center className="loading" children="Loading..." />}
            >
              <Controls />
              <Scene />
            </Suspense>
          </Canvas>
      );
    }
    
    및 내부 색인.js는 컨트롤 폴더에 orbitControls를 추가하여 사용자가 우리의 환경을 둘러싸고 동적 관찰을 할 수 있도록 합니다.셋째js는 더 많은 컨트롤을 제공했습니다(https://threejs.org/docs/#examples/en/controls/OrbitControls.
    extend () 를 사용하면 세 가지 측면에서 본 컴퓨터의 OrbitControl을 확장할 수 있습니다.js와 우리의 코드.
    useRef () 가 useFrame () 함수에 정의된 모든 프레임 렌더링에서 카메라를 참조하고 업데이트해야 합니다.
    OrbitControls는 항상 두 가지 속성을 필요로 합니다. 렌더링할 카메라와dom 요소입니다.우리는 또한 구성 요소에 {...props}를 추가해서 더 많은props를 검색할 가능성을 제공할 것입니다.
    import React, { useRef } from "react";
    import { extend, useFrame, useThree } from "react-three-fiber";
    import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
    
    extend({ OrbitControls });
    
    const Controls = props => {
      const ref = useRef();
      const {
        camera,
        gl: { domElement }
      } = useThree();
      useFrame(() => ref.current && ref.current.update());
      return <orbitControls ref={ref} args={[camera, domElement]} {...props} />;
    };
    
    export default Controls;
    
    경탄했어

    6. 지형 만들기


    지금은 멋진 부분입니다. 우리는 우리의 불빛과 컨트롤이 무엇을 하는지 볼 수 있습니다!장면 구성 요소 내에서 지형 구성 요소를 가져오고 색인을 엽니다.js는 지형 폴더에 있습니다.
    이제 우리는 회전하는 기본 평면 하나만 렌더링합니다.useRef () 를 사용하여 각 프레임에 메쉬의 z축 회전을 추가하여 메쉬를 참조합니다.
    각 메쉬 어셈블리에는 재료와 형상 두 가지가 포함됩니다.여러 가지 다른 재료(https://threejsfundamentals.org/threejs/lessons/threejs-materials.html와 기하학적 형상(https://threejs.org/docs/#api/en/core/Geometry이 세 가지로 나뉜다.js.
    형상의 크기와 위치를 설정하고 재료와 속성을 정의하는 속성을 다시 제공합니다.
    import React, {useRef} from "react";
    import { useFrame } from "react-three-fiber";
    
    const Terrain = () => {
    
      const mesh = useRef();
    
      // Raf loop
      useFrame(() => {
        mesh.current.rotation.z += 0.01;
      });
    
      return (
        <mesh ref={mesh} rotation={[-Math.PI / 2, 0, 0]}>
          <planeBufferGeometry attach="geometry" args={[25, 25, 75, 75]} />
          <meshPhongMaterial
            attach="material"
            color={"hotpink"}
            specular={"hotpink"}
            shininess={3}
            flatShading
          />
        </mesh>
      );
    };  
    
    export default Terrain;
    
    

    이제 기본 평면을 보셔야 합니다.너무 멋있어!우리는 이 비행기에 네가 원하는 색깔이나 무늬를 줄 수 있다.지금 우리는 분홍색을 유지할 것이다.
    추가를 통해 - 수학.PI/2 평면은 수직이 아닌 수평으로 배치됩니다.

    7. 경관 생성


    우리는 이 기본 평면보다 더 재미있는 지형이 있기를 희망하기 때문에, 우리는 절차에 따라 하나를 과장할 것이다.이것은 우리가 알고리즘을 통해 그것을 만드는 것이지 수동으로 만드는 것이 아니라는 것을 의미한다.다시 실을 때마다 지형이 달라진다.
    우선 Terrain 폴더에 perlin이라는 새 파일을 만듭니다.js에서 우리는 베를린 소음이라고 불리는 알고리즘 https://en.wikipedia.org/wiki/Perlin_noise 을 포함할 것이다.
    베를린 벽 안의 내용을 복제하는 알고리즘을 여기서 찾을 수 있다.js 파일:
    https://github.com/josephg/noisejs/blob/master/perlin.js
    그리고 색인으로 가져옵니다.js 파일.
    reactthree fiber의 useUpdate () 를 사용하여 형상 평면을 강제로 업데이트합니다.
    우리의 평면은 많은 정점으로 구성되어 있으며, 우리는 그것들에게 무작위의 너비와 높이를 주어 평면을 하나의 경관처럼 보일 수 있다.이 교점 배열은 실제로 형상 개체 내부에 있습니다.

    useUpdate에서, 우리는 모든 정점을 순환하고, 베를린 소음 알고리즘을 사용하여 모든 값을 랜덤화할 것이다.
    나는 코드 펜에서 발견한 무작위 그룹을 사용했다. https://codepen.io/ptc24/pen/BpXbOW?editors=1010.
    import React from "react";
    import { useFrame, useUpdate } from "react-three-fiber";
    
    import { noise } from "./perlin";
    
    const Terrain = () => {
      const mesh = useUpdate(({ geometry }) => {
        noise.seed(Math.random());
        let pos = geometry.getAttribute("position");
        let pa = pos.array;
        const hVerts = geometry.parameters.heightSegments + 1;
        const wVerts = geometry.parameters.widthSegments + 1;
        for (let j = 0; j < hVerts; j++) {
          for (let i = 0; i < wVerts; i++) {
            const ex = 1.1;
            pa[3 * (j * wVerts + i) + 2] =
              (noise.simplex2(i / 100, j / 100) +
                noise.simplex2((i + 200) / 50, j / 50) * Math.pow(ex, 1) +
                noise.simplex2((i + 400) / 25, j / 25) * Math.pow(ex, 2) +
                noise.simplex2((i + 600) / 12.5, j / 12.5) * Math.pow(ex, 3) +
                +(noise.simplex2((i + 800) / 6.25, j / 6.25) * Math.pow(ex, 4))) /
              2;
          }
        }
    
        pos.needsUpdate = true;
      });
    
      // Raf loop
      useFrame(() => {
        mesh.current.rotation.z += 0.001;
      });
    
      return (
        <mesh ref={mesh} rotation={[-Math.PI / 2, 0, 0]}>
          <planeBufferGeometry attach="geometry" args={[25, 25, 75, 75]} />
          <meshPhongMaterial
            attach="material"
            color={"hotpink"}
            specular={"hotpink"}
            shininess={3}
            flatShading
          />
        </mesh>
      );
    };
    
    export default Terrain;
    
    

    됐어, 잘했어!
    현재 당신은 항성의 형식으로 입자를 추가하고 조명과 컨트롤을 변경하며 심지어 화면에 3D 애니메이션을 추가하고 컨트롤을 추가할 수 있습니다.
    예를 들어, 와이어프레임 ={true}를 재료 속성으로 추가하면 재료를 와이어프레임으로 변경할 수 있습니다.

    또는 flatShading을 smoothShading으로 변경합니다.

    그렇습니다. 3D에서 좋은 것을 만드는 것이 재미있습니다!
    환매 서명: https://github.com/sanderdebr/three-dev-tutorial

    좋은 웹페이지 즐겨찾기