Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

THREE.js blur the frame buffer

I need to blur the frame buffer and I don't know how to get the frame buffer using THREE.js.

I want to blur the whole frame buffer rather than blur each textures in the scene. So I guess I should read the frame buffer and then blur, rather than doing this in shaders.

Here's what I have tried:

Call when init:

var renderTarget = new THREE.WebGLRenderTarget(512, 512, {
    wrapS: THREE.RepeatWrapping,
    wrapT: THREE.RepeatWrapping,
    minFilter: THREE.NearestFilter,
    magFilter: THREE.NearestFilter,
    format: THREE.RGBAFormat,
    type: THREE.FloatType,
    stencilBuffer: false,
    depthBuffer: true
});
renderTarget.generateMipmaps = false;

Call in each frame:

var gl = renderer.getContext();

// render to target
renderer.render(scene, camera, renderTarget, false);
framebuffer = renderTarget.__webglFramebuffer;
console.log(framebuffer);

gl.flush();
if (framebuffer != null)
    gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
var width = height = 512;
var rdData = new Uint8Array(width * height * 4);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, rdData);
console.log(rdData);

// render to screen
renderer.render(scene, camera);

But framebuffer is WebFramebuffer {} and rdData is full of 0. Am I doing this in the right way?

like image 980
Ovilia Avatar asked Nov 30 '22 04:11

Ovilia


1 Answers

Any blur should use shaders to be efficient, but in this case not as materials.

If you want to blur the entire frame buffer and render that to the screen use the effect composer. It's located in three.js/examples/js./postprocessing/EffectComposer.js

Set up the scene camera and renderer as normal but in addition add an instance of the effect composer. With the scene as a render pass.

composer = new THREE.EffectComposer( renderer );
composer.addPass( new THREE.RenderPass( scene, camera ) );

Then blur the whole buffer with two passes using the included blur shaders located in three.js/examples/shaders/

hblur = new THREE.ShaderPass( THREE.HorizontalBlurShader );
composer.addPass( hblur );
            
vblur = new THREE.ShaderPass( THREE.VerticalBlurShader );
// set this shader pass to render to screen so we can see the effects
vblur.renderToScreen = true;
composer.addPass( vblur );

finally in your method called in each frame render using the composer instead of the renderer

composer.render();

Here is a link to a working example of full screen blur

like image 128
Andrew Berg Avatar answered Feb 05 '23 10:02

Andrew Berg