1.Graphics.Blit:Copies source texture into destination render texture with a shader
  声明:
  1.public static void Blit(Texture source, RenderTexture dest, Material mat(缺省), int pass = -1(缺省));
  2.public static void Blit(Texture source, RenderTexture dest, Vector2 scale, Vector2 offset);
  source是源纹理,dest是目标纹理(null则直接输出到屏幕),mat表示用来渲染的材质,pass表示使用材质的哪个通道(-1表示所有通道)
  Blit会设置source为mat的_MainTex变量,并把输出存给dest,dest如果为Null,blit会把输出存给屏幕缓冲区,
  但是,如果main camera(Camera.main)的targetTexture不是Null,则dest输出给的是Camera.main.targetTexture,而不是屏幕缓冲区!
  要想获得源纹理(一般来自当前渲染结果)的更多信息,我们需要把它作为源,通过shader把源的各种信息(法线、位置、深度等)拉到多个rt中使用,
  但是,You can't use the Graphics.Blit since it only set one RenderTexture internally。也就是说blit只能输出到一个rt中,不能切换。
  这个时候就用到MRT技术了:
  一般是先SetRenderTarget设置rb数组接收多个渲染结果,接着设MRTMat的mainTex为source,然后renderQuad把渲染结果写入rb数组,这样就能得到源纹理的许多信息了:
  来自:http://whisperlin.blog.163.com/blog/static/6052371020141287150719/

  RenderTexture oldRT = RenderTexture.active;
  Graphics.SetRenderTarget(mrtRB, mrtTex[].depthBuffer);
  testMRTMaterial.SetTexture("_mainTex", source);//我加的,因为要取源纹理的信息,所以要设置一下,才能取到
  testMRTMaterial.SetPass(); //Pass 0 outputs 2 render textures. GL.Clear(false, true, Color.clear);
GL.PushMatrix();
GL.LoadOrtho();
//Render the full screen quad manually.MRT需要这样做:When using MRT, you have to render the full screen quad manually
GL.Begin(GL.QUADS);
GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0.0f, 0.0f, 0.1f);
GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(1.0f, 0.0f, 0.1f);
GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(1.0f, 1.0f, 0.1f);
GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0.0f, 1.0f, 0.1f);
GL.End();
GL.PopMatrix(); //到这里已经把source的信息提取到mrtRB了,至于提取什么信息就看你testMRTMaterial的shader的第0通道的片段着色器返回什么了(这种片段着色器写法请参考链接)
RenderTexture.active = oldRT;//归还给屏幕 //Show the result
testMRTMaterial.SetTexture("_Tex0", mrtTex[]);
testMRTMaterial.SetTexture("_Tex1", mrtTex[]);
Graphics.Blit(source, destination, testMRTMaterial, );//通道1是用_Tex0/1处理源纹理

  所谓MRT技术无非就是获得更多渲染信息并用于一些处理
  根据Blit的描述:Blit sets dest as the render target, sets source _MainTex property on the material, and draws a full-screen quad
  对照上面MRT的做法,基本可以认为,SetRenderTarget+setMRTMatTex+GL_RenderFullScreenQuad = Blit,也就是说MRT只是用其他方法来解决blit不能多次改变rt的缺点

2.Graphics.SetRenderTarget:Sets current render target
  声明:
  1.SetRenderTarget(RenderTexture rt, int mipLevel(缺省), CubemapFace face(缺省), int depthSlice(缺省));
  2.SetRenderTarget(RenderBuffer colorBuffer, RenderBuffer depthBuffer, int mipLevel(缺省), CubemapFace face(缺省), int depthSlice(缺省));
  3.SetRenderTarget(RenderBuffer[] colorBuffers, RenderBuffer depthBuffer);
  SetRenderTarget的作用是把gpu渲染的中间纹理或最终纹理输出到这个函数的参数中!有点像向GPU索取数据。
  SetRenderTarget(RenderTexture rt)和 RenderTexture.active = rt作用一样,都是把渲染的结果存到rt中,如果为null则输出到屏幕,如果只是想要某个camera的渲染结果,用Camera.targetTexture=rt代替。
  输出到rt或者colorBuffer区别应该不大,只是接收数据的数据结构不同,毕竟RenderBuffer是RenderTexture中存储RGB图和深度图数据的缓存格式,
  RenderTexture.colorBuffer就是RenderBuffer格式。一般我们可以看到输入的RenderBuffer也是先定义一个RT,然后取其rb类型变量colorBuffer来输入。
  特别地,第3个声明用来搞MRT,就是一个渲染输出多个纹理数据到buffers中,可以用这些buffers来输出多个图片或者用来做多样后期效果。可以参考
  以前关于MRT的笔记或这篇博文:http://blog.csdn.net/ylbs110/article/details/53457576

3.Graphics.BlitMultiTap:Copies source texture into destination, for multi-tap shader
  声明:
  void BlitMultiTap(Texture source, RenderTexture dest, Material mat, params Vector2[] offsets);
  一般用来做post-processing effect,比如模糊。和Blit类似,特别地,offsets数组表示顶点纹理采样时的纹理坐标偏移,多个offsets就采样结果混合,比如模糊源纹理时可以offsets:new Vector2(-off,-off),new Vector2(off,-off),new Vector2(-off,off),new Vector2(off,off),这个off是像素单位的。

4.Graphics.ConvertTexture:
  声明:
  1.bool ConvertTexture(Texture src, Texture dst);
  2.bool ConvertTexture(Texture src, int srcElement, Texture dst, int dstElement);
  把src转换成其他格式或尺寸,但目标纹理不能是压缩类格式,成功返回true,对第2个声明的使用不了解,网上没多少例子。
  This function provides an efficient way to convert between textures of different formats and dimensions.
  The destination texture format should be uncompressed and correspond to a supported RenderTextureFormat.
  支持的格式有Currently supported are 2d and cubemap textures as the source, and 2d, cubemap, 2d array and cubemap array textures as the destination.

5.Graphics.CopyTexture:Copy texture contents
  声明:
  1.void CopyTexture(Texture src, Texture dst);
  2.void CopyTexture(Texture src, int srcElement, int srcMip, Texture dst, int dstElement, int dstMip);
  3.void CopyTexture(Texture src, int srcElement, int srcMip, int srcX, int srcY, int srcWidth, int srcHeight,
  Texture dst, int dstElement, int dstMip, int dstX, int dstY);
  可以整个拷贝,也可以拷贝一部分,可以根据mipmap level拷贝
  注意:
  1.拷贝只是单纯拷贝,不会尺寸缩放
  2.源纹理和目标纹理的格式要兼容,如TextureFormat.ARGB32 和 RenderTextureFormat.ARGB32
  3.压缩类格式的源纹理的区域拷贝有限制,比如PVRTC格式只能整个原图拷贝或整个mip level拷贝,DXT, ETC格式区域拷贝必须满足:
  the region size and coordinates must be a multiple of compression block size(4 pixels for DXT)。
  4.可能2个纹理需要设为readable,因为原文这样说:
  If both source and destination textures are marked as "readable" , these functions copy it as well.
  5.更多平台支持信息可查CopyTextureSupport, and use SystemInfo.copyTextureSupport to check

6.Graphics.DrawMesh:Draw a mesh
  声明:
  1.DrawMesh(Mesh mesh, Vector3 position, Quaternion rotation, Material material, int layer, Camera camera, int submeshIndex, MaterialPropertyBlock properties, Rendering.ShadowCastingMode castShadows, bool receiveShadows = true, Transform probeAnchor = null, bool useLightProbes = true);
  2.void DrawMesh(Mesh mesh, Matrix4x4 matrix, Material material, int layer, Camera camera, int submeshIndex, MaterialPropertyBlock properties, Rendering.ShadowCastingMode castShadows, bool receiveShadows = true, Transform probeAnchor = null, bool useLightProbes = true);
  DrawMesh不需要生成模型,不用管理大量gameobject,直接绘制网格(一般而言,我们是在hierarchy生成gobj,然后unity渲染gobj的底层就调用drawmesh,我们直接调用下面的渲染接口,更高效,所以Use DrawMesh in situations where you want to draw large amount of meshes)
  mesh是将要绘制的Mesh,position是位置,rota是朝向,mat是渲染选择的材质,layer是mesh的layer,camera是渲染到哪个摄像机(null是所有),subMeshIndex和materialIndex表示绘制哪个子网格(每个子网格对应一个材质)参考本文档第4大点;properties也是很重要的,因为drawmesh是延时的,drawmesh之前设置mat的参数是不能及时生效的,所以如果多个mesh公用一个mat,就乱了,这个参数就是用来解决这个问题的,多个mesh公用一个mat但参数不同;
  castShadows,receiveShadows,useLightProbes,表示drawMesh得到的mesh是受光照影响的,几乎等同于场景内一个普通模型;
  probeAnchor(如果使用光照探头,这个Tranform的位置就是用来采样光照探头的地方并 find the matching reflection probe)
  matrix是combines position, rotation and other transformations。
  DrawMesh是必须一帧绘制一次,一般在Update里调用,消耗的资源主要是从调用到渲染帧结束期间需要分配资源,性能大致测试过,应该没问题

7.Graphics.DrawMeshNow:Draw a mesh immediately,Currently set shader and material (use Material.SetPass) will be used
  声明:
  void DrawMeshNow(Mesh mesh, Vector3 position, Quaternion rotation, int materialIndex);
  立即绘制网格,不受光照影响,不是每帧调用,只在OnPostRender中调用,这个OnPostRender必须挂在Camera才有效:

    public Mesh mesh;
  public Material mat;
  public void OnPostRender() {
// set first shader pass of the material,必须设置,不然没材质渲染网格
mat.SetPass();
// draw mesh at the origin
Graphics.DrawMeshNow(mesh, Vector3.zero, Quaternion.identity);
}

8.Graphics.DrawMeshInstanced:Draw the same mesh multiple times using GPU instancing
  声明:
  void DrawMeshInstanced(Mesh mesh, int submeshIndex, Material material, Matrix4x4[] matrices, int count = matrices.Length, MaterialPropertyBlock properties = null, Rendering.ShadowCastingMode castShadows = ShadowCastingMode.On, bool receiveShadows = true, int layer = 0, Camera camera = null);
  matrices数组是不同网格的transform数组,其他的类似drawmesh
  DrawMeshInstanced和DrawMesh很像,每帧调用一次,不生成gobj直接绘制网格,在需要绘制大量相同的网格(相同材质/不同材质参数/不同Transform参数)时调用
  材质的shader需要using an instanced shader,material 必须设置Material.enableInstancing为true,需要硬件支持:See SystemInfo.supportsInstancing
  此外,还有其他限制:
  1.使用Lightmap的物体
  2.受不同Light Probe / Reflection Probe影响的物体
  3.使用包含多个Pass的Shader的物体,只有第一个Pass可以Instancing前向渲染时,受多个光源影响的物体只有Base Pass可以instancing,Add Passes不行
  值得注意的是,only draw a maximum of 1023 instances at once,并且因为用了GPU Instance技术,所以(应该是不走通用渲染管线流程了):
  Meshes are not further culled by the view frustum or baked occluders, nor sorted for transparency or z efficiency

9.MaterialPropertyBlock:A block of material values to apply
  这个不是接口,但和6,8关联很大,所以拉出了溜溜,is used by Graphics.DrawMesh/DrawMeshInstanced and Renderer.SetPropertyBlock.
  block的传递是拷贝的方式的,所以最高效的使用方式是只定义一个,使用时设置一下传给函数:
  the most efficient way of using it is to create one block and reuse it for all DrawMesh calls
  对drawMesh一般是用setfloat等完成一次设置,然后drawmesh一次,但DrawMeshInstanced则不同,因为物体有很多,所以需要用setfloatarray,然后在shader里面应该也处理一下(没看过instance shader,不了解),这样每个mesh都对应不同参数了。
  另外,block的方式改变材质参数比直接材质set参数要高效:http://www.jianshu.com/p/eff18c57fa42

10.Graphics.DrawMeshInstancedIndirect:Draw the same mesh multiple times using GPU instancing
  声明:
  void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, Bounds bounds, ComputeBuffer bufferWithArgs, int argsOffset = 0, MaterialPropertyBlock properties = null, Rendering.ShadowCastingMode castShadows = ShadowCastingMode.On, bool receiveShadows = true, int layer = 0, Camera camera = null);
  和这个DrawMeshInstanced类似,但没有上限1024的限制
  bufferWithArgs:需要绘制的每个mesh的顶点数,总mesh数,和3个location(需要测试才知道作用),通过bufferWithArgs.SetData(int[] args)填充buffer
  argsOffset:填充bufferWithArgs时从Int[]参数的第offset个下标开始读,并且连续读5个(分别对应每个mesh顶点数、mesh数、3个location),offset的作用应该是为了方便给不同次调用DrawMeshInstancedIndirect填充不同参数;
  那各个mesh的transform信息呢?这个需要通过另外一个ComputerBuffer来完成:

positionBuffer = new ComputeBuffer(instanceCount, );
Vector4[] positions = new Vector4[instanceCount];
for (int i=; i < instanceCount; i++) {
float angle = Random.Range(0.0f, Mathf.PI * 2.0f);
float distance = Random.Range(20.0f, 100.0f);
float height = Random.Range(-2.0f, 2.0f);
float size = Random.Range(0.05f, 0.25f);
positions[i] = new Vector4(Mathf.Sin(angle) * distance, height, Mathf.Cos(angle) * distance, size);
}
positionBuffer.SetData(positions);
material.SetBuffer("positionBuffer", positionBuffer); // Render
Graphics.DrawMeshInstancedIndirect(
mesh,
,
material,
new Bounds(Vector3.zero, new Vector3(100.0f, 100.0f, 100.0f)),
argsBuffer);

注意,为了读取到positionBuffer传进来的数据,该材质使用的shader必须是特殊定制的

11.Graphics.DrawProcedural:Draws a fully procedural geometry on the GPU
  声明:
  void DrawProcedural(MeshTopology topology, int vertexCount, int instanceCount = 1);
  Procedural:程序上的
  DrawProcedural does a draw call on the GPU, without any vertex or index buffers
  文档说要sm4.5才能用,因为sm4.5才给用户任意读取computerbuffer buffers中的数据,
  这个接口和DrawMeshNow有点类似,使用当前active rt作为输出,使用当前mat.pass作为材质渲染,但不需要输入顶点数据(从computerbuffer读)
  It uses currently set render target, transformation matrices and currently set shader pass
  要先学ComputerBuffer才能知道怎么使用,先仅止了解。

  PS:
  The amount of geometry to draw is read from a ComputeBuffer.
  Typical use case is generating arbitrary amount of data from a ComputeShader and then rendering that, without requiring a readback to the CPU(直接使用computershader的数据进行渲染,即在gpu那边快速完成)
  是否支持:SystemInfo.supportsComputeShaders

12.DrawProceduralIndirect:和Graphics.DrawProcedural类似

13.Graphics.DrawTexture:Draw a texture in screen coordinates.
  声明:
  void DrawTexture(Rect screenRect, Texture texture, Rect sourceRect, int leftBorder, int rightBorder, int topBorder, int bottomBorder, Color color, Material mat = null, int pass = -1);
  screenRect是绘制到屏幕的区域,单位是像素,(0,0)是左上角;sourceRect是读取源纹理的区域,是归一化坐标,(0,0)代表左下角;那些border类似九宫格的原图=》拉伸后的图保留的不拉伸区域;color影响顶点颜色;mat用来渲染tex,null则使用默认的;pass,-1则使用mat 的 all passes

14.Graphics.ExecuteCommandBuffer:Execute a command buffer
声明:
  void ExecuteCommandBuffer(Rendering.CommandBuffer buffer);
  看看commandbuffer先,可不简单。

几个Graphics函数的更多相关文章

  1. iOS 图形处理 Core Graphics Quartz2D 教程

    Core Graphics Framework是一套基于C的API框架,使用了Quartz作为绘图引擎.它提供了低级别.轻量级.高保真度的2D渲染.该框架可以用于基于路径的 绘图.变换.颜色管理.脱屏 ...

  2. iOS使用Core Graphics和UIBezierPath绘画

    通过UIView的子类的- (void)drawRect:(CGRect)rect 函数可用对视图进行重新绘画: 要重新绘画可以通过Core Graphics和UIBezierPath来实现. 1.通 ...

  3. 贝赛尔曲线UIBezierPath

    使用UIBezierPath类可以创建基于矢量的路径,这个类在UIKit中.此类是Core Graphics框架关于path的一个封装.使用此类可以定义简单的形状,如椭圆或者矩形,或者有多个直线和曲线 ...

  4. iOS----自定义UIView,绘制一个UIView

    绘制一个UIVIew最灵活的方式就是由它自己完成绘制.实际上你不是绘制一个UIView,你只是子类化了UIView并赋予子类绘制自己的能力.当一个UIVIew需要执行绘图操作的时,drawRect:方 ...

  5. iOS 视图与视图层次结构(内容根据iOS编程)

    视图基础 视图是 UIView 对象,或者其子对象. 视图知道如何绘制自己. 视图可以处理事件,例如触摸(touch). 视图会按照层次结构排列,位于视图层次结构顶端的是应用窗口. 视图层次结构 任何 ...

  6. iOS开发 贝塞尔曲线

    iOS开发 贝塞尔曲线UIBezierPath - 陌云 时间 2014-03-14 11:04:00  博客园-所有随笔区 原文  http://www.cnblogs.com/moyunmo/p/ ...

  7. UIBezierPath 的使用

    使用UIBezierPath类可以创建基于矢量的路径,这个类在UIKit中.此类是Core Graphics框架关于path的一个封装.使用此类可以定义简单的形状,如椭圆或者矩形,或者有多个直线和曲线 ...

  8. UIBezierPath类 笔记

    使用UIBezierPath类可以创建基于矢量的路径.此类是Core Graphics框架关于path的一个封装.使用此类可以定义简单的形状,如椭圆或者矩形,或者有多个直线和曲线段组成的形状.     ...

  9. iOS开发 贝塞尔曲线UIBezierPath

    最近项目中需要用到用贝塞尔曲线去绘制路径 ,然后往路径里面填充图片,找到这篇文章挺好,记录下来 自己学习! 转至 http://blog.csdn.net/guo_hongjun1611/articl ...

随机推荐

  1. Gradle编译Spring源码

    使用工具:JDK1.8.0_11.Gradle4.9.idea2018.1.3 1. 配置Gradle Gradle下载地址:https://gradle.org/releases/ 在下载页找到自己 ...

  2. Idea debug报错Command line is too long

    问题: 使用idea开发Java项目,写单元测试,debug时,会有红字报错:Command line is too long 解决方法: 在项目的目录下,找到/.idea/workspace.xml ...

  3. day7.关于字符串的相关操作

    一.字符串的相关操作 """ (1)字符串的拼接 (2)字符串的重复 (3)字符串跨行拼接 (4)字符串的索引 (5)字符串的切片: 语法 => 字符串[::] 完 ...

  4. 为写程序而生的连字字体 Fira Code

    Fira Code,等宽的编程连字字体 **等宽 ** 是指所有字符的宽度相同,如: W 和 i 用一样的宽度去显示 连字(ligatures)为文字排印的一个特性,比如「f」和「 i」放在一起的时候 ...

  5. Pytorch_第八篇_深度学习 (DeepLearning) 基础 [4]---欠拟合、过拟合与正则化

    深度学习 (DeepLearning) 基础 [4]---欠拟合.过拟合与正则化 Introduce 在上一篇"深度学习 (DeepLearning) 基础 [3]---梯度下降法" ...

  6. Redis服务之集群节点管理

    上一篇博客主要聊了下redis cluster的部署配置,以及使用redis.trib.rb工具所需ruby环境的搭建.使用redis.trib.rb工具创建.查看集群相关信息等,回顾请参考https ...

  7. [深度学习] Pytorch(三)—— 多/单GPU、CPU,训练保存、加载模型参数问题

    [深度学习] Pytorch(三)-- 多/单GPU.CPU,训练保存.加载预测模型问题 上一篇实践学习中,遇到了在多/单个GPU.GPU与CPU的不同环境下训练保存.加载使用使用模型的问题,如果保存 ...

  8. 2020-07-20:你觉得redis有什么缺点,给你改进的话你会怎么改进?

    福哥答案2020-07-20: 1.由于 Redis 是内存数据库,短时间内大量增加数据,可能导致内存不够用.2.redis是单线程的,单台服务器无法充分利用多核服务器的CPU.3.遇到大量查询时容易 ...

  9. 2020-04-07:说出Servlet的生命周期,并说出Servlet和CGI的区别。

    Servlet的生命周期分为5个阶段:实例化:Servlet容器创建Servlet类的实例.初始化:该容器调用init()方法,通常会申请资源.服务:由容器调用service()方法,(也就是doGe ...

  10. C#LeetCode刷题,走进Google,走近人生

    概述 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/1015 访问. 本系列博文将会向大家展示我在LeetCode上的刷 ...