Unity流水账14:GL、Graphics及CommandBuffer

一、GL
(1)、描述
  底层图形库。
  使用此类可以处理激活转换矩阵,发出类似于OpenGL立即模式的渲染命令以及执行其他低级图形任务。注意:在几乎所有情况下,使用Graphics.DrawMesh或CommandBuffer都比使用立即模式绘图更有效。
  GL立即绘图函数使用当前设置的"current material"(参见Material.SetPass)。材质控制渲染的完成方式(混合方式、使用纹理等),因此,除非你在使用GL绘制函数前将其显式设置为某种东西,否则材质可能是任何东西。另外,如果你从GL绘图代码中调用任何其他绘图命令,它们可以将材质设置为其他内容,因此也需要确保其也处于受控状态。
  GL绘图命令立即执行。这意味着,如果在Update()中调用它们,它们将在渲染照相机之前执行(并且照相机很可能会清除屏幕,从而使GL绘图不可见)。
  调用GL绘图的通常位置是在摄像机附带的脚本的OnPostRender()中或image effect函数(OnRenderImage)

using UnityEngine;

public class GLTest : MonoBehaviour
{
    //当添加物体时,从物体位置绘制彩色摄像
    public int lineCount = 100;
    public float radius = 3.0f;
    static Material lineMaterial;
    static void CreateLineMaterial()
    {
        if (!lineMaterial)
        {
            //unity具有内置的着色器,可用于绘制简单的彩色物体
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            lineMaterial = new Material(shader);
            lineMaterial.hideFlags = HideFlags.HideAndDontSave;
            //开启透明度混合
            lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
            lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
            //关闭背面剔除
            lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
            //关闭深度写入
            lineMaterial.SetInt("_ZWrite", 0);
        }
    }
    //所有常规渲染完成后将被调用
    public void OnRenderObject()
    {
        CreateLineMaterial();
        //应用材质
        lineMaterial.SetPass(0);
        GL.PushMatrix();
        //设置用于绘制的变化矩阵以匹配我们的变换:将当前的模型矩阵设置为指定矩阵
        //用于将顶点从模型空间转到世界空间
        GL.MultMatrix(transform.localToWorldMatrix);
        //绘制lines
        GL.Begin(GL.LINES);
        for(int i = 0; i < lineCount; ++i)
        {
            float a = i / (float)lineCount;
            float angle = a * Mathf.PI * 2;
            //顶点颜色从红色到绿色
            GL.Color(new Color(a, 1 - a, 0, 0.8F));
            //在物体位置的顶点
            GL.Vertex3(0, 0, 0);
            //圆边上的另一个顶点
            GL.Vertex3(Mathf.Cos(angle) * radius, Mathf.Sin(angle) * radius, 0);
        }
        GL.End();
        GL.PopMatrix();
    }
}


  Note:当你需要绘制几条线或三角形并且不想处理网格时,几乎总是使用此类。如果要避免意外,使用方式如下:

using UnityEngine;

public class GLTest : MonoBehaviour
{
    private void OnPostRender()
    {
        //设置你的材质
        GL.PushMatrix();
        //yourMaterial.SetPass();
        //画你的东西
        GL.PopMatrix();
    }
}

  Note:在画你的东西的位置,需要对先前声明的材质进行SetPass(),该材质将用于绘制。如果你不使用SetPass,那么你将无法确定当前使用哪个材质绘制。

(2)、Static Properties

invertCulling:选择是否反转背面剔除(true)或否(false);该标志可以“flip(翻转)”所有渲染对象的剔除模式。主要用例:为镜子、水等渲染反射。由于用于渲染反射的相机已为镜像,因此必须点到剔除顺序。你可以看到Effects标准包中的Water脚本如何执行此操作。
函数定义:public static bool invertCulling;
代码示例:
using UnityEngine;

//当附加到相机上时,此脚本将使所有渲染"从里到外"翻转,即将渲染对象的背面而不是正面
[ExecuteInEditMode]
public class GLTest : MonoBehaviour
{
    private bool oldCulling;
    public void OnPreRender()
    {
        oldCulling = GL.invertCulling;
        GL.invertCulling = true;
    }
    private void OnPostRender()
    {
        GL.invertCulling = oldCulling;
    }
}
LINE_STRIP:开始模式:绘制线条;从起点到终点在经过的每个顶点之间绘制线条。如果传递三个顶点A,B和C,则会绘制两条线:一条在A和B之间,一条在B和C之间。要设置2D绘图屏幕,使用GL.LoadOrho或GL.LoadPixelMatrix。要设置3D绘图屏幕,使用GL.LoadIdentity,然后使用GL.MultMatrix和所需的装换矩阵。
函数定义:public static int LINE_STRIP;
LINES:开始模式:绘制线段。在没对通过的顶点之间绘制线。如果传递四个顶点A,B,C和D,则会绘制两条线:一条在A和B之间,一条在C和D之间。要设置2D绘图屏幕,使用GL.LoadOrho或GL.LoadPixelMatrix。要设置3D绘图屏幕,使用GL.LoadIdentity,然后使用GL.MultMatrix和所需的装换矩阵。
函数定义:public static int LINES;
代码示例:
using UnityEngine;

public class GLTest : MonoBehaviour
{
    //从"start Vertex"变量到当前鼠标位置绘制一条线
    Material mat;
    Vector3 startVertex;
    Vector3 mousePos;
    private void Start()
    {
        startVertex = Vector3.zero;
    }
    private void Update()
    {
        mousePos = Input.mousePosition;
        //按空格键更新startVertex
        if (Input.GetKeyDown(KeyCode.Space))
        {
            startVertex = new Vector3(mousePos.x / Screen.width, mousePos.y / Screen.height, 0);
        }
    }
    private void OnPostRender()
    {
        if (!mat)
        {
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            mat = new Material(shader);
        }
        GL.PushMatrix();
        mat.SetPass(0);
        GL.LoadOrtho();
        GL.Begin(GL.LINES);
        GL.Color(Color.red);
        GL.Vertex(startVertex);
        GL.Vertex(new Vector3(mousePos.x / Screen.width, mousePos.y / Screen.height, 0));
        GL.End();
        GL.PopMatrix();
    }
}

modelview:当前的模型视图矩阵.分配给此变量等效于OpenGL中的glLoadMatrix(mat);在其他图形API中,也有相似功能。更改modelview矩阵会覆盖当前相机的视图参数,因此大多数情况下,你可以使用GL.PushMatrix和GL.PopMatrix保存和还原矩阵。读取此变量将返回当前的模型视图矩阵。
函数定义:public static Matrix4x4 modelview;
QUADS:开始模式:绘制四边形。使用每组传递的4个顶点绘制四边形。如果传递4个顶点,将绘制一个四边形,其中每个顶点称为四边形的一个角。如果传递8个顶点,将绘制2个四边形。要设置2D绘图屏幕,使用GL.LoadOrho或GL.LoadPixelMatrix。要设置3D绘图屏幕,使用GL.LoadIdentity,然后使用GL.MultMatrix和所需的装换矩阵。
代码示例:
using UnityEngine;

//在屏幕上绘制红色菱形,并在左上角绘制一个小的青色四边形
public class GLTest : MonoBehaviour
{
    Material mat;
    private void OnPostRender()
    {
        if (!mat)
        {
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            mat = new Material(shader);
        }
        GL.PushMatrix();
        mat.SetPass(0);
        //0-1范围
        GL.LoadOrtho();
        GL.Begin(GL.QUADS);
        GL.Color(Color.red);
        GL.Vertex3(0, 0.5f, 0);
        GL.Vertex3(0.5f, 1, 0);
        GL.Vertex3(1, 0.5f, 0);
        GL.Vertex3(0.5f, 0, 0);
        GL.Color(Color.cyan);
        GL.Vertex3(0, 0, 0);
        GL.Vertex3(0, 0.25f, 0);
        GL.Vertex3(0.25f, 0.25f, 0);
        GL.Vertex3(0.25f, 0, 0);
        GL.End();
        GL.PopMatrix();
    }
}

sRGBWrite:控制在渲染时是否执行线性到sRGB的颜色转换。仅当使用"Linear Color Space(线性颜色空间)"渲染时,此属性才有意义。通常,当使用线性颜色空间时,非HDR渲染纹理被视为sRGB数据("常规颜色"),而片段着色器的输出被视为线性颜色值。因此,默认情况下,片段着色器的颜色值将转换为sRGB。但是,如果你知道片段着色器由于某种原因已经输出了sRGB颜色值,并且想要关闭"Linear-to-sRGB(线性到sRGB)"写入颜色转换,则可以使用此属性来实现。注意:并非所有平台都支持关闭sRGB写入的功能(通常"tile based"的移动手机的GPU无法做到),因此这被认为是"不得已的功能"。最好使用适当的颜色空间标记(线性vs sRGB)创建RenderTextures,而不要在渲染过程中将转换切换到其中。
函数定义:public static bool sRGBWrite;
TRIANGLE_STRIP:开始模式:绘制三角形线条。从起点到终点在所传递的每个顶点之间绘制三角形。如果传递五个顶点A,B,C,D和E,则会绘制三个三角形。第一个三角形绘制在前三个顶点之间。所有后续三角形均使用前两个顶点,再加上下一个附加顶点。在此示例中,三个绘制的三角形将是A,B,C,然后是B,C,D,最后是C,D,E.要设置2D绘图屏幕,使用GL.LoadOrho或GL.LoadPixelMatrix。要设置3D绘图屏幕,使用GL.LoadIdentity,然后使用GL.MultMatrix和所需的装换矩阵。
函数定义:public static int TRIANGLE_STRIP;
代码示例:
using UnityEngine;

//在屏幕左侧绘制2个看起来像正方形的三角形
public class GLTest : MonoBehaviour
{
    Material mat;
    private void OnPostRender()
    {
        if (!mat)
        {
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            mat = new Material(shader);
        }
        GL.PushMatrix();
        mat.SetPass(0);
        //0-1范围
        GL.LoadOrtho();
        GL.Begin(GL.TRIANGLE_STRIP);
        GL.Color(new Color(0,0,0,1));
        GL.Vertex3(0.25f, 0.5f, 0);
        GL.Vertex3(0, 0.5f, 0);
        GL.Vertex3(0.25f, 0.25f, 0);
        GL.Vertex3(0, 0.25f, 0);
        GL.End();
        GL.PopMatrix();
    }
}

TRIANGLES:开始模式:绘制三角形。使用每组3个顶点绘制三角形。如果传递3个顶点,则将绘制一个三角形,其中每个顶点变为该三角形的一个角。如果传递6个顶点,将绘制2个三角形。
函数定义:public static int TRIANGLES;
代码示例:
using UnityEngine;

public class GLTest : MonoBehaviour
{
    Material mat;
    private void OnPostRender()
    {
        if (!mat)
        {
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            mat = new Material(shader);
        }
        GL.PushMatrix();
        mat.SetPass(0);
        GL.LoadOrtho();
        GL.Begin(GL.TRIANGLES);
        GL.Vertex3(0, 0, 0);
        GL.Vertex3(1, 1, 0);
        GL.Vertex3(0, 1, 0);
        GL.End();
        GL.PopMatrix();
    }
}

wireframe:是否应该在线框中进行渲染。启用线框模式将影响呼叫后渲染的所有对象,知道你重新关闭线框。在Unity编辑器中,线框模式始终在重现绘制任何窗口之前关闭。注意:某些平台(例如移动平台OpenGL ES)不支持线框渲染。
函数定义:public static bool wireframe;
代码示例:
using UnityEngine;

//将此脚本附加到相机,这将使其在线框中渲染
public class GLTest : MonoBehaviour
{
    private void OnPreRender()
    {
        GL.wireframe = true;
    }
    private void OnPostRender()
    {
        GL.wireframe = false;
    }
}


(2)、Static Methods

Begin:开始绘制3D图元。在OpenGL中,它匹配glBegin;在其他图形API上,也有相应功能。在GL.Begin和GL.End之间,调用GL.Vertex,GL.Color,GL.TexCoord和其他即时模式绘制函数是有效的。
函数定义:public static void Begin(int mode)
函数参数:
mode:绘制图元:可以是TRIANGLES,TRIANGLE_STRIP,QUADS或LINES。
代码示例:
{
    Material mat;
    private void OnPostRender()
    {
        if (!mat)
        {
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            mat = new Material(shader);
        }
        GL.PushMatrix();
        mat.SetPass(0);
        GL.LoadOrtho();
        GL.Begin(GL.TRIANGLES);  //三角形
        GL.Color(new Color(1, 1, 1, 1));
        GL.Vertex3(0.50f, 0.25f, 0);
        GL.Vertex3(0.25f, 0.25f, 0);
        GL.Vertex3(0.375f, 0.5f, 0);
        GL.End();
        GL.Begin(GL.QUADS);    //四边形
        GL.Color(new Color(0.5f, 0.5f, 0.5f, 1));
        GL.Vertex3(0.5f, 0.5f, 0);
        GL.Vertex3(0.5f, 0.75f, 0);
        GL.Vertex3(0.75f, 0.75f, 0);
        GL.Vertex3(0.75f, 0.5f, 0);
        GL.End();
        GL.Begin(GL.LINES);  //线段
        GL.Color(new Color(0, 0, 0, 1));
        GL.Vertex3(0, 0, 0);
        GL.Vertex3(0.75f, 0.75f, 0);
        GL.End();
        GL.PopMatrix();
    }
}

Clear:清除当前渲染缓冲区。这将清除屏幕或你当前正在绘制的RenderTexture.在大多数情况下,某些摄像机正在某处绘制某些内容,并且可能已经使用天空盒的背景颜色清除了颜色缓冲区。清除区域受当前视口限制。此操作可能会更改模型/视图/投影矩阵。
函数定义:public static void Clear(bool clearDepth, bool clearColor, Color backgroundColor, float depth = 1.0f);
函数参数:
clearDepth:是否清除深度缓冲
clearColor:是否清除颜色缓冲
backgroundColor:如果clearColor为true,使用此颜色清除颜色缓冲区
depth:当clearDepth为true时,使用此深度值清除Z缓冲区的深度。有效范围是0(近平面)1(远平面)。该值与图形API无关:抽象层将转换该值以匹配当前使用的图形API
ClearWithSkybox:使用摄像机的天空盒清除当前渲染缓冲区。这会将天空盒绘制到屏幕或当前RenderTexture中。如果传递的相机没有自定义的Skybox组件,则将使用RenderSettings中的全局Skybox。
函数定义:public static void ClearWithSkybox(bool clearDepth, Camera camera)
函数参数:
clearDepth:是否清除深度缓冲区
camera:从此相机获取投影参数以及天空盒
Color:设置当前顶点颜色.在OpenGL中,相当于glColor4f(c.r,c.g,c.b,c.a);在其他图形API上,也有相似功能。
函数定义:public static void Color(Color c)
代码示例:
using UnityEngine;

//从屏幕的右下方到左上方绘制一条红线
//从屏幕的左下角到右上角的黄线
public class GLTest : MonoBehaviour
{
    Material mat;
    private void OnPostRender()
    {
        if (!mat)
        {
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            mat = new Material(shader);
        }
        GL.PushMatrix();
        mat.SetPass(0);
        GL.LoadOrtho();
        GL.Begin(GL.LINES);
        GL.Color(Color.red);
        GL.Vertex3(1, 0, 0);
        GL.Vertex3(0, 1, 0);
        GL.Color(Color.yellow);
        GL.Vertex3(0, 0, 0);
        GL.Color(Color.blue);
        GL.Vertex3(1, 1, 0);
        GL.End();
        GL.PopMatrix();
    }
}

End:结束绘制3D图元。在OpenGL中,它对应glEnd函数,在其他图形API中,也有相似功能。
函数定义:public static void End()
Flush:将驱动程序命令缓冲区中排队的命令发送到GPU.Direct3D 11是当前使用的图形API时,此函数对应ID3D11DeviceContext::Flush。当Direct3D 12是当前使用的图形API时,执行挂起的命令列表。当OpengGL是当前使用的图形API时,此调用将映射到glFlush.
GetGPUProjectionMatrix:根据相机的投影矩阵计算GPU投影矩阵。在Unity中,投影矩阵遵循OpenGL约定。但是,在某些平台上,必须对其进行一些转换以匹配本机API要求。使用此函数可以计算最终投影矩阵的样子。该值将与着色器中的UNITY_MATRIX_P矩阵匹配。如果打算使用此投影矩阵渲染RenderTexture,则renderIntoTexture值应设置为true.在某些平台上,它影响最终矩阵的外观。
函数定义:public static Matrix4x4 GetGPUProjectionMatrix(Matrix4x4 proj, bool renderIntoTexture);
函数参数:
proj: 源投影矩阵
renderIntoTexture:该投影将用于渲染到RenderTexture吗?
函数返回值:
Matrix4x4:为当前图形API调整的投影矩阵
InvalidateState:使内部缓存的呈现状态无效。这会使当前使用的图形API的所有缓存渲染状态无效。例如:如果(本机)插件更改了渲染状态设置,则必须调用此函数让Unity的渲染引擎意识到这一点。
函数定义:public static void InvalidateState();
IssuePluginEvent:将用户定义的事件发送到本机代码插件。如果平台和可用CPU的数量允许,则Unity中的渲染可以是多线程的。使用多线程渲染时,渲染API命令发生在与运行脚本的线程完全独立的线程上。因此,你的插件无法立即开始渲染,因为它可能会干扰渲染线程当前的操作。为了从插件进行任何渲染,可以从脚本中调用GL.IssuePluginEvent,这可以让渲染线程调用本机插件。例如,如果从摄像机的OnPostRender函数调用GL.IssuePluginEvent,则在摄像机完成渲染后会立即收到插件回调。回调必须是void UNITY_INTERFACE_API UnityRenderingEvent(int eventId)格式的函数。
函数定义:public static void IssuePluginEvent(IntPtr callback, int eventID);
函数参数:
eventID:用户定义的ID,以发送到回调
callback:Unity渲染器调用的本地回调队列
LoadIdentity:将单位矩阵加载到当前的模型视图矩阵。此功能会覆盖当前相机的视图参数,可以使用GL.PushMatrix和GL。PopMatrix保存和还原矩阵。
函数定义:public static void LoadIdentity();
LoadOrtho:辅助功能可以用于设置正交透视变换。调用LoadOrho之后,查看视椎从(0,0,-1)变为(1,1,100).LoadOrtho可用于以2D形式绘制图元。
函数定义:public static void LoadOrtho()
代码示例:
using UnityEngine;

//在已经绘制的三角形上绘制一个三角形
public class GLTest : MonoBehaviour
{
    Material mat;
    private void OnPostRender()
    {
        if (!mat)
        {
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            mat = new Material(shader);
        }
        GL.PushMatrix();
        mat.SetPass(0);
        //原点在左下角,x轴与y轴的最大值是1
        GL.LoadOrtho();
        GL.Begin(GL.TRIANGLES);
        GL.Color(Color.red);
        GL.Vertex3(0f, 0f, 0);
        GL.Vertex3(0.25f, 0f, 0);
        GL.Vertex3(0f, 0.25f, 0);
        GL.End();
        GL.Begin(GL.TRIANGLES);
        GL.Color(Color.yellow);
        GL.Vertex3(0f, 0f, 1);
        GL.Vertex3(0.25f, 0f, -1);
        GL.Vertex3(0f, 0.25f, -1);
        GL.End();
        GL.PopMatrix();
    }
}

LoadPixelMatrix:设置矩阵(MVP)让像素能正确渲染。
函数定义:
public static void LoadPixelMatrix():这将设置模型视图和投影矩阵,以便X,Y坐标直接映射到像素。(0,0)在当前摄像机视口的左下角,Z坐标从-1+1
public static void LoadPixelMatrix(float left, float right, float bottom, float top):这将设置模型视图和投影矩阵,以便X,Y坐标直接映射到像素。(左、底部在当前摄像机的视口的左下角;(右上)在当前摄像机的视口的右上角。Z坐标从-1+1)。此功能会覆盖当前相机的参数,因此大多数情况下,可以使用GL.PushMatrix和GL.PopMatrix保存和还原矩阵。
代码示例:
using UnityEngine;

//在观察坐标系绘制红色三角形
public class GLTest : MonoBehaviour
{
    Material mat;
    private void OnPostRender()
    {
        if (!mat)
        {
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            mat = new Material(shader);
        }
        GL.PushMatrix();
        mat.SetPass(0);
        //MVP:屏幕空间
        GL.LoadPixelMatrix();
        GL.Begin(GL.TRIANGLES);
        GL.Color(Color.red);
        GL.Vertex3(0f, 0f, 0);
        GL.Vertex3(0f, Screen.height / 2, 0);
        GL.Vertex3(Screen.width / 2, Screen.height / 2, 0);
        GL.End();
        GL.Begin(GL.TRIANGLES);
        GL.Color(Color.red);
        GL.Vertex3(Screen.width, Screen.height, 0);
        GL.Vertex3(Screen.width, Screen.height / 2, 0);
        GL.Vertex3(Screen.width / 2, Screen.height / 2, 0);
        GL.End();
        GL.PopMatrix();
    }
}

LoadProjectionMatrix:将任意矩阵加载到当前的投影矩阵(P).此功能会覆盖当前相机的参数,因此大多数情况下,可以使用GL.PushMatrix和GL.PopMatrix保存和还原矩阵。
函数定义:public static void LoadProjectionMatrix(Matrix4x4 mat)
代码示例:
using UnityEngine;

//在观察坐标系绘制红色三角形
public class GLTest : MonoBehaviour
{
    Matrix4x4 projMtrx = Matrix4x4.identity;
    Material mat;
    private void OnPostRender()
    {
        if (!mat)
        {
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            mat = new Material(shader);
        }
        GL.PushMatrix();
        mat.SetPass(0);
        //P:裁剪空间
        GL.LoadProjectionMatrix(projMtrx);
        GL.Begin(GL.TRIANGLES);
        GL.Color(Color.red);
        //由于是单位矩阵,故Matrix4x4.identity * Vector3 = Vecto3可得裁剪空间坐标
        //然后根据(clip.x / (2 * clip.w) + 1/2) * pixelWidth可得屏幕坐标
        GL.Vertex3(-1f, -1f, 0);
        GL.Vertex3(-1f, 0f, 0);
        GL.Vertex3(0f, -1f, 0);
        GL.End();
        GL.PopMatrix();
    }
}

MultiTexCoord:将当前纹理坐标(v.x, v.y, v.z)设置为实际纹理单位.在OpenGL中,如果可以使用多种纹理,可调用glMultiTexCoord与给定的纹理单位匹配。在其他图形API上,也有此类似功能。Z坐标仅在以下情况下使用:1.访问一个立方体贴图(使用矢量坐标来访问,因此为x,y&z). 2.进行"projective texturing(纹理投影映射)",需使用x和y坐标除以z得到最终坐标。反射水等功能会用到。该函数只能在GL.Begin和GL.End函数之间调用。
函数定义:public static void MultiTexCoord(int unit, Vector3 v);
代码示例:
using UnityEngine;

//在按下空格键是分配给材质的两个纹理之间的变化
public class GLTest : MonoBehaviour
{
    Material mat;
    bool flagTex = true;
    private void Update()
    {
        if(Input.GetKeyDown(KeyCode.Space))
        {
            if (flagTex)
                flagTex = false;
            else
                flagTex = true;
        }
    }
    private void OnPostRender()
    {
        if (!mat)
        {
            Debug.LogError("Please Assign a material on the inspector");
            return;
        }
        GL.PushMatrix();
        mat.SetPass(0);
        GL.LoadOrtho();
        GL.Begin(GL.QUADS);
        if (flagTex)
        {
            GL.MultiTexCoord(0, new Vector3(0, 0, 0)); //main texture
        }
        else
        {
            GL.MultiTexCoord(1, new Vector3(0, 0, 0)); //second texture
        }
        GL.Vertex3(0.25f, 0.25f, 0);
        if (flagTex)
        {
            GL.MultiTexCoord(0, new Vector3(0, 1, 0));
        }
        else
        {
            GL.MultiTexCoord(1, new Vector3(0, 1, 0));
        }
        GL.Vertex3(0.75f, 0.75f, 0);
        if (flagTex)
        {
            GL.MultiTexCoord(0, new Vector3(1, 0, 0));
        }
        else
        {
            GL.MultiTexCoord(1, new Vector3(1, 0, 0));
        }
        GL.Vertex3(0.75f, 0.25f, 0);
        GL.End();
        GL.PopMatrix();
    }
}
MultiTexCoord2:为实际纹理单位设置当前纹理坐标(x, y).在OpenGL中,如果可以使用多种纹理,可调用glMultiTexCoord与给定的纹理单位匹配。在其他图形API上,也有此类似功能。该函数只能在GL.Begin和GL.End函数之间调用。
函数定义:pbulic static void MultiTexCoord2(int unit, float x, float y)
代码示例:
using UnityEngine;

public class Example : MonoBehaviour
{
    // Changes between two textures assigned to a material
    // When pressed space
    Material mat;
    bool flagTex = true;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (flagTex)
            {
                flagTex = false;
            }
            else
            {
                flagTex = true;
            }
        }
    }

    void OnPostRender()
    {
        if (!mat)
        {
            Debug.LogError("Please Assign a material on the inspector");
            return;
        }
        GL.PushMatrix();
        mat.SetPass(1);
        GL.LoadOrtho();
        GL.Begin(GL.QUADS);
        if (flagTex)
        {
            GL.MultiTexCoord2(0, 0, 0); // main texture
        }
        else
        {
            GL.MultiTexCoord2(1, 0, 0); // second texture
        }
        GL.Vertex3(0.25f, 0.25f, 0);
        if (flagTex)
        {
            GL.MultiTexCoord2(0, 0, 1);
        }
        else
        {
            GL.MultiTexCoord2(1, 0, 1);
        }
        GL.Vertex3(0.25f, 0.75f, 0);
        if (flagTex)
        {
            GL.MultiTexCoord2(0, 1, 1);
        }
        else
        {
            GL.MultiTexCoord2(1, 1, 1);
        }
        GL.Vertex3(0.75f, 0.75f, 0);
        if (flagTex)
        {
            GL.MultiTexCoord2(0, 1, 0);
        }
        else
        {
            GL.MultiTexCoord2(1, 1, 0);
        }
        GL.Vertex3(0.75f, 0.25f, 0);
        GL.End();
        GL.PopMatrix();
    }
}
MultiTexCoord3:将当前纹理坐标(x,y,z)设置为实际纹理。在OpenGL中,如果可以使用多种纹理,可调用glMultiTexCoord与给定的纹理单位匹配。在其他图形API上,也有此类似功能。Z坐标仅在以下情况下使用:1.访问一个立方体贴图(使用矢量坐标来访问,因此为x,y&z). 2.进行"projective texturing(纹理投影映射)",需使用x和y坐标除以z得到最终坐标。反射水等功能会用到。该函数只能在GL.Begin和GL.End函数之间调用。
函数定义:public static void MultiTexCoord3(int unit, float x, float y, float z);
代码示例:
using UnityEngine;

public class Example : MonoBehaviour
{
    // Changes between two textures assigned to a material
    // When pressed space
    Material mat;
    bool flagTex = true;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (flagTex)
            {
                flagTex = false;
            }
            else
            {
                flagTex = true;
            }
        }
    }

    void OnPostRender()
    {
        if (!mat)
        {
            Debug.LogError("Please Assign a material on the inspector");
            return;
        }
        GL.PushMatrix();
        mat.SetPass(1);
        GL.LoadOrtho();
        GL.Begin(GL.QUADS);
        if (flagTex)
        {
            GL.MultiTexCoord3(0, 0, 0, 0); // main texture
        }
        else
        {
            GL.MultiTexCoord3(1, 0, 0, 0); // second texture
        }
        GL.Vertex3(0.25f, 0.25f, 0);
        if (flagTex)
        {
            GL.MultiTexCoord3(0, 0, 1, 0);
        }
        else
        {
            GL.MultiTexCoord3(1, 0, 1, 0);
        }
        GL.Vertex3(0.25f, 0.75f, 0);
        if (flagTex)
        {
            GL.MultiTexCoord3(0, 1, 1, 0);
        }
        else
        {
            GL.MultiTexCoord3(1, 1, 1, 0);
        }
        GL.Vertex3(0.75f, 0.75f, 0);
        if (flagTex)
        {
            GL.MultiTexCoord3(0, 1, 0, 0);
        }
        else
        {
            GL.MultiTexCoord3(1, 1, 0, 0);
        }
        GL.Vertex3(0.75f, 0.25f, 0);
        GL.End();
        GL.PopMatrix();
    }
}
MultMatrix:将当前的模型视图矩阵(MV)设置为指定的矩阵(观察空间). 此方法等效于OpenGL中的glLoadMatrix(mat)。在其他图形API中,将仿真相应的功能。由于更改模型视图矩阵会覆盖当前摄像机的视图参数,可以使用GL.PushMatrix和GL.PopMatrix保存和还原矩阵。
函数定义:public static void MultMatrix(Matrix4x4 m)
PopMatrix:从矩阵堆栈的顶部还原投影和MV矩阵。由于更改模型视图矩阵会覆盖当前摄像机的视图参数,可以使用GL.PushMatrix和GL.PopMatrix保存和还原矩阵。
函数定义:public static void PopMatrix();
代码示例:
using UnityEngine;

//从屏幕的左下角到右上角画一条横线
public class GLTest : MonoBehaviour
{
    Material mat;
    private void OnPostRender()
    {
        if (!mat)
        {
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            mat = new Material(shader);
        }
        GL.PushMatrix();  //保存当前状态
        mat.SetPass(0);
        //MVP:屏幕空间
        GL.LoadPixelMatrix();
        GL.Begin(GL.LINES);
        GL.Color(Color.red);
        GL.Vertex3(0f, 0f, 0);
        GL.Vertex3(Screen.width, Screen.height, 0);
        GL.End();
        GL.PopMatrix(); //恢复状态
    }
}
PushMatrix:将投影矩阵和模型视图矩阵都保存到矩阵堆栈中。由于更改模型视图矩阵会覆盖当前摄像机的视图参数,可以使用GL.PushMatrix和GL.PopMatrix保存和还原矩阵。
函数定义:public static void PushMatrix();
RenderTargetBarrier:解析渲染目标,以从中进行后续采样操作。目前,OpenGL的Blend操作是唯一需要解析的情况。
函数定义:public static void RenderTargetBarrier();
TexCoord:为所有纹理单位设置当前纹理坐标(v.x,v.y,v.z)。在OpenGL中,在有多重纹理的情况下,可调用glMultiTexCoord与给定的纹理单位匹配,否则使用glTexCoord。在其他图形API上,也有此类似功能。Z坐标仅在以下情况下使用:1.访问一个立方体贴图(使用矢量坐标来访问,因此为x,y&z). 2.进行"projective texturing(纹理投影映射)",需使用x和y坐标除以z得到最终坐标。反射水等功能会用到。该函数只能在GL.Begin和GL.End函数之间调用。
函数定义:public static void TexCoord(Vector3 v);
代码示例:
using UnityEngine;

//在屏幕中间绘制一个四边形,并向其添加材质的纹理
public class GLTest : MonoBehaviour
{
    Material mat;
    private void OnPostRender()
    {
        if (!mat)
        {
            Debug.LogError("Please Assign a material on the inspector");
            return;
        }
        GL.PushMatrix();  
        mat.SetPass(0);
        GL.LoadOrtho();
        GL.Begin(GL.QUADS);
        GL.TexCoord(new Vector3(0, 0, 0));
        GL.Vertex3(0.25f, 0.25f, 0);
        GL.TexCoord(new Vector3(0, 1, 0));
        GL.Vertex3(0.25f, 0.75f, 0);
        GL.TexCoord(new Vector3(1, 0, 0));
        GL.Vertex3(0.75f, 0.25f, 0);
        GL.End();
        GL.PopMatrix(); 
    }
}
TexCoord2:为所有纹理单位设置当前纹理坐标(x, y).在OpenGL中,在有多重纹理的情况下,可调用glMultiTexCoord与给定的纹理单位匹配,否则使用glTexCoord。在其他图形API上,也有此类似功能。
函数定义: public static void TexCoord2(float x, float y);
代码示例:
using UnityEngine;

public class Example : MonoBehaviour
{
    // Draws a Quad in the middle of the screen and
    // Adds the material's Texture to it.

    Material mat;
    void OnPostRender()
    {
        if (!mat)
        {
            Debug.LogError("Please Assign a material on the inspector");
            return;
        }
        GL.PushMatrix();
        mat.SetPass(1);
        GL.LoadOrtho();
        GL.Begin(GL.QUADS);
        GL.TexCoord2(0, 0);
        GL.Vertex3(0.25f, 0.25f, 0);
        GL.TexCoord2(0, 1);
        GL.Vertex3(0.25f, 0.75f, 0);
        GL.TexCoord2(1, 1);
        GL.Vertex3(0.75f, 0.75f, 0);
        GL.TexCoord2(1, 0);
        GL.Vertex3(0.75f, 0.25f, 0);
        GL.End();
        GL.PopMatrix();
    }
}
TexCoord3:为所有纹理单位设置当前纹理坐标(x,y,z)。在OpenGL中,在有多重纹理的情况下,可调用glMultiTexCoord与给定的纹理单位匹配,否则使用glTexCoord。在其他图形API上,也有此类似功能。Z坐标仅在以下情况下使用:1.访问一个立方体贴图(使用矢量坐标来访问,因此为x,y&z). 2.进行"projective texturing(纹理投影映射)",需使用x和y坐标除以z得到最终坐标。反射水等功能会用到。该函数只能在GL.Begin和GL.End函数之间调用。
函数定义:public static void TexCoord3(float x, float y, float z)
代码示例:
using UnityEngine;

public class Example : MonoBehaviour
{
    // Draws a Quad in the middle of the screen and
    // Adds the material's Texture to it.

    Material mat;
    void OnPostRender()
    {
        if (!mat)
        {
            Debug.LogError("Please Assign a material on the inspector");
            return;
        }
        GL.PushMatrix();
        mat.SetPass(1);
        GL.LoadOrtho();
        GL.Begin(GL.QUADS);
        GL.TexCoord3(0, 0, 0);
        GL.Vertex3(0.25f, 0.25f, 0);
        GL.TexCoord3(0, 1, 0);
        GL.Vertex3(0.25f, 0.75f, 0);
        GL.TexCoord3(1, 1, 0);
        GL.Vertex3(0.75f, 0.75f, 0);
        GL.TexCoord3(1, 0, 0);
        GL.Vertex3(0.75f, 0.25f, 0);
        GL.End();
        GL.PopMatrix();
    }
}
Vertex:提交一个顶点。在OpenGL中,它匹配glVertex3f(v.x,v.y,v.z);在其他图形API上,也有类似功能。该函数只能在GL.Begin和GL.End函数之间调用.
函数定义:public static void Vertex(Vector3 v)
代码示例:
using UnityEngine;

public class Example : MonoBehaviour
{
    // Draws a line from the bottom right
    // to the top left of the Screen
    // Using GL.Vertex
    Material mat;

    void OnPostRender()
    {
        if (!mat)
        {
            Debug.LogError("Please Assign a material on the inspector");
            return;
        }
        GL.PushMatrix();
        mat.SetPass(0);
        GL.LoadOrtho();
        GL.Begin(GL.LINES);
        GL.Vertex(new Vector3(1, 0, 0));
        GL.Vertex(new Vector3(0, 1, 0));
        GL.End();
        GL.PopMatrix();
    }
}
Vertex3:提交一个顶点。在OpenGL中,它匹配glVertex3f(v.x,v.y,v.z);在其他图形API上,也有类似功能。该函数只能在GL.Begin和GL.End函数之间调用.
函数定义:public static void Vertex3(float x, float y, float z);
代码示例:
using UnityEngine;

public class Example : MonoBehaviour
{
    // Draws a line from the bottom right
    // to the top left of the Screen
    // Using GL.Vertex
    Material mat;

    void OnPostRender()
    {
        if (!mat)
        {
            Debug.LogError("Please Assign a material on the inspector");
            return;
        }
        GL.PushMatrix();
        mat.SetPass(0);
        GL.LoadOrtho();
        GL.Begin(GL.LINES);
        GL.Vertex3(0, 0, 0);
        GL.Vertex3(1, 1, 0);
        GL.End();
        GL.PopMatrix();
    }
}
Viewport:设置渲染视口。所有渲染都被限制在传递的pixelRect内部。如果修改了视口,则会拉伸其中的所有渲染内容。
函数定义:public static void Viewport(Rect pixelRect)
代码示例1using UnityEngine;

//绘制一个覆盖视口区域的红色四边形。
//当按下空格键视口内容会扩展到整个屏幕
//并且内容可能会被拉伸。
public class GLTest : MonoBehaviour
{
    Material mat;
    bool stretch = false;
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (stretch)
            {
                stretch = false;
            }
            else
            {
                stretch = true;
            }
        }
    }
    private void OnPostRender()
    {
        if (!mat)
        {
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            mat = new Material(shader);
        }
        GL.PushMatrix();  
        mat.SetPass(0);
        GL.LoadPixelMatrix();
        if (stretch)
        {
            GL.Viewport(new Rect(0, 0, Screen.width, Screen.height));
        }
        else
        {
            GL.Viewport(new Rect(0, 0, Screen.width / 2, Screen.height));
        }
        GL.Begin(GL.QUADS);
        GL.Color(Color.red);
        //从屏幕坐标映射到视口坐标?
        GL.Vertex3(0, 0, 0);
        GL.Vertex3(0, Screen.height, 0);
        GL.Vertex3(Screen.width, Screen.height, 0);
        GL.Vertex3(Screen.width, 0, 0);
        GL.End();
        GL.Begin(GL.TRIANGLES);
        GL.Vertex3(Screen.width / 2, Screen.height / 4, 1);
        GL.Vertex3(Screen.width / 4, Screen.height / 2, 1);
        GL.Vertex3(Screen.width - Screen.width / 4, Screen.height / 2, 1);
        GL.End(); 
        GL.PopMatrix(); 
    }
}

代码示例2(显示结果与代码示例1一致)
using UnityEngine;

//绘制一个覆盖视口区域的红色四边形。
//当按下空格键视口内容会扩展到整个屏幕
//并且内容可能会被拉伸。
public class GLTest : MonoBehaviour
{
    Material mat;
    bool stretch = false;
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (stretch)
            {
                stretch = false;
            }
            else
            {
                stretch = true;
            }
        }
    }
    private void OnPostRender()
    {
        if (!mat)
        {
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            mat = new Material(shader);
        }
        GL.PushMatrix();  
        mat.SetPass(0);
        GL.LoadOrtho();
        if (stretch)
        {
            GL.Viewport(new Rect(0, 0, Screen.width, Screen.height));
        }
        else
        {
            GL.Viewport(new Rect(0, 0, Screen.width / 2, Screen.height));
        }
        GL.Begin(GL.QUADS);
        GL.Color(Color.red);
        GL.Vertex3(0, 0, 0);
        GL.Vertex3(0, 1, 0);
        GL.Vertex3(1, 1, 0);
        GL.Vertex3(1, 0, 0);
        GL.End();
        GL.Begin(GL.TRIANGLES);
        GL.Vertex3(0.5f, 0.25f, 0);
        GL.Vertex3(0.25f, 0.5f, 0);
        GL.Vertex3(0.75f, 0.5f, 0);
        GL.End();
        GL.PopMatrix(); 
    }
}



二、Graphics
(1)、描述
  Unity绘图功能的原始接口。
  这是Unity优化过的网格绘图功能的高级快捷方式。

(2)、Static Properties

activeColorBuffer:当前使用的颜色缓冲区(只读)。
函数定义:public static RenderBuffer activeColorBuffer
activeColorGamut:返回当前使用的色域。当前使用的色域不会在中间帧修改。
函数定义:public static ColorGamut activeColorGamut.
activeDepthBuffer:当前使用的深度/模板缓冲区(只读)。
函数定义:public static RenderBuffer activeDepthBuffer
activeTier:当前设备使用的gpu分类。更改此值会影响所有随后加载的shader。此值最开始是通过检测使用的硬件赋值的。
函数定义:public static Rendering.GraphicsTier activeTier
preserveFramebufferAlpha:若启用Player Settings.preserveFramebufferAlpha(将alpha值保留在帧缓冲区中,仅支持安卓),则为true(只读)。
函数定义:public static bool preserveFramebufferAlpha;

(3)、Static Meth

Blit:将源纹理复制到目标中,以使用着色器渲染纹理。这主要用于实现后处理效果。Blit将dest设置为渲染目标,在材质上设置source_MainTex属性,并绘制全屏四边形。如果dest为null,则将屏幕后缓冲区用作blit目标,除非当前将主摄像机设置为渲染RenderTexture模式(即Camera.main的targetTexture不为null).在这种情况下,blit将主相机的targetTexture用作dest输出。为了确保blit实际上是对屏幕后缓冲区执行的,需确保在调用Blit之前,将Camera.main.targetTexture设置为null。
注意:如果要使用源纹理的深度或模板缓冲区,则必须手动执行Blit功能的等效操作。例如使用Graphics.SetRenderTarget设置目标颜色缓冲区以及源深度缓冲区,设置正交投影(GL.LoadOrtho),这是材质使用的pass(Material.SetPass)并绘制四边形(GL.Begin)。
注意:在线性颜色空间中,需设置正确的sRGB<->Linear颜色转换状态,否则可能得到错误的结果。在进行Blit或任何其他手动渲染之前,可根据需要设置GL.sRGBWrite。
注意:将source和dest设置为相同的RenderTexture的Blit调用可能会导致未定义的行为。最好将自定义的RenderTexture与双缓冲一起使用,或者使用两个RenderTexture在它们之间进行交替替换,手动实现双缓冲。
函数定义:
public static void Blit(Texture source, RenderTexture dest);
public static void Blit(Texture source, RenderTexture dest, Material mat, int pass = -1);
public static void Blit(Texture source, Material mat, int pass = -1);
public static void Blit(Texture source, RenderTexture dest, Vector2 scale, Vector2 offset);
public static void Blit(Texture source, RenderTexture dest, int sourceDepthSlice, int destDepthSlice);
public static void Blit(Texture source, Material mat, int pass, int destDepthSlice);
public static void Blit(Texture source, RenderTexture dest, Vector2 scale, Vector2 offset, int sourceDepthSlice, int destDepthSlice);
函数参数:
1.source:源纹理
2.dest:目标RenderTexture.将此值设置为null可直接将其显示在屏幕上。
3.mat:使用的材质。可用此材质的shader做一些后处理效果。
4.pass:如果为-1(默认),则绘制材质中的所有Pass,否则只绘制给定pass
5.offset:源纹理的UV偏移
6.scale:源纹理的UV缩放
7.sourceDepthSlice:用于执行blit的纹理数组源切片
8.destDepthSlice:用于执行blit的纹理数组目标切片
代码示例:
using UnityEngine;

//将纹理赋值到rTex并在所有摄像机中显示
public class GraphicsTest : MonoBehaviour {
    public Texture aTexture;
    public RenderTexture rTex;
    private void Start()
    {
        if(!aTexture || !rTex)
        {
            Debug.LogError("A texture or a render texture are missing, assign them");
        }
    }
    private void Update()
    {
        Graphics.Blit(aTexture, rTex);
    }
}
BlitMultiTap:将源纹理复制到目标纹理,供multi-tap shader使用。这主要用于实现某些后处理效果。例如高斯或迭代锥形模糊可在多个不同位置取样源纹理。BlitMultiTap将dest设置为当前RenderTexture,将source设置为材质上的_MainTex属性,并绘制全屏四边形。方形的每个顶点都设置了多个纹理坐标,且每个坐标通过offset像素偏移。BlitMultiTap具有与Graphics.Blit相同的限制。
函数定义:
public static void BlitMultiTap(Texture source, RenderTexture dest, Material mat, params Vector2[] offsets);
public static void BlitMultiTap(Texture source, RenderTexture dest, Material mat, int destDepthSlice, params Vector2[] offsets);
函数参数:
1.source:源纹理
2.dest:目标RenderTexture,如果为null则直接将其显示在屏幕上。
3.mat:用于渲染目标RenderTexture的材质,材质的shader应具有一些后处理效果
4.offsets:可变数量的过滤偏移量。偏移量以像素为单位。
5.destDepthSlice:blit的目标纹理数组切片
ClearRandomWriteTargets:清除Shader Model4.5级别片元着色器的随机写入目标。此函数清除先前使用SetRandomWriteTarget设置的所有"random write(随机写入)"目标。
函数定义:public static void ClearRandomWriteTargets();
ConvertTexture:此功能提供了一种在不同格式和尺寸的纹理之间进行转换的有效方法。目标纹理格式应未压缩,并且其RenderTextureFormat受支持。当前支持的是2D和cubemap纹理作为源纹理,以及2D,cubemap,2d数组和cubemap数组纹理作为目标纹理。注意:由于API的限制,DX9以及Mac+OpenGL不支持此功能。
函数定义:
public static bool ConvertTexture(Texture src, Texture dst);
public static bool ConvertTexture(Texture src, int srcElement, Texture dst, int dstElement);
函数参数:
src:源纹理
dst:目标纹理
srcElement:源纹理类型(例如:cubemap face)。对于2D源纹理,将其设置为0.
dstElement:目标纹理类型(例如:cubemap face或texture array)
CopyTexture:复制纹理内容。此功能允许将像素数据有效地从一种纹理复制到另一种纹理。它还允许从不同类型的纹理类型(例如:cubemap face)或特定的mip级别以及纹理的子区域进行复制。复制不做任何缩放,即源纹理与目标纹理的大小必须相同。且纹理格式应该兼容(例如:TextureFormat.ARGB32和RenderTextureFormat.ARGB32)。兼容格式的确切规则在图形API之间有所不同。通常,完全相同的格式始终可以复制。在某些平台(例如D3D11)上,你也可以在位宽相同的格式之间进行复制。压缩纹理格式对具有区域变体的CopyTexture添加了一些限制。例如:不支持PVRTC格式,因为他们不是基于块的(对于这些格式,你只能复制整个纹理或整个Mip级别)。对于基于块的格式(例如DXT,ETC),区域大小和坐标必须是压缩块大小的倍数(DXT为4像素)。如果源纹理和目标纹理都被标记为"可读"(即,系统内存中存在数据副本,可以在CPU上进行读取/写入),这些功能也会对其进行复制。某些平台可能没有各种纹理复制功能(例如:从渲染纹理复制到常规纹理).可以使用SystemInfo.copyTextureSupport进行检查。在CopyTexture之后,调用CopyTexture2D.Apply,Texture2DArray.Apply或Texture3D.Applay会产生未定义结果,因为CopyTexture仅对GPU端进行操作,而Apply将数据从CPU传递到GPU端。
函数定义:
public static void CopyTexture(Texture src, Texture dst);
public static void CopyTexture(Texture src, int srcElement, int srcMip, Texture dst, int dstElement, int dstMip);
public static 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);
函数参数:
1.src:源纹理
2.dst:目标纹理
3.srcElement:源纹理类型(cubemap face, texture array或者3D texture depth slice)
4.srcMip:源纹理mipmap级别
5.dstElement:目标纹理类型(cubemap face, texture array或者3D texture depth slice)
6.srcX:要复制的源纹理区域的X坐标(左侧为0)
7.srcY:要复制的源纹理区域的Y坐标(底部为0)
8.srcWidth:要复制的源纹理区域的宽度
9.srcHeight:要复制的源纹理区域的高度
10.dstX:要复制的目标纹理区域的X坐标(左侧为0)
11.dstY:要复制的目标纹理区域的Y坐标(底部为0)
CreateAsyncGraphicsFence:以GraphicsFenceType.AsyncQueueSynchronization作为第一个参数调用Graphics.CreateGraphicsFence的快捷方式。
函数定义:
public static Rendering.GraphicsFence CreateAsyncGraphicsFence(Rendering.SynchronisationStage stage = SynchronisationStage.PixelProcessing)
public static Rendering.GraphicsFence CreateAsyncGraphicsFence();
函数参数:
stage:同步阶段
函数返回值:
GraphicsFence:返回一个新的GraphicsFence对象
CreateGraphicsFence:创建GraphicsFence,在GPU上完成此调用之前的最后一个Blit,Clear,Draw,Dispatch或Texture Copy命令之后,将传递此GraphicsFence.
函数定义:
Graphics.CreateGraphicsFence(GraphicsFenceType, SynchronisationStage)
函数参数:
1.fenceType:要创建的GraphicsFence的类型。当前唯一支持的值是GraphicsFenceType.AsyncQueueSynchronization
2.stage:在某些平台上,对于给定的绘制调用,顶点处理完成与像素处理完成开始之间存在很大的差距。此参数允许在进行绘制的顶点或像素处理完成之后通过fence.如果compute shader调度是最后提交的任务,则将忽略此参数。
DrawMesh:绘制一个Mesh。DrawMesh绘制一帧mesh。mesh将受到灯光的影响,可以投射和接收阴影,并受到Projectors的影响-就像它是某些游戏对象的一部分一样。它可以被所有摄像机绘制,可以只被特定的摄像机绘制。在需要绘制大量网格物体,但又不希望创建和管理游戏对象的开销的情况下,可使用DrawMesh.注意:DrawMesh不会立即绘制mesh.它只是"submits(提交)"以进行渲染。mesh将作为正常渲染过程的一部分进行渲染。如果要立即绘制mesh,可使用Graphics.DrawMeshNow。由于DrawMesh不会立即绘制mesh,因此在调用此函数之间修改材质属性,不会让mesh接收到此改变。如果要绘制一系列使用相同材质单属性稍有不同的mesh(例如:更改每个mesh的颜色),可使用MaterialPropertyBlock参数。注意:当mesh排队等待渲染时,此调用将创建一些内部资源。分配资源会立即进行,并将一直保留到帧结束(如果对象已为所有摄像机排队)或直到指定的摄像机进行渲染。
函数定义:
public static void DrawMesh(Mesh mesh,Vector3 position,Quaternion rotation,Material material,int layer,Camera camera = null, int submeshIndex = 0, MaterialPropertyBlock properties = null, bool castShadows = true, bool receiveShadows = true, bool useLightProbes = true);
public static void DrawMesh(Mesh mesh,Vector3 position,Quaternion rotation,Material material,int layer,Camera camera = null, int submeshIndex = 0, MaterialPropertyBlock properties, Rendering.ShadowCastingMode castShadows, bool receiveShadows = true, Transform probeAnchor = null, bool useLightProbes = true);
public static void DrawMesh(Mesh mesh,Matrix4x4 matrix,Material material,int layer,Camera camera = null, int submeshIndex = 0, MaterialPropertyBlock properties = null, bool castShadows = true, bool receiveShadows = true, bool useLightProbes = true);
public static 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);
public static void DrawMesh(Mesh mesh,Matrix4x4 matrix,Material material,int layer,Camera camera, int submeshIndex, MaterialPropertyBlock properties, Rendering.ShadowCastingMode castShadows, bool receiveShadows = true, Transform probeAnchor , bool useLightProbes, LightProbeProxyVolume lightProbeProxyVolume = null);
函数参数:
mesh:绘制的mesh
position:mesh的position
rotation:mesh的Rotation
material:使用的材质
layer:使用的Layer
camera:如果为null(默认值),则将在所有摄像机中绘制网格。否则仅在给定的相机中渲染
submeshIndex:要绘制的mesh的子mesh。这仅适用于由多个材质的mesh
properties:在绘制mesh前,设置材质的属性值,可参照:MaterialPropertyBlock
castShadows:设置mesh是否可以投射阴影
receiveShadows:设置mesh是否可以接收阴影
useLightProbes:mesh是否使用light probes
probeAnchor:如果使用light probes,则mesh将使用此Transform的位置来采样light probes并找到匹配的reflection probe。
lightProbeUsage:mesh的LightProbeUsage
代码示例:
using UnityEngine;

public class GraphicsTest : MonoBehaviour {
    public Mesh mesh;
    public Material material;
    private void Update()
    {
        //将使mesh显示在场景中的原点位置
        Graphics.DrawMesh(mesh, Vector3.zero, Quaternion.identity, material, 0);
    }
}
DrawMeshInstanced:使用GPU Instanced多次绘制相同的mesh。与Graphics.DrawMesh相似,此函数绘制一帧网格,而没有创建不必要的游戏对象开销。在使用Instanced shader绘制相同mesh的情况下,可使用此函数。但是不会进行视椎剔除以及bake oc的遮挡剔除,也不会根据透明度以及Z值进行排序。mesh的每个示例的变换矩阵都应该传递到矩阵数组中。可以指定要绘制的实例化数量,默认情况下是矩阵数组的长度。如果shader需要其他数据,则应使用SetFloatArray, SetVectorArray和SetMatrixArray在MaterialPropertyBlock参数上创建数组来提供。若要使用light probes来渲染实例,可通过MaterialPropertyBlock提供light probes数据,并通过LightProbeUsage.CustomProvided指定lightProbeUsage.可查看LightProbes.CalculateInterpolatedLightAndOcclusionProbes获得更详细的信息。注意:调用此函数一次最多只能绘制1023个实例。如果材质的Material.enabledInstancing设置为true或当前平台不支持此API(即如果GPU Instanceing不可用),则将引发InvalidOperationException.可查看SystemInfo.supportsInstancing.
函数定义:
public static void DrawMeshInstanced(Mesh mesh, int submeshIndex, Material material, Matrix4x4[] matrices,int count = matrices.Lenght, MaterialPropertyBlock properties = null, Rendering.ShadowCastingMode castShadows = ShadowCastingMode.On, bool receiveShadows = true, int layer = 0, Camera camera = null, Rendering.LightProbeUsage lightProbeUsage = LightProbeUsage.BlendProbes,LightProbeProxyVolume lightProbeProxyVolume = null);
public static void DrawMeshInstanced(Mesh mesh, int submeshIndex, Material material,List<Matrix4x4>matrices, MaterialPropertyBlock = null, Rendering.ShadowCastingMode castShadows = ShadowCastingMode.On,bool receiveShadows = true, int layer = 0, Camera camera = null, Rendering.LightProbeUsage lightProbeUsage = LightProbeUsage.BlendProbes,LightProbeProxyVolume lightProbeProxyVolume = null);
函数参数:
mesh:绘制的mesh
submeshIndex:要绘制的mesh的子mesh。这仅适用于由多个材质的mesh
material:使用的材质
count:要绘制的实例化数
properties:在绘制mesh前,设置材质的属性值,可参照:MaterialPropertyBlock
castShadows:设置mesh是否可以投射阴影
receiveShadows:设置mesh是否可以接收阴影
layer:使用的Layer
camera:如果为null(默认值),则将在所有摄像机中绘制网格。否则仅在给定的相机中渲染
lightProbeUsage:实例的LightProbeUsage
DrawMeshInstancedIndirect:使用GPU Instanced多次绘制相同的mesh。与Graphics.DrawMeshInstanced类似,此函数绘制同一mesh的多个实例,但是与该方法不同,绘制实例的数量来自bufferWithArgs参数。在使用Instanced shader绘制相同mesh的情况下,可使用此函数。但是不会进行视椎剔除以及bake oc的遮挡剔除,也不会根据透明度以及Z值进行排序。具有bufferWithArgs参数的Buffer必须在给定的argsOffset偏移量处具有5个整数:每个实例的索引计数,实例化数量,起始索引位置,基础顶点位置,起始实例位置。如果mesh中的子网格具有不同的拓扑结构(例如:三角形或直线),unity仅需要submeshIndex参数,其他的有关绘制子网格的所有信息都来自bufferWithArgs参数。
函数定义:
public static void DrawMeshInstancedIndirect(Mesh mesh,int submeshIndex,Material material,Bound bounds,ComputeBuffer bufferWithArgs, int argsOffset = 0, MaterialPropertyBlock properties = null, Rendering.ShadowCastingMode castShadows = ShadowCastingMode.On, bool receiveShadows = true, int layer = 0, Camera camera = null,Rendering.LightProbeUsage lightProbeUsage = LightProbeUsage.BlendProbes,LightProbeProxyVolume lightProbeProxyVolume = null);
函数参数:
mesh:绘制的mesh
submeshIndex:要绘制的mesh的子mesh。这仅适用于由多个材质的mesh
material:使用的材质
bounds:绘制实例的包围盒
bufferWithArg:GPU缓冲区,包含要mesh绘制实例的数量等数据
argsOffset:缓冲区的字节偏移量,在此处开始读取绘制参数
properties:在绘制mesh前,设置材质的属性值,可参照:MaterialPropertyBlock
castShadows:设置mesh是否可以投射阴影
receiveShadows:设置mesh是否可以接收阴影
layer:使用的Layer
camera:如果为null(默认值),则将在所有摄像机中绘制网格。否则仅在给定的相机中渲染
lightProbeUsage:实例的LightProbeUsage
代码实现:注意PlayerSettings中选择合适的Graphics APIs
using UnityEngine;

//这是绘制同一网格多个实例的脚本
public class GraphicsTest : MonoBehaviour {
    public int instanceCount = 100000;
    public Mesh instanceMesh;
    public Material instanceMaterial;
    public int subMeshIndex = 0;

    private int cachedInstanceCount = -1;
    private int cachedSubMeshIndex = -1;
    private ComputeBuffer positionBuffer;
    private ComputeBuffer argsBuffer;
    private uint[] args = new uint[5] { 0, 0, 0, 0, 0 };
    private void Start()
    {
        argsBuffer = new ComputeBuffer(1, args.Length * sizeof(uint), ComputeBufferType.IndirectArguments);
        UpdateBuffers();
    }
    void UpdateBuffers()
    {
        //确保子网格索引在范围内
        if (instanceMesh != null)
            subMeshIndex = Mathf.Clamp(subMeshIndex, 0, instanceMesh.subMeshCount - 1);
        //位置
        if (positionBuffer != null)
            positionBuffer.Release();
        positionBuffer = new ComputeBuffer(instanceCount, 16);
        Vector4[] positions = new Vector4[instanceCount];
        for(int i = 0; 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);
        instanceMaterial.SetBuffer("positionBuffer", positionBuffer);
        //Indirect args
        if(instanceMesh != null)
        {
            args[0] = (uint)instanceMesh.GetIndexCount(subMeshIndex);
            args[1] = (uint)instanceCount;
            args[2] = (uint)instanceMesh.GetIndexStart(subMeshIndex);
            args[3] = (uint)instanceMesh.GetBaseVertex(subMeshIndex);
         }
        else
        {
            args[0] = args[1] = args[3] = args[3] = 0;
        }
        argsBuffer.SetData(args);
        cachedInstanceCount = instanceCount;
        cachedSubMeshIndex = subMeshIndex;
    }
    private void Update()
    {
        //更新起始位置缓冲区
        if (cachedInstanceCount != instanceCount || cachedSubMeshIndex != subMeshIndex)
            UpdateBuffers();
        //Pad input
        if (Input.GetAxisRaw("Horizontal") != 0.0f)
            instanceCount = (int)Mathf.Clamp(instanceCount + Input.GetAxis("Horizontal") * 40000, 1.0f, 
                5000000.0f);
        //Render
        Graphics.DrawMeshInstancedIndirect(instanceMesh, subMeshIndex, instanceMaterial,
            new Bounds(Vector3.zero, new Vector3(100.0f, 100.0f, 100.0f)), argsBuffer);
    }
    private void OnGUI()
    {
        GUI.Label(new Rect(265, 25, 200, 30), "Instance Count: " + instanceCount.ToString());
        instanceCount = (int)GUI.HorizontalSlider(new Rect(25, 20, 200, 30), (float)instanceCount, 1.0f, 5000000.0f);
    }

    private void OnDisable()
    {
        if (positionBuffer != null)
            positionBuffer.Release();
        positionBuffer = null;
        if (argsBuffer != null)
            argsBuffer.Release();
        argsBuffer = null;
    }
}
可使用shader1:
Shader "Instanced/InstancedSurfaceShader"
{
	Properties
	{
        _MainTex("Albedo(RGB)", 2D) = "white"{}
        _Glossiness("Smoothness", Range(0,1)) = 0.5
        _Metallic("Metallic", Range(0,1)) = 0.0
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 200
        CGPROGRAM
        //Physically based Standard lighting model
		#pragma surface surf Standard addshadow fullforwardshadows
		#pragma multi_compile_instancing
		#pragma instancing_options procedural:setup
		
		sampler2D _MainTex;
		struct Input{
			float2 uv_MainTex;
		};
		#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
			StructuredBuffer<float4> positionBuffer;
		#endif
		void rotate2D(inout float2 v, float r){
			float s,c;
			sincos(r, s, c);
			v = float2(v.x * c - v.y * s, v.x * s + v.y * c);
		}

		void setup()
		{
			#ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
				float4 data = positionBuffer[unity_InstanceID];
				float rotation = data.w * data.w * _Time.y * 0.5f;
				rotate2D(data.xz, rotation);
				unity_ObjectToWorld._11_21_31_41 = float4(data.w, 0, 0, 0);
				unity_ObjectToWorld._12_22_32_42 = float4(0, data.w, 0, 0);
				unity_ObjectToWorld._13_23_33_43 = float4(0, 0, data.w, 0);
				unity_ObjectToWorld._14_24_34_44 = float4(data.xyz, 1);
				unity_WorldToObject = unity_ObjectToWorld;
				unity_WorldToObject._14_24_34 *= -1;
				unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
			#endif
		}
		half _Glossiness;
		half _Metallic;
		void surf(Input IN, inout SurfaceOutputStandard o){
			fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb;
			o.Metallic = _Metallic;
			o.Smoothness = _Glossiness;
			o.Alpha = c.a;
		}
        ENDCG		
	}
	FallBack "Diffuse"
}
可使用shader2:
Shader "Instanced/InstancedShader"
{
	Properties
	{
		_MainTex("Albedo(RGB)", 2D) = "white"{}
	}
	SubShader
	{
		Pass
		{
			Tags{"LightMode" = "ForwardBase"}
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight
			#pragma target 4.5

			#include "UnityCG.cginc"
			#include "UnityLightingCommon.cginc"
			#include "AutoLight.cginc"

			sampler2D _MainTex;

			#if SHADER_TARGET >= 45
				StructuredBuffer<float4> positionBuffer;
			#endif

			struct v2f
			{
				float4 pos : SV_POSITION;
				float2 uv_MainTex : TEXCOORD0;
				float3 ambient : TEXCOORD1;
				float3 diffuse : TEXCOORD2;
				float3 color : TEXCOORD3;
				SHADOW_COORDS(4)
			};

			void rotate2D(inout float2 v, float r){
				float s,c;
				//该函数是同时计算 x的 sin值和 cos值,其中 s=sin(x),c=cos(x)。该函数用于“同时需要计算sin 值和cos 值的情况”,比分别运算要快很多!
				sincos(r, s, c);
				v = float2(v.x * c - v.y * s, v.x * s + v.y * c);
			}
			
			v2f vert (appdata_full v, uint instanceID : SV_InstanceID)
			{
			#if SHADER_TARGET >= 45
				float4 data = positionBuffer[instanceID];
			#else
				float4 data = 0;
			#endif
				float rotation = data.w * data.w * _Time.x * 0.5f;
				rotate2D(data.xz, rotation);
				float3 localPosition = v.vertex.xyz * data.w;
				float3 worldPosition = data.xyz + localPosition;
				float3 worldNormal = v.normal;
				float3 ndotl = saturate(dot(worldNormal, _WorldSpaceLightPos0.xyz));
				float3 ambient = ShadeSH9(float4(worldNormal, 1.0f));
				float3 diffuse = (ndotl * _LightColor0.rgb);
				float3 color = v.color;

				v2f o;
				o.pos = mul(UNITY_MATRIX_VP, float4(worldPosition, 1.0f));
				o.uv_MainTex = v.texcoord;
				o.ambient = ambient;
				o.diffuse = diffuse;
				o.color = color;
				TRANSFER_SHADOW(o)
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				fixed shadow = SHADOW_ATTENUATION(i);
				fixed4 albedo = tex2D(_MainTex, i.uv_MainTex);
				float3 lighting = i.diffuse * shadow + i.ambient;
				fixed4 output = fixed4(albedo.rgb * i.color * lighting, albedo.w);
				UNITY_APPLY_FOG(i.fogCoord, output);
				return output;
			}
			ENDCG
		}
	}
}
DrawMeshNow:立即绘制mesh。此函数将立即绘制给定的mesh。将使用当前设置的shader和材质(可查看Material.SetPass)。mesh将只绘制一次,没有逐像素光照,也不会投射和接收实时阴影。如果需要光照和阴影,可使用Graphics.DrawMesh。
函数定义:
public static void DrawMeshNow(Mesh mesh,Vector3 position, Quaternion rotation);
public static void DrawMeshNow(Mesh mesh,Vector3 position, Quaternion rotation, int materialIndex);
public static void DrawMeshNow(Mesh mesh,Matrix4x4 matrix)
public static void DrawMeshNow(Mesh mesh,Matrix4x4 matrix, int materialIndex)
函数参数:
mesh:绘制的mesh
position:mesh的position
rotation:mesh的Rotation
matrix:mesh的变换矩阵(合并的位置、旋转和其他变换)。注意:如果矩阵的比例为负,则网格将无法正确显示。
materialIndex:要绘制的mesh的子网格
代码示例:
using UnityEngine;

//附加此脚本到摄像机上
public class GraphicsTest : MonoBehaviour {
    public Mesh mesh;
    public Material mat;
    public void OnPostRender()
    {
        //设置材质的第一个着色器通道
        mat.SetPass(0);
        //在原点绘制mesh
        Graphics.DrawMeshNow(mesh, Vector3.zero, Quaternion.identity);
    }
}
DrawProcedural:在GPU上绘制程序几何。DrawProcedural在GPU上进行绘制调用,没有任何顶点或索引缓冲区。这主要在Shader Model 4.5级别的硬件上有用,此时着色器可以从ComputeBuffer缓冲区读取任意数据。CommandBuffer中也有类似功能,可查看:CommandBuffer.DrawProcedural。
函数定义:
1.public static void DrawProcedural(Material material,Bounds bounds,MeshTopology topology, int vertexCount, int instanceCount, Camera camera, MaterialPropertyBlock properties, Rendering.ShadowCastingMode castShadows, bool receiveShadows, int layer);
2.public static void DrawProcedural(Material material, Bounds bounds, MeshTopology topogy,GraphicsBuffer indexBuffer, int indexCount, int instanceCount, Camera camera, MaterialPropertyBlock properties,Rendering.ShadowCastingMode castShadows, bool receiveShadows, int layer);
函数参数:
1.material:使用的材质
2.bounds:绘制实例的包围盒
3.topology:程序几何的几何类型
4.instanceCount:绘制的实例数量
5.vertexCount:绘制的顶点数量
6.camera:如果为null(默认值),则将在所有摄像机中绘制网格。否则仅在给定的相机中渲染
7.properties:在绘制mesh前,设置材质的属性值,可参照:MaterialPropertyBlock
8.castShadows:设置mesh是否可以投射阴影
9.receiveShadows:设置mesh是否可以接收阴影
10.layer:使用的Layer
11.indexBuffer:用于将顶点提交给GPU的索引缓冲区
DrawProceduralIndirect:在GPU上绘制程序几何。DrawProceduralIndirect在GPU上执行绘制调用,没有任何顶点或索引缓冲区。要绘制的几何图形数量是从ComputeBuffer中读取的。典型的用例是从ComputeShader生成任意数量的数据,然后渲染该数据,而无需回读CPU.这主要在Shader Model 4.5级别的硬件上有用,此时着色器可以从ComputeBuffer缓冲区读取任意数据。具有参数bufferWithArgs的Buffer必须在给定的argsOffset偏移量处具有四个整数:每个实例的顶点数,实例数,起始顶点位置和起始实例位置。其他图形API如Direct3D11有DrawInstancedIndirect等对应函数。在4.2之前的OpenGL版本以及所有支持indirect渲染的OpenGL ES版本上,最后一个参数是保留的,因此必须为0.CommandBuffer中也有类似的功能,可查看CommandBuffer.DrawProceduralIndirect.
函数定义:
1.public static void DrawProceduralIndirect(Material material, Bounds bounds, MeshTopolopy topology, ComputeBuffer bufferWithArgs, int argsOffset,Camera camera, MaterialPropertyBlock properties, Rendering.ShadowCastingMode castShadows, bool receiveShadows, int layer)
2.public static void DrawProceduralIndirect(Material material,Bound bounds, MeshTopology topology, GraphicsBuffer indexBuffer, ComputeBuffer bufferWithArgs, int argsOffset, Camera camera, MaterialPropertyBlock properties, Rendering.ShadowCastingMode castShadows, bool receiveShadows, int layer);
函数参数:
1.material:使用的材质
2.bounds:绘制实例的包围盒
3.topology:程序几何的几何类型
4.indexBuffer:用于将顶点提交给GPU的索引缓冲区
5.camera:如果为null(默认值),则将在所有摄像机中绘制网格。否则仅在给定的相机中渲染
6.bufferWithArgs:带有绘制参数的缓冲区
7.argsOffset:绘制参数在缓冲区中的字节偏移值
8.properties:在绘制mesh前,设置材质的属性值,可参照:MaterialPropertyBlock
9.castShadows:设置mesh是否可以投射阴影
10.receiveShadows:设置mesh是否可以接收阴影
11.layer:使用的Layer
DrawProceduralIndirectNow:在GPU上绘制程序几何。DrawProceduralIndirectNow在GPU上执行绘制调用,没有任何顶点或索引缓冲区。要绘制的几何图形数量是从ComputeBuffer中读取的。典型的用例是从ComputeShader生成任意数量的数据,然后渲染该数据,而无需回读CPU.这主要在Shader Model 4.5级别的硬件上有用,此时着色器可以从ComputeBuffer缓冲区读取任意数据。具有参数bufferWithArgs的Buffer必须在给定的argsOffset偏移量处具有四个整数:每个实例的顶点数,实例数,起始顶点位置和起始实例位置。其他图形API如Direct3D11有DrawInstancedIndirect等对应函数。在4.2之前的OpenGL版本以及所有支持indirect渲染的OpenGL ES版本上,最后一个参数是保留的,注意:此调用立即执行,类似于Graphics.DrawMeshNow。它使用当前设置的渲染目标,转换矩阵和着色器通道。CommandBuffer中也有类似的功能,可查看CommandBuffer.DrawProceduralIndirect。
函数定义:
1.public static void DrawProceduralIndirectNow(MeshTopology topology,ComputeBuffer bufferWithArgs, int argsOffset);
2.public static void DrawProceduralIndirectNow(MeshTopology topology,GraphicsBuffer indexBuffer,ComputeBuffer bufferWithArgs, int argsOffset);
函数参数:
1.topology:程序几何的几何类型
2.bufferWithArgs:带有绘制参数的缓冲区
3.argsOffset:绘制参数在缓冲区中的字节偏移值
4.indexBuffer:用于将顶点提交给GPU的索引缓冲区
DrawProceduralNow:在GPU上绘制程序几何。DrawProceduralNow在GPU上进行绘制调用,没有任何顶点或索引缓冲区。这主要在Shader Model 4.5级别的硬件上有用,此时着色器可以从ComputeBuffer缓冲区读取任意数据。注意:此调用立即执行,类似于Graphics.DrawMeshNow。它使用当前设置的渲染目标,转换矩阵和着色器通道。CommandBuffer中也有类似的功能,可查看CommandBuffer.DrawProcedural。
函数定义:
1.public static void DrawProceduralNow(MeshTopology topology, int vertexCount, int instanceCount);
2.public static void DrawProceduralNow(MeshTopology topology,GraphicsBuffer indexBuffer,int indexCount, int instanceCount);
函数参数:
1.topology:程序几何的几何类型
2.vertexCount:绘制的顶点数量
3.instanceCount:绘制的实例数量
4.indexBuffer:用于将顶点提交给GPU的索引缓冲区
DrawTexture:在屏幕坐标系中绘制纹理。如果要从OnGUI函数绘制纹理,则应仅从EventType.Repaint事件进行绘制。且最好使用GUI.DrawTexture绘制纹理。
函数定义:
1.public static void DrawTexture(Rect screenRect, Texture texture, Material mat = null, int pass = -1);
2.public static void DrawTexture(Rect screenRect, Texture texture, int leftBorder, int topBorder, int bottomBorder, Material mat = null, int pass = -1);
3.public static void DrawTexture(Rect screenRect, Texture texture, Rect sourceRect, int leftBorder, int rightBorder, int bottomBorder, Material mat = null, int pass = -1);
4.public static void DrawTexture(Rect screenRect, Texture texture, Rect sourceRect, int leftBorder, int rightBorder, int topBorder, int bottomBorder, Color color, Material mat = null, int pass = -1);
函数参数:
1.screenRect:纹理绘制的矩形位置。在像素坐标系中,左上角为(0,0)
2.texture:绘制的texture
3.sourceRect:在矩形位置中要使用的纹理区域。在归一化坐标系中左下角为(0,0)
4.leftBorder:左边不受scale影响的像素数
5.rightBorder:右边不受scale影响的像素数
6.topBorder:顶部不受scale影响的像素数
7.bottomBorder:底部不受scale影响的像素数
8.color:配置输出的颜色,中性值为(0.5, 0.5, 0.5, 0.5)。设置为shader的顶点颜色
9.mat:用于绘制纹理的自定义材质。如果传递null,则使用Internal-GUITexture.shader这个默认材质
10.pass:如果为-1(默认),则绘制材质中的所有通道。否则,进绘制给定pass。
代码示例:如果要从OnGUI函数绘制纹理,则应仅从EventType.Repaint事件进行绘制。且最好使用GUI.DrawTexture绘制纹理。
代码示例:
using UnityEngine;

public class GraphicsTest : MonoBehaviour {
    //在屏幕(10,10)处以100的宽度、100的高度绘制纹理
    public Texture aTexture;
    public void OnGUI()
    {
        if(Event.current.type.Equals(EventType.Repaint))
        {
            Graphics.DrawTexture(new Rect(10, 10, 100, 100), aTexture);
        }
    }
}

Graphics.ExecuteCommandBuffer:执行命令缓冲区。缓冲区中的所有命令将立即执行。
函数定义:
public static void ExecuteCommandBuffer(Rendering.CommandBuffer buffer);
函数参数:
buffer:要执行的缓冲区
ExecuteCommandBufferAsync:在基于传递的ComputeQueueType参数选择相应异步compute队列,并在其上执行命令缓冲区。要求命令缓冲区内的所有命令的类型都适合在异步compute队列上执行。如果缓冲区中包含任何不适合的命令,则将记录错误并显示在编辑器窗口中。具体来说,在用于异步执行的CommandBuffer中允许以下命令:CommandBuffer.BeginSample、CommandBuffer.CopyCounterValue、CommandBuffer.CopyTexture、CommandBuffer.CreateGPUFence、CommandBuffer.DisableShaderKeyword、CommandBuffer.DispatchCompute、CommandBuffer.EnableShaderKeyword、CommandBuffer.EndSample、CommandBuffer.GetTemporaryRT、CommandBuffer.GetTemporaryRTArray、CommandBuffer.IssuePluginEvent、CommandBuffer.ReleaseTemporaryRT、CommandBuffer.SetComputeBufferParam、CommandBuffer.SetComputeFloatParam、CommandBuffer.SetComputeFloatParams、CommandBuffer.SetComputeIntParam、CommandBuffer.SetComputeIntParams、CommandBuffer.SetComputeMatrixArrayParam、CommandBuffer.SetComputeMatrixParam、CommandBuffer.SetComputeTextureParam、CommandBuffer.SetComputeVectorParam、CommandBuffer.SetComputeVectorArrayParam、CommandBuffer.SetGlobalBuffer、CommandBuffer.SetGlobalColor、CommandBuffer.SetGlobalFloat
、CommandBuffer.SetGlobalFloatArray、CommandBuffer.SetGlobalInt、CommandBuffer.SetGlobalMatrix、CommandBuffer.SetGlobalMatrixArray、CommandBuffer.SetGlobalTexture、CommandBuffer.SetGlobalVector、CommandBuffer.SetGlobalVectorArray、CommandBuffer.WaitOnGPUFence。确保缓冲区内的所有命令都在同一队列上执行。如果目标平台不支持异步compute队列,则在图形队列上分派工作。
函数定义:public static void ExecuteCommandBufferAsync(Rendering.CommandBuffer buffer, Rendering.ComputeQueueType queueType)
函数参数:
1.buffer:要执行的CommandBuffer
2.queueType:执行CommandBuffer所需的异步compute队列
SetRandomWriteTarget:为Shader Model4.5级片元着色器设置随机写入目标。Shader Model4.5及更高级别的像素着色器可以写入某些纹理和缓冲区的任意位置,在在UsingDX11GL3Features中称为"unordered access views"(UAV)。
函数定义:
1.public static void SetRandomWriteTarget(int index, ComputeBuffer uav, bool preserveCounterValue = false)
2.public static void SetRandomWriteTarget(int index, RenderTexture uav);
函数参数:
1.index:shader中随机写入目标的索引
2.uav:设置为写入目标的RenderTexture
3.preserveCounterValue:是否使append/consume counter的值保持不变 
SetRenderTarget:设置当前渲染目标。这个设置渲染纹理或渲染缓冲区的组合,将在下一步渲染。在需要手动将一些东西渲染到渲染纹理中时,可实现自定义渲染算法使用它。带有mipLevel和face参数的接口可以渲染RenderTexture的特定mipmap级别或特定cubemap面。使用colorBuffers数组的函数支持使用多个渲染目标(MRT)技术,其中片元着色器可以输出多个最终颜色。使用RenderTexture参数调用SetRenderTarget。使用RenderTexture参数调用SetRenderTarget与设置RenderTexture.active是一样的。注意:在线性颜色空间中,设置正确的sRGB<->线性颜色转换状态是很重要的。根据之前的渲染内容,当前状态可能不是你期望的状态。在执行SetRenderTarget或任何其他手动渲染之前,你可以根据需要设置GL.sRGBWrite。
函数定义:
1.public static void SetRenderTarget(RenderTexture rt, int mipLevel = 0, CubemapFace face = CubemapFace.Unknow, int depthSlice = 0);
2.public static void SetRenderTarget(RenderBuffer[] colorBuffers, RenderBuffer depthBuffer);
3.public static void SetRenderTarget(RenderBuffer colorBuffer, RenderBuffer depthBuffer, int mipLevel = 0, CubemapFace face = CubemapFace.Unknown, int depthSlice = 0);
4.public static void SetRenderTarget(RenderTargetSetup setup);
函数参数:
1.rt:设置为激活的渲染目标的RenderTexture.
2.mipLevel:要渲染的Mipmap级别(如果没有mipmapping,则使用0)
3.face:要渲染的Cubemap面(如果不是Cubemap,则使用Unknown)
4.depthSlice:要渲染的深度切片(如果不是3D或2DArray渲染目标,则使用0)
5.colorBuffer:要渲染的颜色缓冲
6.depthBuffer:要渲染的深度缓冲
7.colorBuffers:要渲染的颜色缓冲(用于多个渲染目标)
8.setup:完整的渲染目标设置信息。
WaitOnAsyncGraphicsFence:使GPU等给定的GraphicsFence渲染完成,才继续图形队列的处理。一些平台无法区分顶点开始处理阶段和像素处理阶段,这些平台将等待下一个项目的顶点处理,而不管传递给stage参数的值如何。函数的fence参数必须使用GraphicsFenceType.AsyncQueueSynchronization隔离类型创建。在不支持GraphicsFences的平台上,此调用不执行任何操作。可查看SystemInfo.supportsGraphicsFence.用户可以使用此功能创建GPU死锁。应注意确保在指示GPU等待前,传递的GraphicsFence可以被完成。此功能会立即在CPU上返回,只有GPU会受fence参数影响。
函数定义:
1.public static void WaitOnAsyncGraphicsFence(Rendering.GraphicsFence fence);
2.public static void WaitOnAsyncGraphicsFence(Rendering.GraphicsFence fence, Rendering.SynchronisationStage = SynchronisationStage.PixelProcessing);
函数参数:
1.fence:将指示GPU等待fence处理完后再继续处理图形队列
2.stage:在某些平台上,对于给定的绘制调用,在顶点处理完成与像素处理开始之间调用, 结果有很大区别。此参数允许请求的等待时间在下一个项目的顶点或像素处理开始之前。如果compute shader调度是要提交的下一项,则将忽略此参数。

三、CommandBuffer
(1)、描述
  要执行的图形命令列表
  命令缓冲区保存渲染命令列表(“设置渲染目标,绘制网格,…”)。可以将它们设置为在相机渲染期间(可参考Camera.AddCommandBuffer)、光照渲染(可参考Light.AddCommandBuffer)等期间执行或立即执行(可参考Graphics.ExecuteCommandBuffer)
  通常,它们将用于以某些自定义方式扩展Unit的渲染管线。例如,你可以在完成所有常规对象后将一些其他对象渲染到延迟渲染的G缓冲区中,或者对光影贴图进行自定义处理。
  可以创建命令缓冲区,然后根据需要执行多次
  可查看Camera.AddCommandBuffer、Light.AddCommandBuffer、CameraEvent、LightEvent、Graphics.ExcuteCommandBuffer

(2)、Properties

name:该命令缓冲区的名称。这可以用于调试,可以更容易的看到Profiler或Frame Debugger中的命令缓冲区活动。该名称完全不影响渲染。
函数定义:public string name
sizeInBytes:此命令缓冲区的大小(以字节为单位)(只读)
函数定义:public int sizeInBytes;

(3)、Constructors

CommandBuffer:创建一个新的空命令缓冲区。可以为命令缓冲区设置名称,以便在Profiler或者Frame Debugger中识别它。
函数定义:public CommandBuffer();

(3)、Public Methods

BeginSample:添加开启profile sampling的命令。用于命令缓冲区执行到这里时的性能分析。这对于测量一个或多个命令在命令缓冲区中花费的CPU和GPU时间很有用。一个以BeginSample开始的采样总是以一个具有相同名称参数的CommandBuffer.EndSample结束。
函数定义:public void BeginSample(string name)
函数参数:
name:profile sampling的名称
Blit:添加一个"blit到render texture"的命令。类似于Graphics.Blit,主要用于从一个(render)texture复制到另一个,可使用自定义的shader。源纹理或渲染目标将使用_MainTex属性传递给材质。使用render texture时,可以用几种方式表示:RenderTexture对象,用GetTemporaryRT创建的临时rendertexture,或者built-in的临时纹理(BuiltinRenderTextureType).所有这些都由RenderTargetIdentifier结构体表示。该结构具有隐式转换操作符以节省输入。注意:Blit改变了当前激活的渲染目标。执行Blit后,dest成为新的激活的渲染目标。通常情况下,不需要保存Blit dest以前的内容。在这种情况下建议使用SetRenderTarget用适当的加载和存储操作,显示激活dest渲染目标。然后Blit dest被设置为BuiltinRenderTextureType.CurrentActive。
函数定义:
public void Blit(Texture source, Rendering.RenderTargetIdentifier dest);
public void Blit(Texture source, Rendering.RenderTargetIdentifier dest, Material mat);
public void Blit(Texture source, Rendering.RenderTargetIdentifier dest, Material mat, int pass);
public void Blit(Texture source, Rendering.RenderTargetIdentifier dest, Vector2 scale, Vector2 offset);
public void Blit(Rendering.RenderTargetIdentifier source, Rendering.RenderTargetIdentifier dest);
public void Blit(Rendering.RenderTargetIdentifier source, Rendering.RenderTargetIdentifier dest, Material mat);
public void Blit(Renering.RenderTargetIdentifier source,Rendering.RenderTargetIdentifier dest, Material mat, int pass);
public void Blit(Rendering.RenderTargetIdentifier source, Rendering.RenderTargetIdentifier dest,Vector2 scale, Vector2 offset);
public void Blit(Rendering.RenderTargetIdentifier source,Rendering.RenderTargetIdentifier dest, int sourceDepthSlice,int destDepthSlice);
public void Blit(Rendering.RenderTargetIdentifier source,Rendering.RenderTargetIdentifier dest, Vector2 scale, Vector2 offset, int sourceDepthSlice, int destDepthSlice);
public void Blit(Rendering.RenderTargetIdentifier source,Rendering.RenderTargetIdentifier dest,Material mat, int pass, int destDepthSlice);
函数参数:
1.source:blit的源纹理或渲染目标
2.dest:blit的目标
3.mat:使用的材质
4.pass:使用的shader pass(默认-1,表示所有pass)
5.scale:源纹理坐标使用的缩放
6.offset:源纹理坐标使用的偏移
7.sourceDepthSlice:用于执行blit的源texture array的序号
8.destDepthSlice:用于执行blit的目标texture array的序号
BuildRayTracingAccelerationStructure:添加一个命令来构建场景中使用的RayTracingAccelerationStructure。
函数定义:public void BuildRayTracingAccelerationStructure(Experimental.Rendering.RayTracingAccelerationStructure accelerationStructure);
函数参数:
accelerationStructure:要生成的RayTracingAccelerationStructure。
Clear:清除缓冲区中的所有命令。从缓冲区中删除所有以前添加的命令并使其为空。
函数定义:public void Clear();
ClearRandomWriteTargets:在Shader Model 4.5级别的片元着色器中清除随机写入目标。这个函数清除以前使用SetRandomWriteTarget设置的任何"random write"目标。
函数定义:public void ClearRandomWriteTargets();
ClearRenderTarget:添加"清除渲染目标"命令
函数定义:public void ClearRenderTarget(bool clearDepth, bool clearColor, Color backgroundColor, float depth);
函数参数:
clearDepth:是否清除深度缓冲
clearColor:是否清除颜色缓冲
backgroundColor:使用此颜色清除颜色缓冲区
depth:使用此深度清除深度缓冲区(默认1.0)
ConvertTexture:复制并转换源纹理为具有不同格式或维度的目标纹理。这个函数提供了一种有效的方法来转换不同格式和尺寸的纹理。目标纹理格式必须是未压缩的,并且与当前设备支持的RenderTextureFormat相对应。你可以使用2D和cubemap纹理作为源纹理,使用2D、cubemap、2D数组和cubemap数组作为目标纹理。注意:由于API的限制,此函数在DX9或Mac+OpenGL上不受支持。
函数定义:
1.public void ConvertTexture(Rendering.RenderTargetIdentifier src, Rendering.RenderTargetIdentifier dst);
2.public void ConvertTexture(Rendering.RenderTargetIdentifier src, int srcElement, Rendering.RenderTargetIdentifier dst, int dstElement);
函数参数:
src:源纹理
dst:目标纹理
srcElement:源纹理索引(例如cubemap面)。对于2D源纹理设置这个为0
dstElement:目标纹理索引(例如cubemap面或纹理数组索引)
CopyCounterValue:添加复制ComputeBuffer计数器值的命令。注意此命令不能用于LightEvent命令缓冲区。可查看:ComputeBuffer.CopyCount。
函数定义:
public void CopyCounterValue(ComputeBuffer src, ComputeBuffer dst, uint dstOffsetBytes);
函数参数:
1.src:计数器缓冲区
2.dst:要将计数器复制到的缓冲区
3.dstOffsetBytes:dst缓冲区中的目标字节偏移值
CopyTexture:添加一个命令,将纹理复制到另一个纹理。这个函数有效地将像素数据从一个纹理复制到另一个纹理。源和目标元素可以是Texture、cube maps、texture array layers或3D texture depth slices。可以指定mip级别以及纹理的子区域进行复制。源纹理与目标纹理的大小必须相同,因为复制不做任何缩放。纹理格式应该兼容(例如:TextureFormat.ARGB32和RenderTextureFormat.ARGB32兼容)。图形API之间的格式兼容性的确切规则各不相同。完全相同的格式总是可以复制的。在某些平台(例如D3D11)上,还可以在相同位宽的格式之间进行复制。压缩的纹理格式对带有区域变体的CopyTexture添加了一些限制。例如:不支持PVRTC格式,因为他们不是基于块的(对于这些格式,你只能复制整个纹理或整个Mip级别)。对于基于块的格式(例如DXT,ETC等),区域大小和坐标必须是压缩块大小的倍数(DXT为4像素)。如果源纹理和目标纹理都被标记为"可读"(即,系统内存中存在数据副本,可以在CPU上进行读取/写入),那么数据将会被复制到系统内存和GPU上。某些平台可能没有各种纹理复制的功能(例如:从渲染纹理复制到常规纹理).可以使用SystemInfo.copyTextureSupport进行检查。可查看:Graphics.CopyTexture.
函数定义:
1.public void CopyTexture(Rendering.RenderTargetIdentifier src, Rendering.RenderTargetIdentifier dst);
2.public void CopyTexture(Rendering.RenderTargetIdentifier src, int srcElement, Rendering.RenderTargetIdentifier dst, int dstElement);
3.public void CopyTexture(Rendering.RenderTargetIdentifier src,int srcElement, int srcMip, Rendering.RenderTargetIdentifier dst, int dstElement, int dstMip);
4.public void CopyTexture(Rendering.RenderTargetIdentifier src, int srcElement, int srcMip, int srcX, int srcY, int srcWidth, int srcHeight, Rendering.RenderTargetIdentifier dst, int dstElement, int dstMip, int dstX, int dstY);
函数参数:
1.src:源纹理或RenderTargetIdentifier,可查看RenderTargetIdentifier
2.dst:目标纹理或RenderTargetIdentifier,可查看RenderTargetIdentifier
3.srcElement:源纹理类型(cubemap face, texture array layer或者3D texture depth slice)
4.srcMip:源纹理mipmap级别
5.dstElement:目标纹理类型(cubemap face, texture array layer或者3D texture depth slice)
6.dstMip:目标纹理mipmap级别
7.srcX:要复制的源纹理区域的X坐标(左侧为0)
8.srcY:要复制的源纹理区域的Y坐标(底部为0)
9.srcWidth:要复制的源纹理区域的宽度
10.srcHeight:要复制的源纹理区域的高度
11.dstX:要复制的目标纹理区域的X坐标(左侧为0)
12.dstY:要复制的目标纹理区域的Y坐标(底部为0)
CreateAsyncGraphicsFence:以GraphicsFenceType.AsyncQueueSynchronization作为第一个参数调用GommandBuffer.CreateGraphicsFence的快捷方式。
函数定义:
1.public static Rendering.GraphicsFence CreateAsyncGraphicsFence();
2.public static Rendering.GraphicsFence CreateAsyncGraphicsFence(Rendering.SynchronisationStage stage)
函数参数:
stage:同步阶段.可查看Graphics.CreateGraphicsFence.
函数返回值:
GraphicsFence:返回一个新的GraphicsFence对象
CreateGraphicsFence:创建GraphicsFence,在GPU上完成此调用之前的最后一次Blit,Clear,Draw,Dispatch或Texture Copy命令之后,将传递此GraphicsFence.这包括那些从这个CommandBuffer或从另一个CommandBuffer执行之前立即创建的fence。有些平台无法区分顶点处理完成阶段和像素处理完成阶段,在这些平台,无论向stage参数传递的值是多少,fence都是在像素处理完成后传递的。此函数可以在不支持GraphicsFences的平台上调用,尽管生成的fence没有函数,并且在等待时什么也不做(可查看Graphics.WaitOnAsyncGraphicsFence和CommandBuffer.WaitOnAsyncGraphicsFence)。
函数定义:
Graphics.CreateGraphicsFence(GraphicsFenceType, SynchronisationStage)
函数参数:
1.fenceType:要创建的GraphicsFence的类型。当前唯一支持的值是GraphicsFenceType.AsyncQueueSynchronization
2.stage:在某些平台上,对于给定的绘制调用,顶点处理完成与像素处理完成开始之间存在很大的差距。此参数允许在进行绘制的顶点或像素处理完成之后传递fence.如果compute shader调度是最后提交的任务,则将忽略此参数。
函数返回值:
void:返回一个新的GraphicsFence
DisableScissorRect:添加一个命令来禁用硬件裁剪矩形
函数定义:public void DisableScissorRect();
DisableShaderKeyword:添加一个命令来禁用全局shader关键字。可查看:EnableShaderKeyword,Shader.DisableKeyword.
函数定义:public void DisableShaderKeyword(string keyword);
函数参数:
keyword:禁用的Shader关键字
DispatchCompute:添加一个命令来执行ComputeShader.当命令缓冲区执行时,compute shader内核被分派,工作组大小要么直接指定(可查看ComputeShader.Dispatch),要么从GPU缓冲区中读取(可查看ComputeShadre.DispatchIndirect)。
函数定义:
1.public void DispatchCompute(ComputeShader computeShader,int kernelIndex, int threadGroupsX, int threadGroupsY, int threadGroupsZ);
2.public void DispatchCompute(ComputeShader computeShader, int kernelIndex, ComputeBuffer indirectBuffer, uint argsOffset);
函数参数:
1.computeShader:执行的ComputeShader
2.kernelIndex:要执行的内核索引,可查看ComputeShader.FindKernel
3.threadGroupsX:X维度的工作组数
4.threadGroupsY:Y维度的工作组数
5.threadGroupsZ:Z维度的工作组数
6.indirectBuffer:带有参数的ComputeBuffer
7.argsOffset:指示参数在缓冲区中的字节偏移值
DispatchRays:添加一个命令来执行一个RayTracingShader。当命令缓冲区执行时,一个RayTracingShader被分配并启动射线生成shader的线程。宽度、高度、深度必须大于0,宽度*高度*深度<=2^30。
函数定义:DispatchRays(RayTracingShader raytracingShader, string rayGenShaderName, int rayGenShaderNameID, int width, int height, int depth, int camera);
函数参数:
1.raytracingShader:执行的RayTracingShader
2.rayGenShaderName:射线生成的着色器名称
3.rayGenShaderNameID:属性名ID.使用Shader.PropertyToID来获取这个ID
4.width:射线生成的着色器的线程网格宽度
5.height:射线生成的着色器的线程网格高度
6.depth:射线生成的着色器的线程网格深度
7.camera:使用摄像机作为环境来调度RayTracingShader。
DrawMesh:添加一个"绘制网格"命令
函数定义:public void DrawMesh(Mesh mesh, Matrix4x4 matrix, Material material, int submeshIndex, int shaderPass, MaterialPropertyBlock properties);
函数参数:
1.mesh:绘制的网格
2.matrix:使用的变换矩阵
3.material:使用的材质
4.submeshIndex:渲染的子网格索引
5.shaderPass:使用shader的哪个pass(默认为-1,即渲染所有pass)
6.properties:绘制网格前应用的材质属性。可查看MaterialPropertyBlock。
DrawMeshInstanced:添加一个"用实例绘制网格"命令。若检测到Material.enableInstancing为false这样的条件,该命令不会立即失败并抛出异常,但它会记录一个错误,并在每次执行命令时跳过渲染。如果当前平台不支持该API(即GPU实例化不可用),InvalidOperationException将被抛出,可查看SystemInfo.supportsInstancing。
函数定义:
1.public void DrawMeshInstanced(Mesh mesh, int submeshIndex,Material material, int shaderPass, Matrix4x4[] matrices,int count, MaterialPropertyBlock properties);
2.public void DrawMeshInstanced(Mesh mesh, int submeshIndex, Material material, int shaderPass, Matrix4x4[] matrices, int count);
3.public void DrawMeshInstanced(Mesh mesh, int submeshIndex, Material material, int shaderPass, Matrix4x4[] matrices);
函数参数:
mesh:绘制的mesh
submeshIndex:要绘制的mesh的子mesh。这仅适用于由多个材质组成的mesh
material:使用的材质
shaderPass:使用的着色器pass,若使用-1则渲染所有pass
matrices:对象的转换矩阵数组
count:要绘制的实例化数
properties:在绘制mesh前,设置材质的属性值,可参照:MaterialPropertyBlock
DrawMeshInstancedIndirect:添加一个"使用间接实例化绘制网格"命令
函数定义:
1.public void DrawMeshInstancedIndirect(Mesh mesh,int submeshIndex,Material material,int shaderPass,ComputeBuffer bufferWithArgs, int argsOffset, MaterialPropertyBlock properties);
2.public void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, ComputeBuffer bufferWithArgs, int argsOffset);
3.public void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, ComputeBuffer bufferWithArgs);
函数参数:
1.mesh:绘制的mesh
2.submeshIndex:要绘制的mesh的子mesh。这仅适用于由多个材质的mesh
3.material:使用的材质
4.ShaderPass:使用的shader pass,-1表示渲染所有pass。
5.properties:在绘制mesh前,设置材质的属性值,可参照:MaterialPropertyBlock
6.bufferWithArg:GPU缓冲区,包含要mesh绘制实例的数量等数据
7.argsOffset:缓冲区的字节偏移量,在此处开始读取绘制参数
DrawMeshInstancedProcedural:添加一个"用实例绘制网格"命令。使用程序实例化绘制网格。这类似于Graphics.DrawMeshInstancedIndirect,如果需要从脚本中传递实例计数,可以使用此方法直接提供他,而不是通过ComputeBuffer提供。若检测到Material.enableInstancing为false这样的条件,该命令不会立即失败并抛出异常,但它会记录一个错误,并在每次执行命令时跳过渲染。如果当前平台不支持该API(即GPU实例化不可用),InvalidOperationException将被抛出,可查看SystemInfo.supportsInstancing。
函数定义:public void DrawMeshInstancedProcedural(Mesh mesh, int submeshIndex, Material material, int shaderPass, int count, MaterialPropertyBlock properties);
函数参数:
mesh:绘制的mesh
submeshIndex:要绘制的mesh的子mesh。这仅适用于由多个材质组成的mesh
material:使用的材质
shaderPass:使用的着色器pass,若使用-1则渲染所有pass
matrices:对象的转换矩阵数组
count:要绘制的实例化数
properties:在绘制mesh前,设置材质的属性值,可参照:MaterialPropertyBlock
DrawOcclusionMesh:在commandbuffer中添加一个命令,将VR设置的遮挡网格绘制到当前渲染目标。渲染命令缓冲区中的命令是可以在脚本中排序的底层图形操作。这个命令特别用于渲染当前激活的VR设备的遮挡网格。在其他渲染方法调用之前调用此方法,以防渲染了位于VR设备可见区域之外的对象。可参考:XRSettings.useOcclusionMesh和XRSettings.occlusionMaskScale。
函数定义:public void DrawOcclusionMesh(RectInt normalizedCamViewport)
函数参数:
1.normalizedCamViewport:当前渲染的摄像机的视口
DrawProcedural:添加"绘制程序几何图形"命令。DrawProcedural在GPU上进行绘制调用,没有任何顶点或索引缓冲区。这主要在Shader Model 4.5级别的硬件上有用,此时着色器可以从ComputeBuffer缓冲区读取任意数据。在顶点着色器中,通常使用SV_VertexID和SV_InstanceID输入变量从某些缓冲区中获取数据。带参数的缓冲区bufferWithArgs必须在给定的argsOffset偏移量处有4个整数:每个实例的顶点数、实例数、开始顶点位置和开始实例位置。这映射到Direct3D11 DrawInstancedIndirect以及到其他图形APIs的等效函数。对于4.2之前的OpenGL版本和所有支持间接绘制的OpenGL ES版本,最后一个参数是保留的,因此必须是0。在顶点着色器中,通常使用SV_VertexID和SV_InstanceID输入变量从某些缓冲区获取数据。
函数定义:
1.public void DrawProcedural(Matrix4x4 matrix, Material material, int shaderPass,MeshTopology topology, int vertexCount, int instanceCount, MaterialPropertyBlock properties);
2.public void DrawProcedural(Matrix4x4 matrix, Material material, int shaderPass, MeshTopology topology, int vertexCount, int instanceCount);
3.public void DrawProcedural(Matrix4x4 matrix, Material material, int shaderPass, MeshTopology.topology, int vertexCount);
4.public void DrawProcedural(GraphicsBuffer indexBuffer, Matrix4x4 matrix, Material material, int shaderPass, MeshTopology topology, int indexCount,int instanceCount, MaterialPropertyBlock properties);
5.public void DrawProcedural(GraphicsBuffer indexBuffer, Matrix4x4 matrix, Material material, int shaderPass, MeshTopology topology, int indexCount,int instanceCount);
6.public void DrawProcedural(GraphicsBuffer indexBuffer, Matrix4x4 matrix, Material material, int shaderPass, MeshTopology topology, int indexCount);
函数参数:
1.matrix:使用的变换矩阵
2.material:使用的材质
3.shaderPass:shader使用的pass(-1表示渲染所有pass)
4.topology:程序几何的几何类型
5.properties:在绘制mesh前,设置材质的属性值,可参照:MaterialPropertyBlock
6.bufferWithArg:带有绘制参数的缓冲区
7.argsOffset:在缓冲区中绘制参数所在的字节偏移值。
DrawProceduralIndirect:添加"绘制程序几何图形"命令。当命令缓冲区执行时,这将在GPU上做一个绘制调用,但没有任何顶点或索引缓冲区。从ComputeBuffer中读取要绘制的几何图形的数量。典型的用例是从ComputeShader中生成任意数量的数据,然后将其渲染出来,而不需要向CPU进行重新读取。这主要在Shader Model 4.5级别的硬件上有用,此时着色器可以从ComputeBuffer缓冲区读取任意数据。
函数定义:
1.public void DrawProceduralIndirect(Matrix4x4 matrix, Material material, int shaderPass, MeshTopology topology, ComputeBuffer bufferWithArgs, int argsOffset, MaterialPropertyBlock properties);
2.public void DrawProceduralIndirect(Matrix4x4 matrix, Material material, int shaderPass, MeshTopology topology, ComputeBuffer bufferWithArgs, int argsOffset);
3.public void DrawProceduralIndirect(Matrix4x4 matrix, Material material, int shaderPass, MeshTopology topology, ComputeBuffer bufferWithArgs);
4.public void DrawProceduralIndirect(GraphicsBuffer indexBuffer, Matrix4x4 matrix, Material material, int shaderPass, MeshTopology topology, ComputeBuffer bufferWithArgs, int argsOffset, MaterialPropertyBlock properties);
5.public void DrawProceduralIndirect(GraphicsBuffer indexBuffer, Matrix4x4 matrix, Material material, int shaderPass, MeshTopology topology, ComputeBuffer bufferWithArgs, int argsOffset);
6.public void DrawProceduralIndirect(GraphicsBuffer indexBuffer, Matrix4x4 matrix, Material material, int shaderPass, MeshTopology topology, ComputeBuffer bufferWithArgs);
函数参数:
1.matrix:使用的变换矩阵
2.material:使用的材质
3.shaderPass:shader使用的pass(-1表示渲染所有pass)
4.topology:程序几何的几何类型
5.properties:在绘制mesh前,设置材质的属性值,可参照:MaterialPropertyBlock
6.bufferWithArg:带有绘制参数的缓冲区
7.argsOffset:在缓冲区中绘制参数所在的字节偏移值。
8.indexBuffer:用于向GPU提交顶点的索引缓冲区。
DrawRenderer:添加一个"绘制渲染器"命令。
函数定义:public void DrawRenderer(Renderer renderer, Material material, int submeshIndex, int shaderPass);
函数参数:
1.renderer:绘制的渲染器
2.material:使用的材质
3.submeshIndex:绘制的子mesh
4.shaderPass:shader使用的pass(默认-1,表示绘制所有pass)
EnableScissorRect:添加一个命令来启用硬件裁剪矩形。此命令可用于从渲染目标中截取屏幕区域。
函数定义:public void EnableScissorRect(Rect scissor);
函数参数:
1.scissor:视口矩形的像素坐标
EnableShaderKeyword:添加一个命令来启用全局shader关键字
函数定义:public void EnableShaderKeyword(string keyword);
函数参数:
keyword:启用的Shader关键字
EndSample:添加命令以结束profile采样。用于命令缓冲区执行到这里时的性能分析。这对于测量一个或多个命令在命令缓冲区中花费的CPU和GPU时间很有用。一个以BeginSample开始的采样总是以一个具有相同名称参数的CommandBuffer.EndSample结束。
函数定义:public void EndSample(string name)
函数参数:
name:profile sampling的名称
GenerateMips:生成渲染纹理的mipmap级别。使用此函数手动重新生成渲染纹理的mipmap级别。render texture必须由mipmaps(useMipmap设置为true)和关闭自动生成mip(autoGenerateMips设置为false)。在一些平台(例如D3D9)没有办法手动生成render texture的mip级别。此时函数不做任何事情。
函数定义:public void GenerateMips(RenderTexture rt)
函数参数:
rt:需要生成mipmaps的render texture。
GetTemporaryRT:添加一个"获取临时渲染纹理"命令。这将创建一个带有给定参数的临时渲染纹理,并使用nameID将其设置为全局着色器属性。使用Shader.PropertyToID创建整形名称。通过传递相同的nameID调用ReleaseTemporaryRT释放临时渲染纹理。任何没有被显式释放的临时纹理将在摄像机渲染完成后或Graphics.ExecuteCommandBuffer后删除。获得临时渲染纹理后,你可以使用SetRenderTarget设置为激活的渲染目标,或作为to/from参数传递给blit。你不需要再命令缓冲区执行期间显示地保留当前激活的渲染目标(当前渲染目标将在执行后保存和恢复)。
函数定义:
1.public void GetTemporaryRT(int nameID, int width, int height, int depthBuffer, FilterMode filter, RenderTextureFormat format, RenderTextureReadWrite readWrite, int antiAliasing, bool enableRandomWrite);
2.public void GetTemporaryRT(int nameID, RenderTextureDescriptor desc, FilterMode filter);
函数参数:
1.nameID:这个纹理的着色器属性名
2.width:像素单位宽度,-1表示相机像素单位宽度
3.height:像素单位高度,-1表示相机像素单位高度
4.depthBuffer:深度缓冲位(01624)
5.filter:纹理过滤模式(默认Point)
6.format:render texture的格式(默认为ARGB32)
7.readWrite:颜色空间转换模式
8.antiAliasing:反锯齿(默认没有反锯齿)
9.enableRandomWrite:是否启用对纹理的随机写入访问(默认为false)
10.desc:在创建临时渲染纹理时,使用RenderTextureDescriptor进行设置。
11.memorylessMode:渲染纹理无记忆模式。
GetTemporaryRTArray:添加一个"获取临时渲染纹理数组"命令。这将创建一个带有给定参数的临时渲染纹理,并使用nameID将其设置为全局着色器属性。使用Shader.PropertyToID创建整形名称。通过传递相同的nameID调用ReleaseTemporaryRT释放临时渲染纹理。任何没有被显式释放的临时纹理将在摄像机渲染完成后或Graphics.ExecuteCommandBuffer后删除。获得临时渲染纹理数组后,你可以使用SetRenderTarget设置为激活的渲染目标,或作为to/from参数传递给blit。你不需要再命令缓冲区执行期间显示地保留当前激活的渲染目标(当前渲染目标将在执行后保存和恢复)。
函数定义:public void GetTemporaryRTArray(int nameID, int width, int height, int slices, int depthBuffer, FilterMode filter, RenderTextureFormat format, RenderTextureReadWrite readWrite, int antiAliasing, bool enableRandomWrite);
函数参数:
1.nameID:这个纹理的着色器属性名
2.width:像素单位宽度,-1表示相机像素单位宽度
3.height:像素单位高度,-1表示相机像素单位高度
4.slices:纹理数组中切片的数量
5.depthBuffer:深度缓冲位(01624)
6.filter:纹理过滤模式(默认Point)
7.format:render texture的格式(默认为ARGB32)
8.readWrite:颜色空间转换模式
10.antiAliasing:反锯齿(默认没有反锯齿)
11.enableRandomWrite:是否启用对纹理的随机写入访问(默认为false)
IncrementUpdateCount:增加纹理的updateCount属性。对于命令缓冲区的执行导致纹理变化,很有用,可以依赖纹理的updateCount来检测到任何变化。
函数定义:public void IncrementUpdateCount(Rendering.RenderTargetIdentifier dest);
函数参数:
dest:需要增加updateCount属性的纹理
IssuePluginCustomBlit:发送一个用户定义的blit事件到本地代码插件。
函数定义:public void IssuePluginCustomBlit(IntPtr callback, uint command, Rendering.RenderTargetIdentifier source, Rendering.RenderTargetIdentifier dest, uint commandParam, uint commandFlags);
函数参数:
1.callback:供Unity的渲染器调用的本机代码回调队列。
2.command:用户定义发送给回调的命令ID
3.source:源渲染目标
4.dest:目的渲染目标
5.commandParam:用户数据,命令参数
6.commandFlags:用户数据,命令标志
IssuePluginCustomTextureUpdateV2:发送一个纹理更新事件到一个本地代码插件。
函数定义:public void IssuePluginCustomTextureUpdateV2(IntPtr callback, Texture targetTexture, uint userData);
函数参数:
1.callback:供Unity的渲染器调用的本机代码回调队列。
2.targetTexture:需更新的纹理资源
3.userData:要发送到本机插件的用户数据。
IssuePluginEvent:将用户定义的事件发送到本机代码插件。可查看GL.IssuePluginEvent。
函数定义:public void IssuePluginEvent(IntPtr callback,int eventID);
函数参数:
1.callback:供Unity的渲染器调用的本机代码回调队列。
2.eventID:要发送给回调的用户定义id。
IssuePluginEventAndData:将带有自定义数据的用户定义事件发送到本地代码插件。
函数定义:public void IssuePluginEventAndData(IntPtr callback, int eventID, IntPtr data);
函数参数:
1.callback:供Unity的渲染器调用的本机代码回调队列。
2.data:将自定义数据传递给本机插件回调函数
3.eventID:发送给回调的built in或用户定义id。
ReleaseTemporaryRT:添加一个"释放临时渲染纹理"命令。如果你之前调用了::GetTemporaryRT创建纹理,则会释放一个带有给定名称的临时渲染纹理。任何没有被显式释放的临时纹理将在摄像机渲染完成后或Graphics.ExecuteCommandBuffer后删除。
函数定义:public void ReleaseTemporaryRT(int nameID);
函数参数:
nameID:这个纹理的着色器属性名。
RequestAsyncReadback:向命令缓冲区添加异步GPU回读请求命令。
函数定义:
1.public void RequestAsyncReadback(ComputeBuffer src, Action<AsyncGPUReadbackRequest> callback);
2.public void RequestAsyncReadback(ComputeBuffer src, int size, int offset, Action<AsyncGPUReadbackRequest>callback);
3.public void RequestAsyncReadback(Texture src, Action<AsyncGPUReadbackRequest> callback);
4.public void RequestAsyncReadback(Texture src,int mipIndex, Action<AsyncGPUReadbackRequest>callback);
5.public void RequestAsyncReadback(Texture src,int mipIndex, TextureFormat dstFormat, Action<AsyncGPUReadbackRequest>callback);
6.public void RequestAsyncReadback(Texture src,int mipIndex, int x, int width, int y, int height, int z, int depth, Action<AsyncGPUReaReadbackRequest>callback);
7.public void RequestAsyncReadback(Texture src, int mipIndex, int x, int width, int y, int height, int z, int depth, TextureFormat dstFormat,Action<AsyncGPUReadbackRequest> callback);
函数参数:
1.src:要从中读取数据的资源
2.size:从ComputeBuffer检索的数据的大小(以字节为单位)
3.offset:在ComputeBuffer中以字节为单位的偏移值。
4.mipIndex:要获取的mipmap的索引
5.dstFormat:数据的目标纹理格式。如果格式与GPU上存储的格式不同,会自动转换。
6.x:获取的纹理数据的开始像素X坐标
7.y:获取的纹理数据的开始像素Y坐标
8.z:获取Texture3D的开始像素Z坐标。获取TextureCube、Texture2DArray和TextureCubeArray的起始层索引。
9.depth:获取Texture3D的像素深度。TextureCube、TextureArray和TextureCubeArray的层数。
10.width:要获取的纹理数据的像素宽度。
11.height:要获取的纹理数据的像素高度。
12.callback:请求完成后调用的委托System.Action。完成的请求会作为参数传递给System.Action。
RequestAsyncReadbackIntoNativeArray:向命令缓冲区添加异步GPU回读请求命令。可查看AsyncGPUReadback.RequestIntoNativeArray。
函数定义:CommandBuffer.RequestAsyncReadback(ref NativeArray_1,ComputeBuffer,Action<AsyncGPUReadbackRequest>)
函数参数:
1.src:要从中读取数据的资源
2.size:从ComputeBuffer检索的数据的大小(以字节为单位)
3.offset:在ComputeBuffer中以字节为单位的偏移值。
4.mipIndex:要获取的mipmap的索引
5.dstFormat:数据的目标纹理格式。如果格式与GPU上存储的格式不同,会自动转换。
6.x:获取的纹理数据的开始像素X坐标
7.y:获取的纹理数据的开始像素Y坐标
8.z:获取Texture3D的开始像素Z坐标。获取TextureCube、Texture2DArray和TextureCubeArray的起始层索引。
9.depth:获取Texture3D的像素深度。TextureCube、TextureArray和TextureCubeArray的层数。
10.width:要获取的纹理数据的像素宽度。
11.height:要获取的纹理数据的像素高度。
12.callback:请求完成后调用的委托System.Action。完成的请求会作为参数传递给System.Action。
ResolveAntiAliasedSurface:强制解析一个反锯齿渲染纹理。如果反锯齿渲染纹理设置了bindTextureMS标志,它将不会被自动解析。有时,在渲染的不同阶段同时具有纹理的解析版本和未解析版本是很有用的。如果省略了target参数,渲染纹理将被解析为自身。
函数定义:public void ResolveAntiAliasedSurface(RenderTexture rt, RenderTexture target);
函数参数:
1.rt:要解析的反锯齿渲染纹理
2.target:解析后的反锯齿纹理。如果设置了此项,则目标渲染纹理必须与源纹理具有相同的尺寸和格式。
SetComputeBufferParam:添加一个命令来设置ComputeShader上的输入或输出缓冲区参数。缓冲区和纹理设置每个内核。通过函数名使用ComputeShader.FindKernel来查找内核索引。将compute缓冲区设置为内核将保持append/consumption计数器值不变。要设置或重置该值,可使用ComputeBuffer.SetCounterValue。
函数定义:
1.public void SetComputeBufferParam(ComputeShader computeShader, int kernelIndex, string name, ComputeBuffer buffer);
2.public void SetComputeBufferParam(ComputeShader computeShader, int kernelIndex, int nameID, ComputeBuffer buffer);
函数参数:
1.computeShader:需设置参数的ComputeShader
2.kernelIndex:需要设置缓冲区的内核。可查看:ComputeShader.FindKernel
3.name:shader中缓冲区变量的名称
4.nameID:属性名ID,可使用Shader.PropertyToID获取这个ID
5.buffer:缓冲区设置
SetComputeFloatParam:添加在ComputeShader上设置浮点参数的命令。常量缓冲区在单个计算着色器资产中的所有内核之间共享。因此,这个函数影响传递的ComputeShader中的所有内核。
函数定义:
1.public void SetComputeFloatParam(ComputeShader computeShader, string name, float val);
2.public void SetComputeFloatParam(ComputeShader computeShader, int nameID, float val);
函数参数:
1.computeShader:需设置参数的ComputeShader
2.name:着色器代码中变量的名称
3.nameID:属性名ID,可使用Shader.PropertyToID获取这个ID
4.val:设置的值
SetComputeFloatFloatParams:添加在ComputeShader上设置多个连续浮点参数的命令。此函数可用于设置浮点向量、浮点数组或浮点向量数组的值。例如,可以通过传递16个浮点数来填充计算着色器中的flat4 myArray[4]。有关数据布局规则的信息,可查看ComputeShaders。常量缓冲区在单个计算着色器资产中的所有内核之间共享。因此,这个函数影响传递的ComputeShader中的所有内核。
函数定义:
1.public void SetComputeFloatParams(ComputeShader computeShader, string name, params float[] values);
2.public void SetComputeFloatParams(ComputeShader computeShader, int nameID, params float[] values);
函数参数:
1.computeShader:需设置参数的ComputeShader
2.name:着色器代码中变量的名称
3.nameID:属性名ID,可使用Shader.PropertyToID获取这个ID
4.val:设置的值
SetComputeIntParam:添加在ComputeShader上设置整数参数的命令。常量缓冲区在单个计算着色器资产中的所有内核之间共享。因此,这个函数影响传递的ComputeShader中的所有内核。
函数定义:
1.public void SetComputeIntParam(ComputeShader computeShader, string name, int val);
2.public void SetComputeIntParam(ComputeShader computeShader, int nameID, int val);
函数参数:
1.computeShader:需设置参数的ComputeShader
2.name:着色器代码中变量的名称
3.nameID:属性名ID,可使用Shader.PropertyToID获取这个ID
4.val:设置的值
SetComputeIntParams:添加在ComputeShader上设置多个连续整数参数的命令。此函数可用于设置整数向量、整数数组或整数向量数组的值。例如:可以通过传递8个整数来填充compute shader中的int4 myArray[2]。有关数据布局规则的信息,可查看ComputeShaders。常量缓冲区在单个计算着色器资产中的所有内核之间共享。因此,这个函数影响传递的ComputeShader中的所有内核。
函数定义:
1.public void SetComputeIntParams(ComputeShader computeShader, string name, params int[] values);
2.public void SetComputeIntParams(ComputeShader computeShader, int nameID, params int[] values);
函数参数:
1.computeShader:需设置参数的ComputeShader
2.name:着色器代码中变量的名称
3.nameID:属性名ID,可使用Shader.PropertyToID获取这个ID
4.val:设置的值
SetComputeMatrixArrayParam:添加在ComputeShader上设置矩阵数据参数的命令。常量缓冲区在单个计算着色器资产中的所有内核之间共享。因此,这个函数影响传递的ComputeShader中的所有内核。
函数定义:
1.public void SetComputeMatrixArrayParam(ComputeShader computeShader, string name, Matrix4x4[] values);
2.public void SetComputeMatrixArrayParam(ComputeShader computeShader, int nameID, Matrix4x4[] values);
函数参数:
1.computeShader:需设置参数的ComputeShader
2.name:着色器代码中变量的名称
3.nameID:属性名ID,可使用Shader.PropertyToID获取这个ID
4.val:设置的值
SetComputeMatrixParam:添加ComputeShader上设置矩阵参数的命令。常量缓冲区在单个计算着色器资产中的所有内核之间共享。因此,这个函数影响传递的ComputeShader中的所有内核。
函数定义:
1.public void SetComputeMatrixParam(ComputeShader computeShader, string name, Matrix4x4 val);
2.public void SetComputeMatrixParam(ComputeShader computeShader, int namemID, Matrix4x4 val);
函数参数:
1.computeShader:需设置参数的ComputeShader
2.name:着色器代码中变量的名称
3.nameID:属性名ID,可使用Shader.PropertyToID获取这个ID
4.val:设置的值
SetComputeTextureParam:添加在ComputeShader上设置纹理参数的命令。纹理和缓冲区设置每个内核。通过函数名使用ComputeShader.FindKernel来查找内核索引。注意:除非着色器指定可读写(无序访问)纹理,否则mipLevel参数将被忽略。通过指定RenderTextureSubElement,可以指示要设置渲染纹理中的哪一种类型的数据。可选的选项是:RenderTextureSubElement.Color、RenderTextureSubElement.Depth、RenderTextureSubElement.Stencil。
函数定义:
1.public void SetComputeTextureParam(ComputeShader computeShader, int kernelIndex, string name, Rendering.RenderTargetIdentifier rt);
2.public void SetComputeTextureParam(ComputeShader computeShader, int kernelIndex, int nameID, Rendering.RenderTargetIdentifier rt);
3.public void SetComputeTextureParam(ComputeShader computeShader, int kernelIndex, string name, Rendering.RenderTargetIdentifier rt, int mipLevel);
4.public void SetComputeTextureParam(ComputeShader computeShader, int kernelIndex, int nameID, Rendering.RenderTargetIdentifier rt, int mipLevel);
5.public void SetComputeTextureParam(ComputeShader computeShader, int kernelIndex, string name, Rendering.RenderTargetIdentifier rt, int mipLevel, Rendering.RenderTextureSubElement element);
6.public void SetComputeTextureParam(ComputeShader computeShader, int kernelIndex, int nameID, Rendering.RenderTargetIdentifier rt, int mipLevel, Rendering.RenderTextureSubElement element);
函数参数:
1.computeShader:需设置参数的ComputeShader
2.kernelIndex:纹理被设置为哪个内核。可查看:ComputeShader.FindKernel
3.name:纹理变量在着色器代码中的名称。
4.nameID:属性名ID,可使用Shader.PropertyToID获取这个ID
5.rt:纹理值或标识符设置。可查看RenderTargetIdentifier
6.mipLevel:可选的读写纹理的mipmap级别
7.element:可选参数,指定要设置的渲染纹理中的数据类型。
SetComputeVectorArrayParam:添加在ComputeShader上设置向量数组参数的命令。常量缓冲区在单个计算着色器资产中的所有内核之间共享。因此,这个函数影响传递的ComputeShader中的所有内核。
函数定义:
1.public void SetComputeVectorArrayParam(ComputeShader computeShader, string name, Vector4[] values);
2.public void SetComputeVectorArrayParam(ComputeShader computeShader, int nameID, Vector4[] values);
函数参数:
1.computeShader:需设置参数的ComputeShader
2.name:属性名
3.nameID:属性名ID,可使用Shader.PropertyToID获取这个ID
4.val:设置的值
SetComputeVectorParam:添加在ComputeShader上设置向量参数的命令。常量缓冲区在单个计算着色器资产中的所有内核之间共享。因此,这个函数影响传递的ComputeShader中的所有内核。
函数定义:
1.public void SetComputeVectorParam(ComputeShader computeShader, string name, Vector4 val);
2.public void SetComputeVectorParam(ComputeShader computeShader, int nameID, Vector4 val);
函数参数:
1.computeShader:需设置参数的ComputeShader
2.name:属性名
3.nameID:属性名ID,可使用Shader.PropertyToID获取这个ID
4.val:设置的值
SetExecutionFlags:设置标记,描述如何执行命令缓冲区。将执行标志设置为none以外的任何值都允许在发出与预期执行方法不兼容的命令时引发异常。例如:用于异步计算的命令缓冲区不能包含纯粹用于渲染的命令。此方法只能针对空的命令缓冲区调用,因此可在构造函数之后或调用CommandBuffer.Clear之后立即调用它。
函数定义:public void SetExecutionFlags(Rendering.CommandBufferExecutionFlags flags);
函数参数:
flags:设置的标志
SetGlobalBuffer:添加"设置全局着色器缓冲属性"命令。在执行命令缓冲区时,会设置全局着色器缓冲区属性。效果等同于调用Shader.SetGlobalBuffer。
函数定义:
1.public void SetGlobalBuffer(string name, ComputeBuffer value);
2.public void SetGlobalBuffer(int nameID, ComputeBuffer value);
SetGlobalColor:添加"设置全局着色器颜色属性"命令。在执行命令缓冲区时,会设置一个全局 着色器颜色属性。效果等同于调用Shader.SetGlobalColor。
函数定义:
1.public void SetGlobalColor(string name, Color value);
2.public void SetGlobalColor(int nameID, Color value);
SetGlobalConstantBuffer:添加一个命令来绑定全局常量缓冲区。可查看Shader.SetGlobalConstantBuffer。
函数定义:public void SetGlobalConstantBuffer(ComputeBuffer buffer, int nameID, int offset, int size);
函数参数:
1.buffer:要绑定的缓冲区
2.offset:ComputeBuffer开始的偏移值(以字节为单位)
3.size:要绑定的区域的大小(以字节为单位)
4.nameID:常量缓冲区的名称(可使用Shader.PropertyToID生成)
SetGlobalDepthBias:添加一个命令来设置全局深度偏差。全局深度偏差被添加到着色器的制定状态中(cull和深度状态)。这通常是有用的,当渲染产生阴影的对象时,以轻微的偏移推动它们远离光源,以防止暗影痤疮。在Unity中内置的渲染阴影产生对象,会在渲染阴影产生对象时设置全局深度偏差(1.0, 1.0);
函数定义:public void SetGlobalDepthBias(float bias, float slopeBias)
函数参数:
1.bias:深度常量偏差
2.slopeBias:Slope-dependent深度偏差
SetGlobalFloat:添加"设置全局着色器float属性"命令。当执行命令缓冲区时,将在此时设置一个全局着色器float属性。效果等同于调用Shader.SetGlobalFloat。
函数定义:
1.public void SetGlobalFloat(string name, float value);
2.public void SetGlobalFloat(int nameID, float value);
3.public void SetGlobalFloat(string propertyName, List<float>values);
4.public void SetGlobalFloat(int nameID, List<float>values);
SetGlobalFloatArray:添加一个"设置全局着色器float数组属性"命令。当执行命令缓冲区时,将在此时设置一个全局着色器浮点数组属性。效果等同于调用Shader.SetGlobalFloatArray。
函数定义:
1.public void SetGlobalFloatArray(string propertyName, float[] values);
2.public void SetGlobalFloatArray(int nameID, float[] values);
3.public void SetGlobalFloatArray(string propertyName, List<float>values);
4.public void SetGlobalFloatArray(int nameID, List<float>values);
SetGlobalInt:为所有着色器设置给定的全局整数属性。在内部,float和integer着色器属性是完全相同的,所以这个函数只是SetGlobalFloat的别名。
函数定义:
1.public void SetGlobalInt(string name, int value)
2.public void SetGlobalInt(int nameID, int value)
SetGlobalMatrix:添加"设置全局着色器矩形属性"命令。当执行命令缓冲区时,将在此时设置全局着色器矩阵属性。效果等价于调用Shader.SetGlobalMatrix。
函数定义:
1.public void SetGlobalMatrix(string name, Matrix4x4 value)
2.public void SetGlobalMatrix(int nameID, Matrix4x4 value)
SetGlobalMatrixArray:添加"设置全局着色器矩阵array属性"命令。当执行命令缓冲区时,将在此时设置一个全局着色器矩阵数组属性。效果等同于Shader.SetGlobalMatrixArray。
函数定义:
1.public void SetGlobalMatrixArray(string propertyName, Matrix4x4[] values);
2.public void SetGlobalMatrixArray(int nameID, Matrix4x4[] values);
3.public void SetGlobalMatrixArray(string propertyName, List<Matrix4x4> value);
4.public void SetGlobalMatrixArray(int nameID, List<Matrix4x4> value);
SetGlobalTexture:添加"设置全局着色器纹理属性"命令,引用渲染纹理.当命令缓冲区被执行时,一个全局着色器纹理属性将在此时被设置。效果等价于调用Shader.SetGlobalTexture,但是使用的是RenderTexture而不是Texture。
函数定义:
1.public void SetGlobalTexture(string name, Rendering.RenderTargetIdentifier value);
2.public void SetGlobalTexture(int nameID, Rendering.RenderTargetIdentifier value);
3.public void SetGlobalTexture(string name, Rendering.RenderTargetIdentifier value);
4.public void SetGlobalTexture(int nameID, Rendering.RenderTargetIdentifier value, Rendering.RenderTextureSubElement element);
SetGlobalVector:添加"设置全局着色器vector属性"命令。当执行命令缓冲区时,将在此时设置全局着色器vector属性。效果等价于调用Shader.SetGlobalVector。
函数定义:
1.public void SetGlobalVector(string name, Vector4 value);
2.public void SetGlobalVector(int nameID, Vector4 value);
SetGlobalVectorArray:添加"设置全局着色器vector数组属性"命令。当执行命令缓冲区时,将在此时设置全局着色器vector数组属性。效果等价于调用Shader.SetGlobalVectorArray。
函数定义:
1.public void SetGlobalVectorArray(string propertyName, Vector4[] values);
2.public void SetGlobalVectorArray(int nameID, Vector4[] values);
3.public void SetGlobalVectorArray(string propertyName, List<Vector4>values);
4.public void SetGlobalVectorArray(int nameID, List<Vector4>values);
SetInstanceMultiplier:添加一个命令,将每个draw call的实例计数乘以一个特定的乘数。改变实例乘法器对于立体渲染优化很有用,比如单pass实例渲染。例如:如果将乘数设置为2,则绘制一个实例的命令将绘制2个实例,而绘制2个实例的命令将绘制4个实例。可查看Single Pass Instanced Rendering。在使用新值再次调用该函数进行重置之前,将一直使用该乘数。默认的乘数是1。将参数值0传递给该函数也会将实例乘数设置为1。实例乘法器影响内部Unity引擎函数以及CommandBuffer提交的绘制调用,例如:CommandBuffer.DrawMesh、CommandBuffer.DrawMeshInstanced、Graphics.DrawMeshInstanced、CommandBuffer.DrawProcedural和Graphics.DrawProcedural。注意:乘数不用于间接命令,例如:CommandBuffer.DrawMeshInstancedIndirect、Graphics.DrawMeshInstancedIndirect、CommandBuffer.DrawProceduralIndirect、Graphics.DrawProceduralIndirect。
函数定义:public void SetInstanceMultiplier(uint multiplier);
SetInvertCulling:想缓冲区中添加"设置invert culling"命令。当执行命令缓冲区时,背面剔除是反转的(当invertCulling设置为tru)还是不反转(当invertCulling设置为false),参见GL.invertCulling.
函数定义:public void SetInvertCulling(bool invertCulling)
函数参数:
1.invertCulling:一个布尔值,指示是否反转背面剔除(true)或不反转。
SetProjectionMatrix:添加一个命令来设置投影矩阵。投影矩阵是将视图空间变换为齐次裁剪空间的矩阵。当你想同时设置视图和投影矩阵时,使用SetViewProjectionMatrices会更有效率,因为它可以在一个命令缓冲区中同时设置。
函数定义:public void SetProjectionMatrix(Matrix4x4 proj)
函数参数:
1.proj:投影(相机到裁剪空间)矩阵
SetRandomWriteTarget:为着色器模型为4.5级片元着色器设置随机写入目标。这等同于调用Graphics.SetRandomWriteTarget。同样的限制以及nad异常也适用于这个函数。
函数定义:
1.public void SetRandomWriteTarget(int index, Rendering.RenderTargetIdentifier rt)
2.public void SetRandomWriteTarget(int index, ComputeBuffer buffer, bool preserveCounterValue);
函数参数:
1.index:在着色器中随机写入目标的索引
2.buffer:设置为写入目标的ComputeBuffer
SetRayTracingAccelerationStructure:添加一个命令来设置要与RayTracingShader一起使用的RayTracingAccelerationStructure。
函数参数:
1.RayTracingShader:使用的RayTracingShader
2.name:着色器编码器中RayTracingAccelerationStructure的名称
3.nameID:属性名ID。使用Shader.PropertyToID来获取这个ID
4.accelerationStructure:要使用的RayTracingAccelerationStructure。
SetRayTracingBufferParam:在RayTracingShader上添加一个命令来设置SetRayTracingBufferParam输入或输出缓冲区参数。
函数定义:CommandBuffer.SetRayTracingBufferParam(RayTracingShader, int, string, ComputeBuffer);
函数参数:
1.name:着色器代码中缓冲区变量的名称
2.nameID:属性名ID。使用Shader.PropertyToID来获取这个ID
3.buffer:设置的buffer
SetRayTracingFloatParam:添加一个命令来设置RayTracingShader上的float参数。
函数参数:
1.public void SetRayTracingFloatParam(Experimental.Rendering.RayTracingShader rayTracingShader, string name, float val);
2.public void SetRayTracingFloatParam(Experimental.Rendering.RayTracingShader rayTracingShader, int nameID, float val);
函数参数:
1.RayTracingShader:设置参数的RayTracingShader
2.name:着色器代码中变量的名称
3.nameID:属性名ID。使用Shader.PropertyToID来获取这个ID
4.val:设置的值
SetRayTracingFloatParams:添加一个命令来设置一个RayTracingShader上的多个连续的float参数。此函数可用于设置float vector, float array或float vector array的值。例如:在光线追踪着色器中的float4 myArray[4]可以通过传递16个浮点数来填充。
函数定义:
1.public void SetRayTracingFloatParams(Experimental.Rendering.RayTracingShader rayTracingShader, string name, params float[] values);
2.public void SetRayTracignFloatParams(Experimental.Rendering.RayTracingShader rayTracingShader, int nameID, params float[] values);
函数参数:
1.RayTracingShader:设置参数的RayTracingShader
2.name:着色器代码中变量的名称
3.nameID:属性名ID。使用Shader.PropertyToID来获取这个ID
4.values:设置的值
SetRayTracingIntParam:添加一个命令来设置RayTracingShader的整形参数
函数定义:
1.public void SetRayTracingIntParam(Experimental.Rendering.RayTracingShader rayTracingShader, string name, int val);
2.public void SetRayTracingIntParam(Experimental.Rendering.RayTracingShader rayTracingShader, int nameID, int val);
函数参数:
1.RayTracingShader:设置参数的RayTracingShader
2.name:着色器代码中变量的名称
3.nameID:属性名ID。使用Shader.PropertyToID来获取这个ID
4.val: 设置的值
SetRayTracingIntParams:添加一个命令来设置一个RayTracingShader上的多个连续整数参数。此函数可用于设置整数向量、整数数组或整数向量数组的值。例如:射线跟踪着色器中的int4 myArray[2]可以通过传递8个整数来填充。
函数定义:
1.public void SetRayTracingIntParams(Experimental.Rendering.RayTracingShader rayTracingShader, string name, params int[] values);
2.public void SetRayTracingIntParams(Experimental.Rendering.RayTracingShader rayTracingShader, int nameID, params int[] values);
函数参数:
1.RayTracingShader:设置参数的RayTracingShader
2.name:着色器代码中变量的名称
3.nameID:属性名ID。使用Shader.PropertyToID来获取这个ID
4.values:设置的值
SetRayTracingMatrixArrayParam:添加一个命令来设置RayTracingShader上的矩阵数组参数。
函数定义:
1.public void SetRayTracingMatrixArrayParam(Experimental.Rendering.RayTracingShader rayTracingShader, string name, params Matrix4x4[] values);
2.public void SetRayTracingMatrixArrayParam(Experimental.Rendering.RayTracingShader rayTracingShader, int nameID, params Matrix4X4[] values);
函数参数:
1.RayTracingShader:设置参数的RayTracingShader
2.name:着色器代码中变量的名称
3.nameID:属性名ID。使用Shader.PropertyToID来获取这个ID
4.values:设置的值
SetRayTracingMatrixParam:添加一个命令来设置RayTracingShader上的一个矩阵参数。
函数定义:
1.public void SetRayTracingMatrixParam(Experimental.Rendering.RayTracingShader rayTracingShader, string name, Matrix4x4 val);
2.public void SetRayTracingMatrixParam(Experimental.Rendering.RayTracingShader rayTracingShader, int nameID, Matrix4x4 val);
函数参数:
1.RayTracingShader:设置参数的RayTracingShader
2.name:着色器代码中变量的名称
3.nameID:属性名ID。使用Shader.PropertyToID来获取这个ID
4.val:设置的值
SetRayTracingShaderPass:添加一个命令来设置要使用的RayTracingShader的pass.
函数定义:public void SetRayTracingShaderPass(Experimental.Rendering.RayTracingShader rayTracingShader, string passName);
函数参数:
1.RayTracingShader:使用的RayTracingShader
2.passName:使用的pass名称
SetRayTracingTextureParam:添加一个命令来设置要使用的RayTracingShader的一个纹理参数
函数参数:public void SetRayTracingTextureParam(Experimental.Rendering.RayTracingShader rayTracingShader, string name, Rendering.RenderTargetIdentifier rt);
函数参数:
1.RayTracingShader:设置参数的RayTracingShader
2.name:纹理变量在着色器代码中的名称
3.nameID:属性名ID。使用Shader.PropertyToID来获取这个ID
4.rt:纹理值或标识符设置,可查看RenderTargetIdentifier
SetRayTracingVectorArrayParam:添加一个命令来设置要使用的RayTracingShader的一个vector数组参数。
函数定义:
1.public void SetRayTracingVectorArrayParam(Experimental.Rendering.RayTracingShader rayTracingShader, string name, params Vector4[] values);
2.public void SetRayTracingVectorArrayParam(Experimental.Rendering.RayTracingShader rayTracingShader, int nameID, params Vector4[] values);
函数参数:
1.RayTracingShader:设置参数的RayTracingShader
2.name:着色器代码中变量的名称
3.nameID:属性名ID。使用Shader.PropertyToID来获取这个ID
4.values:设置的值
SetRayTracignVectorParam:添加一个命令来设置要使用的RayTracingShader的一个vector参数。
函数定义:
1.public void SetRayTracingVectorParam(Experimental.Rendering.RayTracingShadere rayTracingShader, string name, Vector4 val);
2.public void SetRayTracingVectorParam(Experimental.Rendering.RayTracignShader rayTracingShader, int nameID, Vector4 val);
函数参数:
1.RayTracingShader:设置参数的RayTracingShader
2.name:着色器代码中变量的名称
3.nameID:属性名ID。使用Shader.PropertyToID来获取这个ID
4.val:设置的值
SetRenderTarget:添加"设置激活的渲染目标"命令。要使用的渲染纹理可以用几种方式表示:RenderTexture对象,用GetTemporaryRT创建的临时渲染纹理,或者内置的临时纹理之一(BuiltinRenderTextureType)。所有这些都是由RenderTargetIdentifier结构表示的,该结构具有隐式转换操作以节省输入。你不需要再命令缓冲区执行期间显式地保留激活的渲染目标(当前渲染目标将在执行后保存和恢复)。这带有mipLevel和face参数的接口可以渲染RenderTexture的特定mipmap级别或特定cubemap面。在没有显示指定mipLevel、cubemapFace和depthSlice的情况下,会使用RenderTargetIdentifier中指定的mipLevel、cubemapFace和depthSlice值设置单个渲染目标。若设置多个渲染目标且没有另外指定,将把mipLevel、cubemapFace和depthSlice设置为0、Unknown和0。如果有指定,将为所有渲染目标使用指定的mipLevel、cubemapFace和depthSlice。注意:在线性颜色空间中,设置正确的sRGB<->线性颜色转换状态是很重要的。根据之前的渲染内容,当前状态可能不是你期望的状态。在执行SetRenderTarget或任何其他手动渲染之前,你可以根据需要设置GL.sRGBWrite。Rendering.RenderTargetIdentifier.Clear目前不受支持。对ClearRenderTarget的后续调用具有相同的效果,并且在支持清除加载操作的图形API上进行了优化。
函数定义:
1.public void SetRenderTarget(Rendering.RenderTargetIdentifier rt);
2.public void SetRenderTarget(Rendering.RenderTargetIdentifier rt, Rendering.RenderBufferLoadAction loadAction, Rendering.RenderBufferStoreAction storeAction);
3.public void SetRenderTarget(Rendering.RenderTargetIdentifier rt, Rendering.RenderBufferLoadAction colorLoadAction, Rendering.RenderBufferStoreAction colorStoreAction, Rendering.RenderBufferLoadAction depthLoadAction, Rendering.RenderBufferStoreAction depthStoreAction);
4.public void SetRenderTarget(Rendering.RenderTargetIdentifier rt, int mipLevel);
5.public void SetRenderTarget(Rendering.RenderTargetIdentifier rt, int mipLevel, CubemapFace cubemapFace);
6.public void SetRenderTarget(Rendering.RenderTargetIdentifier rt, int mipLevel, CubemapFace cubemapFace, int depthSlice);
7.public void SetRenderTarget(Rendering.RenderTargetIdentifier color, Rendering.RenderTargetIdentifier depth);
8.public void SetRenderTarget(Rendering.RenderTargetIdentifier color, Rendering.RenderBufferLoadAction colorLoadAction, Rendering.RenderBufferStoreAction colorStoreAction, Rendering.RenderTargetIdentifier depth, Rendering.RenderBufferLoadAction depthLoadAction, Rendering.RenderBufferStoreAction depthStoreAction);
9.public void SetRenderTarget(Rendering.RenderTargetIdentifier color, Rendering.RenderTargetIdentifier depth, int mipLevel);
10.public void SetRenderTarget(Rendering.RenderTargetIdentifier color, Rendering.RenderTargetIdentifier depth, int mipLevel, CubemapFace cubemapFace);
11.public void SetRenderTarget(Rendering.RenderTargetIdentifier color, Rendering.RenderTargetIdentifier depth, int mipLevel, CubemapFace cubemapFace, int depthSlice);
12.public void SetRenderTarget(RenderTargetIdentifier[] colors, Rendering.RenderTargetIdentifier depth);
13.public void SetRenderTarget(Rendering.RenderTargetBinding binding);
14.public void SetRenderTarget(Rendering.RenderTargetBinding binding, int mipLevel, CubemapFace cubemapFace, int depthSlice);
15.public void SetRenderTarget(RenderTargetIdentifier[] colors, Rendering.RenderTargetIdentifier depth, int mipLevel, CubemapFace cubemapFace, int depthSlice);
函数参数:
1.rt:渲染目标设置为颜色和深度缓冲区
2.color:渲染目标设置为一个颜色缓冲
3.colors:渲染目标设置为多个颜色缓冲(MRT)
4.depth:渲染目标设置为深度缓冲
5.mipLevel:渲染目标的mip级别
6.cubemapFace:要渲染的cubemap的cubemap面
7.depthSlice:要设置的3D或数组渲染目标的切片
8.loadAction:加载用于颜色和深度/模板缓冲的操作
9.storeAction:存储用于颜色和深度/模板缓冲区的操作
10.colorLoadAction:加载用于颜色缓冲区的操作
11.colorStoreAction:存储用于颜色缓冲区的操作
12.depthLoadAction:加载用于深度/模板缓冲区的操作
13.depthStoreAction:存储用于深度/模板缓冲区的操作
SetShadowSamplingMode:添加"设置阴影采样模式"命令。Shadowmap渲染纹理通常设置为使用比较过滤器进行采样--采样器获取屏幕像素的阴影空间深度值,并返回01,这取决于阴影映射中的深度值是大还是小。ShadowSamplingMode.CompareDepths是渲染阴影默认的比较模式。如果你想在常规纹理中访问阴影贴图的值,将采样模式设置为ShadowSamplingMode.RawDepth。Shadowmap的采样模式将在当前CommandBuffer的最后一个命令之后恢复到默认状态。通过SystemInfo.supportsRawShadowDepthSampling来验证当前运行平台是否支持以这种方式采样阴影。例如:DirectX9不支持。
函数定义:public void SetShadowSamplingMode(Rendering.RenderTargetIdentifier shadowmap, Rendering.ShadowSamplingMode mode)
函数参数:
1.shadowmap:改变采样模式的Shadowmap渲染目标。
2.mode:新的采样模式。
代码示例:
using UnityEngine;
using UnityEngine.Rendering;

public class CommandBufferTest : MonoBehaviour {
    public Light m_Light;
    RenderTexture m_ShadowmapCopy;

	void Start () {
        RenderTargetIdentifier shadowmap = BuiltinRenderTextureType.CurrentActive;
        m_ShadowmapCopy = new RenderTexture(1024, 1024, 0);
        CommandBuffer cb = new CommandBuffer();
        //改变m_Light's shadowmap的阴影采样模式
        cb.SetShadowSamplingMode(shadowmap, ShadowSamplingMode.RawDepth);
        //shadowmap现在可以正常采样-复制到一个不同的渲染纹理中
        cb.Blit(shadowmap, new RenderTargetIdentifier(m_ShadowmapCopy));
        //在shadowmap填充后被执行
        m_Light.AddCommandBuffer(LightEvent.AfterShadowMap, cb);
        //采样模式在这个命令缓冲区完成后自动恢复,因此阴影将正常渲染



	}
    //在完成所有图像完成渲染后,将调用OnRenderImage
    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        //在角落渲染阴影
        Camera.main.rect = new Rect(0, 0, 0.5f, 0.5f);
        Graphics.Blit(m_ShadowmapCopy, destination);
        Camera.main.rect = new Rect(0, 0, 1, 1);
    }
}

Unity流水账14:GL、Graphics及CommandBuffer_第1张图片

SetSinglePassStereo:添加一个命令来设置相机的单通道立体模式。此属性仅在启用虚拟现实时使用。传递给mode的值可以在SinglePassStereoMode枚举中找到。这可以与shader关键字配对(例如:UNITY_SINGLE_PASS_STEREO),以暂时禁用全屏效果的立体声渲染。注意:当启用立体声时,改变单通道立体声模式会导致渲染伪影。
函数定义:CommandBuffer.SetSinglePassStereo(SinglePass StereoMode)
函数参数:
1.mode:相机的单通道立体模式
SetViewMatrix:添加一个命令来设置视图矩阵。视图矩阵是将世界空间转换为摄像机空间的矩阵。在设置视图和投影矩阵时,使用SetViewProjectionMatrices会更有效率。注意:Unity中的相机空间遵循OpenGL约定,所以负z轴是相机的前向。如果你手动创建视图矩阵,例如使用Matrix4x4.LookAt的逆矩阵,你需要在z轴缩放-1来得到一个合适的视图矩阵。
函数定义:public void SetViewMatrix(Matrix4x4 view);
函数参数:
1.view:视图(世界到相机空间)矩阵
代码示例:
using UnityEngine;
using UnityEngine.Rendering;

//将此脚本附加到相机并选择一个网格进行渲染。
//当进入播放模式时,命令缓冲区会在起始位置渲染一个绿色网格
[RequireComponent(typeof(Camera))]
public class CommandBufferTest : MonoBehaviour {
    public Mesh mesh;
    private void Start()
    {
        var material = new Material(Shader.Find("Hidden/Internal-Colored"));
        material.SetColor("_Color", Color.green);
        var tr = transform;
        var camera = GetComponent<Camera>();
        //下面的代码等同于camera.worldToCameraMatrix
        //在这里"手动"来演示如何构造视图矩阵
        //从摄像机的位置沿前轴观察的矩阵
        var lookMatrix = Matrix4x4.LookAt(tr.position, tr.position + tr.forward, tr.up);
        //沿着Z轴进行镜像转换,以匹配摄像机空间的约定(右手坐标系)
        //未起作用?
        var scaleMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1, 1, -1));
        //最终的视图矩阵是LookAt矩阵的逆矩阵,然后沿Z镜像
        var viewMatrix = scaleMatrix * lookMatrix.inverse;
        var buffer = new CommandBuffer();
        buffer.SetViewMatrix(viewMatrix);
        buffer.SetProjectionMatrix(camera.projectionMatrix);
        var meshMatrix = new Matrix4x4(new Vector4(0.1f, 0, 0, 0),
            new Vector4(0, 0.1f, 0, 0),
            new Vector4(0, 0, 1, 0),
            new Vector4(0, 0, 0, 1));
        buffer.DrawMesh(mesh, meshMatrix, material);
        //buffer.DrawMesh(mesh, Matrix4x4.identity, material);
        camera.AddCommandBuffer(CameraEvent.BeforeSkybox, buffer);
    }
}

Unity流水账14:GL、Graphics及CommandBuffer_第2张图片

SetViewport:添加一个命令来设置渲染窗口。默认情况下,在渲染目标改变后,视口被设置为包含整个渲染目标。此命令可用于进一步将渲染限制到指定的像素矩形。
函数定义:public void SetViewport(Rect pixelRect)
函数参数:
1.pixelRect:视口矩形的像素坐标
SetViewProjectionMatrices:添加一个命令来设置视图和投影矩阵。这个函数相当于调用SetViewMatrix和SetProjectionMatrix。当同时改变两个矩阵时,使用此函数效率会稍微高一些。注意:Unity中的相机空间遵循OpenGL约定,所以负z轴是相机的前向。如果你手动创建视图矩阵,例如使用Matrix4x4.LookAt的逆矩阵,你需要在z轴缩放-1来得到一个合适的视图矩阵。
函数定义:public void SetViewProjectionMatrices(Matrix4x4 view, Matrix4x4 proj);
函数参数:
1.view:视图(世界空间到观察空间)矩阵
2.proj:投影(观察空间到裁剪空间)矩阵
代码示例:
using UnityEngine;
using UnityEngine.Rendering;

//将此脚本附加到相机并选择一个网格进行渲染。
//当进入播放模式时,命令缓冲区会在起始位置渲染一个绿色网格
[RequireComponent(typeof(Camera))]
public class CommandBufferTest : MonoBehaviour {
    public Mesh mesh;
    private void Start()
    {
        var material = new Material(Shader.Find("Hidden/Internal-Colored"));
        material.SetColor("_Color", Color.green);
        var tr = transform;
        var camera = GetComponent<Camera>();
        //下面的代码等同于camera.worldToCameraMatrix
        //在这里"手动"来演示如何构造视图矩阵
        //从摄像机的位置沿前轴观察的矩阵
        var lookMatrix = Matrix4x4.LookAt(tr.position, tr.position + tr.forward, tr.up);
        //沿着Z轴进行镜像转换,以匹配摄像机空间的约定(右手坐标系)
        //未起作用?
        var scaleMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1, 1, -1));
        //最终的视图矩阵是LookAt矩阵的逆矩阵,然后沿Z镜像
        var viewMatrix = scaleMatrix * lookMatrix.inverse;
        var buffer = new CommandBuffer();
        //代码生效
        buffer.SetViewProjectionMatrices(viewMatrix, camera.projectionMatrix);
        var meshMatrix = new Matrix4x4(new Vector4(1, 0, 0, 0),
            new Vector4(0, 1, 0, 0),
            new Vector4(0, 0, 1, 0),
            new Vector4(0, 0, 0, 1));
        buffer.DrawMesh(mesh, meshMatrix, material);
        //buffer.DrawMesh(mesh, Matrix4x4.identity, material);
        camera.AddCommandBuffer(CameraEvent.BeforeSkybox, buffer);
    }
}

Unity流水账14:GL、Graphics及CommandBuffer_第3张图片

WaitAllAsyncReadbackRequests:增加了一个"AsyncGPUReadback.WaitAllRequests"命令到CommandBuffer。
函数定义:public void WaitAllAsyncReadbackRequests();
WaitOnAsyncGraphicsFence:指示GPU等待,直到给定的GraphicsFence被传递。如果使用Graphics.ExcuteCommandBuffer或ScriptableRenderContext.ExecuteCommandBuffer执行这个命令缓冲区,那么图像队列的处理将会等待。必须使用GraphicsFenceType.AsyncQueueSynchronization fence类型创建GraphicsFence的参数。如果使用Graphics.ExecuteCommandBufferAsync或ScriptableRenderContext.ExecuteCommandBufferAsyn执行这个命令缓冲区,那么执行命令缓冲区的队列将会等待。在不支持GraphicsFences的平台上,此调用不执行任何操作。可使用SystemInfo.supportsGraphicsFence查询。这个函数在CPU上立即执行返回。只有GPU的处理会受fence的影响。可查看: Graphics.ExecuteCommandBufferAsync、Graphics.CreateGraphicsFence、ScriptableRenderContext.ExecuteCommandBufferAsync、ScriptableRenderContext.CreateGraphicsFence.
函数定义:
1.public void WaitOnAsyncGraphicsFence(Rendering.GraphicsFence fence);
2.public void WaitOnAsyncGraphicsFence(Rendering.GraphicsFence fence, Rendering.SynchronisationStage stage);
函数参数:
1.fence:将指示GPU等待fence处理完后再继续处理图形队列
2.stage:在某些平台上,对于给定的绘制调用,在顶点处理完成与像素处理开始之间调用, 结果有很大区别。此参数允许请求的等待时间在下一个项目的顶点或像素处理开始之前。如果compute shader调度是要提交的下一项,则将忽略此参数。

参考资料:
  1.OnPostRender:在相机完成场景渲染后,将调用OnPostRender,此消息将发送到摄像机附带的所有脚本。
  2.OnRenderImage:在完成所有图像完成渲染后,将调用OnRenderImage。PostProcessing effects。它允许你通过基于着色器的滤镜处理最终图像来修改最终图像。传入的图像是源渲染纹理。结果应最终在目标渲染纹理中。如果你重写此方法,则必须始终发出Graphics.Blit()或渲染全屏四边形。当相机上装有多个图像滤镜时,他们会通过将第一个滤镜的最终图像作为下一个滤镜的源渲染纹理,来顺序处理图像。此消息将发送摄像机附带的所有脚本。
  3.OnPreRender:在照相机开始渲染场景之前调用OnPreRender。仅当脚本已附加到相机并已启用时,才调用此功能。注意,如果你在此处更改摄像机的视图参数(例如:Camera.fieldOfView),则它们只会在下一帧生效。可在OnPreCull中执行此操作。OnPreRender可以是一个coroutine,只需在函数中使用yield语句即可。另外,在调用OnPreRender时,尚未设置相机的渲染目标,并且也为渲染深度纹理。如果你想要设置渲染目标后再进行操作,可使用CommandBuff。
  4.GL
  5.Graphics
  6.CommandBuffer
  7.D3D11笔记——Resource基本概念

你可能感兴趣的:(unity)