技术美术百人计划 | 《3.72 Command Buffer》笔记

入门精要第二章:

问题一: CPU GPU 是如何实现并行工作的?

使用命令缓冲区 (Command Buffer)。它包含了一个命令队列, 由 CPU 向其中添加命令, 而由 GPU从中读取命令,两个过程互相独立。

命令缓冲区使得CPU和GPU可以相互独立工作。当CPU需要渲染一些对象时,它可以向命令缓冲区中添加命令, 而当GPU完成了上一次的渲染任务后,它就可以从命令队列中再取出一个命令并执行它。

命令缓冲区中的命令有很多种类, 而Draw Call 是其中一种,其他命令还有改变渲染状态等 ( 例如改变使用的着色器, 使用不同的纹理等)。

参考文档:

Command Buffers In Unity - 腾讯云开发者社区-腾讯云 (tencent.com)

使用 CommandBuffer 来扩展内置渲染管线 - Unity 手册 (unity3d.com)

Unity Shader-Command Buffer的使用(景深与描边效果重置版)_unity commandbuffer-CSDN博客

Rendering.CommandBuffer - Unity 脚本 API (unity3d.com)

1. 简介

Command Buffer出现的目的是为了扩展Unity的渲染管线(Rendering Pipeline) ,一个Command Buffer 中存储很多绘制命令(Rendering Command),这些 Rendering Command 其实就是OpenGL或者DirectX 中的一些列指令,比如glDrawElementglClear等。

Command Buffer 扩展渲染管线的方法是:预定义一系列的渲染指令,然后在特定的时机去执行这些指令。这些特定的时机是由我们来指定的,下图渲染过程中的绿点说明了这些可以指定的时机:

渲染顺序:Skybox的渲染是在不透明图像效果之后,半透明物体之前,是因为不透明物体的绘制是从前往后,而半透明物体的绘制是从后往前的。

Image Effect:Command buffers 可以代替 Image Effect ,也可以和Image Effect 一起使用。

2. 案例一-简单引例

一个简单的Unlit Shader

将shader颜色设置为红色,点击运行,此时同一个物体,在Scene窗口颜色是红色,而Game窗口是白色,这是渲染命令为其增加了一个白色材质导致的。

打开Frame Debugger,可见胶囊体执行了两次渲染,一次正常渲染,一次Command Buffer渲染:

因此,CommandBuffer作用就是在相机渲染的某个阶段,再另外执行自己的额外渲染,至于渲染的结果就看我们怎么用了。

3. 案例二-官方毛玻璃效果

实现效果:

原理:

在不透明物体和天空盒渲染完成之后,复制渲染图像到一个临时的RT上,然后对其进行模糊处理,将处理的结果应用到一个Shader全局参数上。这么一来,所有在天空盒之后渲染的物体(例如所有的半透明物体)可以采样这个“模糊处理后的场景图像”。这种做法的效果类似 GrabPass ,但是比抓取屏幕的效率更高一些。

问题

1、在Scene视图,目前并不能正确捕捉渲染结果,只能捕捉到天空盒。

2、在Android手机上测试,效果有些差别

用于模糊的shader

//偏移定点uv,使其读取到周围颜色值进行混合。
    v2f vert (appdata_img v) 
    {
        v2f o;
        o.pos = UnityObjectToClipPos(v.vertex);

        o.uv.xy = v.texcoord.xy;

        //计算上下左右用于模糊采样的uv值
        o.uv01 =  v.texcoord.xyxy + offsets.xyxy * float4(1,1, -1,-1);
        o.uv23 =  v.texcoord.xyxy + offsets.xyxy * float4(1,1, -1,-1) * 2.0;
        o.uv45 =  v.texcoord.xyxy + offsets.xyxy * float4(1,1, -1,-1) * 3.0;

        return o;
    }

    //混合颜色值
    half4 frag (v2f i) : COLOR 
    {
        half4 color = float4 (0,0,0,0);

        //使用加权平均
        color += 0.40 * tex2D (_MainTex, i.uv);
        color += 0.15 * tex2D (_MainTex, i.uv01.xy);
        color += 0.15 * tex2D (_MainTex, i.uv01.zw);
        color += 0.10 * tex2D (_MainTex, i.uv23.xy);
        color += 0.10 * tex2D (_MainTex, i.uv23.zw);
        color += 0.05 * tex2D (_MainTex, i.uv45.xy);
        color += 0.05 * tex2D (_MainTex, i.uv45.zw);

        return color;
    }

效果:

4. 总结

  • Command Buffer的功能非常强大,它不仅可以用来处理Render Texture,也可以用于直接渲染物体:使用CommandBuffer.DrawMeshCommandBuffer.DrawRenderer 两个API 来实现,两者不同之处在于:DrawMesh 可以手动指定变换矩阵,更加灵活,同时也更加复杂。
  • 使用Command Buffer 渲染物体时,如果给 shaderPass 形参传递了 -1 值,将会执行Shader中的所有Pass,但是需要注意:
if (!(LightMode == nullLightMode == ForwardBaseLightMode == ForwardAdd))
{
  // Command Buffer执行的渲染结果会出现问题
}
  • 执行Command Buffer 的方法:
    • Camera.AddCommandBuffer()为摄像机指定的渲染事件添加CommandBuffer;
    • Graphics.ExecuteCommandBuffer()立即执行;
    • Graphics.ExecuteCommandBufferAsync()异步执行 。
  • 在使用Command Buffer的时候,一定要特别注意执行的时机和渲染的先后顺序,避免出现不可预估的渲染结果。
  • Command Buffer的特点是可以在指定的时机执行一些特殊的渲染操作,从而达到节省资源和实现特殊效果的目的。
  • 不可为了Command Buffer 而刻意使用Command Buffer,这样往往得不偿失。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值