Developing a high-performing vertex shader in WebGL2 for early frame rendering

Filtering Instances in the Vertex Shader

In my webGL2 project, I am utilizing instanced geometry to render content. Each instance contains a color component with varying alpha values, some of which may be zero.

Instead of passing instances with zero alpha values to the fragment shader for discarding, I decided to check the alpha value in the vertex shader. If the alpha value is zero, I output each vertex as vec4(-2) to position it outside the clipping area or potentially as a 1 pixel point.

I have been unable to find specific information on how the rendering pipeline handles this scenario.

Is this approach the most effective way to eliminate instances from the rendering process?

An alternative method would involve removing the instances from the buffer, but this can be CPU-intensive when dealing with a large number of instances within JavaScript.

The Shader Code

const vertexSrc = `#version 300 es
    #define alphaCut 0.0
    in vec2 verts;
    in vec2 pos;       
    in vec2 scale;     
    in vec2 offset;    
    in float rotate;   
    in float zIdx;     // z index for zBuf clip only 
    in vec4 color;     // RGBA to color.a == 0.0 to remove not render
    in uint spriteIdx; 
    uniform vec4 sheetLayout[128];
    uniform vec2 sheetSize;     
    uniform mat2 view;              
    uniform vec2 origin;  
    out vec2 spr;
    out vec4 col;
    void main() {
        if (color.a <= alphaCut) { 
            gl_Position = vec4(-2); // move this instance outside the clip
            return; 
        }
        col = color;
        vec4 sprite = sheetLayout[spriteIdx];
        spr = sprite.xy + verts * sprite.zw / sheetSize;
        vec2 loc = (verts - offset) * scale * sprite.zw;
        float xdx = cos(rotate);
        float xdy = sin(rotate);
        loc = view * (vec2(loc.x * xdx - loc.y * xdy, loc.x * xdy + loc.y * xdx) + pos - origin);
        gl_Position =  vec4(loc, zIdx, 1);
    }`;

const fragmentSrc = `#version 300 es
    precision mediump float;
    uniform sampler2D tex;
    #define alphaCut 0.0;
    in vec2 spr;
    in vec4 col;
    out vec4 pixel;
    void main() {
        pixel = texture(tex, spr) * col;
        if (pixel.a <= alphaCut) { discard; }
    }`; 

Answer №1

Noted in the responses to the question and the removed answer, an alteration like gl_Position = vec4(vec3(-2), 1) is necessary to shift the vertex beyond the clip space.

If we use gl_Position = vec4(-2), the vertex will be positioned at vec3(1) (top right on the near plane). This falls within the clip area and thereby results in the geometry instance making its way to the fragment shader.

But why does this happen?

Perspective division process

As the vertex transitions from the vertex shader to gl_position, it exists as a 4D vector. For proper clipping of the vertex, a 3D vector that extends beyond the 3D clip space is essential.

The conversion of the vertex from 4D to 3D, known as perspective division, occurs automatically by partitioning the vectors' components (x, y, z) by the w component.

To accurately trim the geometry instance and prevent it from entering the fragment shader...

#define alphaCut 0.1
//...
void main() {
    if (color.a <= alphaCut) { 
        gl_Position = vec4(vec3(2), 1);
        return; 
    }
    //... remaining code

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

Passing a ref from a parent component to a child component in reactjs

I have the following situation, how can I make sure that the attachment field in the child component is accessible from the parent component? class ServiceDeskCustomerCreate extends Component { constructor(props, context) { super(props, context); ...

Tips for developing a nested array of objects using a JavaScript loop

Can someone help me with looping an AJAX response to create an array in this format? "2023-03-30": {"number": '', "url": ""}, "2023-03-30": {"number": '', "url": &quo ...

Unable to resize react-split-pane dimensions

I recently integrated the react-split-pane plugin into my project, but I am encountering some issues with its functionality. Even though I have tested react-split-pane versions 0.1.68, 0.1.66, and 0.1.64, none of them seem to work as expected in my applic ...

Eliminate the need to input the complete URL every time when making server calls

Currently, my springbok application has a React-Typescript frontend that is functioning well. I am using the request-promise library to make requests like this: get('http://localhost:8080/api/items/allItems', {json: true}). However, I would like ...

Querying Denormalized Data in AngularFire 0.82: Best Practices and Strategies

I have a question that is related to querying denormalized data with AngularFire. I am looking for a solution specifically using AngularFire (current version 0.82). Here is an example of the data structure I am working with: { "users": { "user1": { ...

Most efficient method for nesting child objects within an array of objects using JavaScript

Hey experts, I'm on the hunt for the most efficient method to transform this data: [ { "id": 1, "animal": "cat", "age": 6, "name": "loky" }, { "id": 2, "animal": &quo ...

Employ JavaScript regular expressions to extract all the text values from VBA code

Looking to utilize JavaScript regex in order to extract all string values from VBA code. For instance: If cmd = "History Report" Then Range("D2").Formula = "=TEXT(""" & createDate & """,""" & Replace(subtitleFormat, """", """""") & " ...

Sorting a 2D array in Javascript based on numerical values

I've come across a few similar posts regarding this issue, but none have provided solutions that work for my specific situation. I'm feeling lost on how to solve this problem (like Sort a 2D array by the second value) Let me explain the challeng ...

Ways to resolve Content Security Policy issue in a Node application

const express = require('express'); const graphqlHTTP = require('express-graphql'); const schema = require('./schema/schema'); const app = express(); app.use('/graphql', graphqlHTTP({ schema, graphiql: true, ...

Issues with HTML5 video playback in Apple machines using the Firefox browser

On a website I'm developing, I've included an HTML5 video that works perfectly except for one specific issue - it won't play on Firefox in Apple devices. Surprisingly, it functions well on all other browsers and even on Firefox in Windows an ...

Having trouble connecting to the webserver? Make sure the web server is up and running, and that incoming HTTP requests are not being blocked by a firewall

While working on my Visual Studio 2013 Asp.Net web code using the Local IIS Web server Version 7 (Windows 7 x64) and Framework 4.0, I encountered an error message stating: "Unable to start debugging on the web server. Unable to connect to the webserver. V ...

Any suggestions on how to secure my socket connection following user authentication in redux?

After onSubmit, userAction.login is called which then dispatches "SUCCESS_AUTHENTICATE" to set the token of the user and socket state in their respective reducers. How can I proceed to trigger socket.emit("authenticate", {token})? ...

Transfer text from one form to a text field on a different website

I've created a form that allows users to input numbers in a field and then directs the page to a specific URL. Here's the code snippet: <html> <head> <meta charset="utf-8"> <title>Tracking</title> </head& ...

Tips on eliminating borders in react-table components

Within my React.js component, I have implemented a table using react-table along with some material-ui components displayed alongside the table: import React from 'react' import { useTable, useGlobalFilter, usePagination } from 'react-table& ...

Prevent postback in case of validation error

In my current setup, I have a textbox control with the following specifications: <asp:TextBox ID="txtAmount" runat="server" AutoPostBack="true" Width="85px" class="validate[ERExpenseTypeDaterequired,custom[float]]" On ...

Leveraging $scope variables to dynamically generate new scope values within an Angular controller

I am currently faced with the challenge of using latitude and longitude data provided by the server, which is stored in $scope.Address. I am attempting to create a map object with these values as shown below. However, my current implementation is not fun ...

for each and every object, execute the asynchronous function

I have a scenario where I need to loop through objects, call an async method ("search") with a callback, and then write the results (resultSet) to a JSON file once all objects are processed. The issue I'm facing is that the writeFile function is execu ...

Meteor JS: How can I effectively manage the state of a unique template?

I'm currently delving into the realms of Session and reactive data sources within the Meteor JS framework. They prove to be quite useful for managing global UI states. However, I've encountered a challenge in scoping them to a specific instance o ...

Merge text inputs to preview content prior to form submission

I've been on the hunt for a solution to display the collective values entered into multiple text box fields as they are being typed. Currently, I have 6 text boxes (description1, description2, description3, description4, description5, description6) wh ...

Error in Oboe.js due to incorrect value

Originally posed by Sashkan in the Oboe.js Github issues: Receiving a streamed response from a remote API. Upon making an ajax call, the response looks like this: {"company_id":"3e1f975601f59090decc8f2d5ced72010162e481","airplane_type_id":"c10143316664f2 ...