【问题标题】:Change Material of a babylonJs model with react-babylonjs使用 react-babylonjs 更改 babylonJs 模型的材质
【发布时间】:2022-12-15 19:20:44
【问题描述】:

我加载了一个来自 Blender 的模型(使用 babylon js 导出器导出)。该模型带有材料。并且有 5 个网格(非常简单的测试模型)。

我想改变一些材料的反照率(自然光下的颜色),但不知道该怎么做,因为没有与材料相关的组件(因为是进口的)并且在反应中,通常有一个函数可以调用更新内部值(然后触发刷新)。

const onModelLoaded = model => {
  model.meshes.forEach(mesh => {
    console.log(`mesh... `, mesh.material.albedoColor);
    // It shows well albedo of each material
  });
};


export const SceneWithLoad = () => {

  return (
    <div>
      <Engine antialias adaptToDeviceRatio canvasId="babylonJS">
        <Scene>
          <Suspense>
            <Model
              rootUrl="assets/firstLoco.babylon"
              sceneFileName=""
              onModelLoaded={onModelLoaded}
            />
          </Suspense>
          <hemisphericLight ... />
          <arcRotateCamera ... />
        </Scene>
      </Engine>
    </div>
  );
};

加载网格时,我可以在 onModelLoaded 中看到每种材质的反照率(这很棒),现在我想定期更新反照率(setInterval(() =&gt; {changeAlbedo()}, 1000)),但是 Material 对象的引用在刷新时会发生变化,我需要调用用于了解代码的反应功能更新了材质反照率。

在这里找不到诀窍,谢谢您的建议!

【问题讨论】:

    标签: reactjs babylonjs


    【解决方案1】:

    经过无数次测试

    这里材料的ID是已知的。它们用于通过 lodash 过滤器功能在其上设置反照率。在这种情况下,它会在机车的前/后交替显示红/白灯。

    boolBal 是每秒设置为 true 或 false 的值。 SwapMaterial 不显示任何内容,只是场景修改代码的入口点。

    真正不是“反应工作方式”的是场景是可变的(您可以更新场景项而不生成新的引用),原则上反应不是(状态更改=对状态对象的新引用)

    有更好的建议欢迎评论。

    import _ from "lodash";
    import { Engine, Scene, Model, useScene } from "react-babylonjs";
    import { Vector3, Color3 } from "@babylonjs/core";
    import "@babylonjs/loaders";
    
    const colorWhite = new Color3(1, 1, 1);
    const colorRed = new Color3(1, 0, 0);
    
    const SwapMaterial = ({ boolVal }) => {
      const scene = useScene();
    
      _.filter(
        scene.materials,
        r => ["FrontLeft-mat", "FrontRight-mat"].indexOf(r.id) >= 0
      ).forEach(m => {
        m.albedoColor = boolVal ? colorRed : colorWhite;
      });
    
      _.filter(
        scene.materials,
        r => ["RearLeft-mat", "RearRight-mat"].indexOf(r.id) >= 0
      ).forEach(m => {
        m.albedoColor = !boolVal ? colorRed : colorWhite;
      });
    
      return null;
    };
    
    export const SceneWithLoad = () => {
      const [boolVal, boolValSet] = useState(false);
      const ref = useRef({});
      ref.current.boolVal = boolVal;
      ref.current.boolValSet = boolValSet;
    
      useEffect(() => {
        const intId = setInterval(() => {
          ref.current.boolValSet(!ref.current.boolVal);
        }, 1000);
        return () => {
          clearInterval(intId);
        };
      }, []);
    
      return (
        <div>
          <Engine antialias adaptToDeviceRatio canvasId="babylonJS">
            <Scene>
              <Suspense>
                <Model rootUrl="assets/firstLoco.babylon" sceneFileName="" />
              </Suspense>
              <hemisphericLight ... />
              <hemisphericLight ... />
              <arcRotateCamera ... />
              <SwapMaterial {...{ boolVal }} />
            </Scene>
          </Engine>
        </div>
      );
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-04
      • 2017-08-22
      相关资源
      最近更新 更多