Author Topic: How is blockland optimized?  (Read 3142 times)

How is blockland able to handle 60,000+ bricks in a scene, and do shaders on them, and still get 60FPS. How are FxDTS bricks optimized? I know that they can't move, which helps, but how does that help? Is there anything else special about them? Is there something special about the old Torque that helps with this? What's an Oct Tree? How does that help?

Finally, why are StaticShapes so inefficient for bricks compared to FxDTS bricks?

Edit: Thanks for answering all my questions.
« Last Edit: October 24, 2015, 09:12:27 PM by superdupercoolguy »

Bricks as a whole don't actually make fps drops, it's the geometry in it.

when bricks are together, the faces that touch get removed to save geometry.

Things like prop bricks on the other hand can cause extreme fps drops because of all the geometry inside them.

You can also test this (I did) by recreating a 64x64 cube out of 1x1s and it won't lag you because all of the bricks on the inside do not even render
« Last Edit: October 24, 2015, 01:39:53 PM by Trogtor »

What's an Oct Tree?



basically bricks not in view are hidden, like trogtor said
so you don't have to constantly render 60000 bricks when all the bricks you're looking at is 2000
...or something like that

visual demonstration

if bricks are like this

the only parts that are actually rendering are like this

or something like that

you can see the oct tree in effect if you take a modter ramp and stick a brick in it. at certain positions, you'll notice some faces of the brick will derender. This is the oct tree attempting to work, but since modter is not exactly orthogonal bricks stuck in it suffer glitches.

You can also test this (I did) by recreating a 64x64 cube out of 1x1s and it won't lag you because all of the bricks on the inside do not even render
note that it isn't the same as rendering the faces of a 64x cube because you still have to render each 1x1's outward faces

also some large bricks (eg 64x cubes) don't hide faces because it isn't worth computing the coverage at that point, or something along those lines

Okay, thanks. But again, how does the bricks being unable to move make them more effecient? Or does it? Does it have to do with the Octree? Why are static shapes so inefficient for lego bricks compared to FxDTS bricks?

Okay, thanks. But again, how does the bricks being unable to move make them more effecient? Or does it? Does it have to do with the Octree?
exactly that reason. if bricks could move, the octotree optimization would be defunct as you can't predict when the face should/shouldn't be shown. or at least, it would probably not be worth the effort to calculate it as otto-san suggested for big bricks.

Why are static shapes so inefficient for lego bricks compared to FxDTS bricks?
i think it has to do with the fact that they CAN move and so require constant updates of their position to the client (which is why sometimes staticshapes disappear from your screen if you look at them at a funny angle), as well as their incompatibility with the oct tree.

Say one where to make grids that where movable, but every single brick in that grid had to move all at once--individual bricks would still be locked to that grid. Couldn't each grid have its own internal octtree, and only slight performance losses would happen?

Why are static shapes so inefficient for lego bricks compared to FxDTS bricks?
Quote from: otto-san
The fact that use of many of these objects is necessary for the purpose they are serving is also a flaw in this application. StaticShapes are simply not fit for use in large quantities. A fair amount likely are aware that, in Blockland v0002, StaticShapes were used for bricks. The performance implications of this were very evident. Retail Blockland’s most notable change from v0002 was the addition of the fxDTSBrick class for building. fxDTSBrick can support a maximum of 256,000 bricks at once (note: that is only due to a networking limitation). The reason for this is that fxDTSBrick has specific optimisations for usage in large quantities in any kind of structure, large or small. They exist to improve upon everything that StaticShapes lacked for building purposes. I did a brief test in v0002 and in v20 to compare the performance impact of StaticShapes when compared to fxDTSBricks. The test consisted of an 8x4x4 construction of 2x4x1 bricks in the classic bedroom map (note: I removed the miscellaneous objects lying about in the v0002 test). The base FPS in the v0002 test was 240. After construction, performance dropped significantly, hovering at around 145-175. This is around a 33% performance decrease with only 96 additional simple shapes. The v20 test had an FPS baseline of 950-1000. After construction, no change in FPS range was seen. (These tests were done using an Intel Core 2 Duo CPU E8400 @ 3GHz and NVIDIA GeForce GTS 450 w/ ~4GB total memory. The v0002 test was run at a resolution of 640x480 and the v20 test was run at 800x600. Please note that the v0002 was rendered at a smaller resolution and still suffered a more significant performance impact.)


http://forum.blockland.us/index.php?topic=268844.0

Ok so let me put things stright.
Blockland isn't a voxel rendering engine however it could be categorized as a voxel game, due to the limitations of bricks to the grid.
An octree is the 3d version of a binary tree.
A binary tree is a tree where each node has 2 children.
Example:


An octree is the same thing, except each node has 8 children and each corresponds to each of the 8 octants of the cube

Here's how a typical octree would look like:

The leftmost cube represents the root node. The rightmost tree has one of the leaf nodes marked in red. << ignore that i replaced the image so it doesnt apply anymore
In blockland, the most likely scenario is that all bricks are stored in the octree.
The octree is used to optimize the removal of invisible faces. In principal, the octree would be used to efficiently find the adjacent node in the tree and check whether it contains a brick. If it does it removes the face of the brick there.
The problem is when bricks can contain other bricks. The algorithm doesn't take into account that case, and that is why you can see through bricks sometimes when they are partially inside modter bricks.
If you had a cube of size 8 made entirely of 8x8x8 bricks, using the naïve method you would would have to render each face of the cube, which would result in (number of faces per brick)*(number of bricks) = 6 * 8^3 = 3072 faces.
Using the octree, you would only have to render the outer faces, because the inner faces would be removed using the algorithm (in the optimal case), which would result in drawing only (number of large faces)*(number of faces per large face) = 6 * 8^2 = 384 faces.
What i speculate that goes inside blockland is, The algorithm runs over the octree of bricks and removes all hidden faces. After that, it adds in all the faces of all the non-brick objects suck as vehicles, players, projectiles, emitters, and all the like.
After that, it sends all of the data about polygons into the GPU which handles all the rendering, shading, and such.
The reason why I don't consider blockland as a true voxel rendering engine, is because a true voxel rendering engine usually is a raytracing engine, which means that instead of sending data to the GPU it casts rays into the scene and calculates collisions of the ray with the octree.






wow that was quite a reply


EDIT: the thing with static shapes is that they don't use the octree because they are not fixed to the grid, and that's why they are slower
« Last Edit: October 24, 2015, 04:03:38 PM by Klarck »

Say one where to make grids that where movable
not that easy. but if you could, theoretically yes.
the issue with that though is then ALL the bricks must move as well in order to keep with the grid. and no, you can't just "make two grids one static one moving" because what happens if they are on a collision course with each other? the behind-the-scenes processing would probably go up exponentially.

then again i'm just a code plebian so most of what i say is speculation based on my moderate understanding of how code/bl works. although this would be great there's some fundamental issues like the question i brought up that would make it difficult if not impossible to do, at least with torque.

not that easy. but if you could, theoretically yes.
the issue with that though is then ALL the bricks must move as well in order to keep with the grid. and no, you can't just "make two grids one static one moving" because what happens if they are on a collision course with each other? the behind-the-scenes processing would probably go up exponentially.

then again i'm just a code plebian so most of what i say is speculation based on my moderate understanding of how code/bl works. although this would be great there's some fundamental issues like the question i brought up that would make it difficult if not impossible to do, at least with torque.
Yes all blocks would be moving, but you could still have an octree for that grid, so long as they all move at once.
What happens if they are on a collision course? Wouldn't they just collide, and bounce off(or destroy eachother if you programmed that)? There's no need to do face removal for separate grids, I think the moments where grids would be next to eachother would be short-lived.

The whole point of the octree is that it uses the fact that bricks must be fixed to a grid. because of that faces can be completely hidden, and so removed. if bricks weren't fixed to a grid, reguardless of the octree, faces would most likely not overlap so no optimization can be done. this is also why i like raytracing. in raytracing because the thing you need to be able to do the fastest is calculate a collision of a ray with the scene, overlapping faces dont change a thing. you could have arbitrarily positioned and rotated bricks and use a tree such as a KD/BIH/BVH/BSP/any other tree like those to optimize the ray-scene collision detection. Note that raytracing allows for much more realistic effects much more easily, for example, if you wanted to create a mirror in a polygon based engine, you would have to render the scene twice, once in the position that is seen through the mirror, and once in the normal position, not rendering where the mirror is. that obviously makes everything twice as slow. in ray tracing, you would have to find whether the ray hits a mirror. if it does, reflect it relative to the surface normal. the amazing thing about this is, its possible to do that for a surface of any shape.
same goes for shadows and many other effects.

also, collision detection is a completely different problem.
« Last Edit: October 24, 2015, 04:20:55 PM by Klarck »

Yes all blocks would be moving, but you could still have an octree for that grid, so long as they all move at once.
What happens if they are on a collision course? Wouldn't they just collide, and bounce off(or destroy eachother if you programmed that)? There's no need to do face removal for separate grids, I think the moments where grids would be next to eachother would be short-lived.
how would you determine collision when the two grids are non-aligned? imagine the number of calculations required to check if anything is colliding anything else at any one time. you can't assume anything with code; it doesn't work like real life blocks where atoms automatically repel each other if they get too close. in a game, there is no automatic - everything is programmed in. the more complex the task, the more computing power is required to make it work.

and its kinda naiive to think that the time grids would be next to each other is short-lived. what happens if people use moving bricks within a brick hallway to simulate a piston?
« Last Edit: October 24, 2015, 04:24:41 PM by Conan »