How to make a texture looks darker?

The origin image is below, I set it to my scene background:
image
But I want it looks darker like below, how can I achive:
image
My code is:

  var textureLoader = new THREE.TextureLoader();
  var texture = textureLoader.load('./3d/xxx.png');
  texture.encoding = THREE.sRGBEncoding;
  scene.background = texture

If you use Scene.background with a texture, there is no way to change the color or intensity of the rendered background. You have to update the texture itself.

Can I simulate Scene.background effect through the PlaneGeometry, and then what I need to do?

  var planeGeometry = new THREE.PlaneGeometry(50, 100)
  var planeMaterial = new THREE.MeshLambertMaterial({ color: 0x222222 })
  var textureLoader = new THREE.TextureLoader();
  textureLoader.load("./3d/xxx.png", function (map) {
    planeMaterial.map = map;
  });
  var plane = new THREE.Mesh(planeGeometry, planeMaterial)

You have several options, if you donā€™t use the sceneā€™s background:

  • use another canvas to draw your image and manipulate it there, and then get it as a texture via CanvasTexture
  • use the .color property of the material to ā€œtintā€ your image (everything bar white works here) and make it darker, or the .emissive property to make it lighter
  • place another .transparent and using partial .opacity mesh colored black or similar in front of your original mesh
  • although this has an effect on the overall image / WGL canvas, a color matrix filter that you can adapt from this:
      <div>
        <svg>
          <filter id="colormatrix">
            <feColorMatrix color-interpolation-filters="sRGB" type="matrix" values="1.00 0.00 0.00 0.00 0.00  0.00 1.00 0.00 0.00 0.00  0.00 0.00 1.00 0.00 0.00  0.00 0.00 0.00 1.00 0.00" />
          </filter>
        </svg>
        <canvas id="yourthreejsorothercanvas"></canvas>
      </div>

can be used to alter all kinds of things on the element it acts on (similar to other CSS methods), via commands similar to document.querySelector("#colormatrix feColorMatrix").setAttribute("values", [1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0].join(" "));.

As far as I can tell, you could simulate a background via a plane geometry, but then, if, say, you rotate the camera in your scene, youā€™d need to rotate the plane in the same direction and amount as well, in order to keep it facing the camera at all times. So, when it comes to this issue, it would be better to use a Sprite instead - its material is a bit limited compared to others, but maybe it will be enough for your needs in this case.

Hereā€™s a one-liner for darkening textures in three.js

let dArr = texture.source.data.data; dArr.forEach((amt, n) => { dArr[n] = Math.floor(amt / 1.1) })

Handy for quickly toning down the brightness of a HDR/envmap

EDIT: only consider this very hacky approach if environmentIntensity isnā€™t doing it for you

1 Like

Possibly related (and GPU-based) :eyes:

1 Like

environmentIntensity (compared to just using a darker reference texture) tends to control the contrast of the lighting more than its brightness imo

But you are right, environmentIntensity should the thing people should try adjusting first. It was not sufficient in my case and thought I would post my (admittedly very hacky) approach for anyone else looking to overcomplicate their lighting :slight_smile: