How do I take a texture, interpolate it to a larger resolution and then render it?

Hi, I’m working on a fluid dynamics simulation based on the NVidia GPU gems article.

I’ve hit a point where my simulation is too slow to run at screen resolution, but it works fine if I downscale things.

I’d like to calculate the velocity and pressure fields (textures) at a lower resolution, then interpolate that and display it at a larger resolution. The problem is I’m pretty new to all of this and I’m not sure how to go about this.

Currently my scene is set up like this:

function scene_setup(){
scene = new THREE.Scene();
camera = new THREE.OrthographicCamera(w() / -2, w() / 2, h() / 2, h() / -2, 1, 1000);
camera.position.z = 2;
renderer = new THREE.WebGLRenderer();
renderer.setSize( w(), h() );
document.body.appendChild( renderer.domElement );
}
scene_setup();

With textures set up as

THREE.WebGLRenderTarget(w(), h(), ...)

I then have a quad which I put the texture I want to render on

finalMaterial = new THREE.MeshBasicMaterial({map : x.texB});
plane = new THREE.PlaneBufferGeometry(w(), h());
quad = new THREE.Mesh(plane, finalMaterial);
scene.add(quad);

Where x.texB is the texture of some ‘ink’ that you can drop into the velocity field to visualise what’s going on. After rendering each step of my calculations to frame buffers I render the scene:

function render() {
requestAnimationFrame(render);

updateVelocity();
updateInk();
renderer.render( scene, camera );
}
render();

Apologies if this is a weirdly simplistic question, I’ve just lost track of what I need to change to control (a) the size and location of the output display on the screen and (b) the size of the textures being rendered.

You could create your render target like this:

const params = { minFilter: LinearFilter, magFilter: THREE.LinearFilter };
const renderTarget = new THREE.WebGLRenderTarget( w() * 0.5, h() * 0.5 , params );

The linear filter will perform a weighted linear blend between the nearest adjacent texture samples. So the “interpolation to a higher resolution” is something the GPU can do for you.

Thanks for the help! Just tried that and unfortunately it doesn’t seem to work for me.

Would you mind taking a look at my code? https://github.com/makkasu/gyre-cfd If you clone it and launch a localhost server you can mess around with it.

I wanted to make the ‘ink’ texture full resolution and all other textures (velocity, pressure, div_v) at half resolution or less than that. In buffers.js I changed the field class to

function Field(name){
	this.name = name;
	const params = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, type: THREE.HalfFloatType };
	var scale = 0.5;	
	if (name != 'ink'){
		this.texA = new THREE.WebGLRenderTarget(scale*w(), scale*h(), params);
		this.texB = new THREE.WebGLRenderTarget(scale*w(), scale*h(), params);
	}
	else{
		this.texA = new THREE.WebGLRenderTarget(w(), h(), params);
		this.texB = new THREE.WebGLRenderTarget(w(), h(), params);
	}

	this.swap = function(){
		var temp = this.texA;
		this.texA = this.texB;
		this.texB = temp;
	}
}; 

But this results in no errors and zero velocity everywhere, as far as I can tell.