Studio mesh exporter is very inaccurate

Issue Type: Other
Impact: High
Frequency: Constantly
Date First Experienced: 2021-04-18 00:04:00 (-04:00)
Date Last Experienced:

Reproduction Steps:
Insert a primitive cube in studio and export it as a .obj mesh using the mesh exporter (Right click → Export Selection). Now import it into any 3D modelling program. The cube, which should have 18 edges and 8 vertices, will somehow have 30 edges and 24 vertices.

This issue is compounded immensely when exporting UnionOperations. Many times when exporting a UnionOperation, it will also be exported with duplicate faces that do not even line up. Attached below is a .rbxl containing a UnionOperation that suffers from this issue.

BugReproMeshExporter.rbxl (24.6 KB)

Expected Behavior:
I expect the mesh to be exported exactly how it appears in studio.

Actual Behavior:
The mesh exporter incorrectly includes duplicate vertices and edges into the mesh.

Workaround:
Other than creating the mesh entirely in dedicated 3D modelling software, no.

11 Likes

“somehow” → It’s exporting each face individually rather than the mesh holistically: 6 faces x 4 vertices per face = 24 vertices.

You can actually work around this by de-duping the shared vertices in the file. Here’s a tool that sounds like it would work for that: GitHub - jonnenauha/obj-simplify: Object File (.obj) simplifier

But yes, this should be fixed, filed a ticket.

7 Likes

This is especially strange because under certain circumstances, vertices that should theoretically be “shared” (though overlapping) won’t even line up with each other, causing strange gaps between faces.

SM_ArchWallArchLarge.obj (32.7 KB)

2 Likes

Yikes. No idea what’s causing that, that definitely shouldn’t be happening.

3 Likes

Could the fact that I had textures applied to the UnionOperation prior to export have something to do with it? I was abusing a trick I discovered where exporting with textures applied would alter the UV map of the mesh to tile according to the scale of the textures.

3 Likes

Sorry for this bump, but i discovered something about this bug


Appearently, the exporter creates a separated mesh (placed some milimeters over the original mesh) for decals/tile textures that were inserted in the studio and then exports the original mesh without any decal with:

Here is an example of a model that i made in roblox, then exported it as a OBJ file, and as you can see here, the decal is not merged to the mesh


In this image, i separated all the meshes by loose parts, and one of them is effectively a separated mesh for a decal

When in the studio, this doesn’t happens, in fact, it looks perfect


This happens to every model with decal that i export.

Here are some more examples:


EDIT: @tnavarts Any response about this? Is this intentional?

6 Likes

I’m having this same issue today. The workaround is luckily very simple for me for this specific use case, but there have been times where I’ve exported a mesh from the catalog and imported it into Blender, then tried to edit the mesh but had buggy behavior with it and I only just noticed the cause.

As mentioned, it appears that each face has its own vertices associated with them, even when shared by other neighboring triangles. This means it looks totally fine to the eye, but when trying to actually manipulate the mesh it causes issues.

For example, I had a part I wanted to insert from Roblox with a specific size, bevel it, and export it back into Roblox. I immediately tried to bevel all edges, but it seemed like it did absolutely nothing. I expected it to be like the Blender default cube, but it’s not. The cuboid imported from Roblox has 3x the amount of vertices, 2.5x the edges, and double the faces.

Default cube
image

Imported cuboid from Roblox

The best workaround for this specific issue is to resize a cube in Blender and bevel it myself. Merging by distance (sharp/smooth) kind of works, albeit its shading is funky and I’m quite a newbie at this so I don’t know if it’s an easy fix.

2 Likes

Quick update for anyone who’s still running into this issue:

Fundamentally our exporter does it’s best to export exactly the rendered geometry in the scene. It’s not always the great at this - there’s some cases where the exact geometry isn’t actually what you want in an exported file, and some cases where it just flat out fails.
But knowing that we use the rendered geometry should help provide some context as to why these problems occur, and why we made the choices we did.

There’s really 3 issues here:

  • Duplicate Vertices: This is caused by the import process. All meshes are triangulated on import, and each faces gets their own unique vertices.
    As an example for a cube (or any rectangular prism) with 8 vertices and 6 faces as it gets imported each face (consisting of 4 vertices) gets split into 2 triangles each consisting of 3 new vertices. So 6 faces * 4 vertices each = 24 vertices, connecting all those new triangles results in 6 faces * 5 edges = 30 edges.
    Because this is how meshes are stored and rendered internally when we export them this is the format they are in. A tool like the one tnavarts mentioned can help provide a better result, but currently importing a mesh into Roblox is a non idempotent operation so it will rarely be the same exported as it is when it’s imported.

  • Floating Faces: This is actually (believe it or not) a feature. In Roblox we know in what order Decals and textures should render, they should always be on top of the mesh of course! But .obj doesn’t provide a way to export this information. Roblox Decals (and Texture instances, which are handled the same way) are cube mapped and need different UV’s, so we need one set of texture/geometry data for the mesh, and one set for the Decal. In the engine the geometry overlaps and we handle this fine! But if we we’re to export it like that there would be Z-Fighting artifacts. To get around this when we export Decals we offset them along their faces normal by a very small amount. This means that they don’t Z fight in the exported program, but that the geometry is not quite right.
    In most cases this is the solution works, as if you’re doing a render or something of that nature it looks close to perfect, but if you’re relying on the exact geometry than you’ll run into issues.
    In Roblox:


    In blender with the offset:

    In blender without the offset:

  • Incorrect CSG Triangles: This is a bug. UnionOperations geometry should be clean, although it will suffer from exactly the same issues outlined above with the floating faces. That said since this issue was reported I think the CSG engine has been rewritten at least once, maybe twice? So I would double check and make sure that the issue is still happening, and if so report it as a separate issue with repo steps, or reach out to me directly!

TL;DR: .Obj export is a little funky, and unfortunately will have to remain that way until we adopt a new export format, and/or make changes to how we handle mesh data in the engine

3 Likes

I appreciate the explanation!

I’m no expert on 3d mesh formats, would being able to export from Roblox as FBX solve most of these issues?

Someone mentioned that requires major engineering work, so that might not be viable. You could look for a feature request or submit one if there isn’t one already.

Not really looking to write a feature request. I was just asking for information. :slightly_smiling_face:

Do you have a link to this post?

A new export format wouldn’t solve all of the issues, but it would certainly help, even if we wanted to have a more clever solution right now OBJ doesn’t have a way to handle more complex cases. Something like glTF, FBX, or USD which lets us separate and designate better would give us more options.

I think the best long term solution would be exposing export options where you can choose how things like decals are handled similar to how we handle importing.
Unfortunately right now all I can promise is that we are thinking about some of these issues, and hopefully will have more announcements about this in the future!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.