Utilize deferred shading in three.js by employing gl_fragData for optimal rendering performance

Experiencing issues with deferred shading using three.js. Gl_fragData value not received properly. Seeking solutions.

a

Shader Code

//shader1
<script id="vshader1" type="x-shader/x-vertex">

#extension GL_EXT_draw_buffers : require
varying vec2 vUv;

void main(void){
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>

<script id="fshader1" type="x-shader/x-fragment">
uniform sampler2D texture;
varying vec2 vUv;
void main(void) {
    vec4 smpColor = texture2D(texture, vUv);
    gl_FragData[0] = smpColor;
    gl_FragData[1] = smpColor;
}
</script>

//shader2
<script id="vshader2" type="x-shader/x-vertex">
varying vec2 vUv;

void main(void){
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
</script>

<script id="fshader2" type="x-shader/x-fragment">
uniform sampler2D texture;
varying vec2 vUv;
void main(void) {
    vec4 smpColor = texture2D(texture, vUv);
    gl_FragColor = smpColor;
}
</script>

Main program. A fusion of three.js and WebGl code.

function init(){

        var texture = THREE.ImageUtils.loadTexture('img/test.png');
        var mat1 = new THREE.ShaderMaterial({
            vertexShader: document.getElementById('vshader1').textContent,
            fragmentShader: document.getElementById('fshader1').textContent,

            uniforms: {
                texture: {
                    type: 't', value: texture
                }
            },
            transparent: true,
            needsUpdate:true,
        });



        var geometry = new THREE.PlaneGeometry( 100, 100, 10, 10 );
        plane = new THREE.Mesh( geometry, mat1 );
        plane.rotation.x =  220 * ( Math.PI / 180 );
        scene.add( plane );
    }




    var gl;
    var bufs = [];
    var plane;
    var mat;
    var ext;
    var FBO = [];
    var texture1;
    var texture2;

    function initBuffer(){

        gl = renderer.context;
        ext = gl.getExtension("WEBGL_draw_buffers");

        gl.getExtension("OES_texture_float");
        gl.getExtension("OES_texture_float_linear");

        var maxDrawBuffers = gl.getParameter(ext.MAX_DRAW_BUFFERS_WEBGL);


        FBO[0] = gl.createFramebuffer();
        gl.bindFramebuffer(gl.FRAMEBUFFER, FBO[0]);



         var depthRenderBuffer = gl.createRenderbuffer();
        gl.bindRenderbuffer(gl.RENDERBUFFER, depthRenderBuffer);
        gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1024, 1024);
        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRenderBuffer);



        texture1 = createTexture( gl, 1024, 0 );
        texture2 = createTexture( gl, 1024, 1 );

        ext.drawBuffersWEBGL(bufs);

        gl.framebufferTexture2D(gl.FRAMEBUFFER, bufs[0], gl.TEXTURE_2D, texture1.__webglTexture, 0);
        gl.framebufferTexture2D(gl.FRAMEBUFFER, bufs[1], gl.TEXTURE_2D, texture2.__webglTexture, 0);

        var FBOstatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
        if(FBOstatus != gl.FRAMEBUFFER_COMPLETE) {
            console.log("GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO[0]\n");         
        }

        gl.bindFramebuffer(gl.FRAMEBUFFER, null);
        gl.bindRenderbuffer(gl.RENDERBUFFER, null);
        gl.bindTexture(gl.TEXTURE_2D, null);




        texture1.needsUpdate = true;
        texture2.needsUpdate = true;
        texture1.image = new Image();
        texture2.image = new Image();
        new THREE.ImageLoader().load(
            'img/color0.png',
            function ( image ) {
                texture1.image = image;
                texture2.image = image;
        });

        mat = new THREE.ShaderMaterial({
            vertexShader: document.getElementById('vshader2').textContent,
            fragmentShader: document.getElementById('fshader2').textContent,

            uniforms: {
                texture: {
                    type: 't', value: texture1
                }
            },
            transparent: true,
            needsUpdate:true,
        });



        var geometry = new THREE.PlaneGeometry( 100, 100, 10, 10 );
        plane = new THREE.Mesh( geometry, mat );
        plane.position.x = 100;
        plane.rotation.x =  220 * ( Math.PI / 180 );
        scene.add( plane );


        setInterval(function(){
            renderBuffer();
        }, 500 );

    }




    function createTexture( gl, size, buf ){
        var texture = new THREE.Texture();
        texture.__webglTexture = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_2D, texture.__webglTexture );
        texture.__webglInit = true;
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        switch( buf ){
            case 0:
                bufs[0] = ext.COLOR_ATTACHMENT0_WEBGL;
                break;
            case 1:
                bufs[1] = ext.COLOR_ATTACHMENT1_WEBGL;
                break;
            case 2:
                bufs[2] = ext.COLOR_ATTACHMENT2_WEBGL;
                break;
            case 3:
                bufs[3] = ext.COLOR_ATTACHMENT3_WEBGL;
                break;
        }
        gl.bindTexture( gl.TEXTURE_2D, null );
        return texture;
    }





    function renderBuffer(){

        //pass1
        gl.bindFramebuffer(gl.FRAMEBUFFER, FBO[0]);
        gl.viewport(0, 0, size, size);

        renderer.render( scene, camera );

        renderer.setSize(window.innerWidth,window.innerHeight);
        gl.bindFramebuffer(gl.FRAMEBUFFER, null);



        //pass2
        mat.uniforms.texture2.value = texture2;
        plane.material = mat;



        renderer.render( scene, camera );

    }

Answer №1

For those looking to implement deferred shading, it is important to ensure that the WEBGL_draw_buffers extension is enabled in order to utilize multiple render targets. Otherwise, a framebuffer will only allow for one colour attachment.

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

Discovering the significance of a function's scope

I'm a bit confused about how the answer is coming out to be 15 in this scenario. I do understand that the function scope of doSomething involves calling doSomethingElse, but my calculation isn't leading me to the same result as 15. function doSo ...

Efficiently writing to response from MongoDB in JSON format without blocking the execution

My current setup involves using Node/Express.js to create a GET route that fetches data from a Mongo database. While I have successfully implemented this in a non-blocking manner, I encounter a syntax error when attempting to return the data in JSON format ...

Is it possible to utilize ko.observableArray in the form of a map?

Can an ko.observableArray be used as a map or dictionary? For instance: var arr = ko.observableArray(); arr.push('key', { '.. Some object as value ..' }); And then retrieve the value using the key: var value = arr['key']; ...

Issues with the Tumblr platform's back-to-top button functionality

I am quite comfortable with HTML and CSS, but I'm struggling to make the 'back to top' button work on my Tumblr page. Can someone please give me a hand? I've included some JQuery code to make the text fade in and out when scrolling (inf ...

Which specific graphing library does GitHub utilize for its Graphs section?

Which graphing library is utilized by GitHub on its Graphs tab? The graphs displayed at https://github.com/USER/REPOSITORY/graphs/commit-activity are visually appealing, detailed, and adaptable. If they are leveraging an open source javascript library fo ...

Tips for updating or replacing items in a JavaScript array

Explaining what I need, here's the code snippet: Everything works smoothly when adding a product to the items array if it does not already exist (based on id). However, if it does exist, I only want to update the item. The distinction is based on the ...

After the page is reloaded, apply a class to the divs by selecting them based on the "data" attribute

I have a set of four cards labeled "card", each representing different body parts: eyes, torso, arms, and legs. <div class="card" data-lesson="eyes">eyes</div> <div class="card" data-lesson="torso">torso</div> <div class="card" ...

jQuery input checkboxes validation conflict

There seems to be a strange issue with my checkboxes in the table where I have built an Invoice calculator. You can view it here. My goal is to have the inputs for Iva or Irpef not calculated in the Total Amount once they are checked. In the linked example ...

Issue with resizing Ionic carousel when making an $http request

In my Ionic project, I am utilizing a plugin to create a carousel (https://github.com/ksachdeva/angular-swiper). The demo of this plugin includes a simple repeat function. However, when I replaced the default repeat with my own using $http, it caused an is ...

What is the process for utilizing jQuery's advanced ticker feature to extract content from a text file?

I am currently implementing this code on my website: <script> var file = "http://newsxpressmedia.com/files/theme/test.txt"; function getData(){ $.get(file,function(txt){ var lines = txt.responseText.split("\n"); for (var i = ...

The await function does not pause execution before proceeding to the next line of code

Here is the code I've been working on: async function main(collection, token, symbol) { await collection.deleteMany({}); const priceHistory = await makePriceHistoryRequest(token, symbol, slow*2); await insertPriceHistory(collection,priceHistory) ...

Recursive function used to update an array of objects by dynamically mapping replies to comments

I have received a collection of comments from a graphql backend structured like this: [ { "__typename": "Comment", "id": "1", "userId": "1", "postId": "1", "parentCommentId": null, ...

What strategies can be employed to generate new subpages when there are modifications to the API (in JSON format

I would like to incorporate data from the Mixcloud API (an audio hosting service similar to SoundCloud) to automatically generate new subpages whenever a new post is published on Mixcloud. My current project involves creating a website for a podcast. The ...

Attempting to display a singular form

Currently, I am working on a MERN app and encountering a small issue... I am developing an application where users can create rooms and within those rooms, they can plan their daily activities. It's similar to a TODO app but more intricate. I wanted ...

What methods are available for implementing hover effects within attributes using a JavaScript object?

const customPanelStyle = { 'background-color': 'red', 'border': '1px solid green', ':hover'{ 'background': 'blue' } } class some extends React.Component{ rende ...

An aspect of Javascript that includes a conditional parameter is the Singleton class

I am dealing with two classes: useService.ts import { useMemo } from 'react'; /** * This hook will take the singleton service instance and keep it memoized * @param service */ export function useService<T> ( service: { new (): T; getIn ...

Generate a random number using the Math.random() method in Node.js/JavaScript to access a folder on the local machine

I am facing a challenge in reading a JSON file located deep within multiple folders on my local machine. The issue arises because the folder name where the file is stored changes every time, as it is generated using the Math.random() method with the prefix ...

PHP code cannot be outputted to JavaScript due to a syntax error

Although there is a syntax error, the code seems to be working. I am curious about how to make it syntactically correct. The provided code snippet is part of a script that sets up variables for an Ajax call. Depending on the scope, the corresponding varia ...

Using Jquery to encase an element in a div while scrolling down and removing it while scrolling up

After some experimentation, I've managed to wrap an element inside a div using jQuery. My next challenge is to wrap it as you scroll down and unwrap it as you scroll up. Do you think this is achievable? Although I have succeeded in wrapping it while ...

Exploring the world of Bootstrap modals through the lens of

I have integrated AngularStrap into my application in order to utilize the modal feature of Bootstrap. However, I am facing an issue with displaying my template modal. I have followed the documentation and referenced my template with template='#test&a ...