tisdag 18 januari 2011

Or not... :3

If there is anything in life i should know by now, is that just because something looks good, don't mean it has to be.

This is something i always forget, I get all excited about something, just to find out it don't work... and have my dreams shattered :(

The instancing incident looks to be exactly the same, it looks very good in theory, but not so much in application(at leasts not my application).

I'm sure some one could use instancing for the type of engine I'm working on, but i don't think it will be with SunBurn.

So what is the problem?

The problem lays in the structure of witch sunburn handles instancing(maybe this is the normal way, i have only tried instancing with SunBurn), SunBurn works with containers, each container may hold up to 75 objects, all these objects are basically one and the same but located at different locations and they all share the same effects.

in my solution, i had 2 ideas.

1. I have a per-chunk based solution, where every chunk kept track of the blocks in it.
This makes the most sense and is a clean and simple solution, here is an example:

our chunk is made from 256 block, 250 of them are stone and 6 are sand, this means we need 3 containers to store 225 stone, and one to store the rest 25 stone, we also need one container to store the 6 sand.
and you can see, this is ALLOT of wasted container space, and it would happen in evry chunk.

so, the optimal alternative would be.

2. We have one gigantic global multi-array of containers, and every block in the world is added to this array whenever needed, the waste would be as small as it could possible be, BUT it also means:

1# Forget chunk-based Occlusion!, it would be impossible to know witch chunk a block is located in, blocks are basically in a random mess somewhere in that array, and in no way correspond to a chunk, any chunk.

2# for the same reason, it would be very messy to make changes in the terrain, remove a certain block for example, however adding is simple.


There is one more thing that worries me, running the SunBurn instancing example, with 30.000 block gives me <40fps, this can be compared with the original minecraft witch renders 60-70.000+ at 60+ fps, and we don't even have half the objects... no good :3

so what does this mean?
well it means that even tho i love the idea of instancing, i don't think it will work with SunBurn for my needs.

Edit: It should be noted that i don't have anything against Instancing in SunBurn, and i might use it for other things... bonuses, drops on the ground, monsters, and so on... but not blocks in terrain.

måndag 10 januari 2011

I hate it when my friends are right :P

Oky good fokes, it is time for a change in minertopia land :)

My friend have been blabbering about this for ages(even tho i doubt he ever used it him self), so I'm sure he will gloat about the fact that i am now changing my mind and going with "his ways".

And i guess it Don't really help that i am normaly the "wise guy" who win all the discussion i have with him... that is, until this time... (oh there was that other time when i screwd up the XOR gates in Minecraft... but don't tell him i admitted defeat *makes hysshing sound*)

So... anyway... for a very long time, i have been stuck with manually generating my vertice data in xna, vertice for vertice.
This is how i learned things when i started using xna, and even if it tend to get a bit messy at times(indices for example) i still like having that level of control.

but for the minertopia project, I am now considering alternative and drastic changes.

I might be an old dog when it comes to learning new tricks, but I'm not totally immune to common sense(for the most part).

So what is changing? well, i have decided that a technique called Instancing is the way to go in rendering my blocks in minertopia.

For those of you who don't know what it means, it basically means that you tell your graphics card to render the same model in more than once place to make it look like more than one model.
this is very usefull if we for example need to render 100 monsters/bonuses/weapons that all look the same, or in our more relevant case: 70.000 blocks making up the world.

The cool thing about instancing is that you can render 10-20 times the amount of objects for the same performance it would take to render them as separate objects without instancing.

even more cooler is that the newly bought SunBurn Pro engine i got a little while back, support it as well :)

For those who care, here are my arguments for swapping.

  • Less programming needed, i can even create my cubes in 3d modeling software, and import them with Textures, normal maps(and more) without writing a single line of code to generate them(like i do now)
  • I'm no expert on Instancing yet(i have yet to read the small print on the subject), so correct me if I'm mistaking, but it should drastically decrease the amount of memory on GPU needed to store my world, currently it takes about 700mb for my whole world(yikes! yeas... but vertices's in SunBurn takes more space than normal ones in XNA), but with instancing, at least in theory(in my head anyway) it would probably not take much more memory than the coordinates take for each block, since the block data is the same rendered at different locations.
  • Lets face it, it makes perfect sense, if Instancing was created to render objects that looks the same multiple times, then what better scenario is there than a world made from blocks where most of them look the same... just like minecraft, seriously...(PS: Minecraft don't use Instancing)


One thing i liked about custom generated geometry, and was my main selling point for using it(that and stubbornness), was the fact that i want each block of the same type(stone for example) to look different from the stone block next to it, this to avoid the very visible repeat pattern you see in normal minecraft.

This was simple to implement if you generate each surface in real time, you simply randomly pick a texture in a texture atlas(i think minecraft works like this).

now, if we used whole cubes like I'm planning to use with instancing, we cant do this anymore, but instead what i will do is having 6 different textures on each side of the same cube, and randomly rotate it when placing it in the world.
This would give a similar effect for most of the scenarios, but it is not as good as the first approach.

There are ways to work around this, we could still render each surface separately using instancing, but i thought i would keep things simple for now.

This new direction should improve general performance, and make things allot easier for me, less programming and more playing around in 3d editors ;-)

The only downside i can think of is that it would make the game strictly 3.0 shader, but since i use normal maps and parallax maps(planning to anyway) i guess i already had that limit.


Edit:
As it turns out, from some early tests, the amount of memory is minimal when using instancing compared to custom geometry.
The world took around 700mb+ ram before.
Compared to now, wheres 70.000 block take only 23mb of ram!, not bad at all :-)


It might also be worth mentioning , that minecraft takes around 500mb of ram(last time i checked).