# R3F: MeshBasicMaterial too bright after replacing texture

**URL:** <https://discourse.threejs.org/t/r3f-meshbasicmaterial-too-bright-after-replacing-texture/44434>\
**Category:** Questions\
**Tags:** react-three-fiber, textures, materials\
**Created:** [November 7, 2022, 10:04pm UTC](https://discourse.threejs.org/t/r3f-meshbasicmaterial-too-bright-after-replacing-texture/44434 "2022-11-07T22:04:59Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![cat](https://avatars.discourse-cdn.com/v4/letter/c/d07c76/32.png) [@cat](https://discourse.threejs.org/u/cat)\
**Post date:** [November 7, 2022, 10:04pm UTC](https://discourse.threejs.org/t/r3f-meshbasicmaterial-too-bright-after-replacing-texture/44434/1 "2022-11-07T22:04:59Z")

</div>

I’m dynamically replacing textures on a MeshBasicMaterial and when replaced, the second texture is much brighter than the source. Could anyone advise whether it is possible to dynamically replace the texture of a material and ensure that the second texture is displayed at the correct brightness?

In the image below, the same video texture is being displayed twice. On the left plane, the video replaced another texture (and is too bright). On the right, the video was displayed first, and is the correct brightness.

 ![two images - one of which is brighter than the other](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/e/b/eb6bcff67703abfdbdd63f7d10ca98170184ce0f.jpeg)

Minimal reproduction here: [replace-texture-brightness - CodeSandbox](https://codesandbox.io/s/replace-texture-brightness-01f6qw?file=/src/App.js)

Note this is related to [R3F, using screen fill and replace by videoTexture](https://discourse.threejs.org/t/r3f-using-screen-fill-and-replace-by-videotexture/42313) but I am ideally looking to continue using the same material but with a new texture.

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [November 7, 2022, 10:56pm UTC](https://discourse.threejs.org/t/r3f-meshbasicmaterial-too-bright-after-replacing-texture/44434/2 "2022-11-07T22:56:10Z")

</div>

By all appearances, what is missing here is the correct color space (.encoding) on the video texture. But I’ve tried a few variations of `texture.encoding = sRGBEncoding` and it doesn’t seem to be having the expected effect… possibly the material needs to recompile (`material.needsUpdate = true`) when the texture is changed. But I’m not sure how to express that in R3F syntax…

---

<div class="post-metadata">

**Author:** ![cat](https://avatars.discourse-cdn.com/v4/letter/c/d07c76/32.png) [@cat](https://discourse.threejs.org/u/cat)\
**Post date:** [November 7, 2022, 11:10pm UTC](https://discourse.threejs.org/t/r3f-meshbasicmaterial-too-bright-after-replacing-texture/44434/3 "2022-11-07T23:10:57Z")

</div>

Thank you for the reply! In my less-minimal test example which I’m using locally, encoding is correctly set and the issue remains. Does anyone have a sense for how to force a re-compilation in r3f?

Worth noting that my minimal vanilla threejs example works correctly as seen here:

 ![two planes displaying images of similar brightness](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/9/e/9e563bf14c8b2f0a9069f1cf259f28998cabb6b6.jpeg)

Code here: [swap-texture-vanilla-threejs - CodeSandbox](https://codesandbox.io/s/swap-texture-vanilla-threejs-cq0s1q?file=/src/index.js)

---

<div class="post-metadata">

**Author:** ![cat](https://avatars.discourse-cdn.com/v4/letter/c/d07c76/32.png) [@cat](https://discourse.threejs.org/u/cat)\
**Post date:** [November 8, 2022, 2:46am UTC](https://discourse.threejs.org/t/r3f-meshbasicmaterial-too-bright-after-replacing-texture/44434/4 "2022-11-08T02:46:05Z")

</div>

@donmccurdy setting `material.needsUpdate = true;` after replacing the texture did the trick. In react, I used the useEffect hook to recompile the material after every texture replacement:

```nohighlight
function ToggleableVideoMaterial({ texState }) {
  const texture = ToggleableTexture(texState)
  const materialRef = useRef()
  useEffect(() => {
    console.log('swap')
    if (materialRef.current) {
      materialRef.current.needsUpdate = true
    }
  }, [texture])
  return <meshBasicMaterial ref={materialRef} map={texture} toneMapped={false} />
}

```

Fix here: [replace-texture-brightness-fix - CodeSandbox](https://codesandbox.io/s/replace-texture-brightness-fix-cd2q0q?file=/src/App.js:1108-1460)

If anyone has a more elegant solution, please let me know.

Thanks! 🙂

---

<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:** [November 8, 2022, 8:09am UTC](https://discourse.threejs.org/t/r3f-meshbasicmaterial-too-bright-after-replacing-texture/44434/5 "2022-11-08T08:09:15Z")

</div>

```nohighlight
<meshBasicMaterial
  ref={ref}
  map={tex}
  toneMapped={false}
  onUpdate={self => self.needsUpdate = true} />

```

useEffect is OK, but prefer useLayoutEffect to avoid FOUC, uE will fire _after_ render, uLE will fire before. you also don’t need `if (materialRef.current) {` materialRef cannot be null.

the shortest effect notation would be

```javascript
useLayoutEffect(() => void (ref.current.needsUpdate = true), [texture])

```

---

<div class="post-metadata">

**Author:** ![cat](https://avatars.discourse-cdn.com/v4/letter/c/d07c76/32.png) [@cat](https://discourse.threejs.org/u/cat)\
**Post date:** [November 8, 2022, 8:50pm UTC](https://discourse.threejs.org/t/r3f-meshbasicmaterial-too-bright-after-replacing-texture/44434/6 "2022-11-08T20:50:39Z")

</div>

Thanks @drcmda !

Is there a reason materials in @react-three/fiber aren’t automatically set to recompile after an update?

And noted re: UseLayoutEffect.

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [November 8, 2022, 9:19pm UTC](https://discourse.threejs.org/t/r3f-meshbasicmaterial-too-bright-after-replacing-texture/44434/7 "2022-11-08T21:19:04Z")

</div>

It’s not always necessary (e.g. changing .color or .roughness) and will be expensive to do if you don’t need it. Replacing a texture does not in general require a recompile either. I’m not sure if this is specific to swapping Texture vs. VideoTexture, or some change in the encoding behavior, I may not understand how that works with video sources.

---

<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:** [November 9, 2022, 8:58am UTC](https://discourse.threejs.org/t/r3f-meshbasicmaterial-too-bright-after-replacing-texture/44434/8 "2022-11-09T08:58:58Z")

</div>

it doesn’t change what threejs is or how it works. this was deliberate because we don’t want to be an engine, just a different way to express three. technically fiber doesn’t know what three is, it doesn’t even have a dependency on it, you have to provide it. that’s what allows it to be somewhat independent, there is no maintenance effort. if three now needs an update for something, you’ll have to provide it just like in vanilla.

an exception to this is when you abstract your own component. for instance most if not all the components in drei take care of such things.

---

<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:** [May 22, 2023, 12:06pm UTC](https://discourse.threejs.org/t/r3f-meshbasicmaterial-too-bright-after-replacing-texture/44434/9 "2023-05-22T12:06:45Z")

</div>

Hey i have a similar Problem with meshStandardMaterial. When I’m changing the texture, the new texture appears way brighter than it actually is. I tried it like the example with the meshBasicMaterial but it didnt work. From the useCustomization hook i get a String with the texture name. Im changing the texture with two if statements whats the problem?

```javascript
export function Tuerblatt(props) {
  const { material, doorWidth, doorHeight } = useCustomization();
  const { nodes, materials } = useGLTF("./models/tuerBlattV3.gltf");

  const materialRef = useRef()

  const doorWidthMetric = (doorWidth / 0.86)
  const doorHeightMetric = (doorHeight / 2) 

  const tuerBlattTexture = useTexture({
    map: './textures/tuerblattTexture/doorAlt.jpg',
  })

  const tuerBlattTextureAlt = useTexture({
    map: './textures/tuerblattTexture/doorDefault.jpg',
  })

  const tuerBlattTextureWood = useTexture({
    map: './textures/tuerblattTexture/doorHell.jpg',
  })

  tuerBlattTexture.map.wrapS = tuerBlattTexture.map.wrapT = THREE.RepeatWrapping
  tuerBlattTextureAlt.map.wrapS = tuerBlattTextureAlt.map.wrapT = THREE.RepeatWrapping
  tuerBlattTextureWood.map.wrapS = tuerBlattTextureWood.map.wrapT = THREE.RepeatWrapping

  tuerBlattTexture.map.repeat.set(doorWidthMetric, doorHeightMetric)
  tuerBlattTextureAlt.map.repeat.set(doorWidthMetric, doorHeightMetric)
  tuerBlattTextureWood.map.repeat.set(doorWidthMetric, doorHeightMetric)

  useEffect(() => void (materialRef.current.needsUpdate = true), [material])

  return (
    <group {...props} dispose={null} key={material}>
      <mesh
        geometry={nodes.Türblatt.geometry}
        position={[0.13, 0, 0]}
        scale={[1, doorHeightMetric, doorWidthMetric]}
        receiveShadow
        castShadow>
          {/* <meshStandardMaterial {...tuerBlattTexture} /> */}
          <meshStandardMaterial ref={materialRef} envMapIntensity={envMapIntensity} toneMapped={false}
            {...(material === "CPLEicheCerne" ? tuerBlattTexture : (material === "StandardGlatt" ? tuerBlattTextureAlt : tuerBlattTextureWood))}
          />
        </mesh>
    </group>
  );
}

useGLTF.preload("./models/tuerBlatt.gltf");

```

---

<div class="post-metadata">

**Author:** ![Hugo\_P](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hugo_p/32/37159_2.png) [@Hugo\_P](https://discourse.threejs.org/u/Hugo_P)\
**Post date:** [January 16, 2024, 9:44am UTC](https://discourse.threejs.org/t/r3f-meshbasicmaterial-too-bright-after-replacing-texture/44434/10 "2024-01-16T09:44:43Z")

</div>

I had a similar problem while updating an old project from the v146 to v160. The texture was way more bright/exposed than before.

Since the v152 `texture.encoding = THREE.sRGBEncoding` is deprecated, the fix that worked for me is `texture.colorSpace = THREE.SRGBColorSpace` as mentioned in the deprecation notice 👍
