3. js и React-трехволоконная модель полностью черная? - PullRequest
0 голосов
/ 06 августа 2020

Эта модель кажется полностью черной, но другие нет. https://d1iczm3wxxz9zd.cloudfront.net/e4a5c9ee-9fa0-46b2-9ff5-8e52e6286a3b/5ee3baf2-2524-4617-99a7-2a91b4bd20c1/11/ITEM_PREVIEW1.glb

Кто-нибудь знает почему?

В других файлах GLB нет проблем с текстурами. Кажется, у этого есть проблема. Но при загрузке в других онлайн-программах просмотра GLB он загружается нормально. :

import * as THREE from "three";
import React, { useRef, Suspense } from "react";
import { Canvas, useThree, useFrame, extend } from "react-three-fiber";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { Box } from "./Box";
import { Model } from "./Model";

extend({ OrbitControls });
const Controls = (props) => {
  const { gl, camera } = useThree();
  const ref = useRef();

  //@ts-ignore
  useFrame(() => ref.current.update());

  //@ts-ignore
  return <orbitControls ref={ref} args={[camera, gl.domElement]} {...props} />;
};

const ThreeJSComponent = (props) => {
  const {
    width,
    height,
    fallback,
    modelSuccess,
    setBackground,
    background,
  } = props;

  return (
    <div
      style={{
        width: width,
        height: height,
        position: "relative",
      }}
    >
      <div
        onClick={() => setBackground("black")}
        style={{
          position: "absolute",
          top: "0",
          right: "0",
          width: "25px",
          borderRadius: "5px",
          height: "25px",
          background: "black",
          zIndex: 50,
          border: "white 1px solid",
        }}
      ></div>
      <div
        onClick={() => setBackground("white")}
        style={{
          position: "absolute",
          top: "0",
          right: "50px",
          width: "25px",
          height: "25px",
          borderRadius: "5px",
          background: "white",
          border: "black 1px solid",
          zIndex: 50,
        }}
      ></div>
      <Canvas
        style={{
          width: "100%",
          height: "100%",
          background: background,
        }}
        onCreated={({ gl }) => {
          gl.shadowMap.enabled = true;
          gl.shadowMap.type = THREE.PCFShadowMap;
          //@ts-ignore
          gl.outputEncoding = false;
          gl.toneMappingExposure = 0;
        }}
        camera={{
          position: [0, 0, 10],
          isPerspectiveCamera: true,
        }}
        //shadowMap
      >
        {" "}
        <ambientLight intensity={0x222222} />
        <Suspense fallback={fallback}>
          <Model url={props.modelURL} modelSuccess={modelSuccess} />
        </Suspense>
        <Controls
          autoRotate
          enablePan={true}
          enableZoom={true}
          enableDamping
          dampingFactor={0.5}
          rotateSpeed={1}
        />
      </Canvas>
    </div>
  );
};

export default ThreeJSComponent;

и модель:

import React, { useState, useEffect } from "react";
import { useLoader } from "react-three-fiber";

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";

export const Model = (props) => {
  const { url, modelSuccess } = props;

  const [model, setModel] = useState();

  const loadedModel = useLoader(GLTFLoader, url, (loader) => {
    const dracoLoader = new DRACOLoader();
    dracoLoader.setDecoderPath("/draco-gltf/");
    loader.setDRACOLoader(dracoLoader);
  });

  useEffect(() => {
    if (!model) {
      setModel(loadedModel);
    }
  }, []);

  if (model) {
    modelSuccess();
    return (
      <primitive
        position={[0, 0, 0]}
        scale={[1, 1, 1]}
        object={model.scene}
        dispose={null}
      ></primitive>
    );
  } else return null;
};

1 Ответ

0 голосов
/ 07 августа 2020

вам не нужен setState, useLoader использует Suspense, loadedModel будет содержать гарантированную модель, или компонент выдаст.

const { scene } = useLoader(GLTFLoader, url, ...)
return <primitive object={scene} dispose={null} />

яркость окружающего света также неверна, 0 - нет света, 1 - по умолчанию, потом идет выше. вы присваиваете ему невероятно высокое значение.

кроме того, возможно, что модель находится за пределами конуса камеры (слишком большая), она также может быть слишком маленькой. либо путь неверный (он должен быть либо в / publi c, либо он вам нужен import modelUrl as "./model.glb".

вот рабочий пример: https://codesandbox.io/s/r3f-ibl-envmap-simple-k7q9h?file= / src / App. js

import React, { Suspense } from 'react'
import { Canvas, useLoader } from 'react-three-fiber'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { OrbitControls, Html, draco } from 'drei'

function Model({ url }) {
  const { scene } = useLoader(GLTFLoader, url, draco())
  return <primitive object={scene} dispose={null} />
}

export default function App() {
  return (
    <Canvas camera={{ position: [0, 5, 1] }}>
      <directionalLight position={[10, 10, 5]} intensity={2} />
      <directionalLight position={[-10, -10, -5]} intensity={1} />
      <OrbitControls />
      <Suspense fallback={<Html>loading..</Html>}>
        <Model url="/suzanne-draco.glb" />
      </Suspense>
    </Canvas>
  )
}
...