实例演示相机的OnImageRender和Clear Flags清理标识(Unity3D)

简介: 无论多基础、简单的知识,只要不会,就是难。。 这次的总结主要与相机上的Clear Flags及OnImageRender函数有关Clear Flags对于这个选项,我是这么理解的:每一个相机在开始绘制时,都需要对当前RenderBuffer中的颜色缓冲区(ColorBuffer)和深度缓冲区(Z-Buffer)进行是否清除的操作,这个选项控制了清除及清除后的内容。

一、前言

无论多基础、简单的知识,只要不会,就是难。。 这次的总结主要与相机上的Clear Flags及OnImageRender函数有关Clear Flags对于这个选项,我是这么理解的:每一个相机在开始绘制时,都需要对当前RenderBuffer中的颜色缓冲区(ColorBuffer)和深度缓冲区(Z-Buffer)进行是否清除的操作,这个选项控制了清除及清除后的内容。

下面将展示一下不同Clear Flags设置下的区别:

网络异常,图片无法展示
|

(相机绘制一个蓝色的立方体)


Sky box:清除颜色缓冲区和深度缓冲区,并将颜色缓冲区设置为天空盒的颜色。

网络异常,图片无法展示
|

(立方体以外部分的"ColorBuffer"都被天空盒填满)



Solid Color:清除颜色缓冲区和深度缓冲区,并将颜色缓冲区设置为一个固定的颜色。

网络异常,图片无法展示
|

(立方体以外部分的"ColorBuffer"都被选定的颜色填满)

上述两种选项是最容易理解的,只是直接清除了缓冲区内的颜色和深度数据,因此如果场景中存在多个相机,且最后一个相机被设置为上述两种ClearFlags,那么,呵呵,之前的相机绘制结果将无法直接显示(因为都被清掉了)。


Depth Only:保留颜色缓冲区,仅清除深度缓冲区。

网络异常,图片无法展示
|

(两部相机先后绘制)

网络异常,图片无法展示
|

(仅清除了深度缓冲区的绘制)

很容易发现,由于拍蓝色立方体的蓝色相机后绘制,且不清除颜色缓冲区,因此蓝色相机在绘制之前,颜色缓冲区已经被红色相机所拍的结果:SolidColor + 红色立方体所填充,因此蓝色立方体只是在这基础之上进行的绘制。 并且,由于清除了深度缓冲区,蓝色立方体无论空间是否被红色立法体遮挡,总会任性的全部绘制,因此产生了错误的遮挡效果。


Don't Clear:毛都不清除。

网络异常,图片无法展示
|

(毛都不清除的绘制-保留了深度缓冲区)

同上,颜色缓冲区在保留的同时,也保留了深度缓冲区,这样蓝色相机在绘制时,就会被红色立方体的深度值所影响,因此获得了正确的遮挡效果。

对了,如果只有一个相机,并且这个相机还设置了“DepthOnly”或者“Don'tClear“的选项,也就是不清除颜色缓冲区,那么当你拖动一个物体时,就会产生这种撸多了的效果:

网络异常,图片无法展示
|
(无影脚应该就是这么拍的吧)

OnRenderImage 那么OnRenderImage跟这个相机的ClearFlags有什么关系呢? 其实没有什么太大关系。

这个函数通常是用来做什么的? 重写这个函数是为了达到屏幕后处理特效的目的,比如全屏虚化等。

这个函数如何使用及调用时机? 首先,包含这个函数的脚本必须附着在一个相机上; 其次,一旦重写这个函数,这个函数所发生的时机,就是在这个相机完成与自己有关的全部渲染后,即将把这次渲染结果更新给当前RenderBuffer时的那一夜(刻)。

大概的触发时机如下图:

网络异常,图片无法展示
|
注意,如果你重写了这个函数,必须有一个将缓冲区传递给dest的操作,即调用Graphics.Blit(rt,  dest)。如果没有这个操作,可以想象,经过这个相机后,RenderBuffer中将会是一片漆黑。

但是:一片漆黑仅仅是因为没有把正确的颜色缓冲区设置给当前的RenderBuffer中的ColorBuffer部分,深度缓冲区仍然不受影响。

以下将讨论几种情况,希望能把问题说清楚:

测试的环境

网络异常,图片无法展示
|


1、两个立方体的空间位置关系,红色遮挡了蓝色。

2、蓝色相机只拍蓝色立方体,红色相机只拍红色立方体。


3、相机渲染的顺序:红色 → 蓝色。

网络异常,图片无法展示
|


4、蓝色相机的渲染结果同时填充给屏幕左下角的Image,红色相机的渲染结果同时填充给屏幕左下二号Image。


第一种情况

蓝色相机Depth Only, 红色相机Solid Color = 天蓝色。

网络异常,图片无法展示
|
网络异常,图片无法展示
|


第二种情况

蓝色相机Solid Color = 壮汉粉, 红色相机Solid Color = 天空蓝

网络异常,图片无法展示
|
网络异常,图片无法展示
|


第三种情况

蓝色相机Solid Color = 壮汉粉,红色相机Depth Only

网络异常,图片无法展示
|

红色相机第一帧

网络异常,图片无法展示
|

第一帧后

网络异常,图片无法展示
|


第四种情况

蓝色相机Don't Clear,红色相机Solid Color + 空OnImageRender函数

网络异常,图片无法展示
|
红色相机没有做向dst传递颜色缓冲区的动作
网络异常,图片无法展示
|

红色相机没有生成任何东西

网络异常,图片无法展示
|

蓝色受到了红色立方体深度值的影响

分析

网络异常,图片无法展示
|
总结: 只要心心念着颜色缓冲区 和 深度缓冲区,掐指一算就差不多了。



相关文章
|
编解码 开发框架 Java
Unity 之 打包参数 -- Player面板属性详解
Unity Project Setting Player面板详解,看完这篇文章,彻底搞懂各个选项设置实际作用。
2024 0
Unity 之 打包参数 -- Player面板属性详解
|
API 图形学
Unity设置播放模式下始终先执行指定的场景
通过我们使用Unity开发游戏,是在PC/Mac上。而一个游戏通常也会有很多的场景,比如A、B、C、D三个场景,正常流程下的执行顺序是 A –> B –> C –> D。在具体一点,比如 A —— 启动场景、B —— 资源加载场景、C —— 登录场景、D —— 战斗场景。
1597 0
|
8月前
UE4 更新资源时修改导入设置
UE4 更新资源时修改导入设置
54 0
UE4 更新资源时修改导入设置
【PR】简单实现自定义区域播放
【PR】简单实现自定义区域播放
136 0
【PR】简单实现自定义区域播放
|
JavaScript
Cypress系列(20)- 可操作类型的命令 之 clear()
Cypress系列(20)- 可操作类型的命令 之 clear()
177 0
Cypress系列(20)- 可操作类型的命令 之 clear()
|
Linux
linux下使用QT调用FFMPEG读取摄像头一帧数据显示到标签控件上
linux下使用QT调用FFMPEG读取摄像头一帧数据显示到标签控件上
587 0
linux下使用QT调用FFMPEG读取摄像头一帧数据显示到标签控件上
ABAP 事务码 ST22的增强 - 自动在ST22视图显示的源代码里绘制一个佛祖图形
ABAP 事务码 ST22的增强 - 自动在ST22视图显示的源代码里绘制一个佛祖图形
119 0
使用代码批量激活inactive object
使用代码批量激活inactive object
|
Go 图形学 Android开发
Unity 之 自动设置导入资源属性选项(模型、图片、声音)
在项目开发中会经常性的更换、导入很多资源,而且对于资源的设置容易出现设置错误或者忘记设置的情况,下面的Code是用untyi自带的AssetPostprocessor功能把导入的资源根据一定的规则自动设置对应的格式选项,使用的时候也很方便,只需要把脚本...
2593 0

热门文章

最新文章