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

news2024/9/23 13:27:47

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一键放置柱子护角,你get了吗?

今天写个番外篇&#xff0c;给柱子添加护角。 记得几年前刚开始做BIM的时候&#xff0c;有次做车库导视方案模型&#xff0c;记得好像是鼎伦设计的车库一体化方案&#xff0c;当时柱子护角就给了两种方案&#xff0c;而且基本上每颗柱子上都要放护角&#xff0c;然后甲方竟然要…

MySQL8.0 最新版下载安装,手把手式的教程,小白都能安装成功!!

1、打开MySQL数据库官网的下载地址,根据自己的操作系统下载对应的安装包。我这里是Windows的,操作步骤如下: https://dev.mysql.com/downloads/installer/2、选择不登录下载 3、等待下载完成 4、然后点击下载下来的安装包 5、选择安装类型,Custom自定义安装 6、接…

【从Python基础到深度学习】1. Python PyCharm安装及激活

前言&#xff1a; 为了帮助大家快速入门机器学习-深度学习&#xff0c;从今天起我将用100天的时间将大学本科期间的所学所想分享给大家&#xff0c;和大家共同进步。【从Python基础到深度学习】系列博客中我将从python基础开始通过知识和代码实践结合的方式进行知识的分享和记…

Redis中的缓存穿透、雪崩、击穿的原因以及解决方案(详解)

一、概述 ① 缓存穿透&#xff1a;大量请求根本不存在的key&#xff08;下文详解&#xff09; ② 缓存雪崩&#xff1a;redis中大量key集体过期&#xff08;下文详解&#xff09; ③ 缓存击穿&#xff1a;redis中一个热点key过期&#xff08;大量用户访问该热点key&#xff0c;…

【Git】08 多人单分支协作场景

文章目录 一、场景1&#xff1a;不同人修改不同文件1.1 场景描述1.2 场景复现1.2.1 克隆到本地1.2.2 新建分支1.2.3 B修改、提交与推送1.2.4 A修改与提交1.2.5 B再次修改并推送1.2.6 A推送报错 1.3 解决 二、场景2&#xff1a;不同人修改同文件的不同区域2.1 场景描述2.2 场景复…

canvas实现涂鸦画板功能

查看专栏目录 canvas实例应用100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

HarmonyOS SDK 助力新浪新闻打造精致易用的新闻应用

原生智能是HarmonyOS NEXT的核心亮点之一&#xff0c;依托HarmonyOS SDK丰富全面的开放能力&#xff0c;开发者只需通过几行代码&#xff0c;即可快速实现AI功能。新浪新闻作为鸿蒙原生应用开发的先行者之一&#xff0c;从有声资讯入手&#xff0c;基于Speech Kit朗读控件上线听…

大模型为什么会有 tokens 限制?

人是以字数来计算文本长度&#xff0c;大语言模型 &#xff08;LLM&#xff09;是以 token 数来计算长度的。LLM 使用 token 把一个句子分解成若干部分。 token 可以是一个单词、一个单词中的一个部分、甚至是一个字符&#xff0c;具体取决于它使用的标记化方法 (tokenization…

基于麻雀优化算法优化XGBoost参数的优化控制策略

目录 一、背景 二、算法流程图 三、附录 一、背景 为提高极端梯度提升&#xff08;Extreme Gradient Boosting, XGBoost&#xff09;集成算法在时间预测、信贷风险预测、工件参数预测、故障诊断预测等方面中的准确性&#xff0c;研究者提出了一种改进的麻雀算法&#xff08;…

相机图像质量研究(7)常见问题总结:光学结构对成像的影响--镜片固化

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

07-OpenFeign-HTTP压缩优化

gzip是一种数据格式&#xff0c;采用用deflate算法压缩数据&#xff1b;gzip是一种流行的数据压缩算法&#xff0c;应用十分广泛&#xff0c;尤其是在Linux平台。 当GZIP压缩到一个纯文本数据时&#xff0c;效果是非常明显的&#xff0c;大约可以减少70&#xff05;以上的数据…

QTabWidget和QTabBar控件样式设置(qss)

QTabWidget和QTabBar控件样式设置 1、QTabWidget样式可自定义的有哪些示例&#xff1a;效果图 2、QTabBar样式可自定义的有哪些示例效果图 1、QTabWidget样式可自定义的有哪些 QTabWidget::pane{} 定义tabWidgetFrameQTabWidget::tab-bar{} 定义TabBar的位置QTabWidget::tab{}定…

【最详解】如何进行点云的凹凸缺陷检测(opene3D)(完成度80%)

文章目录 前言实现思路想法1想法2想法3 补充实现想法1想法2代码 想法3代码 总结 前言 读前须知&#xff1a; 首先我们得确保你已经完全知晓相关的基本的数学知识&#xff0c;其中包括用最小二乘法拟合曲二次曲面&#xff0c;以及曲面的曲率详细求解。若还是没弄清楚&#xff0…

《幻兽帕鲁》攻略:0基础入门及游戏基础操作 幻兽帕鲁基础设施 幻兽帕鲁基础攻击力 Mac苹果电脑玩幻兽帕鲁 幻兽帕鲁加班加点

今天就跟大家聊聊《幻兽帕鲁》攻略&#xff1a;0基础入门及游戏基础操作。 如果想在苹果电脑玩《幻兽帕鲁》记得安装CrossOver哦。 以下纯干货&#xff1a; CrossOver正版安装包&#xff08;免费试用&#xff09;&#xff1a;https://souurl.cn/Y1gDao 一、基础操作 二、界面…

稳压二极管应用电路

稳压二极管比较特殊&#xff0c;基本结构与普通二极管一样&#xff0c;也有一个PN结。由于制造工艺的不同&#xff0c;当这种PN结处于反向击穿状态时&#xff0c;PN结不会损坏(普通二极管的PN结是会损坏)&#xff0c;在稳压二极管用来稳定电压时就是利用它的这一击穿特性。 由…

【学网攻】 第(23)节 -- PPP协议

系列文章目录 目录 系列文章目录 文章目录 前言 一、PPP协议是什么&#xff1f; 二、实验 1.引入 实验目的 实验背景你是某公司的网络管理员&#xff0c;现在需要与另一个公司进行通信,需要你配置PPP协议保证双方发送的人是真正的而非黑客 技术原理 实验步骤新建Pack…

MySQL学习记录——유 表的约束

文章目录 1、了解2、空属性3、默认值default4、列描述comment就是注释&#xff0c;desc看不到&#xff0c;show能看到。5、zerofill6、主键7、自增长auto_increment8、唯一键9、外键 1、了解 只有数据类型的约束肯定不够&#xff0c;mysql还有表的约束来进而保证数据合法性。约…

安全名词解析-威胁情报、蜜罐技术

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 威胁情报02 蜜罐技术 01 威胁情报 威胁情报(Threat Intelligence)&#xff0c;也被称作安全情报(Security Intelligence)、安全威胁情报(Security Threat Intelligence)。 关于威胁情报的定义有很多…

redis的主从配置模拟(一主双从)

目录 先来给大家扩展机道面试官经常会问到关于redis的题 一、redis有哪些好处 二、redis相比memcached有哪些优势 三、redis常见性能问题和解决方案 四、redis集群的工作原理 五、redis主从的原理 redis的主从配置模拟&#xff08;一主双从&#xff09; 一、准备环境 …

C++ 内存管理(newdelete)

目录 本节目标 1. C/C内存分布 2. C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free 3. C内存管理方式 3.1 new/delete操作内置类型 3.2 new和delete操作自定义类型 4. operator new与operator delete函数 5. new和delete的实现原理 6. 定位new表达式(placem…