剪裁基元概述 - MRTK3

ClippingPrimitive 行为可实现高性能的 planespherebox 形状剪裁,与图形工具着色器配合使用时,能够指定要剪裁基元的哪一侧(内侧或外侧)。

Clipping primitive example

注意

ClippingPrimitive 利用着色器中的剪裁/丢弃指令,并禁用 Unity 的批量剪裁渲染器功能。 利用剪裁基元时,请考虑到这些性能影响。

ClippingPlane.cs、ClippingSphere.cs 和 ClippingBox.cs 可用于轻松控制剪裁基元属性。 将这些组件与以下着色器配合使用就可以使用剪裁方案。

  • Graphics Tools/Standard
  • Graphics Tools/Text Mesh Pro
  • Graphics Tools/Wireframe
  • Graphics Tools/Wireframe
  • Graphics Tools/Non-Canvas/Backplate
  • Graphics Tools/Non-Canvas/Frontplate
  • Graphics Tools/Non-Canvas/Glow
  • Graphics Tools/Non-Canvas/Quad Glow
  • Graphics Tools/Non-Canvas/Beveled

高级用法

默认情况下,每次只有一个 ClippingPrimitive 可以剪裁呈现器。 如果你的项目需要多个 ClippingPrimitive 来影响呈现器,可以通过以下示例代码来了解如何做到这一点。

注意

使用多个 ClippingPrimitive 剪裁呈现器会增加像素着色器指令并影响性能。 请在项目中分析这些更改。

如何让两个不同的 ClippingPrimitive 剪裁呈现器。 例如,同时使用 ClippingSphereClippingBox

// Within GraphicsToolsStandard.shader (or another Graphics Tools shader that supports clipping primitives) change:

#pragma multi_compile_local _ _CLIPPING_PLANE _CLIPPING_SPHERE _CLIPPING_BOX

// to:

#pragma multi_compile_local _ _CLIPPING_PLANE
#pragma multi_compile_local _ _CLIPPING_SPHERE
#pragma multi_compile_local _ _CLIPPING_BOX

注意

上述更改将导致着色器编译时间延长。

如何让两个相同的 ClippingPrimitive 剪裁呈现器。 例如,同时使用两个 ClippingBoxes

// 1) Add the below MonoBehaviour to your project:

using UnityEngine;
using Microsoft.MixedReality.GraphicsTools;

[ExecuteInEditMode]
public class SecondClippingBox : ClippingBox
{
    /// <inheritdoc />
    protected override string Keyword
    {
        get { return "_CLIPPING_BOX2"; }
    }

    /// <inheritdoc />
    protected override string ClippingSideProperty
    {
        get { return "_ClipBoxSide2"; }
    }

    /// <inheritdoc />
    protected override void Initialize()
    {
        base.Initialize();

        clipBoxInverseTransformID = Shader.PropertyToID("_ClipBoxInverseTransform2");
    }
}


// 2) Within GraphicsToolsStandard.shader add the following multi_compile pragma:

#pragma multi_compile_local _ _CLIPPING_BOX2

// 3) In GraphicsToolsStandardInput.hlsl add the following shader variables:

#if defined(_CLIPPING_BOX2)
    half _ClipBoxSide2;
    float4x4 _ClipBoxInverseTransform2;
#endif

// 4) In GraphicsToolsStandardProgram.hlsl change:

#if defined(_CLIPPING_PLANE) || defined(_CLIPPING_SPHERE) || defined(_CLIPPING_BOX)

// to:

#if defined(_CLIPPING_PLANE) || defined(_CLIPPING_SPHERE) || defined(_CLIPPING_BOX) || defined(_CLIPPING_BOX2)

// 5) In the same shader change:

#if defined(_CLIPPING_BOX)
    primitiveDistance = min(primitiveDistance, GTPointVsBox(input.worldPosition.xyz, _ClipBoxInverseTransform) * _ClipBoxSide);
#endif

// to:

#if defined(_CLIPPING_BOX)
    primitiveDistance = min(primitiveDistance, GTPointVsBox(input.worldPosition.xyz, _ClipBoxInverseTransform) * _ClipBoxSide);
#endif
#if defined(_CLIPPING_BOX2)
    primitiveDistance = min(primitiveDistance, GTPointVsBox(input.worldPosition.xyz, _ClipBoxInverseTransform2) * _ClipBoxSide2);
#endif

最后,将 ClippingBoxSecondClippingBox 组件添加到场景中,并为两个框指定同一呈现器。 渲染器现在应该同时被两个框剪裁。

另请参阅