# Does my Code create a new Material all the time? (R3F)

**URL:** <https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537>\
**Category:** Questions\
**Tags:** r3f\
**Created:** [July 5, 2023, 2:10pm UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537 "2023-07-05T14:10:26Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![kalabedo](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/kalabedo/32/43091_2.png) [@kalabedo](https://discourse.threejs.org/u/kalabedo)\
**Post date:** [July 5, 2023, 2:10pm UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/1 "2023-07-05T14:10:26Z")

</div>

Hi, quick question about R3F. Does this code always call new THREE.MeshStandardMaterial when declaring a meshStandardMaterial with the same texture?

```javascript
<mesh
        castShadow
        receiveShadow
        geometry={nodes.zargeKantigRemodeledDichtungLinks.geometry}
        position={[-0.0255 - positionXDichtung, -0.0065, 0.4205 + positionZ]}
        scale={[1, skalierungsFaktorVertikal, 1]}>
          <meshStandardMaterial envMapIntensity={.2} map={oberflächeZarge.map}/>
      </mesh>
      <mesh
        castShadow
        receiveShadow
        geometry={nodes.zargeKantigRemodeledVorneLinks.geometry}
        position={[-0.0255, -0.0065, 0.4205 + positionZ]}
        scale={[1, skalierungsFaktorVertikal, 1]}>
          <meshStandardMaterial envMapIntensity={.2} map={oberflächeZarge.map}/>
      </mesh>
      <mesh
        castShadow
        receiveShadow
        geometry={nodes.zargeKantigRemodeledHintenMitte.geometry}
        position={[-0.1175 - positionXTiefe, 0.9895 + positionYOffsetHorizont, 0]}
        scale={[1, 1, skalierungsFaktorHorizont]}>
          <meshStandardMaterial envMapIntensity={.2} map={oberflächeZarge.map}/>
      </mesh>
      <mesh
        castShadow
        receiveShadow
        geometry={nodes.zargeKantigRemodeledFutterbrettKanteMitte.geometry}
        position={[-0.1175 - positionXTiefeKante, 0.9895 + positionYOffsetHorizont, 0]}
        scale={[1, 1, skalierungsFaktorHorizont]}>
          <meshStandardMaterial envMapIntensity={.2} map={oberflächeZarge.map}/>
      </mesh>

```

---

<div class="post-metadata">

**Author:** ![seanwasere](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/seanwasere/32/20864_2.png) [@seanwasere](https://discourse.threejs.org/u/seanwasere)\
**Post date:** [July 5, 2023, 6:31pm UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/2 "2023-07-05T18:31:41Z")

</div>

Yes.

Each of your meshes have there own instance of a `meshStandardMaterial`. The map is shared though.

I check the `uuid` of objects to doublecheck if something is shared, or is its own instance, or was re-instanced for some reason.

E.g.,

```javascript
import { Canvas, useLoader } from '@react-three/fiber'
import { Environment } from '@react-three/drei'
import { useThree } from '@react-three/fiber'
import { useEffect } from 'react'
import * as THREE from 'three'

function Boxes() {
  const { scene } = useThree()
  const texture = useLoader(THREE.TextureLoader, './img/grid.png')

  useEffect(() => {
    console.log(scene.children[0].material.uuid)
    console.log(scene.children[1].material.uuid)
    console.log(scene.children[2].material.uuid)
  }, [scene.children])

  return (
    <>
      <mesh position={[-1.2, 0, 0]}>
        <boxGeometry />
        <meshStandardMaterial map={texture} />
      </mesh>
      <mesh position={[0, 0, 0]}>
        <boxGeometry />
        <meshStandardMaterial map={texture} />
      </mesh>
      <mesh position={[1.2, 0, 0]}>
        <boxGeometry />
        <meshStandardMaterial map={texture} />
      </mesh>
    </>
  )
}

export default function App() {
  return (
    <Canvas camera={{ position: [0, 0, 3] }}>
      <Environment preset="forest" />
      <Boxes />
    </Canvas>
  )
}

```

The three box materials have there own `uuid`, despite the JSX being identical.

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/f/b/fbd52e850438b0e2948b2f4098f0a7720785c738.png)

* * *

Below is the source code in the material constructor that generates a new `uuid`

> <https://github.com/mrdoob/three.js/blob/master/src/materials/Material.js#L17>

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [July 5, 2023, 6:39pm UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/3 "2023-07-05T18:39:07Z")

</div>

three dedupes shaders, the shader code is the cache key. you can confirm this using r3f-perf, it will show 1 shader.

```jsx
import { Perf } from 'r3f-perf'

export default function App() {
  return (
    <Canvas>
      <Perf />

```

but there still will be three instances, im guessing this must have some kind of overhead still, so you could do this:

```jsx
// In global space
const surface = new THREE.MeshStandardMaterial({ envMapIntensity: .2, map: oberflächeZarge.map })
...
<mesh material={surface} />
<mesh material={surface} />
<mesh material={surface} />

```

or

```jsx
const [material, set] = useState()
return (
  <>
    <meshStandardMaterial ref={set} envMapIntensity={.2} map={oberflächeZarge.map}/>
    {material && (
      <>
        <mesh material={material} />
        <mesh material={material} />
        <mesh material={material} />

```

---

<div class="post-metadata">

**Author:** ![makc3d](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/makc3d/32/10452_2.png) [@makc3d](https://discourse.threejs.org/u/makc3d)\
**Post date:** [July 5, 2023, 7:36pm UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/4 "2023-07-05T19:36:33Z")

</div>

> [@drcmda](#):
>
> three dedupes shaders

people are scared to create new instances even when it does not matter 😔 cant make up my mind if that’s good thing or bad thing.

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [July 5, 2023, 7:56pm UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/5 "2023-07-05T19:56:32Z")

</div>

does it matter? would love to have a final verdict somewhere. debug tools show 1 shader, but there are x classes with their own uuid’s, will they really all refer to the same and it’s something nobody needs to worry about?

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [July 5, 2023, 8:32pm UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/6 "2023-07-05T20:32:41Z")

</div>

Possibly yeah, draw calls on each material clone?

---

<div class="post-metadata">

**Author:** ![makc3d](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/makc3d/32/10452_2.png) [@makc3d](https://discourse.threejs.org/u/makc3d)\
**Post date:** [July 5, 2023, 8:44pm UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/7 "2023-07-05T20:44:37Z")

</div>

> [@drcmda](#):
>
> there are x classes with their own uuid’s

once upon a time there was heated discussion on github over a case where uuids were causing a major memory leak because of the way javascript stores strings internally (mrdoob responded that uuids are critical for people who wish to merge their jsons (I dont think I ever saw a single person who was doing that) and since every change that removed the leak also made uuids slower, the original code will stay) iirc this was the very same discussion that got @munrocket banned.

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [July 5, 2023, 9:06pm UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/8 "2023-07-05T21:06:53Z")

</div>

And regards to synchronising uuids among [socket.io](http://socket.io) environments, does the same apply?

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [July 5, 2023, 9:52pm UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/9 "2023-07-05T21:52:27Z")

</div>

Sounds like drama, but odd that this doesn’t seem to be documented. there’s a little about the material cache key but not enough to know if it becomes a problem if you have multiple instances of the same shader material.

---

<div class="post-metadata">

**Author:** ![PavelBoytchev](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/pavelboytchev/32/38639_2.png) [@PavelBoytchev](https://discourse.threejs.org/u/PavelBoytchev)\
**Post date:** [July 5, 2023, 11:15pm UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/10 "2023-07-05T23:15:52Z")

</div>

> [@makc3d](#):
>
> people are scared to create new instances even when it does not matter 😔 cant make up my mind if that’s good thing or bad thing.

```html
Rules of Optimization:
    Rule 1: Don't do it.
    Rule 2 (for experts only): Don't do it yet. 

– Michael A. Jackson

```

---

<div class="post-metadata">

**Author:** ![kalabedo](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/kalabedo/32/43091_2.png) [@kalabedo](https://discourse.threejs.org/u/kalabedo)\
**Post date:** [July 6, 2023, 5:05am UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/11 "2023-07-06T05:05:01Z")

</div>

Thanks for the replies:) so if i’m declaring a THREE.MeshStandardMaterial once and apply it to every mesh they do not update if im changing the texture…  
This is my Code right now thats working:

```javascript
  const oberflächeZarge = useTexture({
    map: `./textures/zargeTexture/${OFL_ZA}.jpg`
  })

  oberflächeZarge.map.wrapS = oberflächeZarge.map.wrapT = THREE.RepeatWrapping

  oberflächeZarge.map.repeat.set(2, 2)

  useEffect(() => {
    oberflächeZarge.map.needsUpdate = true; // Force texture update
  }, [OFL_ZA]);
[...]
return(
<mesh
        castShadow
        receiveShadow
        geometry={nodes.zargeKantigRemodeledDichtungLinks.geometry}
        position={[-0.0255 - positionXDichtung, -0.0065, 0.4205 + positionZ]}
        scale={[1, skalierungsFaktorVertikal, 1]}>
          <meshStandardMaterial envMapIntensity={.2} map={oberflächeZarge.map}/>
      </mesh>
      <mesh
        castShadow
        receiveShadow
        geometry={nodes.zargeKantigRemodeledVorneLinks.geometry}
        position={[-0.0255, -0.0065, 0.4205 + positionZ]}
        scale={[1, skalierungsFaktorVertikal, 1]}>
          <meshStandardMaterial envMapIntensity={.2} map={oberflächeZarge.map}/>
      </mesh>
)

```

I have alot of meshes where i need the texture on so it would be the best way to declare it once. But as i mentioned the texture doesnt update with correct lighting. (OFL\_ZA is a prop in my component)

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [July 6, 2023, 7:23am UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/12 "2023-07-06T07:23:28Z")

</div>

this document describes all the constructs and properties that require a recompile, texture is one of them [three.js docs](https://threejs.org/docs/#manual/en/introduction/How-to-update-things)

i think it requires needsUpdate on the material according to that document.

btw, something else, useEffect fires _after_ react has rendered and _after_ threejs has rendered out on the screen. this can result in flash of un-styled content (FOUC). useLayoutEffect fires after react but before threejs, it hasn’t rendered yet.

---

<div class="post-metadata">

**Author:** ![kalabedo](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/kalabedo/32/43091_2.png) [@kalabedo](https://discourse.threejs.org/u/kalabedo)\
**Post date:** [July 6, 2023, 8:10am UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/13 "2023-07-06T08:10:34Z")

</div>

I implemented it like this now but same problem, the texture looks washed out as it does not update.

```javascript
const zargeMaterial = new THREE.MeshStandardMaterial()

export function ZargeKantig2({OFL_ZA, FALZ_ZA_TIEF, HOE_ZFM, BR_ZFM, TIEF_ZA, KAUS, FALZ_MASS}) {
  const { nodes, materials } = useGLTF("./models/TürblattStdGlatt/ZargeKantigMitDichtung.glb");

  const texture = new THREE.TextureLoader().load(`./textures/zargeTexture/${OFL_ZA}.jpg`);
  zargeMaterial.map = texture
  zargeMaterial.envMapIntensity = .2

  useLayoutEffect(() => {
    zargeMaterial.map.needsUpdate = true
  }, [OFL_ZA]);

return(
<mesh
        castShadow
        receiveShadow
        material={zargeMaterial}
        geometry={nodes.zargeKantigRemodeledDichtungLinks.geometry}
        position={[-0.0255 - positionXDichtung, -0.0065, 0.4205 + positionZ]}
        scale={[1, skalierungsFaktorVertikal, 1]}>
          {/* <meshStandardMaterial envMapIntensity={.2} map={oberflächeZarge.map}/> */}
      </mesh>
      <mesh
        castShadow
        receiveShadow
        material={zargeMaterial}
        geometry={nodes.zargeKantigRemodeledVorneLinks.geometry}
        position={[-0.0255, -0.0065, 0.4205 + positionZ]}
        scale={[1, skalierungsFaktorVertikal, 1]}>
          {/* <meshStandardMaterial envMapIntensity={.2} map={oberflächeZarge.map}/> */}
      </mesh>
)
}

```

i changed the r3f meshStandardMaterial to the THREE.MeshStandardMaterial in the material property. now it looks like this: (the lower left part is as i had it, not washed out. The frame around is implemented like the code above)  
 ![Screenshot 2023-07-06 100818](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/0/1/019dc0adfe8f1504f2806282ccc3e7f4a0bee0b4.png)

---

<div class="post-metadata">

**Author:** ![makc3d](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/makc3d/32/10452_2.png) [@makc3d](https://discourse.threejs.org/u/makc3d)\
**Post date:** [July 6, 2023, 9:13am UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/14 "2023-07-06T09:13:06Z")

</div>

> [@drcmda](#):
>
> odd that this doesn’t seem to be documented

nothing odd, people who run into problems always write to github tickets, not to documentation files 😅 the issue about uuids is [here](https://github.com/mrdoob/three.js/issues/13069) if you want to read it. but the point is, even though a large number of js objects instances might not translate into a large number of webgl objects 3js creates, you can still run into other unrelated issue, so they cant give you the definite answer that you want.

---

<div class="post-metadata">

**Author:** ![makc3d](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/makc3d/32/10452_2.png) [@makc3d](https://discourse.threejs.org/u/makc3d)\
**Post date:** [July 6, 2023, 9:17am UTC](https://discourse.threejs.org/t/does-my-code-create-a-new-material-all-the-time-r3f/53537/15 "2023-07-06T09:17:59Z")

</div>

probably not, since the complete string is coming over the socket. still an issue on the sending side tho.
