当前位置: 首页 > news >正文

Unity SRP 管线【第十讲:SRP/URP 图形API】

Unity 封装的图形API

文章目录

  • Unity 封装的图形API
    • 一、 CommandBuffer 要执行的图形命令列表
      • 1. CommandBuffer 属性
      • 2. CommandBuffer 常用图形API(方法)
        • (1)设置
        • (2)获取临时纹理 GetTemporaryRT以及释放
        • (3)设置纹理为渲染目标 SetRenderTarget
        • (4)CommandBuffer.Blit
        • (5)填充Shader变量数据
        • (6)绘制
        • (7)转换纹理格式 ConvertTexture
        • (8)复制
        • (9)清除
      • 3. CommandBuffer 不常用图形API
    • 二、 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();取消矩形裁剪

设置缓冲区数据

  1. 缓冲器计数器值:void SetBufferCounterValue(GraphicsBuffer buffer, uint counterValue);
  2. 缓冲器数据: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、TrilinearRenderTextureFormat 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做了以下几点:

  1. 将 active render texture 设置为dest纹理。
  2. 将source作为_MainTex属性传递给mat材质。
  3. 使用材质的着色器绘制从源纹理到目标纹理的全屏表面。

如果你提供一个没有_MainTex属性的mat材质,Blit不会使用source。

你可以使用Graphics.Blit创建后处理效果,通过设置 自定义着色器 mat 到一个材质。

Blit改变了RenderTexture.active。在使用Blit之前存储active render texture,如果之后需要使用它。

避免将source和dest设置为相同的渲染纹理,因为这可能导致未定义的行为。使用带有双缓冲的自定义渲染纹理代替,或者使用两个渲染纹理并在它们之间交替手动实现双缓冲。

在线性色彩空间中,在使用Blit之前设置GL.sRGBWrite,以确保srgb到线性色彩转换是您所期望的。

要在内置渲染管道中blit到屏幕上,请遵循以下步骤:

  1. 将dest设置为空。Unity现在使用Camera.main.targetTexture作为目标纹理。
  2. 设置 Camera.main的Camera.targetTexture 属性为null。

要在通用渲染管道(URP)或高清晰度渲染管道(HDRP)中将数据blit到屏幕上,必须在你从RenderPipelineManager.endContextRendering调用的方法中回调处调用Graphics.Blit或 CommandBuffer.Blit。

如果你想使用源(渲染)纹理一部分的深度或模板缓冲区,或者blit到纹理的子区域,你必须手动编写一个等效的Graphics.Blit函数——即,使用目标颜色缓冲区和源深度缓冲区设置Graphics.SetRenderTarget ,设置orthographic projection(GL.LoadOrtho),设置材质通道(material .setpass)并绘制一个四边形(GL.Begin)。

通常不需要保存Blit dest的先前内容。在这种情况下,建议使用SetRenderTarget使用适当的加载和存储操作显式地激活dest渲染目标。Blit dest应该被设置为BuiltinRenderTextureType.CurrentActive。

(5)填充Shader变量数据

Shader关键字设置

//添加一个命令来禁用全局或本地着色器关键字。
void DisableKeyword(ref Rendering.GlobalKeyword keyword);
void DisableKeyword(ComputeShader computeShader, ref Rendering.LocalKeyword keyword);
void DisableKeyword(Material material, ref Rendering.LocalKeyword keyword);
//添加一个命令来禁用一个给定名称的全局shader关键字。
void DisableShaderKeyword(string keyword);void EnableKeyword(ref Rendering.GlobalKeyword keyword);
.....

设置全局变量

void SetGlobalFloat(string name, float value);
void SetGlobalFloat(int nameID, float value);
同理还有FLoatArray、Int、Matrix、MatrixArray、Texture、Vector、VectorArrayvoid SetProjectionMatrix(Matrix4x4 proj);
void SetViewMatrix(Matrix4x4 view);
void SetViewProjectionMatrices(Matrix4x4 view, Matrix4x4 proj);

渲染纹理绑定:绑定渲染纹理后,才能再Pass中使用该Texture。当命令缓冲区将被执行时,一个全局着色器纹理属性将在此时被设置。

public void SetGlobalTexture(string name, Rendering.RenderTargetIdentifier value);
public void SetGlobalTexture(int nameID, Rendering.RenderTargetIdentifier value);
public void SetGlobalTexture(string name, Rendering.RenderTargetIdentifier value, Rendering.RenderTextureSubElement element);
public void SetGlobalTexture(int nameID, Rendering.RenderTargetIdentifier value, Rendering.RenderTextureSubElement element);
(6)绘制

所有的绘制命令都不会自动添加关于光照、阴影、全局光照等相关数据,如果需要相关变量数据,需要手动设置参数数据。否则,如果在Shader中使用相关变量,结果是未定义的。

// 一般绘制
void DrawMesh(Mesh mesh, Matrix4x4 matrix, Material material, int submeshIndex = 0, int shaderPass = -1, MaterialPropertyBlock properties = null);
// 实例化绘制
void DrawMeshInstanced(Mesh mesh, int submeshIndex, Material material, int shaderPass, Matrix4x4[] matrices, int count, MaterialPropertyBlock properties);
void DrawMeshInstanced(Mesh mesh, int submeshIndex, Material material, int shaderPass, Matrix4x4[] matrices, int count);
void DrawMeshInstanced(Mesh mesh, int submeshIndex, Material material, int shaderPass, Matrix4x4[] matrices);
// renderer数据绘制
void DrawRenderer(Renderer renderer, Material material, int submeshIndex = 0, int shaderPass = -1);
//程序化绘制
public void DrawProcedural(Matrix4x4 matrix, //使用的转化矩阵Matrix4x4.identityMaterial material, 	   //哪一个Shaderint shaderPass, 	   //哪一个PassMeshTopology topology, //程序几何的拓扑结构。MeshTopology.Trianglesint vertexCount, 	   //要渲染的索引计数。int instanceCount = 1, //要渲染的实例数。MaterialPropertyBlock properties = null);//在渲染之前应用额外的材料属性。
void DrawMeshInstancedProcedural(Mesh mesh, int submeshIndex, Material material, int shaderPass, int count, MaterialPropertyBlock properties);// 不常用绘制
void DrawMeshInstancedIndirect(Mesh mesh, int submeshIndex, Material material, int shaderPass, ComputeBuffer bufferWithArgs, int argsOffset, MaterialPropertyBlock properties);
void DrawProceduralIndirect(Matrix4x4 matrix, Material material, int shaderPass, MeshTopology topology, ComputeBuffer bufferWithArgs, int argsOffset, MaterialPropertyBlock properties);
void DrawOcclusionMesh(RectInt normalizedCamViewport);

程序化绘制Procedural(没有任何顶点或索引缓冲区)
当命令缓冲区执行时,这将在GPU上执行绘制调用,没有任何顶点或索引缓冲区。这主要用于Shader Model 4.5级硬件,Shader可以从ComputeBuffer缓冲区读取任意数据。

在顶点着色器中,你通常会使用SV_VertexID和SV_InstanceID输入变量从而从一些缓冲区中获取数据。
注意,这个drawCall不会设置任何与照明相关的着色器数据(光的颜色,方向,阴影,光和反射探针等)。如果材质使用的着色器使用任何与照明相关的变量,结果是未定义的。

(7)转换纹理格式 ConvertTexture

将源纹理转换并复制到具有不同格式或尺寸的目标纹理

// 参数:
//   src:原纹理
//   dst:目标纹理.
//   srcElement:纹理下标(例如CubeMap,Texture2DArray等)
//   dstElement:目标纹理下标
//     Destination element (e.g. cubemap face or texture array element).
public void ConvertTexture(RenderTargetIdentifier src, RenderTargetIdentifier dst)
public void ConvertTexture(RenderTargetIdentifier src, int srcElement, RenderTargetIdentifier dst, int dstElement)
(8)复制
// 只用于GraphicsBuffer 的复制(VAO数据)
CopyBuffer(GraphicsBuffer source, GraphicsBuffer dest);// 用于 ComputeBuffer GraphicsBuffer 的复制
CopyCounterValue(ComputeBuffer/GraphicsBuffer src, ComputeBuffer/GraphicsBuffer dst, uint dstOffsetBytes);//格式必须相同
CopyTexture(Rendering.RenderTargetIdentifier src, Rendering.RenderTargetIdentifier dst);
(9)清除
  • Clear(): 清除缓冲区中的所有命令。
  • ClearRandomWriteTargets();清除level pixel shaders的随机写入目标。
  • ClearRenderTarget(bool clearDepth, bool clearColor, Color backgroundColor, float depth);
    ClearRenderTarget(Rendering.RTClearFlags clearFlags, Color backgroundColor, float depth, uint stencil);

3. CommandBuffer 不常用图形API

纹理计数器
void IncrementUpdateCount(Rendering.RenderTargetIdentifier dest);
背面剔除反转
CommandBuffer.SetInvertCulling
该标志可“翻转”所有已渲染对象的剔除模式。主要用例:渲染镜子、水等的反射。由于为用于渲染此反射的虚拟摄像机生成了镜像,因此必须反转剔除顺序。您可以看到 Effects 标准包中的 Water 脚本是怎样编写的。

异步

//回调
void RequestAsyncReadback
void RequestAsyncReadbackIntoNativeArray<T>
void RequestAsyncReadbackIntoNativeSlice<T>
void WaitAllAsyncReadbackRequests();
//同步处理,GPU在完成Blit, Clear, Draw, Dispatch或纹理复制命令后通过GraphicsFence
Rendering.GraphicsFence CreateAsyncGraphicsFence(Rendering.SynchronisationStage stage);
void WaitOnAsyncGraphicsFence(Rendering.GraphicsFence fence);
void WaitOnAsyncGraphicsFence(Rendering.GraphicsFence fence, Rendering.SynchronisationStage stage);
// 异步执行Flag
void SetExecutionFlags(Rendering.CommandBufferExecutionFlags flags);

本地插件
IssuePluginCustomBlit
IssuePluginCustomTextureUpdateV2
IssuePluginEvent
IssuePluginEventAndData
IssuePluginEventAndDataWithFlags
ComputeShader
添加一个命令来设置ComputeShader上的参数。

  • SetComputeFloatParam、SetComputeIntParam、SetComputeVectorParam 、SetComputeVectorArrayParam、SetComputeMatrixParam…

添加一个命令来执行ComputeShader。

void DispatchCompute(ComputeShader computeShader, int kernelIndex, int threadGroupsX, int threadGroupsY, int threadGroupsZ);
void DispatchCompute(ComputeShader computeShader, int kernelIndex, ComputeBuffer indirectBuffer, uint argsOffset);
void DispatchCompute(ComputeShader computeShader, int kernelIndex, GraphicsBuffer indirectBuffer, uint argsOffset);

RayTracing
添加了一个命令来选择在执行光线/几何相交时使用哪个着色器通道着色。

SetRayTracingShaderPass

添加一个命令来执行RayTracingShader。

void DispatchRays(Experimental.Rendering.RayTracingShader rayTracingShader, string rayGenName, uint width, uint height, uint depth, Camera camera);
SetRayTracingAccelerationStructure
SetRayTracingBufferParam
SetRayTracingConstantBufferParam
SetRayTracingFloatParam
SetRayTracingIntParam
SetRayTracingMatrixParam
SetRayTracingTextureParam
SetRayTracingVectorParam

XR

void SetFoveatedRenderingMode(Rendering.FoveatedRenderingMode foveatedRenderingMode);
SetInstanceMultiplier

其他
SetShadowSamplingMode
CommandBuffer.SetSinglePassStereo(SinglePassStereoMode)
// 延迟锁定
void UnmarkLateLatchMatrix(Rendering.CameraLateLatchMatrixType matrixPropertyType);

二、 ScriptableRenderContext context (2021.3版本)

自定义渲染管线使用的状态和绘制命令。
在这里插入图片描述

定义自定义 RenderPipeline 时,可使用 ScriptableRenderContext 向 GPU 调度和提交状态更新和绘制命令。
RenderPipeline.Render 方法实现通常会针对每个摄像机剔除渲染管线不需要渲染的对象(请参阅 CullingResults),然后对 ScriptableRenderContext.DrawRenderers 发起一系列调用并混合 ScriptableRenderContext.ExecuteCommandBuffer 调用。这些调用会设置全局着色器属性、更改渲染目标、分发计算着色器和其他渲染任务。 若要实际执行渲染循环,请调用 ScriptableRenderContext.Submit。

常用函数方法

context.Cull
public Rendering.CullingResults Cull (ref Rendering.ScriptableCullingParameters parameters);

基于通常从当前渲染的摄像机获取的 ScriptableCullingParameters 来执行剔除。

剔除结果绑定到将与之结合使用的 ScriptableRenderContext;剔除结果所用的内存会在渲染循环完成后得到释放。

context.DrawGizmos
 void DrawGizmos (Camera camera, Rendering.GizmoSubset gizmoSubset);
...//BeforeRendering
...//不透明物体渲染
...//透明物体渲染
if (drawGizmos)
{DrawGizmos(context, camera, GizmoSubset.PreImageEffects);
}
...//AfterRendering
if (drawGizmos)
{DrawGizmos(context, camera, GizmoSubset.PostImageEffects);
}
context.DrawRenderers
void DrawRenderers (Rendering.CullingResults cullingResults, //从ScriptableRenderContext.Cull中获得ref Rendering.DrawingSettings drawingSettings, //DrawRenderers的设置。// 包含:enableDynamicBatching 	是否开启动态批处理//       enableInstancing		是否开启实例化//		 fallbackMaterial       材质失败的备用材质//		 mainLightIndex         配置什么灯应该被用作主灯。//		 overrideMaterial     设置要在该组中渲染的所有物体使用的材质。//		 overrideMaterialPassIndex    Pass下标/*		 perObjectData		 	LightProbe/ ReflectionProbes/LightProbeProxyVolume/ Lightmaps/LightData/MotionVectors/LightIndices/ReflectionProbeData/OcclusionProbe/OcclusionProbeProxyVolume/shadowMask*///      sortingSettings         渲染排序顺序ref Rendering.FilteringSettings filteringSettings, //过滤渲染的物体(层级,QueueRange等)ref Rendering.RenderStateBlock stateBlock);//

RenderStateBlock结构:

//SetDetphState
m_RenderStateBlock.mask |= RenderStateMask.Depth;
m_RenderStateBlock.depthState = new DepthState(writeEnabled, function);
//SetStencilState
m_RenderStateBlock.mask |= RenderStateMask.Stencil;
m_RenderStateBlock.stencilReference = reference;
m_RenderStateBlock.stencilState = stencilState;
在各种Pass中使用,例如:
```cpp
class RenderObjectsPass : ScriptableRenderPass
{public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData){....context.ExecuteCommandBuffer(cmd);cmd.Clear();// Render the objects...context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref m_FilteringSettings, ref m_RenderStateBlock);}
}
void DrawShadows (ref Rendering.ShadowDrawingSettings settings);
//Rendering.ShadowDrawingSettings settings 在此处定义
var settings = new ShadowDrawingSettings(cullResults, shadowLightIndex);
for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
{// 此处设置级联阴影数据settings.splitData = m_CascadeSlices[cascadeIndex].splitData;Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, ref shadowData, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].resolution);ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.CastingPunctualLightShadow, false);ShadowUtils.RenderShadowSlice(cmd, ref context, ref m_CascadeSlices[cascadeIndex],ref settings,m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].viewMatrix);
}//在RenderShadowSlice函数中使用了DrawShadows 
public static void RenderShadowSlice(CommandBuffer cmd, ref ScriptableRenderContext context,ref ShadowSliceData shadowSliceData, ref ShadowDrawingSettings settings,Matrix4x4 proj, Matrix4x4 view)
{cmd.SetGlobalDepthBias(1.0f, 2.5f); // these values match HDRP defaults (see https://github.com/Unity-Technologies/Graphics/blob/9544b8ed2f98c62803d285096c91b44e9d8cbc47/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/HDShadowAtlas.cs#L197 )cmd.SetViewport(new Rect(shadowSliceData.offsetX, shadowSliceData.offsetY, shadowSliceData.resolution, shadowSliceData.resolution));cmd.SetViewProjectionMatrices(view, proj);context.ExecuteCommandBuffer(cmd);cmd.Clear();context.DrawShadows(ref settings);cmd.DisableScissorRect();context.ExecuteCommandBuffer(cmd);cmd.Clear();cmd.SetGlobalDepthBias(0.0f, 0.0f); // Restore previous depth bias values
}
void DrawSkybox (Camera camera);

DrawSkybox函数在DrawSkyboxPass使用,作为单独的一个Pass。

context.DrawWireOverlay(camera);

为给定的场景视图相机安排线框覆盖的绘制。

注意,DrawWireOverlay只在Unity编辑器中起作用,
而且需要 Camera.cameraType设置为 CameraType.SceneView
并且SceneView.CamerMode.drawMode设置为 DrawCameraMode.TexturedWire
如果不满足这些条件,调用DrawWireOverlay就没有效果。

context.ExecuteCommandBuffer(cmd);

提交CommandBuffer缓存,提交后需要手动清除。

ExecuteCommandBufferAsync(Rendering.CommandBuffer commandBuffer, Rendering.ComputeQueueType queueType);,是对异步计算队列调度命令缓冲区的执行。另请参阅:SystemInfo.supportsAsyncCompute、GPUFence。

context.SetupCameraProperties(camera);

此函数可用于设置视图、投影和裁剪面全局着色器变量。

context.Submit();

将所有调度命令都提交给渲染循环来执行。

Submit与ExecuteCommandBuffer的区别:
在调用ScriptableRenderContext.ExecuteCommandBuffer期间, ScriptableRenderContext将commandBuffer参数注册到其要执行的命令的内部列表中。这些命令(包括存储在自定义commandBuffer中的命令)的实际执行发生在ScriptableRenderContext.Submit期间。

如果您的绘制调用依赖于您在CommandBuffer中指定的管道状态,请确保在其他ScriptableRenderContext方法(如DrawRenderers, DrawShadows)之前调用ExecuteCommandBuffer。
即:如果DrawRenderers需要CommandBuffer中的命令作为前置条件,则必须先提交缓存命令,再使用DrawRenderers函数。否则,即使在DrawRenderers函数之前将命令添加到了commandBuffer,但会因为提交顺序导致最终结果的不正确。

if (!context.SubmitForRenderPassValidation()){…}

此方法提交了所有的预设命令到rendering loop用于检查。这个验证检查 由BeginRenderPass调用启动的渲染传递是否可以执行预定的命令。

其他

context.InvokeOnRenderObjectCallback();
在InvokeOnRenderObjectCallbackPass.cs中调用context.InvokeOnRenderObjectCallback();
作为MonoBehaviour 脚本调度 OnRenderObject 回调的调用。

ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);
将 UI 几何形状发射到 Scene 视图以进行渲染。

#if UNITY_EDITOR// Emit scene view UIif (isSceneViewCamera){ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);}
#endif

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Git的基础操作指令
  • uniapp小程序端使用计算属性动态绑定style样式踩坑
  • SpringMVC-请求
  • 345. Reverse Vowels of a String(反转字符串中的元音字母)
  • Leetcode 337 打家劫舍 III
  • 推荐一款开源的跨平台划词翻译和OCR翻译软件:Pot
  • Open CASCADE学习|保存为STL文件
  • thinkphp6入门(18)-- 中间件中除了handle函数,还可以有其它函数吗
  • re:从0开始的CSS学习之路 5. 颜色单位
  • 【教程】Linux使用git自动备份和使用支持文件恢复的rm命令
  • 93 log4j-slf4j-impl 搭配上 log4j-to-slf4j 导致的 StackOverflow
  • Rust语言入门小结(第1篇)
  • SQL,HQL刷题,尚硅谷
  • 【MySQL】字符串函数的学习
  • 使用代理IP有风险吗?如何安全使用代理IP?
  • python3.6+scrapy+mysql 爬虫实战
  • 【347天】每日项目总结系列085(2018.01.18)
  • 【附node操作实例】redis简明入门系列—字符串类型
  • Bytom交易说明(账户管理模式)
  • C# 免费离线人脸识别 2.0 Demo
  • C++类的相互关联
  • ES6语法详解(一)
  • Flex布局到底解决了什么问题
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • springboot_database项目介绍
  • 搞机器学习要哪些技能
  • 基于游标的分页接口实现
  • 开发基于以太坊智能合约的DApp
  • 区块链技术特点之去中心化特性
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • # Panda3d 碰撞检测系统介绍
  • #Linux(帮助手册)
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (20)docke容器
  • (4)Elastix图像配准:3D图像
  • (C语言)字符分类函数
  • (Oracle)SQL优化技巧(一):分页查询
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (七)理解angular中的module和injector,即依赖注入
  • (一) storm的集群安装与配置
  • (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
  • .“空心村”成因分析及解决对策122344
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .NET Core中如何集成RabbitMQ
  • .Net OpenCVSharp生成灰度图和二值图
  • .net Stream篇(六)