URP案例分析(KeepFrame)

大致流程是:

一、DrawOldFramePass:用上一帧的RenderTanget进行旋转偏移之类的操作

二、DrawTransparentObjectPass:绘制场景物件,叠加到DrawOldFramePass绘制的网格上

三、CopyFramePass:生成RenderTarget缓存给下一帧使用

一、RenderFeature

从KeepFrameFeature.cs中看到KeepFrameFeature包含两个PASS,一个是CopyFramePass,另一个是DrawOldFramePass。

CopyFramePass是在AfterRenderingTransparents的时候执行,DrawOldFramePass是在BeforeRenderingOpaques的时候执行,所以DrawOldFramePass优先执行。

    public override void Create()
    {
        m_CopyFrame = new CopyFramePass();
        m_CopyFrame.renderPassEvent = RenderPassEvent.AfterRenderingTransparents; //Frame color is copied late in the frame

        m_DrawOldFame = new DrawOldFramePass();
        m_DrawOldFame.renderPassEvent = RenderPassEvent.BeforeRenderingOpaques; //Old frame is drawn early in the frame
    }

CopyFramePass的作用是把当前相机的RenderTarget保持到缓存m_OldFrameHandle中

        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            if (renderingData.cameraData.camera.cameraType != CameraType.Game)
                return;

            CommandBuffer cmd = CommandBufferPool.Get("CopyFramePass");
            RenderTargetIdentifier opaqueColorRT = destination.Identifier();
            Blit(cmd, source, opaqueColorRT);
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }

DrawOldFramePass是使用上一帧的m_OldFrameHandle传给displayMaterial渲染到一个全屏的长方形面片。

        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            if (m_DrawOldFrameMaterial != null)
            {
                CommandBuffer cmd = CommandBufferPool.Get("DrawOldFramePass");
                cmd.SetGlobalTexture(m_textureName, m_handle.id);
                cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity);
                cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, m_DrawOldFrameMaterial, 0, 0);
                cmd.SetViewProjectionMatrices(renderingData.cameraData.camera.worldToCameraMatrix, renderingData.cameraData.camera.projectionMatrix);
                context.ExecuteCommandBuffer(cmd);
                CommandBufferPool.Release(cmd);
            }
        }

通过FrameDebug也可以观察到大致流程是先执行DrawOldFramePass,再DrawTransparentObjects画场景物,再CopyFramePass。

二、Shader实现

KeepFrameFeature使用的材质是SwirlyFrame,SwirlyFrame使用的shader是SwirlyFrame_Graph。

这里面的_FrameCopyTex就是CopyFramePass传递给DrawOldFramePass用的缓存m_OldFrameHandle。可以看出这个shader就是大致对传入的贴图进行UV旋转、平移和重复展开,然后进行百分比混合。

可以看出大致流程是先对上一帧的RT进行旋转偏移,再画场景物,再缓存当选相机RT,然后得到一种画面残留的感觉

可以通过修改一些设置更容易观察这中间的过程。关闭后处理、阴影、SRPBatch,创建一个简单的模型,对它使用一个unlit材质,场景关闭特效、UI,调整SwirlyFrame参数

可以看到画面有调整

这时候再FrameDebug可以看到流程简化很多,更容易分析。但个人认为这里面的_OldFrameRenderTarget应该是错误的,应该是上一帧的画面才对。:

可以通过打包成exe用RenderDoc分析核对一下渲染过程:

  1. DrawOldFramePass画的是全屏面片,用的是上一帧的RenderTarget

2.在此基础上绘制场景物件

3.CopyFramePass:拷贝RenderTarget操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星星又凉了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值