模型工作流:自动化的模型内部三角面剔除

news2025/1/2 23:35:38

1. 关于自动减面

1.1 自动减面的重要性及现状

三维模型是游戏、三维家居设计、数字孪生、VR/AR等几乎所有三维软件的核心资产,模型的质量和性能从根本上决定了三维软件的画面效果和渲染性能。其中,模型减面工作是同时关乎质量和性能这两个要素的重要工作,一个好的模型减面结果,既能保证模型的渲染品质不会过多降低,又能保证模型面数降到一个合理可用的范围。

但三维模型的减面工作需要耗费大量的人力成本,通常一个模型的减面工作根据模型的复杂程度不同,需要耗费0.5到1人/天的成本,如果模型特别复杂,这个时间还会增加。因此,自动化减面工具的引入能极大提升建模人员的工作效率。

1.2 自动减面的挑战

现有的自动化减面工具,基本上都是基于在1997年发布的《Surface Simplification Using Quadric Error Metrics》(下称QEM算法)这篇论文的实现,比如当前游戏行业最流行的工具 PolygonCruncher 就是基于该论文实现的。该工具能够在保证模型拓扑形状的同时进行减面,最终减面的比例会跟该工具的设定有关,其中轮廓保护程度、纹理坐标保护程度、边角保护程度等等都会影响最终的减面比例,在我们家电场景的实际使用过程中,根据使用经验,一个能保持较高品质的减面比例通常在50%左右,这对于动辄十几万甚至上百万的模型来说,是远远达不到安全可用的要求的。

1.3 QEM算法的开创性和局限性

减面工作本质上是一个基于视觉系统和逻辑判断的事情,建模人员需要通过人眼去观察模型的三角面,并据其与模型的遮挡关系,在脑中判断出这个三角面是否可见,或者说是否应该被剔除掉。所以,想要实现自动减面,要么想办法摆脱对视觉系统的依赖,要么想办法实现一套视觉系统。而QEM算法的思路就是前者。

QEM算法创造性的通过计算出三角网格中每个边的一个特殊度量指标——二次误差,以该指标作为一个三角面是否应该减去的依据,从而绕过了视觉系统,仅通过三维数据的数据计算即可完成减面工作。具体来说,一条边的二次误差越大代表其对该局部区域拓扑结构的影响就越大,就越应该保留下来,反之就越应该减去。

但是QEM算法并非无懈可击,由于不依赖视觉系统,它只能根据对拓扑结构的影响程度来选择要减去的三角面,无法进一步根据三角面的可见性情况进行模型内部三角面的剔除。这也是QEM算法在家电模型减面的场景下表现不佳的根本原因。

关于QEM算法的具体原理,可以查看另一篇文章:《模型工作流:模型减面原理分析及优化思路》

1.4 如何破局

因此,我们可以通过引入模拟的视觉系统,来实现模型内部三角面的识别和剔除,从而让模型能在QEM减面的基础上,进一步的将内部三角面减去,从而实现更高效的减面效率。实现的效果如下图所示:

一个拓扑结构比较复杂的例子

2. 基于深度测试的减面

从生物学上来看,人眼最重要的两个能力是色彩识别、深度识别,其中深度识别就是指大脑能根据两个眼睛的“摄像”结果推断出视网膜中某个“像素点”的空间位置的深度关系。同样,对于减面工作来说,我们需要借助眼睛来判断一个三角面到底是暴露在外部,还是被遮挡在内部,其本质上就是判断两个像素点的深度关系。那么,只要在程序中获取到每个三角面的深度关系,那么我们就能识别出那些三角面是被遮挡的,其基本思路如下:

2.1 基本思路

物体的深度是跟人眼的位置和方向有关的,我们会引入若干个虚拟相机,将它们环绕摆放在模型四周,依次来模拟人眼观察的效果。根据模型的实际使用形态不同,相机的摆放可以灵活设定,一般设置8个朝下看+8个朝上看相机足够应对大部分情况,如下图所示。

在这之后,每个相机会进行拍摄,拍摄的内容是“整个模型”的三角面光栅化后的深度值,以下是其中3个相机的拍摄内容。这样,我们就能从图片中获取到每个像素点位置的深度值,对应的就是该像素位置下的模型表面的深度,也就是d2。

相机1

相机2

相机3

然后,我们需要在程序中,通过空间计算,获取每个三角形的在上述每个相机下的深度值,记为d1。这样,我们依次遍历模型的每一个三角形,计算每个三角形的d1和d2的大小关系,如果d1 > d2,则代表这个三角形的深度比模型表面更深,那么就意味着这个三角形在当前相机位置下是不可见的,如下图所示:

注意,d1的获取我们不能使用光栅化来完成,因为面的数量过大,此时CPU的效率远比GPU一个一个渲染FrameBuffer要高很多。

然后我们每个相机都重复上述操作,记录下每个相机的不可见的三角形的集合,最终把所有这些集合进行一个“取交集”的操作,就能得到在所有相机下都不可见的三角形,这样我们后续就能安全的进行内部三角面的剔除了,伪代码如下:

// 伪代码
-- 遍历每一个相机
for camera in cameras:
    -- 拍摄该相机下的整个模型的深度图
    wholeObjectDepthMap = renderCameraDepthMap camera wholeObject
    -- 遍历改模型的所有物体
    for obj in allObjects:
        -- 遍历该物体的所有三角面
        for face in obj.faces:
            -- 采样该面的关键点
            faceSamplePoints = sampleFacePoints face
            -- 遍历这些关键点
            for point in faceSamplePoints:
                -- 计算关键点的NDC坐标
                ndc = worldToNDCCoord point
                -- 计算关键点的UV坐标
                uv = NDCToUVCoord ndc
                -- 使用UV坐标采样深度图的颜色
                color = readPixel wholeObjectDepthMap uv
                -- 颜色值转深度值,即是d2
                d2 = (1.0 - color/255.0)
                -- ndc坐标系的z值就是d1(根据图形学理论)
                d1 = ndc.z
                -- 如果d1的深度大于d2的深度,那么就代表d1所在的关键点不可见
                if d1 > d2:
                    -- 该三角面的、该点,不可见

2.2 一些优化点

2.2.1 深度精度优化

为了尽可能提升深度值的精度,我们需要把相机视锥参数调整到“恰好包裹起整个物体”的状态,这样才能尽可能的减少相机的near平面和far平面的距离,以此来提升深度精度。

注意,这里我们使用正交投影相机,视锥在程序内部是一个长方体(如图中白色虚线所示),而不是锥形。

2.2.2 三角面关键点

考虑到一个三角面被遮挡的情况千奇百怪,比如可能中间被遮挡边角露出,也可能反过来。因此对三角面的关键点选取数量越多,我们的判断精度就越高。但是三角面数量越多,我们的计算耗时就越大,这需要权衡。经过实践,在三角形的边角和中心区域共6个点可以应对绝大部分情况。

2.2.3 预剔除

有一些物体它本身已经完全隐藏在另一个物体内部,此时这个物体其实可以整个抛弃,没必要再判断每个三角形的可见情况。实现思路也很简单,除了拍摄整个模型的深度图,然后每个物体也拍一个深度图。

伪代码如下:

// 伪代码
-- 遍历每一个相机
for camera in cameras:
    -- 拍摄该相机下的整个模型的深度图
    wholeObjectDepthMap = renderCameraDepthMap camera wholeObject
    -- 遍历改模型的所有物体
    for obj in allObjects:
        -- 拍摄该相机下的“单个物体”的深度图
        objectDepthMap = renderCameraDepthMap camera obj 
        objectBBoxWorld = getObjBBox obj
        objectNDCRange = worldToNDCRange objectBBoxWorld 
        -- 获取UV的坐标范围,如上图红框所示
        objectUVRange = NDCToUVRange objectNDCRange
        -- 遍历两张图在该坐标范围内的像素颜色,进行深度值的判断
        for u in objectUVRange.rows:
            for v in objectUVRange.cols:
                color2 = readPixel wholeObjectDepthMap uv
                color1 = readPixel objectDepthMap uv
                
                d2 = (1.0 - color2/255.0)
                d1 = (1.0 - color1/255.0)
                
                if d1 > d2:
                    -- continue
                else
                    -- exit 有一个像素可见,那么整个物体都可见,直接退出循环

2.3 自动减面效果测试

基于深度测试的减面方法是通用的,因此对于各种品类的家电家具模型都有非常好的效果,相比于传统的基于QEM算法的减面方案,减面效率得到了巨大的提升。

品类

产品

原始面数

纯QEM算法方案

深度测试方案(配合QEM减面)

电饭煲

HRC-FS4042A-FN01D0028

3.3w

1.1w

减面比例:66%

0.52w

减面比例:84%

电水壶

FM00E0000

9.2w

2.8w

减面比例:69%

0.74w

减面比例:92%

吸油烟机

海尔-家用-吸油烟机-CXW-258-EC967U1

12w

7.5w

减面比例:36%

0.83w

减面比例:93%

净水器

卡萨帝-反渗透-净水机-600G-CRO600-DFBGU1

15w

9.6w

减面比例:36%

1w

减面比例:93%

用水

圆镀铬龙头HJ2107

12.5w

8.4w

减面比例:33%

0.5w

减面比例:96%

智能浴霸

海尔-智能浴霸-X3U1

12.6w

7.2w

减面比例:43%

0.78w

减面比例:93%

热水器

卡萨帝-电热-热水器-80L-CES80H-PROS3CEK02U1

39w

21w

减面比例:46%

2.9w

减面比例:92%

洗衣机

海尔-滚筒-洗衣机-10kg-G100318B14LS

59w

43w

减面比例:27%

10w

减面比例:83%

电视

卡萨帝-液晶电视机-K85E10

62w

56w

减面比例:9%

13w

减面比例:79%

壁挂空调

海尔-挂机-空调室内机-2匹-KFR-50GW18MEA83U1套机

66w

59w

减面比例:10%

2.7w

减面比例:96%

柜式空调

海尔-柜机-空调室内机-大3匹-KFR-72LW17DAA81VU1

79w

63w

减面比例:20%

11w

减面比例:86%

冰箱

卡萨帝-多开门-电冰箱-550L-BCD-550WLCFPA4YBU1

150w

70w

减面比例:53%

17w

减面比例:89%

3. 团队介绍

三翼鸟数字化技术平台-筑巢自研平台」依托实体建模技术与人工智能技术打造面向家电的智能设计平台,为海尔特色的成套家电和智慧场景提供可视可触的虚拟现实体验。智慧设计团队提供全链路设计,涵盖概念化设计、深化设计、智能仿真、快速报价、模拟施工、快速出图、交易交付、设备检修等关键环节,为全屋家电设计提供一站式解决方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2268264.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

黑马程序员Java笔记整理(day08)

1.代码块 静态代码块 实例代码块 2.内部类 成员内部类 静态内部类 局部内部类 匿名内部类 认识 常见使用形式 应用场景 简化版本 另一个应用场景 3.函数式编程 Lambda 函数简化 方法引用 4.常用API String ArrayList 5.GUI编程 快速认识 事件处理 三种常用写法 第一种 第二…

redis延迟队列

Redis延迟队列 Redis延迟队列是基于Redis构建的消息队列,用来处理需延迟执行的任务。 基本原理 它借助Redis的有序集合(Sorted Set)数据结构达成目的。会把任务及其执行时间分别当成成员与分值存进有序集合,由于执行时间作为分值&…

爱思唯尔word模板

爱思唯尔word模板 有时候并不一定非得latex https://download.csdn.net/download/qq_38998213/90199214 参考文献书签链接

【JDBC】入门增删改查

JDBC JDBC概述 JDBC(Java DataBase Connectivity, java数据库连接)是一种用于执行SQL语句的Java API。JDBC是Java访问数据库的标准规范,可以为不同的关系型数据库提供统一访问,它由一组用Java语言编写的接口和类组成。 XML方式…

Java开发-后端请求成功,前端显示失败

文章目录 报错解决方案1. 后端未配置跨域支持2. 后端响应的 Content-Type 或 CORS 配置问题3. 前端 request 配置问题4. 浏览器缓存或代理问题5. 后端端口未被正确映射 报错 如下图,后端显示请求成功,前端显示失败 解决方案 1. 后端未配置跨域支持 …

Dify服务器部署教程

Dify的github地址: https://github.com/langgenius/dify 服务器要求:2c4g 1、克隆仓库 可以通过命令或者下载zip解压后上传服务器都行 git clone https://github.com/langgenius/dify.git 2、docker启动 cd dify/dockercp .env.example .envdocker compose up -d…

砝码称重(2021年蓝桥杯)

【问题描述】 你有一架天平和N个砝码,这N个砝码的重量依次是w1,w2,……,wn。(1~n为下标) 请你计算利用N个砝码一共可以称出多少种不同的重量? 【注意】砝码可以放在天平的两边 【输入格式】 第一行包含一个整数N。 第二行包含N个…

KaiOS 4.0 | DataCall and setupData implemention

相关文档 1、KaiOS 3.1 系统介绍 KaiOS 系统框架和应用结构(APP界面逻辑)文章浏览阅读842次,点赞17次,收藏5次。对于Java开发者而言,理解JS的逻辑调用是有点困难的。而KaiOS webapp开发又不同于现代的web开发,更像chrome浏览器内嵌模式。在这里梳理一下kaios平台web应用…

ArcGIS Pro地形图四至角图经纬度标注与格网标注

今天来看看ArcGIS Pro 如何在地形图上设置四至角点的经纬度。方里网标注。如下图的地形图左下角经纬度标注。 如下图方里网的标注 如下为本期要介绍的例图,如下: 图片可点击放大 接下来我们来介绍一下 推荐学习:GIS入门模型构建器Arcpy批量…

win系统B站播放8k视频启用HEVC编码

下载HEVC插件 点击 HEVC Video Extension 2.2.20.0 latest downloads,根据教程下载安装 安装 Random User-Agent 点击 Random User-Agent 安装 配置 Random User-Agent 在youtube中会导致视频无法播放,我选择直接屏蔽了 B站设置

mysql锁机制以及隔离级别下保证并发安全的方式

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 mysql锁机制以及隔离级别下保证并发安全的方式 多事务并发执行可能出现的问题mysql有那些锁全局锁表级锁行锁 在不同的隔离级别下mysql保证并发安全的方式RU隔离级别RC隔离级…

qwenvl 以及qwenvl 2 模型架构理解

qwenvl 模型理解: 参考资料: https://qwenlm.github.io/zh/blog/qwen2-vl/ https://github.com/QwenLM/Qwen2-VL?tabreadme-ov-file https://qwenlm.github.io/zh/blog/qwen2-vl/ 论文: qwenvl https://arxiv.org/abs/2308.12966 Qwen2-VL …

高效使用AI完成编程项目任务的指南:从需求分析到功能实现

随着人工智能工具的普及,即便是零编程基础或基础薄弱的用户,也可以借助AI完成许多技术任务。然而,要高效地使用AI完成编程任务,关键在于如何清晰表达需求,并逐步引导AI实现目标。 在本文中,我们将通过开发…

AI生成视频字幕--VideoCaptioner/卡卡字幕助手

github: https://github.com/WEIFENG2333/VideoCaptioner 123云盘:https://www.123865.com/s/inrnjv-1sk6H提取码:4455 B站教程:https://www.bilibili.com/video/BV1giBqYtEqG?vd_source8e73ffa42accf9446f3cb7fddc85b38c 优点:1.免费&am…

嵌入式单片机窗口看门狗控制与实现

窗口看门狗 注意:WWDG外设没有独立的时钟源,而是挂载在APB1总线下,APB1总线外设时钟为42MHZ。 了解WWDG外设的使用流程,可以参考stm32f4xx_wwdg.c的开头注释,具体流程如下图所示

从 ELK Stack 到简单 — Elastic Cloud Serverless 上的 Elastic 可观察性

作者:来自 Elastic Bahubali Shetti, Chris DiStasio 宣布 Elastic Cloud Serverless 上的 Elastic Observability 正式发布 — 一款完全托管的可观察性解决方案。 随着组织规模的扩大,一个能够处理分布式云环境的复杂性并提供实时洞察的可观察性解决方…

【教程】通过Docker运行AnythingLLM

转载请注明出处:小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你,欢迎[点赞、收藏、关注]哦~ 官方教程:Local Docker Installation ~ AnythingLLM 1、先创建一个目录用于保存anythingllm的持久化文件: sudo mkdir /app su…

RabbitMQ基础篇之快速入门

文章目录 一、目标需求二、RabbitMQ 控制台操作步骤1.创建队列2.交换机概述3.向交换机发送消息4.结果分析5.消息丢失原因 三、绑定交换机与队列四、测试消息发送五、消息查看六、结论 一、目标需求 新建队列:创建 hello.queue1 和 hello.queue2 两个队列。消息发送…

Lottie动画源码解析

Lottie是一个很成熟的开源动画框架,它支持直接使用从AE导出的动画文件,在不同平台均可快速使用,大大减轻了程序员的工作量,也让复杂的动画成为可能。该动画文件使用Json格式来描述内容,可以大大缩减文件的体积。在Andr…

手机发烫怎么解决?

在当今这个智能手机不离手的时代,手机发烫成了不少人头疼的问题。手机发烫不仅影响使用手感,长期过热还可能损害手机硬件、缩短电池寿命,甚至引发安全隐患。不过别担心,下面这些方法能帮你有效给手机 “降温”。 一、使用习惯方面…