Rendering to a texture using the pingpong method in Three.js went smoothly, with no issues detected and the output was not

I attempted to implement the pingpong texture swap technique to generate smoke in threejs by following a tutorial that was published some years ago. Unfortunately, this tutorial utilizes an outdated version of threejs, and I am experiencing difficulties trying to make it work with the latest library version.

Even though there are no visible errors, nothing seems to render on the screen. I am uncertain about where I might have made a mistake. Can someone please help me identify what went wrong?

The code snippet below shows my own endeavor to get the initial step of the tutorial functioning - it encompasses the texture swap and a simple shader that smoothly transitions from black to red. As previously mentioned, everything runs smoothly on an older iteration of the library, which can be observed here. My goal is to comprehend how to successfully execute it on the most recent build of threejs.

I stumbled upon a hint from a related question pointing out that in newer versions of threejs, the .render() method only accepts two arguments. This led me to believe that might be the cause of my issue-less black screen. Despite delving deeper into the documentation and tweaking my code correspondingly, I still cannot seem to get things operational and lack any error messages to guide my troubleshooting efforts.

Below is the JavaScript code:

import * as THREE from 'three';
import FragmentShader from './main.frag';

var scene;
var camera;
var renderer;

function scene_setup(){
    //Basic scene setup
    scene = new THREE.Scene();
    var width = window.innerWidth;
    var height = window.innerHeight;
    
    //Using an orthographic camera instead of perspective
    camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 );
    camera.position.z = 2;

    renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );
}
//Initialize Three.js scene
scene_setup();

  
var bufferScene;
var textureA;
var textureB;
var bufferMaterial;
var plane;
var bufferObject;
var finalMaterial;
var quad;

function buffer_texture_setup(){
    //Creating buffer scene
    bufferScene = new THREE.Scene();
    
    //Generating 2 buffer textures
    textureA = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter});
    textureB = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter} );

    //Assigning textureA to shader
    bufferMaterial = new THREE.ShaderMaterial( {
        uniforms: {
            bufferTexture: { type: "t", value: textureA },
            res : {type: 'v2', value:new THREE.Vector2(window.innerWidth,window.innerHeight)} //Maintains resolution
        },
        fragmentShader: FragmentShader
    } );
    
    plane = new THREE.PlaneGeometry( window.innerWidth, window.innerHeight );
    bufferObject = new THREE.Mesh( plane, bufferMaterial );
    bufferScene.add(bufferObject);

    //Displaying textureB on screen 
    finalMaterial =  new THREE.MeshBasicMaterial({map: textureB});
    quad = new THREE.Mesh( plane, finalMaterial );
    scene.add(quad);
}
buffer_texture_setup();


//Rendering components!
function render() {

    requestAnimationFrame( render );

    //Drawing to textureB
    //renderer.render(bufferScene,camera,textureB,true);
    renderer.setRenderTarget(textureB);
    renderer.clear();
    renderer.render(bufferScene,camera);
      
    //Swapping textureA and B
    var t = textureA;
    textureA = textureB;
    textureB = t;
    quad.material.map = textureB;
    bufferMaterial.uniforms.bufferTexture.value = textureA;

    //Lastly, rendering to the screen
    renderer.render( scene, camera );
}
render();

The shader looks like this:

uniform vec2 res; //Screen width and height 
uniform sampler2D bufferTexture; //Input texture 
void main() {
    vec2 pixel = gl_FragCoord.xy / res.xy;
    gl_FragColor = texture2D( bufferTexture, pixel );
    gl_FragColor.r += 0.01;
}

Answer №1

Providing a solution to my own query, I managed to discover the answer on a discussion forum dedicated to threejs. It turns out that I was nearly there all along! The only adjustment required was:

changing 'textureB' to 'textureB.texture'

swapping 'textureA' with 'textureA.texture'

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

ng-include does not incorporate a partial view

I am facing an issue with ng-include as this code is not functioning properly and I'm unable to identify the error. <select name="select" id="select" class='input-large' ng-model="selectedbien"> ...

Execute a PHP function through an AJAX request to dynamically update a template variable in PHPBB

Should you require a condensed version of the details provided below, do not hesitate to ask for a summary. My objective is to execute a function in my PHP file which will update a template variable. Here is an example of such a function: function get_ve ...

Struggling to integrate the c3 chart library with Angular, encountering loading issues

I've been attempting to utilize the c3 angular charts, but unfortunately nothing is displaying on my page. Despite checking for console errors and following a tutorial, I still can't seem to get anything to show up. I have cloned the git repo an ...

Dropdown selection values were not set appropriately

I've been encountering an issue with setting the selected value in a drop-down list using the code below. The values are being split from a comma-separated string, but it's not functioning as intended. When I use string='text1,text2,text3,t ...

An unusual phenomenon in the controller hierarchy causing issues with accessing the parent scope in AngularJS

Recently delving into the world of angularjs, I encountered something perplexing that seemed like a glitch in the controller hierarchy when it comes to accessing the parent scope. Here are two code snippets that I believed should both function properly bas ...

Changing URL parameters without refreshing the page using query strings

Is there a method similar to how Google adds and removes parameters from the URL in Gmail without requiring a postback? For example, when you start composing a draft, a "?compose=new" parameter is added to the URL. I was considering using `history.pushSta ...

Utilizing React-Spring's useSprings specifically for the active button within an array

I'm currently working on animating the position change of the active box. When the user clicks on a box, I want that box to smoothly transition with a margin-top adjustment while keeping the other boxes at 0px. As the user switches between boxes, the ...

Altering the appearance of an input field upon submission

https://jsfiddle.net/3vz45os8/7/ I'm working on a JSFiddle where I am trying to change the background color of input text based on whether the word is typed correctly or incorrectly. Currently, it's not functioning as expected and there are no e ...

Managing and updating arrays in VueJS2: Conditionally push new items and update only if their properties have changed

I am currently facing an issue with my form where each time a user updates a value in an input field, a new array element is created and added to the form results. I'm looking for a way to update the properties of the existing array element without cr ...

Why is it necessary to use 'this.' to reference a function inside a Component in React?

class First extends React.Component{ handleClick(){ alert('handle click'); } render(){ return <div> <button onClick={this.handleClick}>click</button> </div>; } } Explo ...

Can Chrome Support Bookmarklets?

While attempting to craft a bookmarklet in Chrome using the console, I encountered the following error: Refused to load the script 'https://code.jquery.com/jquery-1.6.1.min.js' because it violates the following Content Security Policy directive: ...

Guide on transmitting data from a pre-populated React input field to Express server

I have integrated a simple support form in my React App using Express and Sendgrid. The post request is functioning with an input form setup like this: support.jsx <form method="POST" action="http://localhost:4000/support"> ...

tips for navigating through an AngularJS $resource instance

I am facing a frustrating issue that I need assistance with. The problem arises when I try to extract specific data from each element of the stock data fetched by my controller from Yahoo Stocks. Although the data is stored in $scope.stocks and can be disp ...

Is "content_scripts" malfunctioning in Chrome version 38 and above?

Just recently, I created a Chrome Extension with the purpose of making all webpages utilize a specific font. Everything was functioning perfectly fine until yesterday (or possibly even earlier). The crucial codes for this extension are: manifest.json fil ...

Obtain value of dropdown selection upon change

What is the best way to retrieve the selected value in a drop-down menu when the ID dynamically changes with each refresh? Is it possible to access the particular selected value even when the ID changes? <select name="status" id="dropdown_status3352815 ...

Every time the page is refreshed, ExpressJS and NodeJS are working together to duplicate the array

var express = require("express"); var router = express.Router(); const fs = require("fs"); const path = require("path"); const readline = require('readline'); const directoryPath = path.resolve(__dirname,"../log ...

What happens in mongoose if one of several consecutive queries fails?

Currently, as I work on my API, I am utilizing two Models: SongModel and UserModel. Whenever a new song is saved, I also execute a query to link the song._id to the user who created it. Unfortunately, a mistake in my code caused the second query to throw a ...

Emphasize the most recent file during the document upload process and ensure the scroll bar moves accordingly to the document

I am currently working on a feature where the scroll bar should move to the newly uploaded document in a list of documents. When I upload a new document, I want the scroll bar to automatically move to that document. Currently, the highlighting changes to t ...

Is there a way for me to modify this carousel so that it only stops when a user hovers over one of the boxes?

I am currently working to modify some existing code to fit my website concept. One aspect I am struggling with is how to make the 'pause' function activate only when a user hovers over one of the li items, preventing the carousel from looping end ...

Multer is experiencing difficulties in uploading files, yet it is not displaying any error messages

When setting up an application to create courses with images, I encountered an issue while using multer for image uploading. Despite adding multer to my route with upload.single('images'), the uploaded images were not appearing in the designated ...