Enhancing visuals with THREE.js and the power of transparency through EffectComposer

I am attempting to blend texture passes in a way that preserves the alpha channel. I have experimented with several methods to achieve this.

  1. The renderer has the alpha property set to true.
  2. Renderer with various setClearColor settings.
  3. The material on the full-screen quad used by the effect passes has transparency enabled.
  4. The textures are indeed transparent.
  5. The shaders being used for blending utilize the alpha channel.

All the textures and passes draw correctly when individually commented out, but I am facing difficulty getting PNG1.png to properly blend over gits.jpg.

var width = window.innerWidth;
var height = window.innerHeight;
var updateFcts    = [];

var masterRenderer = new THREE.WebGLRenderer({
    alpha: true,
    autoClear: false
});
masterRenderer.setSize( window.innerWidth, window.innerHeight );
masterRenderer.setClearColor ( 0xFFFFFF, 1.0);
document.body.insertBefore( masterRenderer.domElement, document.body.firstChild);

var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: false };
var renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );
var masterComposer = new THREE.EffectComposer(masterRenderer, renderTarget);

var gitsTexture = THREE.ImageUtils.loadTexture( "images/gits.jpg" );
var pngTexture = THREE.ImageUtils.loadTexture( "images/PNG1.png" );

// declare passes
var passes = {};
passes.toScreen = new THREE.ShaderPass(THREE.CopyShader); passes.toScreen.renderToScreen = true;
passes.gitsTexturePass = new THREE.TexturePass(gitsTexture);
passes.gitsTexturePass.material.transparent = true;
passes.pngTexturePass = new THREE.TexturePass(pngTexture);
passes.pngTexturePass.material.transparent = true;

//add passes
masterComposer.addPass(passes.gitsTexturePass);
masterComposer.addPass(passes.pngTexturePass);
masterComposer.addPass(passes.toScreen);

// render the webgl

updateFcts.push(function(delta,now){
    masterComposer.render();
})


//////////////////////////////////////////////////////////////////////////////////
//      handle resize                           //
//////////////////////////////////////////////////////////////////////////////////

function onResize(){
    width = window.innerWidth;
    height = window.innerHeight;
    // notify the renderer of the size change
    masterRenderer.setSize( window.innerWidth, window.innerHeight );
    // update the camera
    camera.aspect   = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix();
    resizeFcts.forEach(function(resizeFn){resizeFn()})
}

window.addEventListener('resize', onResize, false)

//////////////////////////////////////////////////////////////////////////////////
//      loop runner                         //
//////////////////////////////////////////////////////////////////////////////////
var lastTimeMsec= null
requestAnimationFrame(function animate(nowMsec){
    // keep looping
    requestAnimationFrame( animate );
    // measure time
    lastTimeMsec    = lastTimeMsec || nowMsec-1000/60
    var deltaMsec   = Math.min(200, nowMsec - lastTimeMsec)
    lastTimeMsec    = nowMsec
    // call each update function
    updateFcts.forEach(function(updateFn){
        updateFn(deltaMsec/1000, nowMsec/1000)
    })
})

Answer №1

Resolution:

To fix the issue, consider using { premultipliedAlpha: false } in the renderer constructor, but be cautious with blending modes if you decide to do so.

This advice successfully addressed my initial problem.


Determining the root cause of my issue proved challenging. It seems that when utilizing the CopyShader, textures may become "pre-multiplied." I managed to achieve the desired effect by creating a custom shader that reverses the alpha multiplication.

    fragmentShader: [


    "uniform sampler2D tBase;",
    "uniform sampler2D tAdd;",
    "uniform float amount;",

    "varying vec2 vUv;",

    "void main() {",

        "vec4 t1 = texture2D( tBase, vUv );",
        "vec4 t2 = texture2D( tAdd, vUv );",
        "gl_FragColor = (t1 * (1.0 - t2.a))+(t2 * t2.a);",

    "}"

].join("\n")

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

Tips on sorting items in React

Hey there, I'm a beginner at react and currently working on my first ecommerce website. My main concern is about filtering products by size. I'm struggling with the logic behind it. Any help or guidance would be greatly appreciated. I also attem ...

A guide on verifying a phone number using just one character

I am looking to validate a phone number with only one character being allowed. For example, the format should be XXX-XXXXXXX where "-" is the only allowed character. Below is my validation function: function validatePhoneNumber() { if(addform.staff_m ...

Passport.js simply redirects to the failure page without invoking the LocalStrategy

I'm facing a persistent issue with Passport.js in my Express.js small application. No matter what I input in the LocalStrategy, I always end up being redirected to the failureRedirect without seemingly passing through the LocalStrategy at all. What am ...

Exploring the functionality of arrays within Selenium IDE

Recently delving into Selenium IDE, I am a beginner and looking for guidance. The challenge at hand: How can I access values from an array generated by execute script | var array1 = document.getElementsByClassName("Post"); return array1; | array1 Initi ...

Unable to place within div

Utilizing HTML5 to implement the "DnD" function. There is a button that adds divs. I want to be able to drag items into these newly added divs. Currently, I can only drag into existing divs and not the ones added later. How can I resolve this issue ...

Tips on retrieving complete information from mongoose when the schema contains a reference

I have a schema that includes [content, name, email], and I need to retrieve all three data fields and render them on the frontend simultaneously. Can you provide an example of JavaScript code that accomplishes this? const UserSchema = new mongoose.Schem ...

Encountered an issue with md-autocomplete: Attempting to read property 'success' of an undefined element

I encountered an issue while using Material Angular framework and md-autocomplete. The error message I receive is: Cannot read property 'success' of undefined. Below is the snippet of my code: /*My app.js*/ var app = angular.module('app&apo ...

Selecting middleware to be executed based on Express JS request parameters

Can someone please advise me on how to select between two distinct middleware functions, based on the request for a specific endpoint? It may involve something along these lines: router.post("/findAvailableAgents", chooseMiddleware(middleware1, ...

sending a selection of JSON string values to a jQuery function

I have a JSON string that contains different items, but I am only interested in the 'locked' array and would like to pass it to a jQuery function. The JSON string was generated using json_encode from PHP. {"ignored":[],"status":{"message":"succe ...

Remove specific data from jQuery datatables using data attribute

My jQuery datatable is loaded with data from a database without any filtering by default, providing all the necessary information for users. In addition to the built-in search functionality of jQuery datatables, I have incorporated custom search input fiel ...

Obtaining HTML data with ajax within a WordPress post

Greetings! I've been putting together a website and I'm eager to include a unique timeline in each of my posts. I'm utilizing WordPress for this project. However, since the timeline I want to insert will vary from post to post, I am unable t ...

Having trouble with Vue component not showing updated data after axios POST request issue

Hi there, I'm facing an issue and could really use some guidance from a skilled Javascript Wizard. Here's the problem: I have a Laravel collection that I'm passing to a Vue component. Within the component, I am looping through the collecti ...

Is there a way to display a secondary header once the page is scrolled down 60 pixels?

.nav-header2{ background: purple; display: flex; justify-content: center; align-items: center; } .header2-container{ width: 68vw; height: 60px; padding: 0 2vh; border: 1px solid red; ...

Over time (a few days), the setInterval function causes the react app to become unresponsive

In my React app (Next.js), I have implemented a feature that displays a QR code refreshing every 5 seconds, alongside a clock that updates every second. Additionally, I have integrated a service worker to enable Progressive Web App (PWA) functionality and ...

The antialiasing feature is not very effective in three.js

Even though I have set antialias to true in three.js when using SVG as a texture, it's still not working perfectly. // RENDERER renderer = new THREE.WebGLRenderer({ antialias: true, precision: "highp", alpha: tru ...

Issue: The object is unable to be executed as a function, resulting in the failure to return an array

Currently, I am extracting table values from the UI row by row. This involves clicking on each row and retrieving the corresponding data. exports.getTableData = function(callback){     var uiArray =[];     var count;         aLib.loadCheck(c ...

Step-by-step guide on repairing a countdown clock using JavaScript, HTML, and

I'm having issues with my JS on my website. I am new to this and currently in the process of setting up a website. I want to add a timer to show when the site will be active. It seems like there is an error somewhere in the JS code that I can't ...

Pass the ASP.NET MVC model onto the AngularJS scope

Here is the code snippet from my view with temporary JavaScript code for testing: I am trying to assign the ASP.NET MVC model (@Model) to the AngularJS scope ($scope.person). Any suggestions on how to accomplish this? Thank you, The View @model MyApp. ...

While observing a camera in motion, the particles tinted by texture display sporadic flickering on WebGL and Three.js

Check out this jsfiddle I created to illustrate an issue with particles "flickering" when colored using a texture and the camera is moving. Update: The problem occurs even when there is no animation or movement on the particles. If you notice flickering o ...

Initiate a unidirectional ajax request

My WCF service has a slow processing time when called for the first time, but caches the results in HttpRuntime.Cache afterwards. To initialize this cache, I want to initiate a fire-and-forget ajax call from JavaScript. Currently, my page contains the fol ...