Table of Contents

管线状态

Stride 让你完全掌控图形管线状态。这包括:

  • 光栅化器状态
  • 深度和模板状态
  • 混合状态
  • 效果
  • 输入布局
  • 输出描述

状态被编译为不可变的 @'Stride.Graphics.PipelineState' 对象,它们描述了整个管线。然后通过 @'Stride.Graphics.CommandList' 绑定它们。

**代码:**创建状态对象

// 创建管线状态对象
var pipelineStateDescription = new PipelineStateDescription();
var pipelineState = PipelineState.New(GraphicsDevice, ref pipelineStateDescription);
 
// 将状态应用到管线
CommandList.SetPipelineState(pipelineState);

@'Stride.Graphics.MutablePipelineState' 类让你可以独立设置状态,同时缓存底层的管线状态。

**代码:**可变管线状态

// 创建管线状态对象
var mutablePipelineState = new MutablePipelineState();

// 设置值并重建
mutablePipelineState.State.BlendState = BlendStates.AlphaBlend;
mutablePipelineState.Update();
 
// 将状态应用到管线
CommandList.SetPipelineState(mutablePipelineState.CurrentState);

光栅化器状态

光栅化器可以通过 @'Stride.Graphics.PipelineStateDescription.RasterizerState' 属性设置。@'Stride.Graphics.RasterizerStates' 类持有一组预定义的描述。它们处理剔除模式(cull mode),对于大多数用例应该已经足够:

  • @'Stride.Graphics.RasterizerStates.CullNone':不剔除
  • @'Stride.Graphics.RasterizerStates.CullFront':正面剔除
  • @'Stride.Graphics.RasterizerStates.CullBack':背面剔除

**代码:**设置剔除模式

pipelineStateDescription.RasterizerState = RasterizerStates.CullNone;
pipelineStateDescription.RasterizerState = RasterizerStates.CullFront;
pipelineStateDescription.RasterizerState = RasterizerStates.CullBack;

你可以创建自己的自定义状态。有关选项列表和默认值,请参阅 @'Stride.Graphics.RasterizerStateDescription' API 文档。

**代码:**自定义光栅化器状态

var rasterizerStateDescription = new RasterizerStateDescription(CullMode.Front);
rasterizerStateDescription.ScissorTestEnable = true; // 启用裁剪测试
pipelineStateDescription.RasterizerState = rasterizerStateDescription;

深度和模板状态

@'Stride.Graphics.PipelineStateDescription.DepthStencilState' 属性包含深度和模板状态。@'Stride.Graphics.DepthStencilStates' 类定义了一组常用状态:

  • @'Stride.Graphics.DepthStencilStates.Default':使用小于比较进行深度读写
  • @'Stride.Graphics.DepthStencilStates.DefaultInverse':使用大于等于比较进行读写
  • @'Stride.Graphics.DepthStencilStates.DepthRead':使用小于比较仅读取
  • @'Stride.Graphics.DepthStencilStates.None':既不读也不写

**代码:**设置深度状态

pipelineStateDescription.DepthStencilState = DepthStencilStates.Default;
pipelineStateDescription.DepthStencilState = DepthStencilStates.DefaultInverse;
pipelineStateDescription.DepthStencilState = DepthStencilStates.DepthRead;
pipelineStateDescription.DepthStencilState = DepthStencilStates.None;

你也可以设置自定义深度和模板状态。有关选项列表和默认值,请参阅 @'Stride.Graphics.DepthStencilStateDescription' API 文档。

**代码:**自定义深度和模板状态

// 启用深度测试但不写入
var depthStencilStateDescription = new DepthStencilStateDescription(true, false);
pipelineStateDescription.DepthStencilState = depthStencilStateDescription;

模板引用值不是 @'Stride.Graphics.PipelineState' 的一部分。它通过 @'Stride.Graphics.CommandList.SetStencilReference(System.Int32)' 设置。

**代码:**设置模板引用值

CommandList.SetStencilReference(2);

混合状态

@'Stride.Graphics.PipelineStateDescription.BlendState' 和 @'Stride.Graphics.PipelineStateDescription.SampleMask' 属性控制混合。@'Stride.Graphics.BlendStates' 类定义了一组常用混合状态:

  • @'Stride.Graphics.BlendStates.Additive':将颜色相加
  • @'Stride.Graphics.BlendStates.AlphaBlend':使用源的 alpha 对目标颜色进行混合相加
  • @'Stride.Graphics.BlendStates.NonPremultiplied':使用源的 alpha 对两个颜色相加
  • @'Stride.Graphics.BlendStates.Opaque':替换颜色

**代码:**设置混合状态

// 设置常用混合状态
pipelineStateDescription.BlendState = BlendStates.Additive;
pipelineStateDescription.BlendState = BlendStates.AlphaBlend;
pipelineStateDescription.BlendState = BlendStates.NonPremultiplied;
pipelineStateDescription.BlendState = BlendStates.Opaque;

// 设置采样掩码
pipelineStateDescription.SampleMask = 0xFFFFFFFF;

你可以设置自定义深度和混合状态。有关选项列表和默认值,请参阅 @'Stride.Graphics.BlendStateDescription' API 文档。

**代码:**自定义混合状态

// 创建描述每个渲染目标混合状态的对象
var blendStateRenderTargetDescription = new BlendStateRenderTargetDescription();
blendStateRenderTargetDescription.BlendEnable = true;
blendStateRenderTargetDescription.ColorSourceBlend = Blend.SourceColor;
// 等等

// 创建 blendStateDescription 对象
var blendStateDescription = new BlendStateDescription(Blend.SourceColor, Blend.InverseSourceColor);
blendStateDescription.AlphaToCoverageEnable = true; // 启用 alpha to coverage
blendStateDescription.RenderTargets[0] = blendStateRenderTargetDescription;
pipelineStateDescription.BlendState = blendStateDescription;

混合因子不是 @'Stride.Graphics.PipelineState' 的一部分。它通过 @'Stride.Graphics.CommandList.SetBlendFactor(Stride.Core.Mathematics.Color4)' 设置。

**代码:**设置混合因子

CommandList.SetBlendFactor(Color4.White);

效果

管线状态还包括你想用于绘制的着色器。 要将 @'Stride.Graphics.Effect' 绑定到管线,请将 @'Stride.Graphics.PipelineStateDescription.EffectBytecode' 和 @'Stride.Graphics.PipelineStateDescription.RootSignature' 属性设置为该效果的对应值。

@'Stride.Shaders.EffectBytecode' 包含实际的着色器程序。更多信息请参阅效果与着色器。

@'Stride.Graphics.RootSignature' 描述了效果所需资源的数量和种类。下一章介绍如何将资源绑定到管线。

**代码:**绑定效果

var effectInstance = new EffectInstance(EffectSystem.LoadEffect("MyEffect").WaitForResult());
pipelineStateDescription.EffectBytecode = effectInstance.Effect.Bytecode;
pipelineStateDescription.RootSignature = effectInstance.RootSignature;

输入布局

管线状态通过 @'Stride.Graphics.PipelineStateDescription.InputElements' 和 @'Stride.Graphics.PipelineStateDescription.PrimitiveType' 属性描述顶点发送到设备的布局方式。

绘制顶点页面更详细地介绍了如何创建自定义顶点缓冲区及其 @'Stride.Graphics.VertexDeclaration'。

**代码:**设置输入布局

VertexDeclaration vertexDeclaration = new VertexDeclaration();
pipelineStateDescription.InputElements = vertexDeclaration.CreateInputElements();
pipelineStateDescription.PrimitiveType = PrimitiveType.TriangleStrip;

输出描述

@'Stride.Graphics.PipelineStateDescription' 的 @'Stride.Graphics.PipelineStateDescription.Output' 属性定义了所有已绑定渲染纹理的数量和 @'Stride.Graphics.PixelFormat'。

有关如何将渲染纹理绑定到管线的信息,请参阅纹理与渲染纹理。

**代码:**创建输出描述

var renderOutputDescription = new RenderOutputDescription(GraphicsDevice.Presenter.BackBuffer.Format, GraphicsDevice.Presenter.DepthStencilBuffer.Format);
pipelineStateDescription.Output = renderOutputDescription;

你可以使用 @'Stride.Graphics.RenderOutputDescription.CaptureState(Stride.Graphics.CommandList)' 检索最近一次在 @'Stride.Graphics.CommandList' 上设置的输出描述。当渲染目标无法事先知道时,这与 @'Stride.Graphics.MutablePipelineState' 结合使用尤其有用。

**代码:**捕获输出描述

mutablePipelineState.State.Output.CaptureState(CommandList);
mutablePipelineState.Update();