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、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做了以下几点:

  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、VectorArray

void 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.identity
	Material material, 	   //哪一个Shader
	int shaderPass, 	   //哪一个Pass
	MeshTopology topology, //程序几何的拓扑结构。MeshTopology.Triangles
	int 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 UI
        if (isSceneViewCamera)
        {
            ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);
        }
#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/377484.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CV | SAM在医学影像上的模型调研【20240207更新版】

本文主要是SAM&#xff08;Segment Anything&#xff09;在医学影像上的数据集&#xff0c;模型及评估方法调研【持续更新】~ 1.开源数据集 可参考这篇【数据集 | 基于计算机视觉的医学影像处理数据集_CSDN博客】 2.算法模型 2023.04_SAM 论文&#xff1a;2018.08.05v_Segm…

MySQL数据库⑤_基本查询DQL_表的增删查改DML

目录 1. CRUD介绍 2. Create 新增 2.1 单行数据全列插入 2.2 多行数据指定列插入 2.3 插入否则更新 2.4 替换数据 3. Retrieve 查找 3.1 select 查询 3.2 where 条件 3.2.1 MySQL运算符 3.2.2 NULL的查询 3.3 order by 结果排序 3.4 limit 筛选分页结果 4. Updat…

机器学习1一knn算法

1.基础知识点介绍 曼哈顿距离一般是比欧式距离长的除非在一维空间 拐弯的就是曼哈顿距离 Knn查看前5行数据head()&#xff0c;info看空非空 查看特征对应的类型 Head()默认前5行&#xff0c;head&#xff08;3&#xff09;就是前3行数据 Unique()可以查看分类后的结果 csv的…

MongoDB部署策略

内 容 简 介 本文介绍了MongoDB数据库的优点的数据存储模式的安装部署过程。 利用MongoDB在存储海量数据上的优势&#xff0c;部署存储空间大数据。 欢迎批评指正补充 由于编者水平有限&#xff0c;所搜集资料也很有限&#xff0c;制定的规范肯定有考虑不周全、甚至完全错误…

JavaEE作业-实验三

目录 1 实验内容 2 实验要求 3 思路 4 核心代码 5 实验结果 1 实验内容 简单的线上图书交易系统的web层 2 实验要求 ①采用SpringMVC框架&#xff0c;采用REST风格 ②要求具有如下功能&#xff1a;商品分类、订单、购物车、库存 ③独立完成&#xff0c;编写实验报告 …

Linux---线程

线程概念 在一个程序里的一个执行路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程是“一个进程内部的控制序列” 一切进程至少都有一个执行线程 线程在进程内部运行&#xff0c;本质是在进程地址空间内运行 在Linux系统中&#xff0c;在CPU眼中…

java学习06---方法

一 方法 方法&#xff08;method&#xff09;是程序中最小的执行单元 注意&#xff1a; 方法必须先创建才可以使用&#xff0c;该过程成为方法定义 方法创建后并不是直接可以运行的&#xff0c;需要手动使用后&#xff0c;才执行&#xff0c;该过程成为方法调用 二 方法的…

(注解配置AOP)学习Spring的第十七天

基于注解配置的AOP 来看注解式开发 : 先把目标与通知放到Spring里管理 : Service("userService") public class UserServiceImpl implements UserService {Overridepublic void show1() {System.out.println("show1......");}Overridepublic void show2…

SpringBoot + Tess4J 实现本地与远程图片的文字识别

1 前言 1.1 概要 在本文中&#xff0c;我们将探讨如何在Spring Boot应用程序里集成Tess4J来实现OCR&#xff08;光学字符识别&#xff09;&#xff0c;以识别出本地和远程图片中的文字。 我们将从添加依赖说起&#xff0c;然后创建服务类以实现OCR&#xff0c;最后展示如何处…

Java项目使用jasypt加密和解密配置文件中关键信息

一、使用背景 项目中application.yml 配置文件中&#xff0c;如数据库、redis、加密算法的私钥等各种配置的username&#xff0c;password的值都是明文的&#xff0c;其实存在一定的安全隐患&#xff0c;如果被人拿到这些配置文件&#xff0c;将直接对系统安全构成极大威胁&…

多维时序 | Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预测

多维时序 | Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预测 目录 多维时序 | Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现RF-Adaboost随机森林结合Adaboost多变量时间序列预…

【PyQt】06-.ui文件转.py文件

文章目录 前言方法一、基本脚本查看自己的uic安装目录 方法二、添加到扩展工具里面&#xff08;失败了&#xff09;方法二的成功步骤总结 前言 方法一、基本脚本 将Qt Designer&#xff08;一种图形用户界面设计工具&#xff09;生成的.ui文件转换为Python代码的脚本。 pytho…

TI毫米波雷达开发——High Accuracy Demo 串口数据接收及TLV协议解析 matlab 源码

TI毫米波雷达开发——串口数据接收及TLV协议解析 matlab 源码 前置基础源代码功能说明功能演示视频文件结构01.bin / 02.binParseData.mread_file_and_plot_object_location.mread_serial_port_and_plot_object_location.m函数解析configureSport(comportSnum)readUartCallback…

不到1s生成mesh! 高效文生3D框架AToM

论文题目&#xff1a; AToM: Amortized Text-to-Mesh using 2D Diffusion 论文链接&#xff1a; https://arxiv.org/abs/2402.00867 项目主页&#xff1a; AToM: Amortized Text-to-Mesh using 2D Diffusion 随着AIGC的爆火&#xff0c;生成式人工智能在3D领域也实现了非常显著…

计算机网络概念、组成、功能和分类

文章目录 概要1.怎么学习计算机网络2.概念3.功能、组成4.工作方式、功能组成5.分类 概要 概念、组成、功能和分类 1.怎么学习计算机网络 2.概念 通信设备&#xff1a;比如路由器、路由器 线路&#xff1a;将系统和通信设备两者联系的介质之类的 计算机网络是互连的、自治的的计…

CTFshow web(php命令执行 37-40)

?ceval($_GET[shy]);&shypassthru(cat flag.php); #逃逸过滤 ?cinclude%09$_GET[shy]?>&shyphp://filter/readconvert.base64-encode/resourceflag.php #文件包含 ?cinclude%0a$_GET[cmd]?>&cmdphp://filter/readconvert.base64-encode/…

spring boot和spring cloud项目中配置文件application和bootstrap加载顺序

在前面的文章基础上 https://blog.csdn.net/zlpzlpzyd/article/details/136060312 日志配置 logback-spring.xml <?xml version"1.0" encoding"UTF-8"?> <configuration scan"true" scanPeriod"10000000 seconds" debug…

Leetcode 213 打家劫舍 II

题意理解&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋&#xff0c;每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 &#xff0c;这意味着第一个房屋和最后一个房屋是紧挨着的。同时&#xff0c;相邻的房屋装有相互连通的防盗系统&#xff0c;如果…

mysql 对于null字段排序处理

最近遇到一个需求 &#xff0c;需要对一个报表的多个字段进行多字段复杂条件排序 排序字段为NULL时 Mysql对于排序字段为NULL时&#xff0c;有自身默认的排序规则&#xff0c;默认是认为null 值 是无穷小 ELECT id,script_id,last_modified,live_count,next_show FROM virtua…

python-自动化篇-办公-一键将word中的表格提取到excel文件中

文章目录 代码 工作中&#xff0c;经常需要将Word文档中的表格粘贴到Excel文件中&#xff0c;以便汇总及分析。一个一个复制粘贴&#xff0c;非常不方便&#xff0c;还是Python自动化操作&#xff0c;省心省力。要求如下图所示&#xff0c;即将word中的所有表格&#xff0c;转存…