目录

  • 改进算法的必要性
  • 改进方案
  • 题外话
  • 1/10日更新:别存切线!

改进算法的必要性

因为知乎帖子(https://zhuanlan.zhihu.com/p/234535777)写的比较全面(建议先去看他的帖子,我只是他 的改进),我有充裕的时间去优化迭代完成我的单子,就对他的算法做出了一点优化。

本以为只是一个小小的优化,但实际上Fbx的顶点数是真的多,时间复杂度的改进会非常明显。我拿了一个22万面的mesh做测试,改进前导入花费了50分钟,改进后7秒(共43秒,后面是ue4的模型转换逻辑导致)。可以说不改的话,顶点数一多就不能用了,所以改进是必要的。

以下是压力测试的结果:
原本耗时50分钟

改进后耗时43秒

改进方案

时间都是消耗在查找重叠点上的,很多网上方案查找重复序号用了二重循环,这样,模型顶点数一多就撑不住了。也看到用排序或者多线程(unity job system)的,其实没必要搞那么复杂,花费一点空间换时间,以序号为健名存在字典里面就好了,计算量大减。
(O(n^2)->O(n))

题外话

我改的是切线的,如果你需要存在其他地方,还要额外修改。另外这是Ue4代码片段,实际上还做了一些Fbx导入的UI勾选项等,这部分可以去找FbxSkeletalMeshImportData.h和FbxMainImport.cpp。因为本贴分享的重点在于时间复杂度的优化,就不全部贴出了。

如何还有什么需要在意的话,那就是法线平均值其实还有三种:等加权、角度加权、面积加权。(甚至还可以有混合的面积角度加权)但顶点偏移法画出的描边粗细会随着NdotV变化,没有一种方案是完成正确的,而且区别也不大,不用过渡纠结。(不过面积加权肯定是不好的,看猴子耳朵和壶嘴)

如果想实现角度加权可以去遍历面,但效果不一定会提升可能还会变差。

1/10日更新:别存切线!

存切线的话,切线空间都会乱掉,法线贴图会用不了,切空间各自操作都会用不了!存顶点色,uv都可以,别存切线。

void UnFbx::FFbxImporter::StoreAVGNormalsToTangent(FbxMesh* mesh)
{// 如果不存在 自动生成切线 副切线if (mesh->GetElementTangentCount() == 0 || mesh->GetElementBinormalCount() == 0){mesh->GenerateTangentsData(0, true);}//获取layerFbxLayer* layer0 = mesh->GetLayer(0);//依次获取layer中的顶点色、2uv、法线、切线、副法线FbxLayerElementNormal* VertNormal = layer0->GetNormals();FbxLayerElementTangent* VertTangent = layer0->GetTangents();TMap<int, FbxArray<FbxVector4>> VertexNormalsGroup;TMap<int, FbxVector4> VertexAVGNormals;//逐顶点遍历缓存法线信息for (int i = 0; i < mesh->GetPolygonVertexCount(); ++i){int vtxIdx = mesh->GetPolygonVertices()[i];FbxVector4 Normal = VertNormal->GetDirectArray()[i];//将顶点法线们 以顶点序号为key 填入字典if (!VertexNormalsGroup.Contains(vtxIdx)){FbxArray<FbxVector4> Normals;Normals.Add(Normal);VertexNormalsGroup.Add(vtxIdx, Normals);}else{VertexNormalsGroup[vtxIdx].AddUnique(Normal);}}//遍历tmap计算等权法线平均值for (auto& kvp : VertexNormalsGroup){FbxVector4 EqualWeightedSmoothNormal;if (kvp.Value.Size() == 1) {VertexAVGNormals.Add(kvp.Key, kvp.Value[0]);}else{for (int n = 0; n < kvp.Value.Size(); ++n){//万一法线模不为1,之前max脚本里看到过不是单位向量的法线EqualWeightedSmoothNormal += kvp.Value[n];}EqualWeightedSmoothNormal.Normalize();VertexAVGNormals.Add(kvp.Key, EqualWeightedSmoothNormal);}}VertexNormalsGroup.Empty();//FbxVector4::DotProduct()//改写顶点切线为法平均for (int j = 0; j < mesh->GetPolygonVertexCount(); ++j){int vtxIdx = mesh->GetPolygonVertices()[j];VertTangent->GetDirectArray().SetAt(j, VertexAVGNormals[vtxIdx]);}VertexAVGNormals.Empty();
}

参考了很多大佬的帖子:

【Ue4卡通渲染描边方案】平均法线存入切线的改进算法——O(n)时间复杂度相关推荐

  1. unity 3d物体描边效果_从零开始的卡通渲染描边篇

    序言: 一直对卡通渲染非常感兴趣,前后翻找了不少的文档,做了一些工作.前段时间<从零开始>的手游上线了,试着渲染了一下的其中模型,觉得效果很不错.打算写一个专栏记录其中的渲染技术.在后面的 ...

  2. 卡通渲染描边的另一种做法

    在我之前的文章中有一遍的说描边的问题汇总的: https://blog.csdn.net/llsansun/article/details/83744775 这里面也说了一些问题,最典型的问题是描边的 ...

  3. 卡通渲染-平均法线描边

    [01]从零开始的卡通渲染-描边篇] 最近在学习渲染,入门的时候也学了Back facing描边法,但是表现在正方体上割裂严重,就先略过了. 看了这篇文章才了解到平均法线的做法,作者将平均法线存到模型 ...

  4. Unity下的日式卡通渲染实现-描边篇(三)

    这边文章讲述的是项目中用到的一些卡通渲染描边相关技术. 一.Back Face外扩描边 背面外扩描边和后处理描边是卡通渲染中主要应用到的描边方式. 1.1 实现原理 第一个Pass正常渲染物体.第二个 ...

  5. UE4全场景卡通渲染

    UE4全场景卡通渲染效果 这个配色实在是.. 大概效果就是这样了. 用后处理材质做卡通渲染 色块渲染和描边都是用后处理材质做的.描边就不详细说了,以前的文章有. 色块渲染,前面文章UE4卡通渲染提到的 ...

  6. 【非真实渲染】【卡通渲染技术点介绍】

    阅读指南 文本介绍卡通渲染的基本技术,实现会放在另外的文档 关键词 Cel Shading,ToonShading,色块.色调,各向异性,描边,高光 特征 看起来像手绘的图片 少渐变(指光影的变换), ...

  7. 二次元卡通渲染——进阶技巧

    前言 随着<原神>游戏的盛行,国内对于二次元游戏这块儿领域越来越看重了.二次元项目中本身基于日本的卡通动漫而来,所以最后的本质都是为了尽量还原2D立绘,而并不像PBR追求物理正确,只要好看 ...

  8. 寄存器分配图着色_【02】从零开始的卡通渲染-着色篇1

    专栏目录 2173:[01]从零开始的卡通渲染-描边篇​zhuanlan.zhihu.com 2173:[02]从零开始的卡通渲染-着色篇1​zhuanlan.zhihu.com 2173:[03]从 ...

  9. 着色器实例 代码+注释 更新中【描边、卡通渲染、法线颜色、贴图动画等等】

    描边着色器 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader " ...

最新文章

  1. 使用HTML5画布实现的超棒javascript动画仪表板:gauge.js
  2. 可可肉的奋斗(第一天)2012-12-24
  3. php 中的 mysqli事务处理
  4. webbrowser 百度列表点击_前嗅ForeSpider采集教程:关键词的「检索列表」采集「检索结果」...
  5. 微型php框架 include/mysql.class.php
  6. Typescript实现单例之父类调用子类
  7. 进击的程序媛:从 Google 第一位程序媛到硅谷女王进化史
  8. 社交界的 Linux,为何败给了 Facebook、Twitter?
  9. 如何查看IOS系统APP的包名
  10. vscode win10笔记本 蓝屏_老鸟教你win10开机蓝屏0xc000000d的详尽解决办法
  11. 分享一个返利系统源码,前端uni+后端php开发的影票返利系统源码
  12. 用VScode搭建uni-app项目(较全)
  13. 用Python画圣诞树
  14. SpringBoot+Vue 实现大文件断点下载
  15. SQL查询语句逻辑执行顺序
  16. 6.27软件园与血站见习报告
  17. ShardingSphere使用(一)
  18. JSJ——java基本概念二
  19. ubuntu下如何批量修改文件后缀名
  20. c语言 整数和浮点数_C ++处理整数和浮点数

热门文章

  1. 高速公路ETC卡签之我见6-省级密钥系统建设
  2. GL/gl.h: No Such file or directory...
  3. c语言中接口和函数的区别,接口与类的关系_接口函数和调用函数有什么区别
  4. Bill Gates的博物馆
  5. 用数字键盘打出特殊符号
  6. Burp suite遇到的常见问题
  7. 华三2019校招笔试
  8. 魔兽事件表态期望早日找到解决办法 - 丁磊
  9. MySQL读写锁总结
  10. 几种允许跨域请求的方法