(TODO)3D场景中实现局部毛玻璃效果
最近的一个需求,要实现用户点击3D场景中的某个物体后,对该物体进行聚焦效果:放大该物体,并且物体之外的屏幕出现毛玻璃效果。
UnrealBloomPass的灵感-针对场景里面的部分物体生效的后处理器
我在前面做单个物体泛光效果的时候,参考过这个官方示例,此时想起来,是否也可以用这个示例的分层的方案来实现局部模糊呢?这样的后处理器可以只针对场景里面的部分物体生效。
将焦点物体加入焦点层,将其他物体加入普通层,然后给普通层加一个毛玻璃的图片纹理,最后将普通层和焦点层通过Shader进行纹理合并。
大致流程如下:
1、准备一张毛玻璃图片作为纹理
2、加载图片纹理,作为shader的输入
3、着色器里面,给常规层的每个像素叠加毛玻璃效果,生成纹理2
4、焦点层里面,根据颜色确定模型的位置(非黑色即为模型范围),确定要不要叠加纹理2
后来想了下,这个还是太麻烦了,可以有更简单的方式:
1、准备一张毛玻璃图片作为纹理(canvas生成毛玻璃效果)
2、加载图片纹理,作为shader的输入(或者准备一个类似Halftone的后处理通道也可以)
3、提取焦点模型的Points,对其使用ShaderMaterial
4、根据颜色确定模型的位置(非黑色即为模型范围),确定要不要叠加纹理
然后我发现,这样是不行的,因为普通层的毛玻璃效果是针对场景中每个物体都生效的效果,没物体的空间也有效果,这样叠加起来后,整体都会布满效果(比如模糊的点)。
不过这种方式其实有很广泛的应用场景的,虽然没解决我这个问题,但是也是收获颇多,今后说不定什么时候就能用上。
技巧:分层+获取顶点+叠加纹理,能解决很多问题。
(TODO)webgl_postprocessing_dof2-通过景深实现
(TODO)切换材质
最终方案
后面看到了这个例子:three.js实现鼠标位置周边区域的模糊特效 - 踏得网
发现之前我都想复杂了,参考这个例子,也不用分图层,直接通过Shader对屏幕中心一定范围之外做模糊处理即可。
传入焦点物体信息
我们可以把焦点物体的中心点和尺寸的半径作为参数传入着色器,这样就可以将焦点物体之外的屏幕处理为模糊效果,而焦点物体仍然是清晰的视图效果。
这里会涉及坐标变换,因为物体的坐标是3D空间的坐标,我们要将其转换为屏幕坐标,才能在Shader代码中进行计算。
这里参考《Three.js-坐标》这个博文中的get2DCoordinateOfObject3D()方法即可,此处不再赘述。
(TODO)线性的模糊边界
这个例子的模糊区域和非模糊区域是界限很明确的,为了效果更好一些,需要将这个界限做成线性的,因此还要修改下着色器代码。
一些想法
1、这个示例的鼠标跟随效果,可以用来实现放大镜的特效。
2、在render循环中,修改shader参数,有很多应用场景。