react 3 섬유에 대한 주석

35849 단어 3dr3fthreejs

Originally published on my blog


이것은 내가 정리한 필기집인데, 목적은React에서 어떻게 3D 기술을 사용하는지 더욱 잘 이해하는 것이다.내가 이 글을 쓰는 것은 나 자신을 위해서이다. 왜냐하면 이것이 바로 내가 이 글을 쓰는 목적이기 때문이다. 그러나 다른 사람들이 그것이 유용하다고 생각한다면 그것도 매우 멋있다.그러나 그것은 교과서나 그 어떤 것으로도 작성된 것이 아니다.경고한다!

설치 프로그램
설치:
yarn add react-three-fiber three @react-three/drei

전체 페이지를 100% 너비와 높이로 설정하기
* {
  box-sizing: border-box;
}

html,
body,
#root {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

이것들은 모두 무엇이냐
캔버스 어셈블리는 DOM 요소가 아닌 세 개의 JS 요소를 나타냅니다.그것은 전체 용기의 높이와 너비를 필요로 하기 때문에, 전체 페이지의 3D 렌더링을 하려면 용기의 너비와 높이를 100%로 설정해야 한다.
우리는 화포에서 HTML 요소를 직접 사용할 수 없다. 비록 이 점을 할 수 있는 방법이 있지만, 나는 뒤에서 소개할 것이다.
Canvas 어셈블리는 세 개의 JS 요소를 렌더링하므로 메쉬, 구 측정, meshStandard Material 등을 사용할 수 있습니다.이것은 상하문을 통해 이 모든 내용을 보여주는 하위 요소에 제공하고threejs API를 정상적으로 사용할 수 있는React 구성 요소로 변환합니다. 그러면 우리는 도구를 이 요소/구성 요소에 전달할 수 있습니다.

메쉬, 형상 및 재료
메쉬는 와이어프레임이나 모델과 같은 객체의 기본 뼈대와 유사합니다.
형상은 메쉬가 사용할 모양입니다. 재료는 메쉬를 덮어쓰는 내용과 메쉬의 모양입니다.객체와의 상호 작용과 동작을 변경할 수 있는 다양한 유형의 재료를 사용할 수 있습니다.
HTML 요소와 같은 다양한 기하학적, 재질은 캔버스에서 직접 사용할 수 있다.예를 들어 메쉬 표준 재료나 구 측정법.
위의 형상 및 재료의 부착 도구는 요소를 부모 요소에 부착합니다. 이 경우 메쉬가 설정값으로 사용됩니다.따라서 구면계는 메쉬에 형상으로 부착되고 메쉬 표준 재료는 메쉬에 재료로 부착됩니다.
구조 함수 매개 변수는argsprop과 함께 전달됩니다.잉크 측량법은 많은 구조 함수 파라미터를 채택하였는데, 앞의 세 가지 파라미터는 반경, 너비, 높이이다.자세한 내용은 SphereGeometry docs on threejs를 참조하십시오.예를 들어, 구의 구조 함수 매개변수는 다음과 같습니다.
  • 반경 - 구체반경.기본값은 1입니다.
  • 너비 세그먼트 - 수평 세그먼트의 수입니다.최소값은 3이고 기본값은 8입니다.
  • 고도 세그먼트 - 수직 세그먼트의 수입니다.최소값은 2이고 기본값은 6입니다.
  • phiStart-수평 시작 각도를 지정합니다.기본값은 0입니다.
  • philength - 수평 스윕 각도 크기를 지정합니다.기본값은 수학입니다.π*2.
  • 시작점 - 수직 시작점 각도를 지정합니다.기본값은 0입니다.
  • 길이 - 수직 스윕 각도의 크기를 지정합니다.기본값은 수학입니다.원주율.

  • 등불
    만약 광원을 제공하지 않는다면 물체는 검은색이 될 것이다.이것은 일리가 있다. 빛이 없으면 우리는 현실 생활에서 티타늄을 볼 수 없기 때문이다.라이트 리스트는 Asmashing magazine article에서 가져옵니다.
  • 점.포인트 라이트는 전구와 비슷하게 작동할 수 있으며 미리 정의된 범위 내에 있으면 모든 객체에 동일한 방식으로 영향을 줍니다.천장 불빛이 투사하는 빛을 모방할 수 있다.
  • 점.스폿라이트는 포인트 라이트와 유사하지만 초점을 맞추고 해당 피라미드와 해당 범위 내의 객체만 비춥니다.그것은 점광원처럼 모든 물체를 고르게 비추지 않기 때문에 물체는 음영을 투사하고 어두운 면이 있다.
  • 환경 온도.그러면 장면의 모든 객체에 동일한 영향을 주는 광원이 추가됩니다.일영 같은 환경 광원은 일반 광원으로 사용됩니다.이것은 그림자 속의 물체를 볼 수 있게 한다. 왜냐하면 직사광선 아래에 숨겨진 모든 것이 완전히 어두워지기 때문이다.환경광의 일반적인 성질 때문에 광원의 위치는 불빛이 장면에 영향을 주는 방식을 바꾸지 않는다.
  • 반구.이 광원의 작업 원리는 당구대등과 매우 비슷하다. 왜냐하면 장면 위에 직접 위치하고 불빛이 이 점에서만 분산되기 때문이다.
  • 방향성.평행광도 원추의 모든 것에 영향을 미치기 때문에 점광원과 스포트라이트와 유사하다.가장 큰 차이는 평행광이 범위가 없다는 것이다.그것은 빛이 무한히 지속되기 때문에 물체와 멀리 떨어진 곳에 놓을 수 있다.
  • 구역.필드 라이트는 장면에서 특정 속성을 가진 객체로부터 직접 전송되므로 아날로그 현수형 램프와 LCD 백라이트 등의 장치에 유용합니다.영역 라이트를 형성할 때는 일반적으로 사각형 또는 원형인 모양과 크기를 선언하여 라이트가 덮어쓸 영역을 결정해야 합니다.

  • 서로 다른 재질의 구체.

    이 세 개의 코드
    <Canvas>
      <mesh
        visible // object gets render if true
        userData={{ test: "hello" }} // An object that can be used to store custom data about the Object3d
        position={[0, 0, 1]} // The position on the canvas of the object [x,y,x]
        rotation={[0, 0, 0]} // The rotation of the object
        castShadow // Sets whether or not the object cats a shadow
        // There are many more props.....
      >
        {/* A spherical shape*/}
        <sphereGeometry attach="geometry" args={[1, 16, 16]} />
        {/* A standard mesh material*/}
        <meshStandardMaterial
          attach="material" // How the element should attach itself to its parent
          color="#7222D3" // The color of the material
          transparent // Defines whether this material is transparent. This has an effect on rendering as transparent objects need special treatment and are rendered after non-transparent objects. When set to true, the extent to which the material is transparent is controlled by setting it's .opacity property.
          roughness={0.1} // The roughness of the material - Defaults to 1
          metalness={0.1} // The metalness of the material - Defaults to 0
        />
      </mesh>
      {/*An ambient light that creates a soft light against the object */}
      <ambientLight intensity={0.5} />
      {/*An directional light which aims form the given position */}
      <directionalLight position={[10, 10, 5]} intensity={1} />
      {/*An point light, basically the same as directional. This one points from under */}
      <pointLight position={[0, -10, 5]} intensity={1} />
      {/* We can use the drei Sphere which has a simple API. This sphere has a wobble material attached to it */}
      <Sphere visible position={[-3, 0, 1]} args={[1, 16, 16]}>
        <MeshWobbleMaterial
          attach="material"
          color="#EB1E99"
          factor={1} // Strength, 0 disables the effect (default=1)
          speed={2} // Speed (default=1)
          roughness={0}
        />
      </Sphere>
      {/* This sphere has a distort material attached to it */}
      <Sphere visible position={[3, 0, 1]} args={[1, 16, 16]}>
        <MeshDistortMaterial
          color="#00A38D"
          attach="material"
          distort={0.5} // Strength, 0 disables the effect (default=1)
          speed={2} // Speed (default=1)
          roughness={0}
        />
      </Sphere>
    </Canvas>
    

    델레
    Drei는 react three fiber의 많은 지원과 요약을 포함하는 유용한 패키지입니다.내가 주의한 것은Nextjs에서drei를 사용하면 내용을 가져오려고 시도할 때 오류가 발생합니다. 모듈 밖에서 import 문장을 사용할 수 없습니다.Nextjs가 서버에서 공공 js 모듈을 사용하기 때문입니다.다음 Transfile 모듈에서 withTM를 사용할 수 있습니다.drei에서 흔히 볼 수 있는 js 내용을 전송하기 위해 파일을 설정합니다.drei 구성 요소를 사용하여 구성 요소를 동적으로 가져오고 서버 쪽 렌더링을 비활성화해야 합니다.this issuethis PR 참조

    Nextjs를 사용하고 있다면...
    import dynamic from "next/dynamic";
    const ThreeBall = dynamic(
      () => import("./../../src/components/post/three-ball"),
      { ssr: false }
    );
    

    다음.배치하다.js
    const withTM = require("next-transpile-modules")([
      "three",
      "drei",
      "postprocessing",
    ]);
    
    module.exports = withTM();
    

    주요 참가자
    react three fiber (R3F) 의 렌더기는 id나 클래스 이름을 통해 특별히 추가하지 않는 한 DOM에 동적으로 추가된 HTML 캔버스 요소입니다.
    이 장면은 하나의 무대로 모든 것이 이곳에서 상연된다.메쉬에는 조명, 그룹, 3D 위치 및 카메라가 포함됩니다.하나의 장면은 극장 장면으로 여겨질 수 있다. 그 중에서 격자나 격자 그룹은 재생할 동작이다. 불빛은 격자와 그 기하학적 재료와 재질을 장면에 부여하고 서로 다른 각도에서 격자를 비추며 나타나는 배경을 제공한다.카메라와 위치는 우리로 하여금 서로 다른 각도에서 그것들을 볼 수 있게 한다.

    편리한 캔버스 구성 요소
    나는 내가 원하는 모든 3D 물건을 렌더링하기 위해 편리한 캔버스 부품을 만들었다.Chakraui를 사용하지만 스타일은 스타일 탭과 쉽게 연결되거나 CSS 파일에 추가할 수 있습니다.
    import React, { Suspense } from 'react';
    import { Canvas } from 'react-three-fiber';
    import { Box } from '@chakra-ui/core';
    
    /**
     * A container with a set width to hold the canvas.
     * @param {String} width - The width of containing element
     * @param {String} height - The height of containing element
     * @param {Array}  position - The position of the camera, [x, y, z] axis.
     * @param {Number} fov - The field of view of the camera. The higher the number, the further away the view
     * @param {Number} zoom - If the camera should be zoomed in. Provide a number. Defaults to 1.
     * ...rest = any styles you want to apply to the containing div
     */
    const CanvasContainer = ({
      width,
      height,
      position,
      fov,
      zoom,
      children,
      ...rest
    }) => {
      return (
        <Box height={height} width={width} {...rest}>
          <Canvas
            colorManagement
            camera={{
              position,
              fov,
              zoom,
            }}
          >
            <Suspense fallback={null}>{children}</Suspense>
          </Canvas>
        </Box>
      );
    };
    
    export default CanvasContainer;
    

    모델
    Poimandres팀에서 제공한 도구를 사용하여 모델과 함께 일하는 것이 매우 재미있고 상당히 가볍다.일반적으로 3D 컨텐트를 로드하는 사양인 GLTF를 사용합니다.JSON(.gltf) 또는 바이너리(.glb) 형식을 모두 적용합니다.이렇게 단일 무늬나 자원을 저장하는 것이 아니라jgp 또는.png, gltf는 3D 컨텐트를 표시하는 데 필요한 모든 컨텐트를 패키지화합니다.이는 메쉬, 형상, 재료 및 텍스쳐 등의 모든 영역을 포함할 수 있습니다.자세한 내용은 3개docs를 참조하십시오.
    공용 폴더에 저장해야 하는gltf 파일을 가져와서 이 파일을 읽고 React 구성 요소를 만들 수 있는 gltfjsx 패키지를 사용할 수 있습니다.만약gltf모델에 애니메이션이 있다면 패키지도 구성 요소 내부에 애니메이션 논리를 만들어 줍니다.우리는 세 가지 예 중의 새 한 마리를 들 수 있다.
    이 새의 코드는 우리를 위해 자동으로 생성된 것이다.보아하니 이렇다.
    /*
    auto-generated by: https://github.com/pmndrs/gltfjsx
    */
    import React, { useRef, useState, useEffect } from "react";
    import { useFrame } from "react-three-fiber";
    import { useGLTF } from "@react-three/drei/useGLTF";
    import * as THREE from "three";
    import { PerspectiveCamera } from "@react-three/drei";
    
    export default function Stork(props) {
      const group = useRef();
      const { nodes, materials, animations } = useGLTF("/stork.glb");
    
      const actions = useRef();
      const [mixer] = useState(() => new THREE.AnimationMixer());
      useFrame((state, delta) => mixer.update(delta));
      useEffect(() => {
        actions.current = {
          storkFly_B_: mixer.clipAction(animations[0], group.current),
        };
        actions.current.storkFly_B_.play(); // To play the animation we have to call the play method
        return () => animations.forEach((clip) => mixer.uncacheClip(clip));
      }, [animations, mixer]);
      return (
        <group ref={group} {...props} dispose={null}>
          <PerspectiveCamera makeDefault position={[-10, 50, 250]} />
          <hemisphereLight args={["white", 2, 2]} />
          <spotLight
            intensity={0.2}
            position={[20, 25, 14]}
            angle={0.15}
            penumbra={1}
            castShadow
          />
          <mesh
            material={nodes.mesh_0.material}
            geometry={nodes.mesh_0.geometry}
            name="mesh_0"
            morphTargetDictionary={nodes.mesh_0.morphTargetDictionary}
            morphTargetInfluences={nodes.mesh_0.morphTargetInfluences}
          />
        </group>
      );
    }
    
    useGLTF.preload("/stork.glb");
    

    편리한 모델 어셈블리
    나는 또 편리한ltlf 모형 부품을 만들었다.이 어셈블리는 모델의 경로와 같은 여러 도구를 사용합니다.gltf 파일, 모형은 캔버스에 있는 위치에 [x, y,z]의 Vector3 수조 형식으로 추가된 회전 및 모형 격자에 전달할 추가 도구입니다.
    import React from 'react';
    import { useGLTF } from '@react-three/drei';
    import { useFrame } from 'react-three-fiber';
    
    /**
     * A basic gltf modal renderer component.
     * @param {String} scenePath - The path to the scene file. Should be kept in the public folder
     * @param {Array} position - The position on the canvas the model should take
     * @param {Array} rotation - Optional rotation of the model. If provided [x, y, z] values are mapped to the useFrame hook which will rotate the model in the given direction(s)
     */
    const GLTFModal = ({ scenePath, position, rotation, ...rest }) => {
      const gltf = useGLTF(scenePath, true);
      const mesh = React.useRef();
      useFrame(() =>
        rotation
          ? ((mesh.current.rotation.x += rotation[0]),
            (mesh.current.rotation.y += rotation[1]),
            (mesh.current.rotation.z += rotation[2]))
          : null,
      );
      return (
        <mesh castShadow ref={mesh} {...rest} position={position}>
          <primitive object={gltf.scene} dispose={null} />
        </mesh>
      );
    };
    
    export default GLTFModal;
    
    
    그런 다음 다음과 같이 사용됩니다.
      <GLTFModal
        scenePath="/scene.gltf"
        position={[0, -1, 0]}
        rotation={[0, 0.01, 0]}
      />
    

    좋은 웹페이지 즐겨찾기