有关Unity3D的OnRenderImage()和Blit()的一些问题

转载 2015年07月07日 15:13:36
大家好!本人最近在使用Unity3D做master阶段的图形学实验平台。在实验过程中会频繁的对多个不同的RenderTexture(以下简称RT)进行一些运算,因此自然会用到Blit这个函数。在实验中,我们遇到了一些非常神奇的问题,希望能跟大家一起讨论一下。
Blit(src,dest,mat,pass)函数的作用,按照Unity官方API的说法是将src这个RT用mat这个材质中的某个pass渲染,然后复制到dest中。如果要给渲染加一些后处理效果(SSAO,HDR,bloom之类的),几乎可以肯定会用到这个函数。根据Unity自带文档中的例子,在OnRenderImage中调用Blit,然后用指定的mat渲染出来。OnRenderImage(src,dest)是Camera的一个回调(message),他会在camera执行渲染时候被调用,官方给的大部分Image Effect的实现都是用了这个回调。不过,经过最近的实验我发在OnRenderImage里面不能多次调用Blit绘制多个不同的RT。这个坑爹的问题困扰了本人很长时间...

也就是说形如:
  1. void OnRenderImage(RenderTexture src, RenderTexture dest ){

  2. Graphics.Blits(someRT, RT1, someMat, 1);
  3. Graphics.Blits(someRT, RT2, some,Mat, 2);
复制代码
这样的操作不会得到预计的效果。

考虑到可能是因为渲染管线在一次Blit之后没有把render Target改成另外一个RT,于是本人进行了多次实验,包括:

1.手动设置camera.targetTexture为要渲染的RT,未果
2.在每次Blit之前加上RenderTexture.active = 要渲染的RT,未果
3.在每次Blit之前设置Graphics.SetRenderTarget()为要渲染的RT,未果

一气之下,本人怒写了一发Blit()的Brute实现...:
  1. static public void Blit(RenderBuffer COLOR,RenderBuffer DEPTH, Material MRTMat,int pass)
  2.         {
  3.                 Graphics.SetRenderTarget(COLOR, DEPTH);
  4.                 RenderQuad (MRTMat, pass);
  5.         }
复制代码
  1. static public void RenderQuad( Material MRTMat,int pass)
  2.         {

  3.                 GL.PushMatrix();
  4.                 GL.LoadOrtho();
  5.                 MRTMat.SetPass(pass);
  6.                 GL.Begin(GL.QUADS);
  7.                 GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0.0f, 1.0f, 0.1f);
  8.                 GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(1.0f, 1.0f, 0.1f);                
  9.                 GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(1.0f, 0.0f, 0.1f);                
  10.                 GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0.0f, 0.0f, 0.1f);                
  11.                 GL.End();
  12.                 GL.PopMatrix();
  13. }
复制代码

并且在Update中进行了调用,完全放弃了Unity那种在OnRendermage中做处理的模式。喜大普奔地发现问题竟然解决了...

通过多次试验,我们发现,似乎在执行OnRenderImage这个回调过程中,一旦给摄像机设置了RenderTarget(也就是某个RT),在这一次回调中就不能再更改了。我们在做了一个实验,在编辑器里手动给camera设置renderTarget,然后在OnRenderImage中执行:
  1. Blit(someRT, RT1, mat);
  2. Blit(someRT, RT2, mat);
  3. Blit(someRT, RT3, mat);
  4. Blit(someRT, RT4, mat);
复制代码

这样的操作。最后只有手动设置的那张RT会被渲染,其他的都没有被渲染。不知道这是不是Unity有意为之,还是说算一个Bug。

我们对这个问题的解决方法就是直接在Update中调用自己写的Blit函数,目前一切perfect。有意思的是,我们将所有摄像机都删除,只留下自己写的Blit,statics那里显示的Draw call数竟然是0...

欢迎大家一起就这个问题分享一下自己的看法,求大神讲解下这是为神马啊!!!

 有关Unity3D的OnRenderImage()和Blit()的一些问题

相关文章推荐

UnityShader:MRT多重渲染

UnityShader:深度图获取,屏幕后期处理特效 中学习了如何使用unityshader处理摄像机画面,这次来看看多重渲染的使用。 有时候我们想同时获得一个画面的不同后期效果:比如需要同时显示深...

【转】Unity3.5是一次较大的更新.它包含的新功能和改进会让你爱不释手.

Shuriken粒子系统内建寻路系统升级遮挡裁切和增加LOD系统谷歌Chrome浏览器的Native Client支持线性空间照明和HDR主要的新功能Adobe Flash:现在版本支持Adobe S...

Unity 画图效果

using UnityEngine; using System.Collections; using System; using System.Collections.Generic; using S...

Unity Shader-后处理:简单均值模糊

今天来学习一下后处理中比较常用的一种效果,屏幕模糊效果。屏幕模糊效果是一些高级后处理效果的基础,比如景深,运动模糊等等效果都需要用屏幕模糊效果来实现,所以我们首先看一下屏幕模糊效果,然后通过屏幕模糊,...

Unity3D 个人免费版不支持Camera.OnRenderImage

昨天在实现一个Unity屏幕特效一直不能成功,后来发现原因是实现该功能需要Unity Pro版本。 具体如下 void Start() { if (SystemInfo.supportsIm...

【Unity Shaders】使用Unity Render Textures实现画面特效——建立画面特效脚本系统

本系列主要参考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同时会加上一点个人理解或拓展。这里是本书所有的插图。这里是本书所需的代码和资源(当然你也可以...

Unity3d-OnRenderImage

OnRenderImage用于一些图像特效 它是怎么工作的呢 写一个shader,通过传入原始texture经过处理,输出的Texture即为最终特效 在这个过程中,可以通过Graphics.B...

unity MRT(渲染到多个目标)

转载:http://forum.unity3d.com/threads/152050-MRT-example?p=1118431&viewfull=1#post1118431 Uni...

Unity3D导入MAX文件的一些问题

1、轴向偏转 MAX模型导入Unity3D后,X轴会自动偏转-90度。是因为Unity3D采用的是左手坐标系,而3DMax采用的是右手坐标系。无奈啊,这是很多游戏引擎跟Max结合后都会产生的问题。兼...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)