Unity 封装的图形API
文章目录
- Unity 封装的图形API
-
- 一、 CommandBuffer 要执行的图形命令列表
- 二、 ScriptableRenderContext context (2021.3版本)
-
- 常用函数方法
-
- context.Cull
- context.DrawGizmos
- context.DrawRenderers
- void DrawShadows (ref Rendering.ShadowDrawingSettings settings);
- void DrawSkybox (Camera camera);
- context.DrawWireOverlay(camera);
- context.ExecuteCommandBuffer(cmd);
- context.SetupCameraProperties(camera);
- context.Submit();
- if (!context.SubmitForRenderPassValidation()){...}
- 其他
一、 CommandBuffer 要执行的图形命令列表
命令缓冲区保存渲染命令列表(“设置渲染目标,绘制网格,…”)。它们可以设置为在相机渲染(参见camera . addcommandbuffer)、灯光渲染(参见light . addcommandbuffer)或立即执行(参见Graphics.ExecuteCommandBuffer)期间的不同处执行。
通常情况下,它们会以自定义方式扩展Unity的渲染管道。例如,您可以在完成所有常规对象之后将一些附加对象渲染到延迟渲染G-buffer中,或者对光影贴图进行自定义处理。有关详细信息,请参阅 command buffers overview概述页面。
如果需要,可以创建命令缓冲区,然后多次执行。(也就是说一般使用完毕后需要手动清除缓存,如果命令是Loop的,则可以循环执行)
1. CommandBuffer 属性
- string name:Name of this command buffer.
- int sizeInBytes: Size of this command buffer in bytes (Read Only).
//
// 摘要:
// List of graphics commands to execute.
[NativeType("Runtime/Graphics/CommandBuffer/RenderingCommandBuffer.h")]
[NativeHeader("Runtime/Shaders/ComputeShader.h")]
[UsedByNativeCode]
[NativeHeader("Runtime/Shaders/RayTracingShader.h")]
[NativeHeader("Runtime/Export/Graphics/RenderingCommandBuffer.bindings.h")]
public class CommandBuffer : IDisposable
{
}
2. CommandBuffer 常用图形API(方法)
(1)设置
void SetViewport(Rect pixelRect);设置视口矩形大小
void EnableScissorRect(Rect scissor);设置裁剪矩形大小
void DisableScissorRect();
void DisableScissorRect();取消矩形裁剪
设置缓冲区数据
- 缓冲器计数器值:void SetBufferCounterValue(GraphicsBuffer buffer, uint counterValue);
- 缓冲器数据:void SetBufferData(GraphicsBuffer buffer, Array data);
(2)获取临时纹理 GetTemporaryRT以及释放
CommandBuffer.GetTemporaryRT;获取临时渲染纹理
static int nameID = Shader.PropertyToID("_FrameBuffer");
public void GetTemporaryRT(
int nameID, //这个纹理的Shader属性名。
int width, int height,
int depthBuffer, //深度缓冲位(0,16或24)。
FilterMode filter, //纹理过滤模式(默认为Point)。还有Bilinear、Trilinear
RenderTextureFormat format, //RenderTexture的格式。(常用有:ARGB32(Default)、Depth、Shadowmap、...)
RenderTextureReadWrite readWrite, //Linear,sRGB,Default(与project settings有关)
int antiAliasing, //抗锯齿(默认为no anti-aliasing)。
bool enableRandomWrite);//是否应该启用对纹理的随机写入访问(默认为false)。
使用ReleaseTemporaryRT释放临时渲染纹理,传递相同的nameID。任何没有明确释放的临时纹理将在相机完成渲染时,或在Graphics.ExecuteCommandBuffer结束后被删除。
获得临时渲染纹理后,您可以将其设置为活动(SetRenderTarget)或 blit to/from it。在命令缓冲区执行期间,您不需要显式地保留活动渲染目标(当前渲染目标将在之后保存和恢复)。
RenderTextureReadWrite:
如果使用Gamma色彩空间,RenderTextureReadWrite readWrite的设置没有任何作用。
- sRGB :如果使用Linear色彩空间,默认输入为sRGB,fragment输出为线性空间颜色。当渲染到texture时,fragment输出转化为sRGB空间。当在Shader中采样纹理,sRGB色彩空间会自动转为线性空间。
- Linear:然而,如果你的渲染纹理包含非颜色数据(法线,速度,其他自定义值),那么你不希望Linear<->sRGB转换发生。
- 当纹理类型为 “HDR” (floating point) formats、Depth、Shadowmap,则无论readWrite设为什么,都会使用线性空间。
我们可以通过RenderTexture.sRGB,了解渲染纹理使用sRGB或是Linear。如果为sRGB,返回true;如果为Linear,返回false。
释放:
void ReleaseTemporaryRT(int nameID);
(3)设置纹理为渲染目标 SetRenderTarget
public void SetRenderTarget(
Rendering.RenderTargetIdentifier color, //渲染目标设置为颜色缓冲。
Rendering.RenderBufferLoadAction colorLoadAction, //用于颜色的加载操作。
Rendering.RenderBufferStoreAction colorStoreAction, //用于颜色的存储操作。
Rendering.RenderTargetIdentifier depth, //将渲染目标设置为深度缓冲区。
Rendering.RenderBufferLoadAction depthLoadAction, //用于深度/模板缓冲区的加载操作。
Rendering.RenderBufferStoreAction depthStoreAction);//用于深度/模板缓冲区的存储操作
public void SetRenderTarget(
RenderTargetIdentifier[] colors, // MRT 多重纹理渲染(DBuffer)
Rendering.RenderTargetIdentifier depth,
int mipLevel, //要渲染到的渲染目标的mip级别。
CubemapFace cubemapFace, //要渲染到立方体哪一个方向的表面。
int depthSlice); //要设置的3D或阵列渲染目标的层。
渲染纹理可以用几种方式表示:一个RenderTexture对象,一个用GetTemporaryRT创建的临时渲染纹理,或者一个内置的临时纹理(BuiltinRenderTextureType)。所有这些都由RenderTargetIdentifier结构体表示,该结构体具有隐式转换操作符以节省输入。
Rendering.RenderBufferLoadAction
当GPU开始渲染到渲染目标时,此设置指定应该在表面的现有内容上执行的操作。如果加载动作是Clear或not care,Tile-based GPUs可能会获得性能优势。用户应该避免使用RenderBufferLoadAction。尽可能Load 。
请注意,并非所有平台都有加载/存储操作,因此此设置可能在运行时被忽略。通常面向移动设备的图形api (OpenGL ES, Metal)会利用这些设置。
如果你使用RenderBufferLoadAction.DontCare,渲染可能会失败或产生伪影,因为深度纹理中未定义的像素会导致深度测试失败。你可以使用LoadStoreActionDebugModeSettings 来突出显示未定义的像素。
- Load:当这个RenderBuffer被激活时,保留它的现有内容。这种设置在基于tile的gpu上很昂贵,应该尽可能避免。
- Clear:激活渲染缓冲区后,清除其内容。目前只能与RenderPass API一起工作。
- DontCare:当这个RenderBuffer被激活时,GPU被指示不关心RenderBuffer的现有内容。在基于tile的gpu上,这意味着RenderBuffer内容不需要加载到tile内存中,从而提供了性能提升。
Rendering.RenderBufferStoreAction
这个枚举描述了当GPU完成渲染到渲染目标时应该在渲染目标上做什么。
当GPU完成渲染到渲染目标时,此设置指定应该对渲染结果执行的操作。如果存储操作为“不关心”,基于tile的gpu可能会获得性能优势。例如,如果渲染帧后不需要深度缓冲区内容,则此设置可能很有用。
请注意,并非所有平台都有加载/存储操作,因此此设置可能在运行时被忽略。通常面向移动设备的图形api (OpenGL ES, Metal)会利用这些设置。
如果你使用RenderBufferLoadAction.DontCare,渲染可能会失败或产生伪影,因为深度纹理中未定义的像素会导致深度测试失败。你可以使用LoadStoreActionDebugModeSettings来突出显示未定义的像素。
- Store:RenderBuffer内容需要存储到RAM中。如果表面启用了MSAA,则存储多采样版本(未解析的表面)。
- Resolve:解析MSAA曲面后再保存。
- StoreAndResolve:解析MSAA表面,但也存储多采样版本。
- DontCare:RenderBuffer的内容是不需要的,可以被丢弃。基于tile的gpu将完全跳过写入表面内容,从而提供性能提升。
RenderTargetIdentifier结构体
(4)CommandBuffer.Blit
void Blit(Texture source, Rendering.RenderTargetIdentifier dest, Material mat, int pass);
添加一个命令,使用着色器将纹理中的像素数据复制到渲染纹理中。
这个方法增加了一个命令,将像素数据从GPU上的纹理复制到GPU上的渲染纹理。这是复制纹理最快的方法之一。
当你使用Graphics.Blit, Unity做了以下几点:
- 将 active render texture 设置为dest纹理。
- 将source作为_MainT