教你如何使用GPA导出模型,另送一个 GPA CSV2MESH Tool in unity
Posted Jave.Lin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了教你如何使用GPA导出模型,另送一个 GPA CSV2MESH Tool in unity相关的知识,希望对你有一定的参考价值。
文章目录
以前写过一篇:Unity - RenderDoc 抓帧导出 FBX(带UV)
吐槽
我估计GPA是怕收律师函,因为如果 GPA 将所有资源一键提取,一键导出,那么可能很多开发商会告他
GPA Geometry Output 没有 UV
可以看到也好几个帖子问 GPA 官方,都是被官方忽悠回答了:
(除了这个,我自己还搜索过还几个类似有人问这个问题,结果同样被官方忽悠)
- 我之前尝试过用 GPA,RenderDoc 来抓取模型,结果 GPA 导不出 UV,而且 VBV 数据长度还对不上,RenderDoc 还不能对抓取模拟器 - unity shader - 圣斗士星矢 人物 shader 还原 - GPA 抓帧提取资源、shader,ROOT权限、救砖、ro.debuggable=1(最终还是RenderDoc无法抓帧) - 在现在这篇文章我尝试着将不同 VBV 元素长度的组装,我都以 indices 的长度来读取顶点数据的长度来构建模型,结果发现还真的可行,就是有不少无用的 primitive
- RenderDoc 是可以直接导出带 UV 的,可以查看我之前的一篇:Unity - RenderDoc 抓帧导出 FBX(带UV)
既然GPA不整模型导出带UV,那么今天我们实现一个 GPA 中的模型导出 UV 的工具
问题实例
如果直接将 input gemoetry 导出
会得到一个除了 position 之外,没有其他数据的网格,如下:
然后,对应的 shader vs input 有6个 register
如果我们要向将这些顶点数据都导出来,直接使用 GPA 功能默认的Geometry output是导不出来的
开始实现
提取 VBV, IBV
上面的 VS_INPUT
可以看到 input attribute 的定义
但是这些数据是从哪些 VBV(vertex buffer viewer) 输入的呢?
我们可以点击 Resource 中的 Shader,选择:Vertex shader 后
然后查看使用到的数据有哪些,如下图:
OK,留意:
然后我们可以将每个 VBV 个、单个 IBV 设置导出 CSV Titles 格式,下面以导出 position.csv 为例
- 根据shader input attribute 定义,定位使用的 vbv序号
- 在 resource 中,找到对应的 vbv
- 给 vbv 的 titles 设置好格式
- 最后 导出 csv
其他的 tangent, normal, uv0, uv1, color0 都可以使用类似的方式导出,如上图,这个模型的数据我是使用下面的格式导出的
因为我们使用的是 unity mesh,那么TEXCOORD0 的 position 我们需要将其 semantic 修改为 POSITION,同理,normal 和 uv0 都使用对应的:NORMAL, TEXCOORD0 来替代
参考如下(注意每个 shader 的 VBV 是干嘛用的,需要自行去查看 shader 怎么使用,以此分析他们的所属的 semantic,因为每个 shader 都有可能不一样):
VBV, IBV 导出的 csv format:
-
position : VBV1 -
float POSITION.x;float POSITION.y;float POSITION.z;
-
tangent : VBV2 -
float TANGENT.x;float TANGENT.y;float TANGENT.z;float TANGENT.w;
-
normal : VBV3 -
float NORMAL.x;float NORMAL.y;float NORMAL.z;
-
uv0 : VBV0 -
half TEXCOORD0.x;half TEXCOORD0.y;byte4p
-
uv1 : VBV0 -
byte4p; half TEXCOORD4.x;half TEXCOORD4.y;
-
color0 : VBV1
float TEXCOORD5.x;float TEXCOORD5.y;float TEXCOORD5.z;float TEXCOORD5.w; byte4p
ubyte COLOR0.x;ubyte COLOR0.y;ubyte COLOR0.z;ubyte COLOR0.w; byte4p
ubyte TEXCOORD5.x;ubyte TEXCOORD5.y;ubyte TEXCOORD5.z;ubyte TEXCOORD5.w; byte4p
- 这个会使用比较多,但是这个有些问题:没有 normalizednubyte TEXCOORD5.x;nubyte TEXCOORD5.y;nubyte TEXCOORD5.z;nubyte TEXCOORD5.w; byte4p
- 然后添加了前缀n
后,还是不能 normalized,所以这个我在工具中特殊弄了一些开关,可是设置 VBV 是否需要 normalized
-
index : IBV - 不需要格式,直接导出,只要确保第二列是 index 的值即可
工具演示导出
GPA 的 VBV,IBV的 BUG
我之前就怀疑还原模型的话,如果这些 IBV, VBV 长度都不对的话,除了浪费数据,还可能出问题
因为很多 VBV 和 IBV 的元素数量是对不上的
今天在抓帧某个角色的 卧蚕(眼部底下部分) 模型时候就出现这个问题
从下面的 IBV 可以看到1091,1092 之间的索引跨度很大,是有问题的
23901 的索引直接就超出了 VBV 顶点总数的数量
从下面的数据分析, Primitive 总数才 364 个三角形
VBV position 数量才 10313,但是 IBV 的索引已经远超这个范围了,这个很明显是 GPA 的数据显示上的 BUG
所以部分模型的导出可能遇到:
Fail setting triangles. Some indices are referencing out of bounds vertices. IndexCount: 2046, VertexCount: 10314
Fail setting triangles. The number of supplied triangle indices must be a multiple of 3.
must be a multiple of 3 的解决办法
在我的工具中,是这么来处理的:
因为是在 set triangles 的时候发生的错误
那么我们只要将 indices 的长度保持在 缓存元素数量可以整除3即可:indices.Count % 3 == 0
// jave.lin : push padding or remove padding
// jave.lin : 这么处理可以避免 https://blog.csdn.net/linjf520/article/details/127066726 文章中提及的 BUG:
// - Fail setting triangles. Some indices are referencing out of bounds vertices. IndexCount: xxx, VertexCount: xxx
// - Fail setting triangles. The number of supplied triangle indices must be a multiple of 3.
if (indices.Count > 0 && indices.Count % 3 != 0)
var loopCount = 0;
var lastOneVal = indices[indices.Count - 1];
var lastOneIsZeroVal = lastOneVal == 0;
while (indices.Count > 0 && indices.Count % 3 != 0)
if (loopCount > 10)
break;
loopCount++;
if (lastOneIsZeroVal)
// jave.lin : remove padding 如果尾部是 0 索引,我们可以用删除 padding 的方式
indices.RemoveAt(indices.Count - 1);
else
// jave.lin : push padding, 否则我们使用 push 最后一个顶点作为 padding 的方式
indices.Add(lastOneVal);
indices out of bounds vertices - 暂无解决方法
这个问题是 GPA 的 BUG
暂时无解,连 index 的数值都错了,我们是不可能知道正确的数值的,只能猜:比如,可能是 数据类型溢出?
就是新版本的 fbx 模型,可能使用了 index buffer 的索引值的压缩技术,可能在 GPA 中没有对应实现解析,那么肯定会有报错的
这个 index 索引值的压缩技术大概是这么个思路:
- 如果
index < byte.MaxValue
,那么 index 使用byte
类型解析 - 如果
index < ushort.MaxValue
,那么 使用ushort
类型解析 - 如果
index < uint.MaxValue
,那么 使用uint
类型解析
Project
- github 工程后续上传
- 百度盘工程后续上传
References
- GPA-Mesh - hub友 C++写的一个,没用过,也不知道怎么用
- INTEL GPA mesh ripper tutorial + tool (x32,x64,DX9,10,11) - 2014 年的时候国外友人写了 GPA Hook 来抓自己想要的资源
如何根据GPA对数组列表进行升序排序? arraylist 包含一个对象数组。 (Java)[重复]
【中文标题】如何根据GPA对数组列表进行升序排序? arraylist 包含一个对象数组。 (Java)[重复]【英文标题】:How ro sort the array list in ascending order based on GPA? The arraylist is holding an array of objects. (Java) [duplicate] 【发布时间】:2019-08-20 23:17:01 【问题描述】:我正在尝试根据 GPA 升序对这个数组列表进行排序。 Student 类封装了 3 条信息:学号、姓氏、平均绩点。
所以我需要使用gradePointAverage 对它们进行排序。
//student array
studentArray[0] = student;
studentArray[1] = new Student(9093891, "Brown", 2.55);
studentArray[2] = new Student(9301879, "Carson", 1.11);
studentArray[3] = new Student(3910880, "Deardon", 4.01);
studentArray[4] = new Student(8891783, "Ellis", 2.66);
studentArray[5] = new Student(3899132, "Fisher", 0.55);
//filling my studentlist
studentList.add(student);
studentList.add(studentArray[0]);
studentList.add(studentArray[1]);
studentList.add(studentArray[2]);
studentList.add(studentArray[3]);
studentList.add(studentArray[4]);
ArrayList<String> sortedArrayListDescending = studentList.sortDescending();
【问题讨论】:
我知道它说 studentList.sortDescending() 但即使这样也不起作用。那是在胡闹。我收到“错误:找不到符号” "我得到一个"错误:找不到符号"" 那是因为 List 中没有sortDescending
和 sortAscending
方法,有 sort
方法它采用Comparator
,它表示用于检查两个比较对象之间的机制是否相等,大于或小于第二个。
【参考方案1】:
使用Collections.sort()
升序
Collections.sort(studentList,Comparator.comparingDouble(Student::getGradePointsAverage));
降序
Collections.sort(list,Comparator.comparingDouble(Student::getGradePointsAverage).reversed());
【讨论】:
以上是关于教你如何使用GPA导出模型,另送一个 GPA CSV2MESH Tool in unity的主要内容,如果未能解决你的问题,请参考以下文章
如何从 python 中的用户 2 值读取并找到最高 GPA?