插件链接

支持WebGl端使用,性能开销低,无显著缺陷和限制。
捕获的过程不涉及射线检测,因为这是一个后处理器,所以也规避了unity6以下版本中不能使用gpu计算的问题,但也需要手动将插件提供的后处理部分启用才能继续使用插件。
选择需要捕获的模型,传入到管理器脚本的模型列表中,开始运行后,可以在后处理中调整捕获的范围,像素精度等等,结合捕获器模块,实现在屏幕空间中识别各个材质的位置及其中心点。

唯一的性能瓶颈是将像素桶排序的时候,这时需要遍历像素合并孤岛,然后基于孤岛数据给出中心点数据。
这个中心点坐标不是计算加权中心得出来的,仅和像素排序桶数量相关,速度快,且无需担心会出现和任何其他像素位置冲突的情况。
但无论如何都需要遍历所有像素,所以务必控制像素数量。
如何使用
以下是一些可以设定的字段值
// 指定后处理只在特定标签的摄像机上运行。
GeoLayerPickerRenderPassFeature.Instance.onlyOnMainCamera;
// 匹配像机标签
GeoLayerPickerRenderPassFeature.Instance.cameraMatchMode;
// 拾取尺寸,像素数量越高,单帧压力越大(尽量控制在像素总数2k以下,精度越高,可以拾取的像素精度越高)
GeoLayerPickerRenderPassFeature.Instance.pickRTSize;
// 获取和设置采样范围
GeoLayerPickerRenderPassFeature.Instance.sampleRect;
// 设置cpu端回传处理数据的速率
GeoLayerPickerRenderPassFeature.Instance.readbackInterval;
// 启用调试视图和日志
GeoLayerPickerRenderPassFeature.Instance.enableDebugLog;
这是一段使用示例
var islands = GeoLayerPickerRenderPassFeature.Instance.GetMaterialIslands();
foreach (var islandData in islands)
{
var pool = useLeft ? LeftLabelPool : RightLabelPool;
var go = pool.Get();
var goRectTrans = go.RectTransform();
var text = goRectTrans.GetChildrenBFS().GetComponents<TMP_Text>();
text.ForEachDo(a => a.text = islandData.materialName);
goRectTrans.anchoredPosition = islandData.position;
useLeft = !useLeft;
}通过GetMaterialIslands()方法获得一个只读的材质孤岛列表,这里的做法是通过各向异性编组提取同类型像素孤岛,返回这些孤岛的数据。
然后你可以使用这些孤岛的坐标,材质名称等信息实现更多的功能。
需要注意的是,由于是后处理图像,导致它无法继续开放更多属性了。现在的纹理上包含的是(xyz世界坐标,w材质索引),目前看来世界坐标其实没有什么太大用处(因为转到屏幕空间后可以再通过相机矩阵换回射线重新在场景中得到坐标数据),或许可以将这些通道改为其他属性。