使用threejs离屏渲染实现高斯模糊效果

之前的博客里我使用webgl实现了简单的离屏渲染效果,最近在使用threejs库开发项目的时候,想实现点击物体高亮,背景物体虚化的效果。为了实现这个效果,我决定将每帧渲染出来的图片拿出来,进行一次高斯模糊,在把它贴到一个背景板上。

        这里面由于使用了离屏渲染就有几点需要注意

        1.两组摄像机、两个scene、一个WebGLRenderTarget。

        两组摄像机分别对应两个场景,及渲染贴图场景(a)与屏幕绘制场景(b),a场景中放置了一个地球,一个正方体,以及天空盒。b场景只有一个与屏幕一样宽高的平面,将a场景每一帧渲染出的画面(target.texture)贴在b场景的平面上。a场景的摄像机是透视投影,物体近大远小,b场景摄像机是正交相机,远近一样大。所以render的代码就和以前有所不同,多了一个场景的渲染,当然这个场景的渲染不是渲染到屏幕上二是target上,这个target在我的理解里就类似webgl里的帧缓冲,下面是渲染的部分代码:

function render() {

   camera.lookAt( buffer_scene.position );

       composeCamera.lookAt(scene.position);

       //Render onto our off screen texture
       renderer.render(buffer_scene,camera,target);

       //Finally, draw to the screen
   	renderer.render( scene, composeCamera );

       controls.update();

}

        下面要说的就是高斯模糊的算法了,该算法实际上来说就是对图像进行卷积计算。在计算每一个片元的颜色时,将其左边四个点和右边四个点的颜色进行一定比例的加和(横向高斯模糊),再对其上面四个点和下面四个点的颜色按照一定比例进行加和(纵向高斯模糊)最终得到模糊的画面,这里值得注意的是我们在进行高斯模糊时最后所乘的系数和一定要控制在1,不然就会出现图片过亮的状态,下面是片元着色器的代码:

   uniform sampler2D tDiffuse;
uniform float h;
uniform float v;

varying vec2 vUv;

void main() {


vec4 sum = vec4( 0.0 );

//纵向高斯模糊
sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * (0.051/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * (0.0918/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * (0.12245/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * (0.1531/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * (0.1633/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * (0.1531/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * (0.12245/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * (0.0918/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * (0.051/2.0);

//横向高斯模糊
sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * (0.051/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * (0.0918/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * (0.12245/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * (0.1531/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * (0.1633/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * (0.1531/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * (0.12245/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * (0.0918/2.0);
sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * (0.051/2.0);

gl_FragColor = sum;

}

最后放一下效果图:

Github:https://github.com/StringKun/ThreeJSBlur/tree/master

最后,我将所有demo的演示都放在了:https://stringkun.github.io/DemoShow/example/index.html

猜你喜欢

转载自blog.csdn.net/weixin_36065510/article/details/81946672