brianzinn / react-babylonjs

React for Babylon 3D engine
https://brianzinn.github.io/react-babylonjs/
812 stars 102 forks source link

Unable to add material to mesh from prop value #244

Closed fliptrail closed 1 year ago

fliptrail commented 1 year ago

If I try to assign a material this way, it does not work

    const groundMaterial = new StandardMaterial("groundMaterial")
    const diffTex = new Texture("./textures/floor/floor_pavement_diff_1k.png")
    groundMaterial.diffuseTexture = diffTex

    return (
        <>
        <ground
            name="ground"
            width={10}
            height={10}
            material={groundMaterial}>
        </ground>

But the below approach using JSX works

        <ground
            name="ground"
            width={10}
            height={10}>
                <standardMaterial
                        name={`groundMaterial`}
                        diffuseTexture={new Texture("./textures/floor/floor_pavement_diff_1k.jpg")}
                  />
        </ground>
brianzinn commented 1 year ago

hi @fliptrail - good questions - the docs aren't very good at the moment. Right now the material prop of <ground ../> is not picked up by this renderer. I'm assuming you simplified your code for simplicity, but what you have there would create a new texture on every render otherwise. What you want to do can be accomplished in a couple of different ways - this is a way to assign a material instance you have:

  <ground ...>
   <standardMaterial fromInstance={groundMaterial} ... />
  </ground>

If you are using fromInstance and you want the instance disposed automatically then there is an opt-in mechanism and you just need the prop disposeInstanceOnUnmount like:

  <standardMaterial fromInstance={groundMaterial} disposeInstanceOnUnmount />

You can also assign the texture - what you have there will also new up a Texture on every render. The advantage of a declarative texture is also that you can assign and change props from state:

  <ground name='ground' ...>
    <standardMaterial name='groundMaterial'>
       <texture 
           assignTo="diffuseTexture"
           url="./textures/floor/floor_pavement_diff_1k.jpg"
       />
    </standardMaterial>
  </ground>

The "configurations" can also be declarative: https://github.com/brianzinn/react-babylonjs/blob/master/packages/storybook/stories/babylonjs/Textures/pbr-configuration.stories.js

Does that answer your question or did you need material prop assignable still?

fliptrail commented 1 year ago

Thank you very much for an extremely quick response. All of these workloads would work perfectly fine for me. I was just wondering why the first approach did not work.