Metal 框架之渲染到多个视口

439 阅读2分钟

「这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战

概述

视口定义了渲染目标的一部分,绘图命令会渲染到该区域内。使用视口选择,可以为绘图命令提供多个视口,并且可以为绘图命令渲染的每个图元动态选择其中的一个视口。通过视口选择,使用更少的绘图命令,可以更轻松地将渲染合并到多个视口中。例如,

渲染立体图像或者渲染其他图像的内容到渲染目标的多个部分试时,可以使用视口选择。

多视口.png

检查设备对象是否支持多个视口

macOS 系列中的所有 GPU 都支持多个视口。从系列 5 开始,Apple GPU 系列提供多个视口的支持。如下代码测试设备支持情况:

- (Boolean) supportsMultipleViewports
{
    return [_device supportsFamily: MTLGPUFamilyMac1 ] ||
           [_device supportsFamily: MTLGPUFamilyApple5 ];
}

有关每个 GPU 系列可以使用的最大视口数,请参阅使用 《 Metal 功能特性集合表 》

选择视口

要指定图元应渲染到哪个视口,需要添加具有 [[viewport_array_index]] 属性的顶点输出。顶点着色器必须设置此值,以便 Metal 知道要渲染到哪个视口。

下面的示例使用实例化渲染将图元渲染到多个视口中。需要在顶点输出中添加 viewPort 以指定目标切片。目标视口(被当做每个实例属性的一部分)作为输入,并被复制到顶点输出中。


typedef struct
{
    ...
    uint   viewport [[viewport_array_index]];
} ColorInOut;

vertex ColorInOut vertexTransform (
    const Vertex in [[ stage_in ]],
    const uint   instanceId                       [[ instance_id ]],
    const device InstanceParams* instanceParams   [[ buffer ]],
{
    ColorInOut out;
    out.viewport = instanceParams[instanceId].viewport;
    ...
}

顶点函数必须为构成任何给定图元的所有顶点返回相同的索引。

光栅化阶段使用选定的视口和相关的裁剪矩形来转换顶点输出,然后将数据传递到片段阶段。通过查找顶点输出中设置的相同字段值,可以知道片段着色器所渲染的视口。

在绘图命令中指定视口和裁剪矩形

调用 setViewports:count: 指定多个视口,调用 setScissorRects:count: 指定裁剪矩形:

[renderEncoder setViewports:viewPortsArray count:4];
[renderEncoder setScissorRects:scissorRectsArray count:4];

需要指定相同数量的裁剪矩形和视口。编码渲染指令的代码与着色器中的代码相配合使用,以便着色器生成的索引在提供的值范围内。

总结

本文介绍了使用 Metal 渲染到多个视口的步骤,首先使用视口选择为顶点着色器中的每个图元选择一个视口,其次在绘图命令中指定相同数量的视口和裁剪矩形。