Three.js和React-三纤维模型是完全黑色的吗?

时间:2020-08-06 16:12:39

标签: reactjs three.js 3d gltf react-three-fiber

此模型似乎完全加载了黑色-但其他模型则没有。 https://d1iczm3wxxz9zd.cloudfront.net/e4a5c9ee-9fa0-46b2-9ff5-8e52e6286a3b/5ee3baf2-2524-4617-99a7-2a91b4bd20c1/11/ITEM_PREVIEW1.glb

有人碰巧知道为什么吗?

其他GLB文件的纹理没有问题。这似乎有一个问题。但是,当将其加载到其他在线GLB查看器中时,它会加载正常。

使用reactjs,react-three-fibre和three.js。

这是three.js代码:

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 :(得分:0)

您不需要setState,useLoader使用悬念,loadedModel将包含保证的模型,否则组件将抛出。

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

环境光强度也是错误的,0是无光,默认值是1,然后变高。您会赋予它难以置信的高价值。

除了模型可能不在相机视锥范围之外(太大),它也可能太小。或路径错误(它应该在/ public中,或者您需要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>
  )
}