问个关于“模糊”的着色器问题

将一个纹理进行高斯模糊渲染比较容易,网上的着色器代码也很多。
但是,如何用一个ColorLayer盖在已经进行了复杂渲染(比如下面有一个游戏的主界面,里面有很多活动的节点动画等等),然后将整个背景模糊化呢?

总觉得应该可以用混合来实现吧?openGL用的不太多,没有试过,我想的是能不能再混合的时候,dst用GL_ONE,src用透明度?想问一下有没有老哥实现过。
直观上来看,其实就是把改在上面的LayerColor当作一块毛玻璃。

另外,直接用截图的方式,把当前背景截屏下来,然后再高斯模糊渲染一遍的方法可以,但这样背景就只是一个截图,要实现毛玻璃,意味着每一帧都要重新进行一个截图的纹理,显然不科学。

你别说最后一种方式在我19年去的一家公司,做的横版格斗类游戏就是这么做的,每帧截图。不过当时用的2dx性能问题感觉没太大影响

只需要截一次屏,然后生成纹理,后面就是显示这个纹理图片。

看到楼上老哥的答案,感觉这个问题可能要去3D引擎的论坛里问一下。。毕竟3D游戏的毛玻璃,我想应该是一个非常常用的功能吧,走截图方式,我脑补了一下,感觉太影响性能了

renderertexture做后处理
例子:
https://wujiayish.github.io/cocos2d-x-examples/index.html?3

别走这里就是3d引擎论坛啊,rendertexture 获取的纹理做模糊算法 赋值给sprite

RenderTexture的方式相当于是做了一次截图啊,把当前纹理做一次缓存,然后再用缓存去做高斯模糊渲染到上层。
也就是说,所有的下层节点都要被再visit一次,渲染量就翻倍了。

主要我总觉得在渲染当前着色器的时候,采用目标1,源头0的方式去做一次混合,用这个混合后的颜色去做高斯模糊就行了啊。这样既不会改引擎渲染,又不破坏现有的渲染流程,而且代码上就是加了一个普通的layer就实现了,改动的东西也就只是多做一个片元着色器。

我是这么理解的,感觉应该可以实现的。不然3D游戏加个毛玻璃,那又要剪裁又要缓存,性能开销直接翻倍,直接就被玩家喷炸了。

虽然没做过,但感觉RenderTexture的性能消耗并不大吧。只是多了一个相当于背景图的纹理内存和增加一个drawcall吧。

主要的开销在于模糊的采样

全屏截屏,不知道是不是直接从帧缓冲里面取?
限定节点范围,才要每个节点visit渲染到纹理? 猜测

所谓的毛玻璃,不等于把一个背景图片模糊化处理。而是会将毛玻璃覆盖下的所有节点,都渲染后的结果进行模糊化处理。

只是模糊背景,也就不会来问了。

别的不说,你考虑一下只是把当前屏幕中显示的所有东西都存到RenderTexture中,需要怎么写,我觉得应该就不会说性能消耗不大的话了

一个相机渲染主界面并且负责模糊,另一个相机负责弹出的对话框,性能主要消耗应该就在模糊算法上两个相机并不会造成很大的性能消耗而且还是分层的相机

用两个相机好像就搞复杂了。。。我还从来没有改过cocos2dx的相机。。。

帖子就这么沉了吗嘤嘤嘤

unity 可以用 Graphics.Blit 来实现

最近自己想了一下,发现我对渲染的理解产生了很大的问题。
渲染的本质,是在当前的画布上增加新的颜色和纹理,混合改变的东西,也只是即将渲染上去的那个颜色是会变成什么样的,而当前这个画布上已经成什么样的了,GPU在目前cocos的渲染流程上是没法直接获得的(或许其实是支持的,只是cocos没有去支持?),所以才没法如我想的那样,使用混合的方式获得当前已经采样的效果并直接改变。

不知道有没有渲染大佬可以指导一下,我这个想法的正确性?

颜色混合是两个颜色按一个比例规则混合出一个新的颜色。这个方案不会使图片模糊的。高斯模糊是讲一个位置的颜色通过周边几个位置的颜色做混合运算实现的。而你说的颜色混合是同一个位置的两个颜色混合,如果masklayer是纯色的那只是一个变色的结果。如果是一个图片那结果是两个图片的混个图也是一个不会模糊的结果。所以要高斯模糊你需要用shader写,在着色阶段降每个像素的颜色改成周边几个像素颜色的混合

我写一个类似三原色 混合shader 发觉编辑器里面是正常 到了h5 就不正常了

能用一张毛玻璃图片直接盖上去吗,只是效果应该也会差不多吧 :thinking:

https://learnopengl.com/Advanced-Lighting/Bloom