整理PostEffect流程(随笔)

粗略的随笔,未来会整理成文。


起因:

希望做屏幕扰动 PostEffect.

改动方向:两个相机,第一个相机的渲染结果作为第二个渲染相机的输入参数,以便后续处理。

目前的现状: PostEffect 流程是个单件,且和MainCamera绑死了。


调查:

u3d有一个 PostEffectStack 的实现,里面超级复杂,整合了大量PostEffect,并可以协同工作。大致参考了下结构和流程,就开始动手改项目里的了。


仿照其工作原理,设计了三个层次的类:

PostEffectProcess , 负责各种 PostEffect的具体实现。

PostEffectQueue, 和某个具体的Camera关联, 负责组织各种PostEffect, 传递U3D的 onRenderImage 事件给各个PostEffectProcess。

PoestEffectManager, 负责Queue的管理,也是整个PostEffect系统对外开放功能接口的地方。


这里因为不了解u3d的渲染流程(其实其他常规引擎的流程也是一知半解),走了弯路。有几个特别影响设计的前置知识不能不知道:

知识1、Double Buffer 。

    U3D系统存在一个DB,但是无法直接得到这俩Buffer(更别说精确控制用哪个了)。唯一可以影响DB的是 onRenderImage(RenderTexture source, RenderTexture destination) 函数里,如果 destination 为 null ,则在使用 Graphics.Blit(source, null) 时是往DB里拷贝贴图内容。没有尝试在其他时机是否也这样。(onPreRender, onPostRender, 以及新的 CommandBuffer里定义的其他时机等)

    为了将各种PostEffect串联起来,有两种做法: 

    A. 利用 MonoBehaviour 的 onRenderImage 规则: 在一个Camera上挂若干个MonoBehaviour,它们的 onRenderImage函数会依次串联起来,前一个destination是后一个的source。但不保证source或destination一定是主DB对应的RenderTarget,也有可能是u3d自己开的一个临时RenderTexture. 

    B. 自行开辟2个RT, 手工控制串联流程。 ( 我选择了此方法,理由参看知识2)

知识2、降低渲染分辨率

    为了做到此效果,有两种做法:

    A. 修改 Application.resolution ,整体降低渲染分辨率。 3D相机和UI相机的质量都降低了。

    B.UI保持精度不变,只降低3D相机的输出精度。 这就要求必须将3d Camera输出到一张指定的RT, 而UI则输出到DB。且在u3d里,要将一个camera的RT拷贝到DB中,在不增加新的Camera的情况下,只有如下写法才成立:
    B.1  onPreRender里设置 camera.targetTexture = yourRT;
    B.2  onPostRender里将 camera.targetTexture = null;

    B.3  脚本里不可以写 onRenderImage 函数

知识3、RenderTexture 的 cache ,不要自己做

        完全交给U3D的 RenderTexture.CreateTemporary / ReleaseTemprorary , 它已经做了。

知识4、 Process 之间的关系

        其实有共存和覆盖逻辑的,一般不需要搞一个二维表来做配置,只需要合理的安排先后顺序和排他性即可。这需要多年图形学经验的老司机来指导。


实现:

PostEffectQueue

        开RT是一个需要极力避免的事情,而只缩3D渲染分辨率(后简称ScreenScale)是后续所有PostEffect的起点,因此针对Scale是否为1,写了两套MonoBehaviour,区别则只有是否 写了 onRenderImage。按需做enable.

        在scale=1时,不创建2个RT,直接使用原始流程。
        在Scale != 1时, 创建两个缩放过的 RT, 模拟DB的工作流, 在 onPostRender函数中调用  各 postEffectProcess的 onRenderImage(source, destination).  


PostEffectProcess

    各种PostEffectProcess 因为总是伴随着参数调整,为了不自己写serializing相关代码,可以将其作为UnityEngine.ScriptableObject 的子类。 这样 PostEffectProcess里的 onRenderImage 需要改成 doRenderImage,不然会报错。


PostEffectManager 

        对外的主要接口有两个:

        BeginEffect( string key, int queueIndex)

        EndEffect(string key, int queueIndex)

其他接口都是辅助的,比如获取某个Process的中间RT之类的(屏幕虚化之类).


设计完成后, PostEffect 流程就每相机N份,跨相机的流程要共享信息也很方便扩展了。

Extends Unity's post processing with 34 additional screen effects. Aiming to provide visual enhancers or feedback effects. Edge detection Highlight the edges of objects or colors Fog Distance and height fog with 2D density noise. As well as single, gradient and skybox color modes. Sunshafts Radiate sun rays from a directional light and skybox Caustics Projects an animated caustics texture over the scene, within a certain height range Color Grading LUT Use any third-party LUT strip, with the option to fade two LUTs over distance. Cloud Shadows Projects a texture over the world (cloud example texture included) Tilt Shift Horizontal or Radial depth of field effect Ripples Make the image appear to wave Lens Flares Draw procedural lens flares on bright spots Colorize Remaps the screen's color to a gradient texture (eg. night or thermal vision) Refraction Create cracked glass, scratches, frost etc. Kuwuhara Transforms the image into a real-time oil-painting Sketch Creates a hatching effect based on luminance Ambient Occlusion 2D Adds self shadowing based on luminance Light streaks JJ-Abrams style lens flares. Extends bloom with light streaks Blur Gaussian and Box blurring methods Speed Lines Anime/cartoon speed effect Color Split Simulates the derefraction of color channels Radial blur Blurs the image towards the edges of the screen (aka Bethesda-style pain effect) Pixelize A retro resolution effect, creates pseudo pixelart Dithering Creates a checker-pattern Lo-Fi shading effect Posterize Limits the screen to old school 1-16bit color depth Sharpen Makes the image appear crisper (useful when using TAA) Double Vision Crosseyed vision, either full-screen or limited to the edges Hue Shift 3D Simulates psychedelic color breathing Overlay Fix an image to the screen, includes blending options Kaleidoscope Splits the screen up into mirrored "pie" pieces Transition Steps through a gradient to transition to a black screen (eg. GBA Pokemen)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值