[Client Beta] In-experience Mesh & Image APIs now available in published experiences

Every MeshPart has collision geometry, whether they’re backed by a MeshId or backed by an EditableMesh. If you’re using a different method for collision, you can’t completely get rid of the collision geometry, but you can minimize the overhead.

Specifically, when converting from an EditableMesh to a MeshPart, you can use:
AssetService:CreateMeshPart( emesh, { CollisionFidelity=Enum.CollisionFidelity.Box }), which is cheap in memory use and CPU time.

3 Likes

And I am pretty sure this limit didn’t exist at one point because I saw this on X,
like it was so good why did they have to add the limit :frowning:

1 Like

Please please please prioritize removing this awful eMesh limit :frowning:

Still waiting for the asset permission system to become better :mask: ive had so many usecases for editableimages and editablemeshes, which were snuffed out by the fact that theres wonky and annoying limitations when switching between user-made and group-made assets. please laxen these restrictions!

3 Likes

We are actively working on making the workflow better especially for permission controls on user owned or group owned assets. Please stay tuned.

6 Likes

Hello! CreateEditableMeshAsync(Content.fromObject(editableMesh)) is available now, which is useful for both clone and memory management. For memory management case, this allows you to create a blank editable mesh with AssetService:CreateEditableMesh() , modify it, and then clone a FixedSize version of it using CreateEditableMeshAsync(Content.fromObject(editableMesh)) . You can then destroy the original unbounded mesh.

EM FixedSize/budget related qoute
7 Likes

Thank you for the feedback! We are actively optimizing performance and will gradually increase the limits based on our analysis. Our long-term goal is to get rid of fixed limits and dynamically adjust resource usage per device. We truly appreciate your understanding as we navigate the memory-intensive nature of this feature, and hope the CreateEditableMeshAsync update above serves as a useful interim solution!

1 Like

I’m very confused. Using CreateEditableMeshAsync still goes towards the memory budget. Just because it’s fixed, it doesnt change anything for me as I can only generate 8 editable meshes at a time, even with this “fix”.

Could I get some clarification if this is the case, or if I’m using the API wrong? Currently my code looks like this:

emesh:RemoveUnused()
local sealed = AssetService:CreateEditableMeshAsync(Content.fromObject(emesh))
emesh:Destroy()
return sealed

The behavior I would expect from reading your post would be that the editable mesh, in this case “emesh” once, destroyed, would be removed from the memory budget of eight, and the sealed mesh would not count towards it, essentially allowing me to generate more than 8 editable meshes, if I’m sealing them as I go. However, after generating merely 3 editable meshes using this method, it throws the memory budget error.

This is for a terrain LOD system, so once the chunks are generated, they don’t need to be edited again. I really need to figure this out for my project.

Thanks for your time!

EDIT: Apparently there is some kind of hidden triangle limit as well? I fixed my issue by lowering the amount of triangles per editable mesh.

  • Jab2Roblox

Hi! Would it at all be possible to raise the max size limits of EditableImages in studio-only? I’ve spent the past 3 days writing a script that takes high quality in-game images of our models, however given that they’re restricted to 1024x1024, its hard to make some of them look good without losing detail or zooming in too much.

I tried this new ‘sealed’ editable meshes. It works great for reducing memory, but it appears the sealed version has issues calculating collisions. This first video shows where my player falls through a sealed mesh:

While, same code just not sealing the original editable mesh:

I am confused by the explanation about EditableImage and restrictions on free-form drawing. In a previous update it was said that Editables would be moderated and then replicated if it passed. Is it possible to have a game that uses EditableImage to allow users to draw on a surface in a game, which gets moderated and then replicated?

2 Likes

Does anybody know why when I draw a circle onto an editable image with a predetermined compressed size, the circle appears compressed as well? Is there a way to avoid this?

Hello! Unbounded and FixedSize emesh share the same memory budget, so, it is not like creating 8 unbounded emesh are guaranteed - we currently don’t regulated emesh by numbers. It could be the emesh you created was already big, and the memory est of its Fixed Version is still cost a lot for the budget.

FixedSize would make a big difference in the case If your object uses significantly fewer vertices than an unbounded emesh expects and converting it to FixedSize would assign it a decent memory cost instead of using the maxCost. Feel free to DM me the placefile and I can double check. Thanks!

1 Like

Interesting! Do you have a placefile to reproduce this that we can take a look?

Are there any plans for us to be able to ‘seal’ an emesh 100% so that it can’t be edited anymore and behaves like a regular MeshPart that doesn’t count towards the memory budget anymore?
I would really need this for my project.

1 Like

EDIT: EditableImage documentation is incomplete. I was tipped off that only 1 EditableImage can be updated per frame. I had to create a wrapper that copies buffers into appropriate locations for a single EditableImage.

Got a bug regarding EditableImages.

Each EditableImage is created separately, assigned to its own content object, and assigned to its own ImageLabel.

However, despite using asserts to check if an EditableImage is created or not, the engine does not want to cooperate with updating more than 1 EditableImage.

In the video you can see me enabling/disabling each actor’s script.

Both EditableImages are created, assigned to a Content Object, and set to their respective ImageLabels in serial, of which rendering is then done in Parallel before calling task.synchronize() to use WritePixelsBuffer for each EditableImage.

I am looking to avoid using any Parallel Luau cross-thread communication for performance reasons, so I need this to be fixed otherwise my project is dead in the water.

2 Likes

Hello, thanks for the feedback – it’s on our roadmap!

1 Like

Disappointing that such a promising feature has such a fixed limit; 8 editable meshes on the client is a joke- makes it borderline impossible to get anything done

One way to fix this would be to allow editable meshes to be locked- stopping edits, and fixing the memory, and in turn the triangle and vertex information

At the moment, creating editable meshes of fixed sized from existing meshes does not work- as removing the original editable mesh so that it does not count towards the editable mesh memory budget will also wipe the content

Such a promising feature- cant wait for it to be fine tuned, but right now restrictions on memory and mesh count are making this unviable for any real use

3 Likes

At the moment, creating editable meshes of fixed sized from existing meshes does not work- as removing the original editable mesh so that it does not count towards the editable mesh memory budget will also wipe the content

Hi, did you apply/replace the new FixedSize emesh to the original meshPart? Happy to look at your case where the content get wiped out. local newEmesh = CreateEditableMeshAsync(Content.fromObject(editableMesh)) basically cloned a FixedSize version of unbounded emesh, and you would then follow createMeshPartAsync()... to apply it to workspace, for example:

local emesh2 = game.AssetService:CreateEditableMeshAsync(Content.fromObject(emesh))
mp:ApplyMesh(game:GetService("AssetService"):CreateMeshPartAsync(Content.fromObject(emesh2)))
emesh:Destroy()

One way to fix this would be to allow editable meshes to be locked- stopping edits, and fixing the memory, and in turn the triangle and vertex information

Thanks for the feedback and this is on our roadmap!

1 Like

Do you remember your use case for using FindClosestVertex() to find points that were not part of a face?

1 Like