Using shaderMaterial from three.js DREI make the texture way darker than the original


Everything is in the title. I created a custom glsl shader and even if I dont modify anything, the result is way darker than the original. I am using this:
vec3 texture = texture2D(uTexture, uv).rgb;

to get the texture so perhaps the error is there.

You can see the original picture in /public et nature_morte.jpg.

codesandbox link

Do you have any idea of what is going on ? The code is a bit messy, I can clean it up if necessary.
Perhaps the problem is linked to that : three.js - Washed out color in ShaderMaterial - Stack Overflow

Thanks for your help

link broken. but shaderMaterial is nothing else than a plain THREE.ShaderMaterial. what you are most likely missing is encoding and tonemapping includes but that’s the case with any custom shader in threejs.

    gl_FragColor = ...
    #include <tonemapping_fragment>
    #include <encodings_fragment>

Ok, I’ll check that. I have updated the link if you want to have a look.For sure, I encoded nothing for the moment.

still getting “Project not found” it’s probably set private. but either way, every color shader in threejs needs encoding and tonemapping fragments.

Thank you anyway

Does this works better ?

I add this as you told :slight_smile: #include <encodings_pars_fragment>;

I now have the message “this function already has a body” which means the package is already loaded. How not to load it twice ? basic question but I only found c# answer to this.

it needs to be in the fragment, inside the main function underneath gl_FragColor. the correct includes are

#include <tonemapping_fragment>
#include <encodings_fragment>

not “pars”

it might also be that the texture you’re giving is has a wrong colorSpace. you will have more luck if you search for THREE.ShaderMaterial specifically (stackoverflow etc) because that’s where the issue is. drei/shaderMaterial is just a helper that creates setter/getters, but wouldn’t change how the shader works:

function shaderMaterial(uniforms, vertexShader, fragmentShader) {
  return class extends THREE.ShaderMaterial {
    constructor(parameters = {}) {
      const entries = Object.entries(uniforms)
        uniforms: entries.reduce((acc, [name, value]) => {
          const uniform = THREE.UniformsUtils.clone({ [name]: { value } })
          return { ...acc, ...uniform }
        }, {}),
      entries.forEach(([name]) =>
        Object.defineProperty(this, name, {
          get: () => this.uniforms[name].value,
          set: (v) => (this.uniforms[name].value = v),
      Object.assign(this, parameters)
1 Like

your sandbox is still unavailable but give this a try

shaderMaterial.toneMapped = false
texture.colorSpace = THREE.SRGBColorSpace
1 Like

I have this error:

I had this:
#include <tonemapping_fragment>;
#include <encodings_fragment>;

and both tone mapped and three.colorSpace

Do you have a link to a similar code which is working ? I also have an alpha map

texture = SRGBToLinear(texture) 

I’m not sure this is valid glsl, you’d probably want to convert your textures color space outside of the shader before passing it in as a uniform…

I removed the srgbtolinear:

I now have his error. What to do ?

And it is how I load the image:


Both images are jpg

As it suggests in the console error, probably delete the semicolon after your endif and the second semicolon further on? Glsl has a strict syntax that needs to be followed in order for it to compile…


Thank you for so many answer, it works perfectly

Always a pleasure :slight_smile: