Creating Stunning Light Effects in Three.js using Volumetric Shading and Additive Blending

Greetings to all who are taking the time to read this message;

I've embarked on a journey to create a model of the Solar System using three.js. My goal is to simulate the Sun with a volumetric light effect similar to the one demonstrated here. However, since the tutorial utilizes an older version of three.js, I'm in the process of adapting the code to the latest edition.

The concept is rather straightforward:

  1. Set up two scenes within the same environment – one containing the volumetric light and a completely black object in orbit, and the other housing the object with the appropriate material
  2. Implement the volumetric light shading on the concealed layer
  3. Apply an additive blending shader on the top layer, utilizing the texture generated from rendering the hidden layer

I have successfully configured the two scenes as intended. However, here's the outcome:

Access Codepen Here

View Result Image Here


    import { RenderPass } from 'https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="087c607a6d6d483826393a3f2638">[email protected]</a>/examples/jsm/postprocessing/RenderPass.js';
    import { ShaderPass } from 'https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="daaeb2a8bfbf9aeaf4ebe8edf4ea">[email protected]</a>/examples/jsm/postprocessing/ShaderPass.js';
    import { EffectComposer } from 'https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2d59455f48486d1d031c1f1a031d">[email protected]</a>/examples/jsm/postprocessing/EffectComposer.js';
    
    THREE.VolumetericLightShader = {
       // Uniforms and shaders
      };
      
      THREE.AdditiveBlendingShader = {
         // Uniforms and shaders
      };
      
      
    
    
    // RENDERER and scene setup
   // Camera, lights, and geometries
   
    function animate() {
        requestAnimationFrame(animate);
        render();
    };
    
    function render() {
        // ... camera and light adjustments
    
        //  Modification positions and rendering steps
        
        // Final rendering
       
    }
    
    animate();

Currently, there seems to be an issue where the texture utilized by the additive blending shader does not acknowledge the post-processing volumetric light effect. Interestingly, when I separately render the two layers by commenting out either the

oclcomposer.render()

or

composer.render()

at the end of the script, the effect renders correctly:

Rendered Hidden Layer (commenting composer.render())

Rendered Default Layer (commenting oclcomposer.render())

I'm facing challenges in troubleshooting this issue, mainly due to my limited expertise in 3D programming. Initially, I had hoped for a seamless integration of the shader to achieve the desired effect. Now, I seek to comprehend why the volumetric shader does not seem to impact the additive blending. Any assistance or insights would be greatly appreciated.

Answer №1

After experimenting with different approaches, I was able to achieve the desired effect using these steps:

  • Introduce a dummy pass in the hidden layer (a CopyShader pass)
  • Instead of retrieving the overlay image from renderTargetOcl.texture, I now directly access it from the oclcomposer writeBuffer by adding this line:
addingPass.uniforms.tAdd.value = oclcomposer.writeBuffer;

Interestingly, removing the dummy pass or switching to readBuffer disrupts the functionality. This is perplexing because:

  1. The CopyShader readBuffer is supposed to draw from the preceding pass, which should already contain the volumetric light shading effect
  2. The Volumetric Light Shading effect should inherently include the effect stored in its writeBuffer

While I don't have a logical explanation for this inconsistency, the code does yield the intended outcome.

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

Concealing specific sections of HTML content in a webview on the fly

I've been experimenting with a proof of concept feature to implement the ability to conceal certain parts of a web page loaded in a webview, but I seem to be encountering some issues... Within a UIWebview extension, I have something similar to this c ...

Leverage the power of jQuery to manipulate video tags

Here's the challenge: I need to utilize a jQuery function to extract a URL from a link's REL attribute and then transfer it to a video element. The extraction process and transmission seem to be working smoothly. However, my struggle lies in act ...

Unleashing the power of a headless browser with Selenium WebDriver using Chromedriver

I have a piece of code that I'm looking to adapt in order to use a hidden browser window for the same task. var webdriver = require('selenium-webdriver'); var chrome = require('selenium-webdriver/chrome'); var path = require(&apos ...

Combining Objects within an Array in JavaScript When Certain Conditions Are Satisfied

In my scenario, I am seeking assistance with merging the values of objects in an array if the id matches the warehouse_item_id. Specifically, there are two objects that need to be merged: id 191 and id 52 because id 52 has a warehouse_item_id of 191. Ple ...

Using Javascript to create alerts that display all objects

Is there a way to send a single alert with all objects? Whenever I attempt it, I keep getting undefined or [object, object] var array =[]; function object ( name, username, password) this.name = name this.user = username this.pwd = password var obj ...

Trigger the Material UI DatePicker to open upon clicking the input field

I have a component that is not receiving the onClick event. I understand that I need to pass a prop with open as a boolean value, but I'm struggling to find a way to trigger it when clicking on MuiDatePicker. Here is an image to show where I want to ...

Display a dialogue box in close proximity to a text area without utilizing a pop-up or alert notification

How can I display a short message next to a textarea when it is clicked? Below is the code that needs modification: <textarea id="txt" ></textarea> and : $('#txt').click(function(){ // What should be added here to show a dialog bo ...

Is the input field not properly centered on the page?

Can someone explain why the input field is not aligning in the center? I am new to web development and need some assistance. <input type="text" id="search_bar" class="form-control" placeholder="Search" align="center"> In my CSS, I've ...

Is it possible to trigger a reflow prior to initiating a lengthy JavaScript operation?

Ready to face the criticism, I understand that this question has been asked many times before, and I am aware that there are likely more efficient ways to achieve what I'm trying to do... In a JavaScript function, I have a process that can take up to ...

Whenever the useState hook is utilized, it will trigger a re-execution

In my code for form validation in the next.js V1, I am experiencing a problem. The code snippet is as follows: setErrorF((errorF) => { if( errorF.FNameAndLName !== "" || errorF.phoneNumber !== "" || errorF.location1 !== ...

In what way does ReactJS enable me to utilize constant functions before they are declared?

I'm intrigued by the concept of using a value before defining it in ReactJS. Let's explore this through an example: function CounterApp() { const [counter, setCounter] = useState(0); const increaseValueTwice = () => { increaseValue() ...

Route is searching for static files in the incorrect directory

There seems to be a specific route, /admins/:id, that is looking for static files in /public/admins/ instead of /public/. This issue is causing 404 errors and preventing the js and css files from loading on this page. All other routes are correctly fetchin ...

When the mouse is released, modify the button

Looking for assistance with changing the background color of a button when clicked, without any post back. I have multiple buttons and want only the clicked one to change color while the others stay the same. Any suggestions on how to achieve this? ...

Tips on transferring large JSON data (250kb) to a MySQL database through the use of AJAX, JavaScript, and PHP

function sendProjectData(docsId, data) { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function () { localStorage.setItem('updatedData',JSON.stringify(data)); if (this.readyState == 4 && this.sta ...

A versatile multi-select jQuery widget featuring the ability to choose options within a specific opt

I am on the hunt for a cool jQuery tool that has the following characteristics: It enables you to create multiple groups, such as: Group 1 - Sub 1 1 - Sub 1 2 - Sub 1 3 Group 2 - Sub 2 1 Group 3 - Sub 3 1 - Sub 3 2 By clicking on Group 1, for instance, ...

Automatically expanding and contracting text input area that adjusts to different amounts of content up to a certain

While similar questions have been asked before, none of them quite address the specific requirements in my title. My goal is to create a basic textarea input that automatically adjusts its height based on content, up to a maximum height limit. Once this l ...

The position of the scroll bar remains consistent as you navigate between different websites

Is it possible for me to click on a link within my HTML website and have the other website load with me in the exact same position? For example, if I'm halfway down a webpage and click a link, can I be taken to that same point on the new page? If so, ...

Combining strings with JQuery

Looking for help with a code snippet <script> function goToDetails($i){ $(function(){ var transValue = $('#trans'+$i).html(); var mileageValue = $('#mileage'+$i).html(); var engineValue = $('#eng'+$i).html ...

Vue is alerting me that I cannot assign a reactive property to an undefined, null, or primitive value, specifically null

When retrieving data from Firebase, I am attempting to update the properties of the object being displayed on the UI. However, whenever I try to make any changes to the data, an error is thrown. Error in v-on handler: "TypeError: Cannot use 'in&apos ...

All Event Monitor

Is it possible to use Event Listeners in jQuery to display information when a specific word is clicked? For example, showing a definition when a word is clicked. Thanks, Adam. I need help with creating a feature where clicking on a person's name in a ...