? the mesh cube needing to be downloaded would not make any difference. it is downloaded right at the start of the game, and once it is seen on the screen, both cubes are being stored in VRAM and unless there’s something special about Roblox’s primitives, they would take up the same amount of VRAM.
This is incorrect. Downloading makes a huge difference. It can literally make the difference between whether your game is playable or not. Also, whether it is downloaded at the start of the game or not is not a constant fact, it is determined on how your game works.
A mesh’s geometric data is stored in the memory, a Roblox privative’s geometric data does not need to be stored, only it’s properties do.
the mesh is downloaded to the computer to some temporary location, but the VRAM is what matters here as far as memory optimization for games. Anything being rendered on the screen needs to be stored in VRAM first, whether it’s your own cube mesh, or Roblox’s cube mesh.
Roblox privatives don’t need to be stored in the memory, they are baked in. They can be rendered from whatever is coded.
What do you by “they are baked in”? They’re literally just 3D models, with vertices and edges and faces.
3D model is a general term for a 3-dimensional object that has, as you said, vertices, edges, and faces, however, at the end of the day they are just code. In order to use 3D models consistently in multiple programs, we have file formats like .obj and .fbx that can store information about the 3D model, and 3D software and game engines have an importer to import and use those 3D models.
However, game engines, like Roblox can have primitive parts which are 3D models like any other but technically work differently. First of all, primitive shapes do not need to be stored as other 3D models do. The code to render that object can be put right into the code of the game engine, which is what I mean by “baked” in. They do not need to be stored like separate file formats that need to have more code to run it (which can slow down performance). As a result, these primitive shapes are not unique models and can be consistently programmed for better performance than 3D models imported from a 3D model file format like .obj or .fbx. The engine knows what the primitive part is and therefore, any calculations, data, or information can be stored rather than being calculated in real-time (once again, not as great for performance.
In 3D terms, baking is basically storing the information of a 3D object before real-time use. In other words, it’s an attempt to reduce the need for real-time calculations and improve performance by taking certain things and calculating them ahead of time, and storing the result. 3D models, textures, simulations, animations, lighting, shadows, etc. can all be baked. The common downside of baking is that it makes it more difficult for you to make changes later, but it can significantly improve performance.
3D model file formats, along with image textures, and generally any other external file is stored on Roblox’s server (usually attached to an asset ID), and that asset needs to be downloaded directly (which is usually bulky), and then the file needs to be read, the geometric data along with other data probably needs to be stored in the memory, and then it needs to be rendered (which for 3D models, can result in hurting the game performance because Roblox can not use baked calculations and instead has to calculate in real-time)
Roblox’s baked 3D primitive shapes, however, are not as bulky and can be rendered quickly from the engine code. Since the geometric data and other data are baked into the engine, the engine probably only needs the properties such as size, position, color, transparency, etc., and then can be stored. Storing those values in memory is usually not as hurtful to the game performance as storing 3D models. This is why many developers recommend avoiding the use of many different 3D models in a game. Not only can be hurtful to your game’s performance to use multiple 3D models within a certain distance due to the file and downloading, but the calculations can also slow down your game performance.
Now, you may be wondering, well if the 3D model file (like a .obj or .fbx) is a basic primitive shape like a cube, cylinder, etc. why would it not perform as well? Well, they are not primitive shapes to Roblox’s game engine, they are primitive shapes to us. Roblox does not know they are primitive shapes because it probably only sees it as a 3D model, not as a cube, cylinder, etc. and so, it uses the 3D model like any other. So, for example, a cube imported from another 3D modeling software is not going to perform as well as Roblox’s primitive shapes. However, one can also argue that lower tri counts would make it perform better. However, the performance differences between an imported 3D primitive shape and Roblox’s game engine’s 3D primitive shape can be so significant, that as a result, you need a significantly more optimized 3D model to improve your game’s performance. A few hundred fewer triangles probably won’t make much of a difference.
So in this case the octagon would be better for performance.
Although it does depend of which side of performance the 3D model impacts.
Doesn’t this mean that performance is only affected by the 3D model being loaded? If the model has already been loaded and it has a very low polygon count, then it shouldn’t do much to the general performance right?
The Octogon mesh made perform better than the Cylinder mesh (assuming both are imported 3D models), however, the Octogon mesh may not perform better than the Roblox cylinder shape. As I said, a mesh has to be significantly more optimized than its part made counterpart to perform better. You are probably not going to see these performance differences with primitive shapes, you may instead see it with complicated models like buildings, vehicles, robots, etc.
Well, there are 2 major things to consider.
- The downloading of the asset.
- The rendering of the asset.
In order to use a 3D model or image texture, for example, the game needs to download it from Roblox’s servers. This part can take a long time, which is why you should avoid using too many assets that need to be downloaded. There is a reason why many games outside of Roblox have huge file sizes like 10-20GB+, it’s because a lot of what is taking up storage is assets like 3D models and textures. This is why you shouldn’t be using imported 3D models and PBR textures like games outside of Roblox do, because then the download size will be large, and your game will probably be unplayable.
When you use built-in Roblox primitive shapes, they don’t take up storage like that for the reasons mentioned in my previous post. So basically, the download part itself is a big problem for performance. I am pretty sure even AAA games have to reuse assets as much as possible. Remember, while game engines like Unity and Unreal Engine may seem like you get unlimited power, this is just what you see. Game development is most of the time going to involve you making smart sacrifices to get both the look you want and the performance you want. When games don’t optimize their assets and don’t plan correctly, the game sizes may become large and the game may be unoptimized. (Which is something you can probably see happening with a lot of AAA games).
Once an asset has been downloaded though, you can reuse it multiple times and it won’t need to download it each time, it only needs to download it once. For example, if you download an image, you don’t need to download that image every time you want to use it. However, keep in mind, too many assets being downloaded can slow down your game, and sometimes, Roblox may remove an asset from memory as it is no longer needed (for example, if a player walks away from a 3D model, the game may no longer need to render it). If it is removed, you need to download it again, so try to reuse assets as much as you can.
Besides downloading, however, the rendering of the asset can also be slower than rendering a Roblox primitive shape.
The reason why is this paragraph. ^
I know what baking is in the context of 3D, and it is irrelevant here. 3D models, including Roblox’s primitives aren’t “baked”. A texture can be baked, a simulation result can be baked, lightmaps can be baked, etc, but the 3D model itself can’t be baked into some more efficient form that is easier to render - I mean, wouldn’t everyone be doing that for every model, then? lol. I agree that the primitives are almost certainly not stored in a conventional 3D format, and are like integrated into the engine code so that a box primitive with x dimensions and y location will have triangles created at certain coordinates. That’s not the point, though.
Regardless of whether Roblox’s primitives are stored in a format like OBJ or FBX, or if they are more directly integrated in the engine code, the GPU still needs to know the positions of each vertex when the object is being rendered, so that data has to be stored in the VRAM, the same as it has to be for an imported object. The rendering process is the same. Literally the main difference is that an imported object will need to be downloaded to some temporary location at the start of gameplay, but this will not impact performance once it is loaded in (and once the objects are downloaded, features like frustum-culling won’t mean the model has to be re-downloaded).
I suggest you re-read my reply since what you are talking about very little to do with what I said.
I’ve read your reply multiple times. You haven’t explained why a 12-triangle cube like the primitive in Roblox would perform better than a 12-triangle cube imported from an OBJ or FBX, once that object has been downloaded to the computer (which would probably take less than a second). Yes, of course, the downloading of many assets can take time, and if one uses only Roblox primitives, that loading phase won’t be taken into account. But once the assets are on the computer, and if both cubes are in VRAM, there should be no difference in performance. Remember: even though an OBJ or FBX file can have unnecessary data stored in it which would theoretically use up more VRAM, the entire file isn’t being stored there, but instead the pertinent data like vertex data - which are the same things Roblox has to somehow get on VRAM when rendering parts.
No, I did not say in-game render performance is dependent on the file format. I said the data transferred is dependent on how Roblox stored primitive shapes compared to how other file formats behave.
Then, I go on to explain why it still makes not perform as well.
The speed of downloading multiple assets does not exponentially increase. It will pile up if you use 3D models the way you are trying to.
They do not need to be stored in memory in the same way. As I said, Roblox’e engine does not know the unique shape of a 3D model, and so, it must store all of that model’s data to render it. Primitive shapes do not need to be stored as the shape, only their properties need to be stored, the engine can then render it from the engine code.
This may also mean that loading a mesh in and out of memory could hurt performance more than loading a Roblox primitive shape in and out of memory.
Post from a Roblox Engineer
did you read the quote you linked from the Roblox engineer?
This one. He’s literally explaining how there are big memory usage benefits to using meshparts instead of parts. He explains how parts have non-neglible memory footprints because of the many properties - not just because they’re parts, but because each part is an individual instance/object, instead of a single mesh.
If you scroll up just slightly on that thread, you’ll see the memory benefits from using Meshparts quantified.
The engineer didn’t say mesh parts always provide big memory usage benefits compared to parts, they very specifically categorized the use case as
The post also says that properties have to be stored, not their geometry, unlike meshes which need to have their geometry stored. For complex meshes, mesh parts may be better for performance, however, when comparing a mesh vs Roblox primitive part, this is not the case.
When he says this, he is not implying that parts work in such a way that their geometry data does not need to be stored. He is explaining why 16,000 parts will take up more memory than 1000 meshes with the same total geometry - he explains that this is due to the fact that each individual part will take up memory because they are each individual objects with many different properties that need to be stored. He has to make this clarification of “nothing to do with their geometry” because many users earlier in the thread make claims of the performance difference having to do with geometry being stored differently or taking up different amounts of space.
I mean… you could just set the collision to Box and even make it CanCollide false then place a few transparent parts for the bounds of the mesh.
You would get the same result from just keeping CanCollide true while having box collision.
Placing transparent parts around the mesh would be highly inefficient.
Highly inefficient in what way exactly? I’ve considered several methods for sparing memory and processing. It’s much better than having every complex mesh set to ‘PreciseConvexDecomposition’, which eats up the GPU when the player’s within range of those meshes. This is a good alternative to that since parts that are transparent aren’t rendered and don’t take up any GPU.
You have an archway mesh and the default bounds are kinda jacked up, so you opt for more precise bounds, that’s going to be a lot worse for performance than setting CollisionFidelity to Box, set CanCollide to False, then have a couple of transparent parts act as the bounds. You’re basically making a hitbox.
Well, in your case doing that would make sense, but it really depends on the complexity of the mesh and whether or not having all of those transparent parts would be heavier on performance.
With a very complex mesh, it might be better, but having a low poly mesh and still doing this would just add the small performance impact from those 3 or 4 transparent parts, while the geometry of the mesh is low enough that having precise collision would yield the same result.
I agree, i’d only do this with meshes that have jacked up default bounds as it’s unnecessary otherwise.