f3d-app / f3d

Fast and minimalist 3D viewer.
https://f3d.app
BSD 3-Clause "New" or "Revised" License
2.88k stars 207 forks source link

models with a large number of bones crash f3d #1050

Closed Shinmera closed 10 months ago

Shinmera commented 1 year ago

Describe the bug Trying to load a gltf or glb model file crashes on my system with a segfault.

To Reproduce Steps to reproduce the behavior:

  1. Open the file using f3d --dry-run example.glb

Expected behavior The file shows.

System Information:

F3D Information Paste the content of f3d --version: F3D 2.2.1

F3D - A fast and minimalist 3D viewer Version: 2.2.1. Build date: 2023-10-05 15:03:05. Build system: Linux 64-bits. Compiler: GNU 13.2.1. External rendering module: ON. Raytracing module: ON. VTK version: 9.2.6.

Additional context Add any other context about the problem here. Trying with verbose crashes with the following:

ERROR: In vtkShaderProgram.cxx, line 498
vtkShaderProgram (0x5640e1c56230): Links failed: Vertex info
-----------
Internal error: assembly compile error for vertex shader at offset 1324:
-- error message --
line 33, column 9:  error: invalid parameter array size
line 44, column 43:  error: offset for relative array access outside supported range
line 51, column 43:  error: offset for relative array access outside supported range
line 53, column 43:  error: offset for relative array access outside supported range
line 54, column 43:  error: offset for relative array access outside supported range
line 60, column 43:  error: offset for relative array access outside supported range
line 61, column 43:  error: offset for relative array access outside supported range
line 62, column 43:  error: offset for relative array access outside supported range
line 63, column 43:  error: offset for relative array access outside supported range
line 64, column 43:  error: offset for relative array access outside supported range
line 65, column 43:  error: offset for relative array access outside supported range
line 66, column 43:  error: offset for relative array access outside supported range
line 67, column 43:  error: offset for relative array access outside supported range
line 71, column 21:  error: out of bounds array access
line 72, column 21:  error: out of bounds array access
line 73, column 21:  error: out of bounds array access
line 74, column 34:  error: out of bounds array access
line 75, column 21:  error: out of bounds array access
line 76, column 21:  error: out of bounds array access
line 77, column 21:  error: out of bounds array access
line 81, column 35:  error: out of bounds array access
line 82, column 25:  error: out of bounds array access
line 83, column 25:  error: out of bounds array access
line 84, column 39:  error: out of bounds array access
line 87, column 39:  error: out of bounds array access
line 88, column 25:  error: out of bounds array access
line 89, column 39:  error: out of bounds array access
line 90, column 25:  error: out of bounds array access
line 91, column 23:  error: out of bounds array access
line 92, column 39:  error: out of bounds array access
-- internal assembly text --
!!NVvp5.0
OPTION NV_internal;
OPTION NV_bindless_texture;
# cgc version 3.4.0001, build date Sep 12 2023
# command line args:
#vendor NVIDIA Corporation
#version 3.4.0.1 COP Build Date Sep 12 2023
#profile gp5vp
#program main
#semantic jointMatrices
#semantic normalMatrix
#semantic tcMatrix
#semantic MCDCMatrix
#semantic MCVCMatrix
#var float4 gl_Position : $vout.POSITION : HPOS : -1 : 1
#var float4 vertexMC : $vin.ATTR0 : ATTR0 : -1 : 1
#var float4x4 jointMatrices[0] :  : c[0], 4 : -1 : 1
#var float4 joints : $vin.ATTR1 : ATTR1 : -1 : 1
#var float4 weights : $vin.ATTR2 : ATTR2 : -1 : 1
#var float4 vertexVCVSOutput : $vout.ATTR0 : ATTR0 : -1 : 1
#var float3 tangentMC : $vin.ATTR3 : ATTR3 : -1 : 1
#var float3 tangentVCVSOutput : $vout.ATTR2.xyz : ATTR2 : -1 : 1
#var float3 normalMC : $vin.ATTR4 : ATTR4 : -1 : 1
#var float3x3 normalMatrix :  : c[1420], 3 : -1 : 1
#var float3 normalVCVSOutput : $vout.ATTR3.xyz : ATTR3 : -1 : 1
#var float2 tcoord : $vin.ATTR5 : ATTR5 : -1 : 1
#var float2 tcoordVCVSOutput : $vout.ATTR4.xy : ATTR4 : -1 : 1
#var float4x4 tcMatrix :  : c[1423], 4 : -1 : 1
#var float4 scalarColor : $vin.ATTR6 : ATTR6 : -1 : 1
#var float4 vertexColorVSOutput : $vout.ATTR1 : ATTR1 : -1 : 1
#var float4x4 MCDCMatrix :  : c[1427], 4 : -1 : 1
#var float4x4 MCVCMatrix :  : c[1431], 4 : -1 : 1
PARAM c[1435] = { program.local[0..1434] };
ATTRIB vertex_attrib[] = { vertex.attrib[0..6] };
OUTPUT result_attrib[] = { result.attrib[0..4] };
TEMP R0, R1, R2, R3, R4, R5;
TEMP T;
TRUNC.S R0.x, vertex.attrib[1].y;
MUL.S R0.x, R0, {4, 0, 0, 0};
MOV.S R5.w, R0.x;
TRUNC.S R0.x, vertex.attrib[1];
MUL.S R2.x, R0, {4, 0, 0, 0};
MOV.S R5.z, R2.x;
MUL.F32 R1, vertex.attrib[2].y, c[R5.w + 1];
MUL.F32 R0, vertex.attrib[2].y, c[R5.w];
TRUNC.S R2.y, vertex.attrib[1].z;
MUL.S R2.y, R2, {4, 0, 0, 0}.x;
TRUNC.S R2.x, vertex.attrib[1].w;
MUL.S R2.x, R2, {4, 0, 0, 0};
MOV.S R5.y, R2;
MAD.F32 R1, vertex.attrib[2].x, c[R5.z + 1], R1;
MOV.S R5.x, R2;
MAD.F32 R1, vertex.attrib[2].z, c[R5.y + 1], R1;
MAD.F32 R4, vertex.attrib[2].w, c[R5.x + 1], R1;
MAD.F32 R0, vertex.attrib[2].x, c[R5.z], R0;
MAD.F32 R1, vertex.attrib[2].z, c[R5.y], R0;
MAD.F32 R3, vertex.attrib[2].w, c[R5.x], R1;
MUL.F32 R0, R4, vertex.attrib[0].y;
MAD.F32 R2, R3, vertex.attrib[0].x, R0;
MUL.F32 R1, vertex.attrib[2].y, c[R5.w + 2];
MAD.F32 R1, vertex.attrib[2].x, c[R5.z + 2], R1;
MAD.F32 R1, vertex.attrib[2].z, c[R5.y + 2], R1;
MAD.F32 R1, vertex.attrib[2].w, c[R5.x + 2], R1;
MUL.F32 R0, vertex.attrib[2].y, c[R5.w + 3];
MAD.F32 R0, vertex.attrib[2].x, c[R5.z + 3], R0;
MAD.F32 R0, vertex.attrib[2].z, c[R5.y + 3], R0;
MAD.F32 R0, vertex.attrib[2].w, c[R5.x + 3], R0;
MUL.F32 R5.xyz, vertex.attrib[4].y, R4;
MAD.F32 R2, R1, vertex.attrib[0].z, R2;
MAD.F32 R0, vertex.attrib[0].w, R0, R2;
MUL.F32 R2, R0.y, c[1428];
MAD.F32 R2, R0.x, c[1427], R2;
MAD.F32 R2, R0.z, c[1429], R2;
MAD.F32 result.position, R0.w, c[1430], R2;
MUL.F32 R2, R0.y, c[1432];
MAD.F32 R2, R0.x, c[1431], R2;
MAD.F32 R2, R0.z, c[1433], R2;
MAD.F32 R5.xyz, vertex.attrib[4].x, R3, R5;
MUL.F32 R4.xyz, R4, vertex.attrib[3].y;
MAD.F32 R0.xyz, vertex.attrib[4].z, R1, R5;
MAD.F32 result.attrib[0], R0.w, c[1434], R2;
MUL.F32 R2.xyz, R0.y, c[1421];
MAD.F32 R2.xyz, R0.x, c[1420], R2;
MAD.F32 result.attrib[3].xyz, R0.z, c[1422], R2;
MAD.F32 R3.xyz, R3, vertex.attrib[3].x, R4;
MAD.F32 R2.xyz, R1, vertex.attrib[3].z, R3;
MUL.F32 R0.xyz, vertex.attrib[5].y, c[1424].xyww;
MUL.F32 R1.xyz, R2.y, c[1421];
MAD.F32 R0.xyz, vertex.attrib[5].x, c[1423].xyww, R0;
MAD.F32 R1.xyz, R2.x, c[1420], R1;
ADD.F32 R0.xyz, R0, c[1426].xyww;
MAD.F32 result.attrib[2].xyz, R2.z, c[1422], R1;
ADD.F32 R0.xyz, R0, {0, 0, 0, 0}.x;
MOV.F result.attrib[1], vertex.attrib[6];
DIV.F32 result.attrib[4].xy, R0, R0.z;
END
# 58 instructions, 6 R-regs

I unfortunately can't provide the model file, as it is part of a private project.

FWIW other OpenGL programs run fine and I haven't noticed any other issues.

Shinmera commented 1 year ago

On further examination, this may be from trying to allocate a uniform that's too large. Possibly for the pose matrix uniform? This model has quite a lot of joints.

Meakk commented 1 year ago

Indeed, there is a 4x4 matrix per joint in the uniform variables.
What's the number of joints in your model?

Shinmera commented 1 year ago

366. You might want to consider switching to a texture based approach instead to remove the uniform limit.

Meakk commented 1 year ago

Yes that could be a solution

Shinmera commented 1 year ago

Fwiw I've implemented a simple texture1DArray RGBA texture that stores the palette as 3xN colors in my engine and that approach works perfectly fine.

mwestphal commented 1 year ago

Should we close this one @Meakk ? or label as wont fix ?

Shinmera commented 1 year ago

In the very least don't just segfault on a model that has too many bones, come on.

mwestphal commented 1 year ago

It is a VTK issue, not a F3D one. We can keep it open but the fix, if it possible, should be done in VTK.

mwestphal commented 1 year ago

But I may be wrong, waiting on @Meakk input

Meakk commented 1 year ago

I don't see myself start working on it without a dataset to reproduce anyway.
Switching to a texture should be doable, but it has to be done in VTK indeed.

mwestphal commented 1 year ago

@Shinmera do you have a dataset you can share?

mwestphal commented 1 year ago

In the very least don't just segfault on a model that has too many bones, come on.

Please share a dataset so that we can reproduce the issue and fix the segfault as least.

Shinmera commented 1 year ago

I'm sorry, I'm not a rigger myself, and the dataset I used is proprietary so I can't share it publicly.

mwestphal commented 1 year ago

Ok, I will try to look around the web for a dataset to reproduce.

mwestphal commented 11 months ago

I'm afraid I'm unable to find a dataset to reproduce the issue so far. Please find a dataset that you can share so that we can reproduce and fix the issue.

snoyer commented 11 months ago

I generated some simple tubes with bones using three.js's SkinnedMesh and GLTF exporter. I get the first segfault at 253 bones so here's that and the last working one at 252 bones

glb_tubes.zip

Meakk commented 10 months ago

I fixed it in #1117
I decided to go with SSBO instead of textures. It requires OpenGL 4.3 but I think that's ok nowadays.
If there are less than 250 bones, we continue using uniforms as it seems to be faster.

Meakk commented 10 months ago

It's now merged in master. We'll release 2.3 soon, but the fix will be available in nightly tomorrow.
It would be appreciated if you can confirm the fix is working fine on your datasets @Shinmera

Shinmera commented 10 months ago

Will do! Thanks for the work!

mwestphal commented 10 months ago

last nightly available here: https://github.com/f3d-app/f3d/releases/tag/nightly

Shinmera commented 10 months ago

Can confirm it working! Thanks again!