What is the best way to prevent the background image from transitioning from white to grey while utilizing toneMapping in three.js?

I have implemented the following code snippet in a class to set up the renderer:

// initializing the renderer
        this.renderer = new THREE.WebGLRenderer( { antialias: true });
        this.renderer.setClearColor (0xffffff, 1); // setting background color
        this.renderer.outputEncoding = THREE.sRGBEncoding;
        this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
        this.renderer.toneMappingExposure = 1;
        this.renderer.physicallyCorrectLights = true;

The next piece of code is used to add a white image as the background in the scene:

var texture11 = new THREE.TextureLoader().load("https://www.publicdomainpictures.net/pictures/30000/velka/plain-white-background.jpg");
        
        this.scene.background = texture11 ;

However, when utilizing toneMapping, the white image appears grey in the rendered scene shown below:

https://i.sstatic.net/aGEGy.png

Is there a way to maintain the original color of the image during rendering?

Answer №1

Textured backgrounds automatically adjust to tone mapping and there is no direct way to prevent this behavior without modifying the shader code.

If you want to avoid this default behavior, you can create a custom skybox with tone mapping disabled using the following code snippet:

let camera, scene, renderer;

init();
animate();

function init() {

  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
  camera.position.z = 1;

  scene = new THREE.Scene();

  const loader = new THREE.CubeTextureLoader();
  loader.setPath('https://threejs.org/examples/textures/cube/Bridge2/');

  const cubeMap = loader.load(['posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg']);
  cubeMap.encoding = THREE.sRGBEncoding;

  //scene.background = cubeMap;

  const skybox = new THREE.Mesh(
    new THREE.BoxBufferGeometry(10, 10, 10),
    new THREE.ShaderMaterial({
      uniforms: THREE.UniformsUtils.clone(THREE.ShaderLib.cube.uniforms),
      vertexShader: THREE.ShaderLib.cube.vertexShader,
      fragmentShader: THREE.ShaderLib.cube.fragmentShader,
      depthTest: false,
      depthWrite: false,
      side: THREE.BackSide,
      toneMapped: false
    })
  );

  skybox.material.uniforms.envMap.value = cubeMap;

  Object.defineProperty(skybox.material, 'envMap', {

    get: function() {

      return this.uniforms.envMap.value;

    }

  });

  scene.add(skybox);

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.outputEncoding = THREE.sRGBEncoding;
  renderer.toneMapping = THREE.ACESFilmicToneMapping;
  renderer.toneMappingExposure = 2;
  document.body.appendChild(renderer.domElement);

}

function animate() {

  requestAnimationFrame(animate);
  renderer.render(scene, camera);

}
body {
      margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4e3a263c2b2b0e7e607f7c7a">[email protected]</a>/build/three.js"></script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Customize your markers on Google Maps

I have integrated Markerclusterer with Google Maps in a similar way to the example provided. Here is my code snippet: var map = new google.maps.Map(document.getElementById("map"), options); var markers = []; for (var i = 0; i < 100; i++) { var latLn ...

Issue: TypeError - The function addTicket is not recognized as a valid function. Utilize the useState hook within the modal component

I'm currently facing some challenges with the implementation of the useState hook and I am struggling to understand why it is not working as expected. My project involves creating a basic ticket system where users can click on a button to open a moda ...

What could be causing this axios.get request to fail?

I am currently enrolled in Colt Steele's Web Developer bootcamp and facing a challenge... In the tutorial, we are using axios as 'request' has been discontinued, so I am trying to follow along with this change. My goal is to set up a Get r ...

Creating dynamic attributes in Angular: How to programmatically change HTML attributes based

In my Angular 1.5 project, I am facing a scenario where I need to dynamically add directive attributes to HTML based on certain conditions. For example, when the condition is true, I want to include directive1 and directive2 as attributes: <ng-form cl ...

Creating an integer key in JavaScript populates an array with null values

Currently in my Javascript code, I am setting up an array where the product id serves as the key. However, due to the numeric nature of the key, the array ends up filling gaps with null values. For instance, if I only have two products with ids 5 and 7, t ...

Rails application's generated link with jQuery is directing to localhost inaccurately

I've been delving into the world of RoR for a few months now and have encountered a puzzling issue involving Rails and javascript. While the HTML appears to display the correct URL, clicking on the link redirects to localhost instead. The link in my ...

Is there a way to efficiently install web assets such as bootstrap, jquery, and font-awesome without relying on a content delivery network

Is there a way to automatically install jquery, bootstrap, and font-awesome without going through npm and manually moving the files to the correct folders? Are there any programs that can update these libraries and place them in the appropriate directories ...

Choose from a dropdown menu in Select2 that will display "x selected" once the third item has been selected

Is there a way to display "x selected" after the third choice in the code below, using select2 for multiple selection from a dropdown? Currently, all choices are shown and it results in a huge textbox. <select multiple id="e1" style="width:300px"> ...

What sets apart .andReturn(...) from .respondWith(...) when running AJAX call tests in JavaScript using Jasmine?

While utilizing the jasmine-ajax library for testing JavaScript code, I have discovered a way to mock ajax responses. There are essentially two methods to achieve this: Method #1: jasmine.Ajax.requests.mostRecent().respondWith({ status: 200, contentT ...

What is the best way to conceal a division upon submitting a form in PHP once the database-side validations have been verified as accurate?

Just diving into the world of PHP development and I have an application with a home.php page where users are required to enter a security code before submitting. If the entered security code is correct, I want two divisions (with div ids window and securit ...

Where can you find the invalid character causing a syntax error in the jQuery $.ajax call?

My jQuery code is calling a WCF method, and although the method returns a Boolean true and logs successfully, the error handler displays "AJAX call failed in CallIsDataReady" with a "Syntax Error: Invalid character." This causes the callUpdateGrid function ...

In order to utilize Next.js with pkg, you must enable one of the specified parser plugins: 'flow' or 'typescript'

Utilizing next.js with the pkg in my project, following the steps outlined in this tutorial, I encountered an error when running the pkg command: > Error! This experimental syntax requires enabling one of the following parser plugin(s): 'flow, t ...

Using Javascript to extract values from a multi-select dropdown menu

Is there a way to use Javascript to set the values of a picklist? For instance, when a page loads, I need specific values in a picklist to be preselected. These values will be generated from a database using PHP and then echoed as actual Javascript code. ...

Spin the object in the vertex shader

Currently, I am delving into the world of instanced buffer geometries and experimenting with extending the LambertMaterial shader to apply rotation to each instance. #define LAMBERT mat4 rotationX( in float angle ) { return mat4( 1.0, 0, ...

Utilizing ng For in a personalized directive to fill a selection menu

I encountered an issue while trying to populate a selected dropdown using ngRepeat inside a custom directive. I came across this example that seemed similar to what I wanted to achieve here. Although it worked for the example, it didn't work for me. ...

Incorporate a Fadein effect into the current CSS for mouseover link interaction

Is there a way to enhance my current css code for a mouseover link with a background image by adding a fade in and out effect? What's the most effective method to achieve this using jquery? .sendB { width: 100%; height: 125px; background: ...

Uncovering the Secrets of Accessing Tag Attributes in ReactJS

I have developed a small app using reactjs. I have set an attribute on the button tag and passed a value to it. Now, when I click on the button, I want to retrieve the attribute value. How can I achieve this with react js? Here is a sample code snippet: ...

"Change opacity smoothly with the FadeToggle feature for a

I have a question that might seem silly, but I can't quite figure it out. How can I extend the duration of the fade effect? window.switchIn = function() { $('.red').fadeToggle(function(){ $('.blue').fadeToggle(function() { ...

Discover the method for measuring the size of a dynamically generated list

I'm currently working on a chat box that displays messages as a list. One issue I'm facing is that when I click on the start chat button, the chat box opens but the length of the list always remains zero. How can I resolve this problem? $(docu ...

What is the process for receiving updates while subscribing in ReactReduxContext.Consumer?

I am currently seeking a solution to staying updated on changes to a stored value in the Redux store by subscribing. I have attempted the following method: <ReactReduxContext.Consumer> {({store}) => { console.log('store:& ...