您当前的位置: 首页 >  unity

Jave.Lin

暂无认证

  • 7浏览

    0关注

    704博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

教你如何使用GPA导出模型,另送一个 GPA CSV2MESH Tool in unity

Jave.Lin 发布时间:2022-09-28 10:24:32 ,浏览量:7

文章目录
  • 吐槽
  • GPA Geometry Output 没有 UV
  • 问题实例
  • 开始实现
    • 提取 VBV, IBV
      • GPA buffer list view format 攻略
  • 工具演示导出
  • GPA 的 VBV,IBV的 BUG
    • must be a multiple of 3 的解决办法
    • indices out of bounds vertices - 暂无解决方法
      • indices out of bounds vertices - 尝试解决的方法
  • Project
  • References

以前写过一篇:Unity - RenderDoc 抓帧导出 FBX(带UV)

吐槽

我估计GPA是怕收律师函,因为如果 GPA 将所有资源一键提取,一键导出,那么可能很多开发商会告他

GPA Geometry Output 没有 UV

可以看到也好几个帖子问 GPA 官方,都是被官方忽悠回答了:

  • UV MAPS capture
  • GPA: No UV map support?

(除了这个,我自己还搜索过还几个类似有人问这个问题,结果同样被官方忽悠)

  • 我之前尝试过用 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;

    • half 精度的 tangent : half TANGENT.x;half TANGENT.y;half TANGENT.z;half TANGENT.w; - 有些精度低一些,为了性能考虑的是有的,抓帧逆向效果都可以看到很多地方有类似的做法
  • normal : VBV3 - float NORMAL.x;float NORMAL.y;float NORMAL.z;

    • half 精度的 tangent : half NORMAL.x;half NORMAL.y;half 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 - 这个会使用比较多,但是这个有些问题:没有 normalized
    • nubyte TEXCOORD5.x;nubyte TEXCOORD5.y;nubyte TEXCOORD5.z;nubyte TEXCOORD5.w; byte4p - 然后添加了前缀 n 后,还是不能 normalized,所以这个我在工具中特殊弄了一些开关,可是设置 VBV 是否需要 normalized
  • index : IBV - 不需要格式,直接导出,只要确保第二列是 index 的值即可

另外要记得[type][n]p的padding设置,这样才能stride到对应的vertex data 长度

比如下面的法线,使用的是 half 精度的,而且有 36 个 byte 的 padding 在这里插入图片描述

那么我们使用: half NORMAL.x;half NORMAL.y;half NORMAL.z;half NORMAL.w;byte36p; list view 格式即可

在这里插入图片描述

GPA buffer list view format 攻略

上面我是提取: 《CFDG》 的方式,可以罗列出下面的 buffer view format,基本上 CFDG 的 MRA 流 PBR 都是这套规则即可

// jave.lin : 下面提供 list view format 的样例,可以用于CTRL+C,V到 GPA list view 中
// 注意 : padding 不要处理
// 注意 : semantic 要设置对 (依赖 shader 分析 对应的作用后,才能正确设置 semantic)

// position-float3
float POSITION.x;float POSITION.y;float POSITION.z;

// tangent-float4
float TANGENT.x;float TANGENT.y;float TANGENT.z;float TANGENT.w;
// tangent-half4
half TANGENT.x;half TANGENT.y;half TANGENT.z;half TANGENT.w;

// normal-float4
float NORMAL.x;float NORMAL.y;float NORMAL.z;float NORMAL.w;
// normal-half4
half NORMAL.x;half NORMAL.y;half NORMAL.z;half NORMAL.w;

// normal-float3
float NORMAL.x;float NORMAL.y;float NORMAL.z;
// normal-half3
half NORMAL.x;half NORMAL.y;half NORMAL.z;

// uv0-float2
float TEXCOORD0.x;float TEXCOORD0.y;
// uv0-half2
half TEXCOORD0.x;half TEXCOORD0.y;

// uv1-float2
float TEXCOORD1.x;float TEXCOORD1.y;
// uv1-half2
half TEXCOORD1.x;half TEXCOORD1.y;

// color0-ubyte4
ubyte COLOR0.x;ubyte COLOR0.y;ubyte COLOR0.z;ubyte COLOR0.w;

工具演示导出

请添加图片描述

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 - 暂无解决方法

比如:Failed setting triangles. Some indices are referencing out of bounds vertices. IndexCount: 2049, VertexCount: 281

这个问题是 GPA 的 BUG 暂时无解,连 index 的数值都错了,我们是不可能知道正确的数值的,只能猜:比如,可能是 数据类型溢出? 就是新版本的 fbx 模型,可能使用了 index buffer 的索引值的压缩技术,可能在 GPA 中没有对应实现解析,那么肯定会有报错的

这个 index 索引值的压缩技术大概是这么个思路:

  • 如果 index < byte.MaxValue,那么 index 使用 byte 类型解析
  • 如果 index < ushort.MaxValue,那么 使用 ushort 类型解析
  • 如果 index < uint.MaxValue,那么 使用 uint 类型解析
indices out of bounds vertices - 尝试解决的方法

可以尝试将后续开始 indices 是很大的数值统统删除,保留前面的数据,95% 是OK的,就可以导出来了

Project
  • github 工程后续上传
  • GPA_CSV2MESH_TOOL_opt_sss_吕蒙_白起_马云禄_再次优化_projectsetting_shadowsize_法线RG解析
References
  • GPA-Mesh - hub友 C++写的一个,没用过,也不知道怎么用
  • INTEL GPA mesh ripper tutorial + tool (x32,x64,DX9,10,11) - 2014 年的时候国外友人写了 GPA Hook 来抓自己想要的资源
关注
打赏
1664331872
查看更多评论
立即登录/注册

微信扫码登录

0.0754s