0

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

有人碰巧知道为什么吗?

其他 GLB 文件的纹理没有问题。这个好像有问题。但是当加载到其他在线 GLB 查看器中时,它加载得很好。

使用 reactjs、react-three-fiber 和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;
};

4

1 回答 1

1

你不需要 setState,useLoader 使用 suspense,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>
  )
}
于 2020-08-07T08:41:57.543 回答