Help with choppy scenes

Blitz3D Forums/Blitz3D Beginners Area/Help with choppy scenes

Fey(Posted 2007) [#1]
Hello. I've never worked with 3D programming untill now and need some help with what is probably just very basic concepts.

I adapted an old 2D maze making function of mine so that it would create the maze in 3D using CreateCube()

EDIT: Image seen below in next post.

I'm pretty happy with the restuls, but when I actually run around it in first person the movement stutters depending on where in the maze I am and what direction I'm facing. The best I can tell, the stuttering happens more often when there's "more maze" in front of the camera (but behind the wall and thus not visible to the player), which seems strange to me.

Shouldn't any "maze" area that isn't actually be getting seen just get ignored? Or is it drawing the whole dungeon from far to near? Is there any obvious way to improve performance?

I'd be willing to reduce the camera draw range, or use fog, or any number of things since when the game is done the maze is going to be quite dark anyway. Also, since the maze is twisty, I doubt the player would ever be able to see very far in the distance anyway before a wall obstructed there vision.

Anyway, I'm stumped, this is a new kind of problem for me having come from 2D and text based games.

Thanks in advance :)


Fey(Posted 2007) [#2]
Picture isn't showing in the post. Oh well, the URL to see it is


I'm not sure how much it would have assisted in helping me anyway. As you can see from the image though, the maze is just that one infinite plane for a ground level, and then cubes with texture for walls.

EDIT: lol, ok, so just putting the URL down without any silly code around it seems to have loaded the image. Good times.


Matty(Posted 2007) [#3]
Hi Anony,

Blitz will cull anything which is not 'in view of the camera' automatically. However it will draw everything which is in view of the camera. Although an object may be behind another (for example an orc behind a door) it will draw the orc first followed by the door (render back-to-front). The same applies to your cubes. Also, each of those cubes will have its own surface (read up on surfaces - they are pretty important with blitz3d), and when you have a lot of surfaces things will slow down.

While it is certainly easy to simply drop cubes into position for walls it is not the most efficient way. There are other options though which include things like:

Create the level in a 3d editor (such as milkshape3d for example) but don't use cubes, instead create each wall/face polygon by polygon.

Or

Create your own routine which will generate the mesh such that the cubes' bottom sides are not created, nor are sides which are joined to another cube. IE Only create polygons that are possible to be visible to the player

Hope that helps somewaht.


Fey(Posted 2007) [#4]
Good stuff, though I'm not sure if it's within my competancy range to make good use of the advice :(

I can't pre-create the mazes because they are dramatically different each time. They are randomized and have several ajustable features. Rooms, hallway depth ranges, etc

I'll probalby have to look into the second thing you said very seriously. I definatly don't need top and bottom sides for the cubes, for example. Would I have to manualy be making my wall cubes using... whichever commands do that?

It would definatltly be slower to make a routine that compared the players position to each cube and then hid the cube if it was out of "range", right?

I should probaly just try a few things out before asking any more questions, see what I can work out for my own. Thanks for the information, I didn't know that objects that were fully obstructed by other objects were still being drawn.


jfk EO-11110(Posted 2007) [#5]
A further note:

It's the way it works, it will render faster when there are more surfaces and polygons in view.
EDIT:OOPS did I really write that?!? Of course I meant:
It's the way it works, it will render slower when there are more surfaces and polygons in view.

Dependng on the hardware, the Rate may toggle: from reaching full 60 HZ (using Flip 1) and dropping down to only 30 Hz frequently. This feels very "stuttering". You may try to use "Flip 0" and see if this was the cause.

The sooner or later you should use something like Delta correction, where the elapsed frametime is used to as a factor to be multiplied with all motion commands, so, no matter how the framerate is, the players stepwidth will always be relative to the elapsed time.

PS to speed things up you may try to use CopyEntity for the cubes, instead of CreateCube (well the very first cube must be made using CreateCube noless, of course).


Fey(Posted 2007) [#6]
So I'm trying to read up on surfaces and how to manualy work with vertexes and stuff. When I run CreateCube, is it returning a cube shape with 6 different surfaces? And if I'm reading things right, it is surfaces I should be minimizing, not necisarily pure poly count?

I'll try to see if I can make my own cube creating function tonight that doesn't bother with the top and bottom side, and that is only one surface. If nothing else, it'll better help me understand how meshes work.

Oh, and the idea of multiplying character movement by elapsed time is a neat idea. Originally I was just going to limit how often the character movement routine got caller per second. So much stuff too look into >:(


Sledge(Posted 2007) [#7]

I'll try to see if I can make my own cube creating function tonight that doesn't bother with the top and bottom side, and that is only one surface. If nothing else, it'll better help me understand how meshes work.


The quickest, easiest way to improve matters is to make a template cube and CopyEntity new instances rather than creating completely new ones.


Andy(Posted 2007) [#8]
You should read up on this: http://www.blitzbasic.com/b3ddocs/command.php?name=CreateSurface&ref=3d_cat

In Blitz an object has a surface(can be more than one, but always one) Surfaces kill framerate, so you should always use them sparingly. The number of triangles rendered is also very important to the framerate, so don't render triangles if they are invisible(ie will never be seen).

The surface consists of vertices(invisible points in 3D), like every corner of the cubes you have chosen to build with.

To the vertices, you attach triangles(each corner of the triangle attaches to a vertex), so for a cube, you would have 2 triangles for each side.

In the map image that you have posted, it looks like there is around 1000 cubes, this means 1000 surfaces and lots of triangles which are never seen, but still rendered.

You will find that one object with few surfaces with a number of vertices(verts) and triangles(tris) will render faster than the 1000 objects you are now trying to render.

I assume that you are basing the 3D on a 2D image in memory. If this is the case, then you are looking at an individual pixel and then decide to create a cube for that point. In stead, you could create 4 functions, each adding 4 vertices to the maze object(addvertex) and then 2 triangles(addtriangle) based on the square the side will be facing. If there is an empty square then you sdd the verts and triangles, but it there is an other occupied square, then you don't need to add any triangles because then the side will never be seen.


Andy


octothorpe(Posted 2007) [#9]
Here's a really easy solution for ya!

Just AddMesh()ing all your cubes into a single mesh, leaving you with only one surface (try CountSurfaces() to check for yourself.) Don't forget to free the cubes after you've added them. The example program below will show the difference - you may have to adjust the constant "n" (number of cubes) depending on your computer.



Note that you'll need to do this for each terrain type (e.g. one for your stone walls, one for your doors) because all triangles on one surface must share the same texture and colour.

Of course, you still have a lot of wasted triangles between wall segments that will never be seen and are just eating up cycles. The next step (if necessary) would be to generate only the quads (two triangles forming a square) you need instead of relying on CreateCube().


Stevie G(Posted 2007) [#10]
Here's another version which culls unwanted poly's ... if you want to see the original poly count uncomment the flag = 0 command.

Stevie




Fey(Posted 2007) [#11]
I havn't checked back in with the forum in a few days, didn't relize I had recieved more help on this topic.

Just wanted to update everyone, at the moment I'm no longer using cubes except on certain walls that don't occur very frequently. (I have 2 kinds of walls, walls that represent boundries for rooms and the maze as a whole, then regular walls)



The screen shot isn't as meaningfull now, since I'm making surfaces manually now and without the top surface much of maze isn't visible from the top. The program is running much faster now, and it only required I do a little bit more work (I'm so lazy). I've not fully tested it though, and I'm wondering if this tecnhique alone will be usefull on my mazes that utilize the whole 45X25 space more completely.

Still havn't looked at octothorpe or Stevie G's suggestions, but I intend to soon. Once again, thanks everyone, this project would have probably allready been doomed with out you all :)


Stevie G(Posted 2007) [#12]
Here's another version which retains texture coords if it interests you ..