当前位置: 首页 > 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

相关文章:

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

Unity 封装的图形API 文章目录 Unity 封装的图形API一、 CommandBuffer 要执行的图形命令列表1. CommandBuffer 属性2. CommandBuffer 常用图形API&#xff08;方法&#xff09;(1)设置(2)获取临时纹理 GetTemporaryRT以及释放(3)设置纹理为渲染目标 SetRenderTarget(4)Command…...

使用playwright进行自动化端到端测试

项目希望能接入自动化端到端测试提高可靠性&#xff0c;发现微软的 playwright 还挺好用的&#xff0c;推荐一下&#xff0c;顺便说下遇到的一些难点以及最佳实践。 难点 登录 项目不能帐号密码登录&#xff0c;只能扫二维码 临时方案是先自己扫码保存 cookie 用于测试&#…...

ES实战-相关性搜索

ES打分机制 1.TF-IDF 词频-逆文档频率 2.Okapi BM25 3.随机性分歧- DFR相似度 4.基于信息 - IB相似度 5.LM Dirichlet 相似度 6.LM Jelinek Mercer相似度 解释一个查询的结果集 curl -XPOST localhost:9200/get-together/_search?pretty -H Content-Type: application/json -…...

MQTT的学习与应用

文章目录 一、什么是MQTT二、MQTT协议特点三、MQTT应用领域四、安装Mosquitto五、如何学习 MQTT 一、什么是MQTT MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的消息传输协议&#xff0c;设计用于在低带宽、不稳定的网络环境中进行高效的通信…...

编译原理实验1——词法分析(python实现)

文章目录 实验目的实现定义单词对应的种别码定义输出形式&#xff1a;三元式python代码实现运行结果检错处理 总结 实验目的 输入一个C语言代码串&#xff0c;输出单词流&#xff0c;识别对象包含关键字、标识符、整型浮点型字符串型常数、科学计数法、操作符和标点、注释等等。…...

C语言——oj刷题——模拟实现库函数strlen

目录 方法一&#xff1a;迭代法 方法二&#xff1a;递归法 方法三&#xff1a;指针算术法 方法四&#xff1a;汇编指令法 当我们使用C语言进行字符串操作时&#xff0c;经常会用到库函数strlen来获取字符串的长度。strlen函数的作用是计算一个以null字符结尾的字符串的长度…...

对进程与线程的理解

目录 1、进程/任务&#xff08;Process/Task&#xff09; 2、进程控制块抽象(PCB Process Control Block) 2.1、PCB重要属性 2.2、PCB中支持进程调度的一些属性 3、 内存分配 —— 内存管理&#xff08;Memory Manage&#xff09; 4、线程&#xff08;Thread&#xff09;…...

「数据结构」线性表

定义和基本操作 定义&#xff1a;相同数据类型的 n ( n ≥ 0 ) n(n \ge 0) n(n≥0)个数据元素的有限序列&#xff0c;其中n为表长&#xff0c;当n0时线性表是一个空表一般表示&#xff1a; L ( a 1 , a 2 , … … , a i , a i 1 , a n ) L(a_1,a_2,……,a_i,a_{i1},a_n) L(a…...

GEE:关于在GEE平台上进行回归计算的若干问题

作者&#xff1a;CSDN _养乐多_ 记录一些在Google Earth Engine &#xff08;GEE&#xff09;平台上进行机器学习回归计算的问题和解释。 文章目录 一、回归1.1 问&#xff1a;GEE平台上可以进行哪些机器学习回归算法&#xff1f;1.2 问&#xff1a;为什么只有这四种&#xf…...

Vivado -RAM

ip_ram 定义了一个名为ip_ram的模块&#xff0c;该模块具有以下端口&#xff1a; sys_clk&#xff1a;系统时钟输入。 sys_rst_n&#xff1a;系统复位输入。 module ip_ram( input sys_clk, input sys_rst_n);wire ram_en ; wire ram_wea …...

备战蓝桥杯---图论之最短路dijkstra算法

目录 先分个类吧&#xff1a; 1.对于有向无环图&#xff0c;我们直接拓扑排序&#xff0c;和AOE网类似&#xff0c;把取max改成min即可。 2.边权全部相等&#xff0c;直接BFS即可 3.单源点最短路 从一个点出发&#xff0c;到达其他顶点的最短路长度。 Dijkstra算法&#x…...

C#系列-C#实现秒杀功能(14)

在C#中实现商品秒杀功能&#xff0c;通常需要考虑并发控制、数据库事务、缓存策略、限流措施等多个方面。下面是一个简单的示例&#xff0c;演示了如何使用C#和数据库来实现一个基本的商品秒杀功能。 首先&#xff0c;假设你有一个商品表&#xff08;Product&#xff09;和一个…...

Java ‘Elasticsearch‘ 操作

依赖 <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-elasticsearch --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</ar…...

【AI视野·今日NLP 自然语言处理论文速览 第七十八期】Wed, 17 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Wed, 17 Jan 2024 (showing first 100 of 163 entries) Totally 100 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Deductive Closure Training of Language Models for Coherence, Accur…...

实验5-4 使用函数计算两点间的距离

本题要求实现一个函数&#xff0c;对给定平面任意两点坐标(x1​,y1​)和(x2​,y2​)&#xff0c;求这两点之间的距离。 函数接口定义&#xff1a; double dist( double x1, double y1, double x2, double y2 );其中用户传入的参数为平面上两个点的坐标(x1, y1)和(x2, y2)&…...

【JavaEE】_JavaScript(Web API)

目录 1. DOM 1.1 DOM基本概念 1.2 DOM树 2. 选中页面元素 2.1 querySelector 2.2 querySelectorAll 3. 事件 3.1 基本概念 3.2 事件的三要素 3.3 示例 4.操作元素 4.1 获取/修改元素内容 4.2 获取/修改元素属性 4.3 获取/修改表单元素属性 4.3.1 value&#xf…...

ARM交叉编译搭建SSH

首先搭建好arm-linux交叉编译环境&#xff0c;开发板和主机可以ping通。 一、下载需要的源码 下载zlib: zlib-1.2.3.tar.gz 下载ssl: openssl-0.9.8d.tar.gz 下载ssh: openssh-4.6p1.tar.gz 二、交叉编译 新建目录/home/leo/ssh&#xff0c;并且将三个源码复制到该目录下。…...

###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯

前言&#xff1a;感谢您的关注哦&#xff0c;我会持续更新编程相关知识&#xff0c;愿您在这里有所收获。如果有任何问题&#xff0c;欢迎沟通交流&#xff01;期待与您在学习编程的道路上共同进步。 目录 一. 延时函数的生成 1.通过延时计算器得到延时函数 2.可赋值改变…...

回归预测模型:MATLAB多项式回归

1. 多项式回归模型的基本原理 多项式回归是线性回归的一种扩展&#xff0c;用于分析自变量 X X X与因变量 Y Y Y之间的非线性关系。与简单的线性回归模型不同&#xff0c;多项式回归模型通过引入自变量的高次项来增加模型的复杂度&#xff0c;从而能够拟合数据中的非线性模式。…...

「计算机网络」数据链路层

数据链路层的地位&#xff1a;网络中的主机、路由器等都必须实现数据链路层信道类型 点对点信道&#xff1a;使用一对一的点对点通信方式广播信道 使用一对多的广播通信方式必须使用专用的共享信道协议来协调这些主机的数据发送 使用点对点信道的数据链路层 数据链路和帧 链…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...