Using shaders to adjust the background color of a scene in three.js: A step-by-step guide

Is there a way to modify the background color of a basic three.js scene using shaders or ShaderMaterial? I have tried inputting glsl code within the brackets of renderer.setClearColor(/*insert color here*/) or scene.background = new THREE.Color(/*insert color here*/), but it does not seem to be effective. How can I achieve this?

Answer №1

Implementing WebGLRenderTarget.texture as the scene.background:

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 100);
camera.position.set(0, 0, 10);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", event => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
  gu.resolution.set(innerWidth, innerHeight);
});

const gu = {
  time: {value: 0},
  resolution: {value: new THREE.Vector2(innerWidth, innerHeight)}
}

const light = new THREE.DirectionalLight(0xffffff, 0.8);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.2));

const ico = new THREE.Mesh(new THREE.IcosahedronGeometry(3, 0), new THREE.MeshLambertMaterial({color: 0xff4488}));
scene.add(ico);

// <background stuff>
const backScene = new THREE.Mesh(new THREE.PlaneGeometry(2, 2), new THREE.MeshBasicMaterial({
  color: 0x004488,
  onBeforeCompile: shader =>  {
  shader.uniforms.time = gu.time;
  shader.uniforms.resolution = gu.resolution;
  shader.vertexShader = `
    varying vec2 vUv;
  ` + shader.vertexShader;
  shader.vertexShader = shader.vertexShader.replace(
    `#include <uv_vertex>`,
    `vUv = uv;`
  );
  shader.fragmentShader = `
    ${noise}
    uniform float time;
    uniform vec2 resolution;
    varying vec2 vUv;
  ` + shader.fragmentShader;
  shader.fragmentShader = shader.fragmentShader.replace(
    `vec4 diffuseColor = vec4( diffuse, opacity );`,
    `
      vec2 tUv = vUv * 5.0;
      tUv.x *= resolution.x / resolution.y;
      float t = time * 0.5;
      tUv -= vec2(t * 0.25, t);
      float n1 = snoise(vec3(tUv, time * 0.125));
      n1 = (n1 + 1.0) * 0.5;
      
      float n2 = snoise(vec3(n1 * 10., 1, 1));
      n2 = sin(((n2 + 1.0) * 0.5) * 3.1415926 * 2.);
      
      float effect = smoothstep(0.1, 0.125, n1) * (1. - smoothstep(0.375, 0.4, n2));
      float coef = sin(n2 * 3.141526 * 0.5) * 0.125;
      float e = effect - abs(coef);
      e = n1 > 0.25 && n1 < 0.75? e * e : pow(e, 16.);

      vec4 diffuseColor = vec4(diffuse * e, opacity);
    `
  );
}
}));
const backCamera = new THREE.Camera();
const backRT = new THREE.WebGLRenderTarget(innerWidth, innerHeight);
scene.background = backRT.texture; // setting it to background
// </background stuff>

const clock = new THREE.Clock();

renderer.setAnimationLoop( _ => {
  const t = clock.getElapsedTime();
  gu.time.value = t;
  
  ico.rotation.x = t * 0.31;
  ico.rotation.y = t * 0.27;
  
  renderer.setRenderTarget(backRT); // assigning render target
  renderer.render(backScene, backCamera); // rendering the background
  
  renderer.setRenderTarget(null); // removing render target, now rendering to default buffer
  renderer.render(scene, camera); // rendering the scene again
  
  renderer.render(scene, camera);
})
body{
  overflow: hidden;
  margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script>
  var noise = `
  //
/*

Truncated for brevity...
*/ 

`;
</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

Is there a way to emphasize the closing div in editplus by automatically highlighting it when I click or select the corresponding opening

Does editplus have a feature that highlights the closing div when I select the opening div? I'm aware that this functionality exists for braces in edit plus, but it would be more convenient if the same applied to div elements. ...

Discover a helpful tip for using Pentadactyl with StackExchange's voting buttons

Does anyone know how to enable hinting for voting arrows on StackExchange using Pentadactyl (a fork of Vimperator)? I've tried removing my .pentadactylrc file and restarting Firefox, but still can't figure out how to upvote questions and answers ...

Connecting to a fresh dynamic route does not impact the getInitialProps data

I am struggling to understand the difference between componentDidMount and getInitialProps. Despite my best efforts to research, I still can't figure out when to use each one in my specific case. Let me give you some context. I have a page called /co ...

Running npm build/deploy is not functioning properly and is throwing a "failed to compile errors" message

I attempted to use npm run deploy/build, but it was unsuccessful and resulted in an error in the terminal. As a novice in git and github, I am looking to upload the changes I made in my most recent commit to my github pages. However, no matter how many tim ...

Utilizing JavaScript For Loops for Code Repetition

Apologies for the ambiguous question title - struggling to articulate this properly. Essentially, I have some JavaScript code that I am looking to streamline by using a for loop. $('.q1').keyup(function () { if ($.inArray($(this).val().toLo ...

Jquery vertical menu with a dynamic sliding animation from the right side to the left side

Hello everyone, I am looking to have my vertical menu slide from right to left instead of the typical top to bottom sliding that comes with using .toggle() in jQuery. Specifically, when the hamburger menu is clicked, I want the menu to slide out from right ...

The jQuery css method fails to apply styles to SVG circle elements

HTML: <div class="container"> <article class="caption"> <svg class="grid-point" width="100" height="100" style="height: 120px; width: 625px;"> <circle class="myPoint" cx="50" cy="50" r="5" fill="#80E1EE" / ...

Arranging DIVs based on attribute using JQuery

I am attempting to utilize buttons for the purpose of sorting a group of DIV elements based on custom attributes. I came across an example that I tried to follow, but encountered issues when trying to implement it with custom attributes. I suspect that the ...

Leverage the ajax variable within HighCharts

I am retrieving data from MySQL using AJAX. However, I am facing an issue in using this data in HighCharts. Here is a brief overview of the situation: var Name; (function fetchData() { $.ajax({ url: './riza.php', ...

Differences between Vue.js onMounted and watching refsVue.js offers

When it comes to calling a function that requires an HTMLElement as an argument, the element in question is rendered within my page template and therefore I need to ensure it is actually in the DOM before making the call. Two potential methods for waiting ...

Developing an ASP.NET application that returns a custom object in JSON format

I have a class called CodeWithMessage that I need to return as a json object from my web service. Here is how the class is defined: namespace UserSite //Classes For my site { namespace General { public class CodeWithMessage { ...

Does Typescript fail to recognize the "delete" operator?

Whenever I utilize the delete operator in Typescript, it appears that the system does not recognize that the property has been eliminated. For instance: interface HasName { name: string; } interface HasNoName { name: never; } function removeName( ...

Switch to a new section element every 20 seconds

After conducting research, I discovered that my initial approach to this task is not feasible. I have two elements on a page: a graph created using the chart.js framework and a data table. The data in the chart only changes once a day, and the data retriev ...

The removeEventListener method seems to be malfunctioning when used within an if statement in my three.js code

I am relatively new to JavaScript, although I have a background in mathematics which includes concepts like coordinate systems and trigonometry. I've been learning JavaScript through Codecademy for the past couple of weeks, and recently attempted to c ...

The total number of items in the cart is experiencing an issue with updating

For a recording of the issue, click here: While everything works fine locally, once deployed to production (vercel), it stops working. I've tried numerous approaches such as creating a separate state in the cart, using useEffect with totalQuantity in ...

Requests exceeding 8 kilobytes

I am looking to measure the round trip time between a client and server. Users have the option to determine the size of the request/response message they want to send. On the client side, I am using the Ajax-Post method to transmit 100 messages every 100 m ...

Unable to navigate through bootstrap dropdown items using keyboard shortcuts

I am currently working on a bootstrap dropdown menu that is filled with time zone details. Everything seems to be in order as the dropdown gets populated correctly. However, when I click on it and try to select an item by pressing a key on the keyboard (fo ...

Distinguishing between if(a) and if(a!=null && a!=undefined)

While attempting to populate data in the DOM, I am encountering numerous issues due to the absence of values in the objects or arrays I am trying to utilize. Take, for instance, the following object: var obj = { name: 'rajat', age: 20 } Gi ...

Is there a method available to minimize the size of a local storage list containing strings?

Hey there, I am trying to load a large 2.5MB json file in my browser so that I can use it for some typeAhead functions. Unfortunately, I'm facing an issue with my local storage being constantly full. When using Firefox, I receive the following error ...

I require a browse button on my JSP page that allows users to select folders, not individual files

In search of ideas for my JSP page, I am looking to browse a folder rather than just a file. Can anyone assist with this requirement? ...