cullingResults | 要绘制的可见对象集。通常从 ScriptableRenderContext.Cull 获取。 |
drawingSettings | 描述如何绘制对象的结构体。 |
filteringSettings | 描述如何过滤可见对象集的结构体,以便 Unity 仅绘制子集。 |
stateBlock | Unity 用于覆盖 GPU 渲染状态的一组值。 |
tagName | 一个 SubShader 标签 或 Pass 标签 的名称。 |
isPassTagName | 如果设置为 true,则 tagName 指定一个 Pass 标签。否则,tagName 指定一个 SubShader 标签。 |
tagValues | 一个 ShaderTagId 结构体数组,其中 name 是给定 SubShader 标签 或 Pass 标签 的值。 |
renderTypes | 一个 ShaderTagId 结构体数组,其中 name 是名称为 "RenderType" 的 SubShader 标签 的值。 |
stateBlocks | 描述要覆盖 GPU 渲染状态的哪些部分的结构体数组。 |
安排绘制可见对象集,并可选地覆盖 GPU 的渲染状态。
此函数创建用于绘制指定几何体的命令,并将命令添加到 ScriptableRenderContext
的内部命令列表中。当调用 ScriptableRenderContext.Submit 时,ScriptableRenderContext
会执行其内部列表中的所有命令。
此示例演示如何使用 CommandBuffer 清除渲染目标,然后调用此函数绘制几何体。
using UnityEngine; using UnityEngine.Rendering;
public class ExampleRenderPipeline : RenderPipeline { public ExampleRenderPipeline() { }
protected override void Render(ScriptableRenderContext context, Camera[] cameras) { // Create and schedule a command to clear the current render target var cmd = new CommandBuffer(); cmd.ClearRenderTarget(true, true, Color.black); context.ExecuteCommandBuffer(cmd); cmd.Release();
// Iterate over all Cameras foreach (Camera camera in cameras) { // Get the culling parameters from the current Camera camera.TryGetCullingParameters(out var cullingParameters);
// Use the culling parameters to perform a cull operation, and store the results var cullingResults = context.Cull(ref cullingParameters);
// Update the value of built-in shader variables, based on the current Camera context.SetupCameraProperties(camera);
// Tell Unity which geometry to draw, based on its LightMode Pass tag value ShaderTagId shaderTagId = new ShaderTagId("ExampleLightModeTag");
// Tell Unity how to sort the geometry, based on the current Camera var sortingSettings = new SortingSettings(camera);
// Create a DrawingSettings struct that describes which geometry to draw and how to draw it DrawingSettings drawingSettings = new DrawingSettings(shaderTagId, sortingSettings);
// Tell Unity how to filter the culling results, to further specify which geometry to draw // Use FilteringSettings.defaultValue to specify no filtering FilteringSettings filteringSettings = FilteringSettings.defaultValue;
// Schedule a command to draw the geometry, based on the settings you have defined context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
// Schedule a command to draw the Skybox if required if (camera.clearFlags == CameraClearFlags.Skybox && RenderSettings.skybox != null) { context.DrawSkybox(camera); }
// Instruct the graphics API to perform all scheduled commands context.Submit(); } } }
覆盖渲染状态
使用此函数绘制几何体时,可以使用一个或多个 RenderStateBlock 结构体以以下方式覆盖 GPU 的渲染状态。
stateBlock
参数提供单个 RenderStateBlock 结构体。Unity 对此函数绘制的所有几何体都使用 stateBlock
中定义的渲染状态。stateBlocks
参数提供一个 RenderStateBlock 结构体数组,并使用 renderTypes
参数提供名称为 RenderType
的 SubShader 标签 的值数组。对于 renderTypes
数组中的每个元素,如果 Unity 找到名称为 RenderType
且值匹配的 SubShader 标签几何体,则使用 stateBlocks
数组对应元素中定义的渲染状态。如果有多个匹配项,则 Unity 使用第一个匹配项。如果 renderTypes
数组中的元素具有 ShaderTagId 的默认值,则 Unity 将其视为通配符,并对所有几何体使用相应的渲染状态。stateBlocks
参数提供一个 RenderStateBlock 结构体数组,并使用 tagName
、tagValues
和 isPassTagName
参数指定任何 SubShader 标签 或 Pass 标签 的名称和值。对于 tagNames
和 tagValues
数组中的每个元素,Unity 会识别具有匹配的 SubShader 标签或 Pass 标签名称和值的几何体,并应用 stateBlocks
数组对应元素中定义的渲染状态。如果有多个匹配项,则 Unity 使用第一个匹配项。如果 tagValues
中的元素具有 ShaderTagId 的默认值,则 Unity 将其视为通配符,并对所有几何体使用相应的渲染状态。此示例演示如何覆盖渲染状态。
using UnityEngine; using UnityEngine.Rendering; using Unity.Collections;
public class OverrideRenderStateExample { ScriptableRenderContext scriptableRenderContext;
// Override the render state for all geometry that this function draws public void OverrideRenderStateForAll(CullingResults exampleCullingResults, DrawingSettings exampleDrawingSettings, FilteringSettings exampleFilteringSettings) { // Tell Unity how to override the render state var stateBlock = new RenderStateBlock(RenderStateMask.Depth); stateBlock.depthState = new DepthState(true, CompareFunction.LessEqual);
// Schedule a command to draw the geometry using the desired render state // Unity will execute all scheduled commands during the next call to ScriptableRenderContext.Submit scriptableRenderContext.DrawRenderers(exampleCullingResults, ref exampleDrawingSettings, ref exampleFilteringSettings, ref stateBlock); }
// Override the render state for all geometry that has a SubShader Tag // with a name of "RenderType" and a value of "ExampleRenderTypeTagValue" public void OverrideRenderStateUsingRenderTypeTag(CullingResults exampleCullingResults, DrawingSettings exampleDrawingSettings, FilteringSettings exampleFilteringSettings) { // Create the parameters that tell Unity how to override the render state var stateBlock = new RenderStateBlock(RenderStateMask.Depth); stateBlock.depthState = new DepthState(true, CompareFunction.Greater); var stateBlocks = new NativeArray<RenderStateBlock>(1, Allocator.Temp); stateBlocks[0] = stateBlock;
// Create the parameters that tell Unity when to override the render state ShaderTagId renderType = new ShaderTagId("ExampleRenderTypeTagValue"); var renderTypes = new NativeArray<ShaderTagId>(1, Allocator.Temp); renderTypes[0] = renderType;
// Schedule a command to draw the geometry using the desired render state // Unity will execute all scheduled commands during the next call to ScriptableRenderContext.Submit scriptableRenderContext.DrawRenderers(exampleCullingResults, ref exampleDrawingSettings, ref exampleFilteringSettings, renderTypes, stateBlocks);
// DrawRenderers copies the array contents, so it is safe to dispose of the native arrays stateBlocks.Dispose(); renderTypes.Dispose(); }
// Override the render state in two different ways. // Use one state for all geometry that has a Pass Tag // with a name of "ExamplePassTagName" and a value of "ExamplePassTagValue". // For all other geometry, use a second state. public void OverrideRenderStateUsingPassTag(CullingResults exampleCullingResults, DrawingSettings exampleDrawingSettings, FilteringSettings exampleFilteringSettings) { // Create the parameters that tell Unity how to override the render state var stateBlock0 = new RenderStateBlock(RenderStateMask.Depth); stateBlock0.depthState = new DepthState(true, CompareFunction.Greater); var stateBlock1 = new RenderStateBlock(RenderStateMask.Depth); stateBlock1.depthState = new DepthState(true, CompareFunction.Less); var stateBlocks = new NativeArray<RenderStateBlock>(2, Allocator.Temp); stateBlocks[0] = stateBlock0; stateBlocks[1] = stateBlock1; // default override
// Create the parameters that tell Unity when to override the render state ShaderTagId tagName = new ShaderTagId("ExamplePassTagName"); bool isPassTagName = true; var tagValues = new NativeArray<ShaderTagId>(2, Allocator.Temp); tagValues[0] = new ShaderTagId("ExamplePassTagValue"); tagValues[1] = new ShaderTagId(); // catch all
// Schedule a command to draw the geometry using the desired render state // Unity will execute all scheduled commands during the next call to ScriptableRenderContext.Submit scriptableRenderContext.DrawRenderers(exampleCullingResults, ref exampleDrawingSettings, ref exampleFilteringSettings, tagName, isPassTagName, tagValues, stateBlocks);
// DrawRenderers copies the array contents, so it is safe to dispose of the native arrays stateBlocks.Dispose(); tagValues.Dispose(); } }