Tips for rendering objects in webgl without blending when transparency is enabled

My goal is to display two objects using two separate gl.drawArrays calls. I want any transparent parts of the objects to not be visible. Additionally, I want one object to appear on top of the other so that the first drawn object is hidden where it overlaps the second one.

In order to achieve this, I have set up my render loop as follows:

 gl.clearColor(0, 0, 0, 1);
 gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
 gl.enable(gl.BLEND);
 gl.disable(gl.DEPTH_TEST);

I am not entirely sure about the blend functions but I utilize them to enable transparency. However, this causes the two objects to blend and create a yellow color (one object is red and the other is green). My intention is to have the final color be either red or green depending on the order they are drawn in, while still maintaining transparency.

To illustrate the issue, observe the following code snippet:

const fShaderSource2 = `#version 300 es

precision mediump float;

out vec4 outColor;

void main() {
  outColor = vec4(0.0, 1.0, 0.0, 1.0);
}

`;

...

minibatch.push(redText);
minibatch.push(greenText);

Although I draw the red object first and then the green object, the resulting color is yellow instead of the desired outcome. I aim to rectify this discrepancy.

Answer №1

The main issue lies in the improper use of the blend function (blendFunc). Blending essentially combines fragment color outputs with colors already present in the color buffers. The first parameter acts as a factor for the fragment color output, while the second parameter serves as a factor for the existing color in the color buffer. By default, colors are summed due to the standard blend equation being FUNC_ADD.

Thus, the blend function:

gl.blendFunc(gl.SRC_ALPHA, gl.ONE);

can be understood through the formula:

destColor = srcColor * srcAlpha + destColor * 1 

Here, destColor represents the current framebuffer color, and srcColor is the color designated for the fragment (outColor). This approach maintains the color in the framebuffer (multiplied by 1) and incorporates the new color multiplied by the alpha channel. If the current framebuffer color is red (1, 0, 0) and the new color is green (0, 1, 0), then the resulting color is yellow (assuming an alpha channel value of 1):

(0, 1, 0) * 1 + (1, 0, 0) * 1 == (1, 1, 0)    

To resolve this, utilize the following blend function:

gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

This will facilitate a "mixing" effect between the framebuffer color and the new color based on the alpha channel of the latter:

destColor = srcColor * srcAlpha + destColor * (1-srcAlpha)

The fundamental concept of Alpha blending is akin to that of OpenGL (given WebGL's close adherence to OpenGL ES standards), hence additional insights can be gleaned from the OpenGL wiki entry on Blending.

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

Embed a YouTube video within the product image gallery

Having trouble incorporating a YouTube video into my Product Image Gallery. Currently, the main product photo is a large image with thumbnails that change it. You can see an example on my website here. Whenever I attempt to add a video using the code below ...

Is it possible to incorporate conditionals within a jade template using JavaScript?

I've been working on a Jade template that includes some logic, but I seem to be encountering an issue. Here's the code snippet: #container -for(var col=0; col < 2 ;col++){ - if(col % 4 == 0){ .movie_row - } ...

Clear previously filtered items

I am currently working on implementing a search functionality using Javascript for my project, but I've hit a snag. After hiding certain items, I'm having trouble making them appear again. JSFiddle The code I have so far is as follows: $(' ...

Tips on transferring key values when inputText changes in ReactJs using TypeScript

I have implemented a switch case for comparing object keys with strings in the following code snippet: import { TextField, Button } from "@material-ui/core"; import React, { Component, ReactNode } from "react"; import classes from "./Contact.module.scss" ...

Using a React PureComponent to pass parameters from a Child component

I am facing an issue with my TodosList component that displays a list of individual Todo components. Below is the code snippet for the Todo component: export class Todo extends React.PureComponent { render() { return ( <li onClick={this.pr ...

Tips for incorporating dynamic content into React Material UI expansion panels while maintaining the ability to have only one tab active at a time

I'm working on a project using WebGL and React where I generate a list of users from mock data upon clicking. To display this content in an accordion format, I decided to use Material UI's expansion panel due to my positive past experience with ...

Exploring the depths of deep populating in Mongo and Node.js

I am currently struggling with a complex data population issue. var commentSchema = mongoose.Schema({ name: String }); var userSchema = mongoose.Schema({ userId: { type: String, default: '' }, comments: [subSchema] }); var soci ...

Update state within React components without impacting any other state variables

Imagine I have an object structured like this: person : { name : "Test", surname : "Test", age : 40, salary : 5000 currency : "dollar", currency_sign : "$", . . . } I am looking to achieve the following I will make ...

Error encountered with Node.js clustering

Hey there! I'm currently diving into the world of node.js and javascript. My goal is to build a cluster.js using the nodejs cluster module, where at the end of my if statement I invoke server.js to kickstart the application. Here's my cluster.js ...

Disabling and enabling a link before and after an AJAX call using jQuery

I have been trying to disable a link before making an ajax call and then re-enable it right after receiving the response. However, my current approach doesn't seem to be working as expected: jQuery(this).prop('disabled', false); Here is my ...

Is it possible for a method within a class to retrieve properties from a different object within the same class?

I'm facing an issue with accessing the necessary object properties within a method. In my scenario, I have a Game class that generates a new game object. Once the object is created, I attempt to execute the draw method. This draw method requires infor ...

Vue.JS component containing DOM elements outside of the designated $el scope

Transitioning from a custom front-end framework to Vue is a new adventure for me. Our website is gradually integrating Vue, and as we refactor old components, I've encountered an issue. My question is: Can a component create DOM elements outside of i ...

Update the styling of each div element within a designated list

Looking for a way to assist my colorblind friend, I am attempting to write a script. This is the layout of the page he is on: <div class="message-pane-wrapper candy-has-subject"> <ul class="message-pane"> <li><div style=" ...

Associating data with controller upon click event

My application displays a tab full of objects for the user to choose from by clicking on any line. Once they make their selection, I need to send specific data related to that object to the server. This is what the interface looks like: The tab is create ...

Could you explain the distinction among req.path, req.params, and req.query?

I'm curious about the distinctions among req.path, req.params, req.query, and req.body in node.js. Can someone provide an explanation? ...

Issue with confirming deletion of tabulated records

HTML Code: <td>random_data_1</td><td><button id="random_data_1"></button></td> <td>random_data_2</td><td><button id="random_data_2"></button></td> <td>random_data_3</td ...

What is the reason behind the browser crashing when a scrollbar pseudo-class is dynamically added to an iframe?

1. Insert a new iframe into your HTML: <iframe id="iframe-box" onload=onloadcss(this) src="..." style="width: 100%; border: medium none; "></iframe> 2. Incorporate the following JavaScript code into your HTML file ...

Dynamic page url redirection involves creating search-engine friendly URLs for dynamic

After successfully incorporating URL rewriting into my PHP website, I am facing an issue with displaying the links as desired. mydomain.com/komet-india/Best-Indian-Hill-Stations-1/Delhis-Hotel The elements Best-Indian-Hill-Stations,1,Delhis-Hotel in the ...

Encountering an issue when attempting to establish a connection to Redis using a cache manager within a Nest

Incorporating the NestJS framework into my project and utilizing Cash Manager to connect with Redis cache. Successfully connected with Redis, however encountering an error when attempting to use methods like set/get which shows 'set is not a function& ...

Using jQuery to refresh a div element

I am struggling with updating the "right" div in my jsp page using the script below. Despite being contained in a single file, the update does not seem to work. Any assistance is appreciated. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//E ...