obsidian/笔记文件/2.笔记/CommandBuffer.md
2025-03-26 00:02:56 +08:00

2.8 KiB
Raw Blame History

#unity/日常积累

CommandBuffer保存渲染指令,并在特定渲染阶段与渲染路径相关执行。渲染指令与之前介绍的渲染接口类似特定的渲染阶段与Camera处理流程相关。

6.1 渲染路径与Camera事件

上一章节中提到了两种渲染路径的原理。此处给出详细的Camera渲染流程

!Pasted image 20240131135940.png

!Pasted image 20240131135945.png

总体来说,两种渲染路径都是按照先渲染不透明对象(由近及远,天空盒最后),再渲染透明对象。延迟渲染路径中,对于无法支持的渲染对象会使用前向渲染方式处理。

6.2 关键API

CommandBuffer接口与Graphics有很多作用类似的接口此章节会略过这一部分如有需要参考。

https://zhuanlan.zhihu.com/p/442781670

CommandBuffer

  • SetRenderTarget将Shader属性对应的RT设置为绘制对象
  • SetGlobalTexture设置全局Shader纹理变量与Shader.SetGlobalTexture作用类似
  • GetTemporaryRT获取RT并与Shader属性绑定
  • ReleaseTemporaryRT释放Shader属性对应的RT

Camera

  • AddCommandBuffer为Camera添加CommandBuffer
  • RemoveCommandBuffer为Camera移除CommandBuffer

BuiltinRenderTextureType

  • CurrentActive当前active纹理
  • CameraTargetCamera绘制的纹理
  • Depth深度纹理
  • GBuffer0延迟渲染颜色纹理
  • GBuffer2延迟渲染normals纹理
// 拷贝屏幕纹理到Shader属性
int screenCopyID = Shader.PropertyToID("_ScreenCopyTexture");
buf.GetTemporaryRT(screenCopyID, -1, -1, 0, FilterMode.Bilinear);
buf.Blit(BuiltinRenderTextureType.CurrentActive, screenCopyID);

踩坑Tips

CommandBuffer.GetTemporaryRT获取的RT会在Graphics.ExecuteCommandBuffer或者CameraEvent渲染完成后被回收这就可能导致在不同CameraEvent获取RT时取得之前创建的RT覆盖原有的效果。如果是持续化显示通过RenderTexture.GetTemporary接口可以避免这类问题。

CameraEvent.AfterImageEffects获取的屏幕纹理是翻转的具体原因不清知道的大佬告知一下。

6.3 Demo

测试内容场景中存在不透明和半透明两种小球两类小球渲染完成时分别进行截图。截图时并绘制一个Cube两通道输出到两张RT上。传送门RanderAPI场景

https://link.zhihu.com/?target=https%3A//github.com/manaijin/3D

!Pasted image 20240131140044.png

七、总结

从渲染组件、渲染接口以及渲染流程三个方面基本理清了Unity底层渲染逻辑以及拓展方式。在Unity 2018之后提供了SRP对管线的修改给出了更便捷的处理方式之后会学习这部分内容。补充阅读麦老师的手动渲染管线对渲染管线会有更好得认识

https://zhuanlan.zhihu.com/p/43588045

https://zhuanlan.zhihu.com/p/43742196