Home Technical Talk

Slicing a level up in Max before exporting to a game engine

Seeing as 3D engines these days have moved away from BSP and more towards static meshes, I'm assuming that it's standard practice to chop a level up before importing it into whatever engine you're using?

My question is simple - what's the best way of doing this in max? Say slicing a racetrack up into 12 or so pieces. Manually make cuts, then detach them as a seperate object or?

Cheers,
RumbleSushi

Replies

  • yiannisk
    Offline / Send Message
    yiannisk polycounter lvl 14
    which engine are you using?
  • rumblesushi
    My own 3D engine. As part of the deferred processing and culling broadphase, I calculate the bounding boxes of entire models from their verts, and if they are deemed to be off screen, I can completely skip iterating over their polygons to possibly be rendered.

    Without a level created with a BSP structure, I imagine most 3D engines have a similar method of doing things, and I heard someone else mention slicing a level up before exporting.

    I would just like to know the most efficient way of doing the actual slicing in Max.
  • yiannisk
    Offline / Send Message
    yiannisk polycounter lvl 14
    hmm there is not enough information.
    is your level an entire mesh ?
    by level you mean terrain, foliage, buildings, props?
    Is it symmetrical? etc.


    i would divide it to logical sectors and export it.

    But for slicing, the slice tool should be enough.
    While I have no idea how your level looks, how big it is, what kind of terrain you use, etc. here is a generic workflow for slicing big models. (i don't like the sound of it but it's your engine, you know best :))

    You can select certain areas (polys) that need to be cut and use the quickslice tool, or use the slice modifier on the entire model (this way you will get already separate pieces that you will not have to rename\detach).

    By using the slice tool you can cut and remove, and then duplicate the model and Rotate the slicer 180 or 90 as necessary. then repeat and use multiple slicers and copies as needed. With this method, you will end up with clean cut parts of your model.

    I have cut HUGE terrain tiles with this method as well as other relatively symmetrical large objects. There are scripts, but you will get random cuts.

    If you do not care about that go ahead but in general it doesn't sound like a good idea :)
  • AlecMoody
    Offline / Send Message
    AlecMoody ngon master
    In my experience race tracks haven't ever been handled with BSP. They are large open spaces and there isn't much occlusion going on. I have also not seen anyone slice up the road surface in an effort to hide pieces not on screen. I think it would be near impossible to hide a large percentage of a track if it's is designed like any real road or oval course.


    Racing games I have worked on have either handled the track surface as splines that can subdivide at various distances (which will require building a custom track editor among other things) or just a regular geometry with no LODs where slicing is only done to seperate drivable from collision surfaces.


    However, track side objects should definately get mulitple LOD stages.
  • rumblesushi
    Well to keep things simple, let's pretend it's just one big mesh, perhaps with some buildings welded into it, foliage to be added in engine. So basically just a big tacetrack with a few buildings.

    As you may have guessed, I haven't even created the level yet, I just want to know in advance, as creating a level is my next step in learning modelling.

    Thanks for the info though, I would certainly like to do it manually for cleanness, I was imagining cuts, but I'll have a play around with the slice tool.

    By the way, you said you don't like the sound of slicing big models, why not? I actually assumed that was how things were done these days. A big model would be sliced into small (ish) sections before being imported into the engine.

    With BSP, that's not necessary, as a BSP tree handles the culling broadphase, and any node that isn't visible not only doesn't get rendered, but it's polygons don't even have to be checked.
  • rumblesushi
    AlecMoody wrote: »
    In my experience race tracks haven't ever been handled with BSP. They are large open spaces and there isn't much occlusion going on. I have also not seen anyone slice up the road surface in an effort to hide pieces not on screen. I think it would be near impossible to hide a large percentage of a track if it's is designed like any real road or oval course.


    Racing games I have worked on have either handled the track surface as splines that can subdivide at various distances (which will require building a custom track editor among other things) or just a regular geometry with no LODs where slicing is only done to seperate drivable from collision surfaces.


    However, track side objects should definately get mulitple LOD stages.

    The funny thing is, even though BSP is ideally suited to interiors, it was originally developed for flight sims, and just like racetracks, there is almost no occlusion at all, so it seems quite odd.

    By the way, on oval type course I agree, it probably wouldn't be worth it. You'd be viewing half of it at any one time.

    But say a windy mountain pass, or a more intricate Mario Kart esque track? There is no doubt if you sliced up one of those tracks, you would be able to make big savings on the amount of polygons you had to check, by mass culling sections of the track that were deemed invisible.

    A more intricate track, you'd only be viewing a small section of it at a time. It wouldn't make sense to iterate through 100% of the track's polygons, when you're only viewing like 5 or 10% at a time.

    Also Alec, you said racing games you've worked on dynamically triangulated a spline right? Did it do that at runtime? Would parts of the spline that were deemed to be off screen therefore contain no polygons to be iterated over?

    And your second method, just regular geometry, do you know how the culling broadphase was handled for the levels in that game?

    Take another outdoor game, something like Mario 64 DS, it has some pretty big levels. Either at the geometry level, or with a tree, a level like that would have to be divided up to some degree, to do mass culling, so you weren't iterating over every polygon in the terrain despite only seeing a small section of it at a time.
  • AlecMoody
    Offline / Send Message
    AlecMoody ngon master
    Track side objects like buildings, grandstands, garages... should be separate objects. Collision surfaces like walls should also be separated from driving surfaces. My experience is only in building real racetracks, so if you are planning some fantasy mountain course or something then you can probably split things up and hide a lot of the track. However, at a real road course (and especially at an oval) Its rare that you cant see the majority of the track and you really wouldn't be able to create any consistency in how many sectors could be hidden around the track. You might get one spot on the back straight where you can hide 1/3 or even half the track but inevitably in another area you will be able to see nearly all sectors. If you made 12 partitions of a race track each partition would be a pretty large stretch of track, it would be especially unlikely that you could hide pieces that large.

    You could design your tracks to intentionally have a large hill on the infield is so that you could occlude some of the track, but that would look odd.
  • rumblesushi
    I guess having worked mainly circuit racers, then occlusion wouldn't be much of an issue, as you would be viewing a lot of the track at any one time, and yep LODs would be more efficient.

    I'm going to make some very windy/hilly mountain tracks, where you really would be only viewing about 5% of the track at once.

    I probably should have mentioned my 3D engine is Flash, and the performance is almost identical to a DS, so we're talking proper low poly stuff. 2000 polygons a frame at 60 frames a second.

    LODing wouldn't really be possible with the track or buildings, as they would be as simple as possible to start with, it would only be worth LODing cars.

    As I already have per model culling in place, and I'm not using BSP at all, slicing up a level seems like the simplest option. It's either that or using a grid or quadtree for the culling broadphase.

    I had actually planned to weld buildings to the racetrack, not have them as seperate objects, mainly for depth sorting issues (ie the building cuts a hole out of the track mode, to avoid z fighting), but it would be easy enough to just split them to the terrain yet retain them as seperate objects.
  • Eric Chadwick
    I created something similar for an underwater deep-ocean-trench kind of game.
    http://ericchadwick.com/img/nte_strike_retrieve.html

    The last shot on that page shows the layout in 3dsmax. I created a set of short-ish track variations, similar to the way Trackmania does it (check out their level editor, the PC game is free). Each section snaps to the most of the others, and the vertex normals were massaged to make sure they fit together seamlessly.
  • rumblesushi
    Thanks for the insight Eric. What platform is the game for? Unity?

    And so actually, you didn't do any slicing at all did you? You just created sections to be snapped together. How did you get precise snapping in max? They are fairly small sections too. Were all aspects of the scenery embedded into each section of the track?

    I was thinking of developing my own level editor to do something similar, but for now, I'd probably rather do most of the work in max, so I can get on with making a game soon.
  • Eric Chadwick
    Custom engine, for PC, made by a now-largely defunct company. The engine had some really cool tech, but it was very rudimentary in the tools dept., so we used Max as the level editor. Which in fact many other companies do.

    No slicing, yes snapped. Max's snap errors can be made small enough that they aren't noticeable if Max's units are setup to match what works well in the game's own scale. Big enough to contain the whole level, but small enough that snap gaps aren't noticeable. Read up on the System Units in the Help.

    The POV vehicle was about 2 meters long, with each canyon about 50 meters long, and the camera could get about .5 meters close to the walls.

    Scenery items were placed in Max as placeholder meshes, that just exported as Pos/Rot/Scale and entity type. Similar to Max's own Xref behavior, but custom-rolled because of Max's Xref instability. Then in the game they were replaced with the actual instanced meshes. Pretty common methodology for a Level Design tool.
  • rumblesushi
    Thanks again Eric, these workflow tips are helpful.

    By the way that morphing tech is very impressive. I know that 2D morphing algorithms are not simple in the slightest, I wonder how they went about that, used some existing 2D morph code then just morphed the verts in 3D, or did the 2D transitions from scratch too.

    And how common is it to use Max as a level editor? I've been contemplating building my own level editor, but if possible, I would rather get on with making a game using Max as the editor. Certain things seemed like it wouldn't be possible to use just max, such as adding items/enemies etc.

    How would you go about creating a dummy placeholder with an identifier to which enemy type is to be loaded in, then in game the appropriate enemy class is loaded in at the right place etc? Same thing for items etc.

    I assume you must have done this right, seeing as you used Max as the sole level editor?
  • Eric Chadwick
    The Whatif system is (was?) very unorthodox, but therein lies its strength. The CTO is a visionary guy, one of the smartest minds I've had the pleasure of working with. He did things that are just plain amazing, that morphing demo is just a tiny slice of it. More info on that site if you dig around, probably a bit cryptic.

    For placeholder entities in Max there are many ways to do this. One of the best ways would probably be Custom Attributes, i.e.. The dummies already have PRS data, so the CAs allow you to add custom entity types and other flags like collidable vs. not, sound triggers, etc.

    My most recent employer also used Max for level editing. Worked fine. We had a three-person team devoted solely to greasing the export pipeline. Had to jump thru hoops here and there, not everything is exposed nicely in the SDK. Depends how much you want it to do though.

    If you don't mind the overhead & limitations, they have a ready-to-roll game-export framework called 3DXI. Has some limits apparently, but might help you get setup quickly. I'm not an engineer tho, can't help with the details.
  • rumblesushi
    Hey Eric, do you know why the company is now defunct? It seems a shame that the company of such a clever guy isn't doing better.

    Also, you know once you'd set the whole level up in chunks, as per the example on your website, how was it all exported? What was the whole export/import workflow from when the level was done, to actually getting it in the engine?

    I've only experimented with importing single objects to my engine, and just setting things up with code, inside the engine.

    (this demo for example http://rumblesushi.com/snowscape.html - there was no "level editing" per se, just some randomly generated terrain, with randomly placed trees and ice boulders etc).

    One more thing - Custom Attributes - would I need to write my own custom exporter with Maxscript, or are CA's something that can be used in conjunction with standard model files, like collada/3ds/OBJ etc?

    I've worked absolutely hardcore developing an excellent 3D engine (by Flash standards of course) but in regards to game development and 3D workflows, I have no experience at all, so I'm doing everything possible to get up to speed and get on with actually making a game :)
  • Eric Chadwick
    The individual pieces were exported as individual files using a custom exporter, written using a combination of the Max SDK and MAXScript. Most of the pieces were in the same Max file, for easier development by us artists. A separate max file was used for the layout, with each piece in there just exporting as P/R/S with a name and some tags. Some more detail from another similar project on my site.

    The company suffered the fate of many others these days, just plain ran out of funding. What can I say, it's been a tough economic climate for the past few years.

    How much effort you put into your exporter should depend on who you intend will use it. If it's just you, do only enough to make it work. But if you want artists to use it, make it user-friendly, otherwise it will take them forever to iterate, which ultimately means they would avoid improving the assets because it takes too long to see their changes in-game.
  • rumblesushi
    I see I see, so you weren't using standard file formats at all, those pieces were exported as a custom format for the engine?

    Did the exporter automatically centre them before exporting, then the engine initiated them using the coordinate they should have in world space using a CA?

    And by the way, I totally understand about the guy's company, I'm self employed, and since the recession, making money isn't easy.

    All this info has been helpful, I can't wait to start actually putting things together and making a level.
  • Eric Chadwick
    Yeah, each "real" terrain piece was centered at export time, then after some swizzling they were written to the proprietary format. Actually IIRC they were all stored in a single binary file, not separate files, so the engine simply pulled out the ones it needed at render time. The special file format was simply to process them into their special way for storing and retrieving UVs, morph targets, etc., in a kind of n-dimensional compression & retrieval system.

    We didn't use Custom Attributes, we used Note Tracks instead, because we had to extract time-specific data from animation files. Note Tracks work great for this, you can put ASCII data in the timeline, and then use them as "bookmarks" to extract animation poses at specific points in time. Well actually the UI for Note Tracks wasn't great, we had to write a bunch of custom tools to automatically create and massage them (wizards, find/replace, etc.). I think CA's make more sense for non-time-sensitive data, since they're more flexible and easier to access.
  • rumblesushi
    Ah, thought so. And the note tracks you used, presumably they were used to store each section's world coordinate, so that even though the section itself was centred, it would be positioned where it should be when loaded into the engine? This is something CA's do though right, and that's what I would be better off using?

    Thanks again for your help Eric, even though this is all basic stuff, it's very useful for someone with no knowledge of the 3D workflow and level design etc.
  • Eric Chadwick
    No, the exporter extracts and stores each entity's offset from world center, then moves it to world center for exporting. Artists didn't type any transform values into the note tracks, that would be tediously crazy.

    Note Tracks (or Custom Attributes) are just a way for a level designer to attach game-specific data to each entity. Like "I should spawn sound 7 when I am hit" or "anything hitting me will receive 14 points in damage" ... that kind of thing.

    CA's just offer a different way to store and access those settings, a way that's usually easier for the level designers or artists to use.
  • yiannisk
    Offline / Send Message
    yiannisk polycounter lvl 14
    Well to keep things simple, let's pretend it's just one big mesh, perhaps with some buildings welded into it, foliage to be added in engine. So basically just a big tacetrack with a few buildings.

    As you may have guessed, I haven't even created the level yet, I just want to know in advance, as creating a level is my next step in learning modelling.

    Thanks for the info though, I would certainly like to do it manually for cleanness, I was imagining cuts, but I'll have a play around with the slice tool.

    By the way, you said you don't like the sound of slicing big models, why not? I actually assumed that was how things were done these days. A big model would be sliced into small (ish) sections before being imported into the engine.

    With BSP, that's not necessary, as a BSP tree handles the culling broadphase, and any node that isn't visible not only doesn't get rendered, but it's polygons don't even have to be checked.

    I have no personal experience with racing games as my studio already had finished one when i joined.So the guys who replied will know more about it.

    i work mostly with unreal and proprietary engines as well as infernal.
    in infernal it is more straight forward, we export the entire level and then add other actors like props etc.

    unreal prefers almost everything exported in pieces and sorted in relevant packages. They have certain streaming channels that you should assign your assets depending on their usage and it is quite explicitly organized. World, Cinematics, Weapons etc. and in each category separate streaming channel for each basic texture category, diffuse, normals, specular.
  • rumblesushi
    No, the exporter extracts and stores each entity's offset from world center, then moves it to world center for exporting. Artists didn't type any transform values into the note tracks, that would be tediously crazy.

    Note Tracks (or Custom Attributes) are just a way for a level designer to attach game-specific data to each entity. Like "I should spawn sound 7 when I am hit" or "anything hitting me will receive 14 points in damage" ... that kind of thing.

    CA's just offer a different way to store and access those settings, a way that's usually easier for the level designers or artists to use.

    Haha, I didn't think you'd be doing it manually, I thought part of the process could be storing the world coordinate in the note tracks automatically.

    It does sound superb though that CA's are that versatile, to be able to carry very game specific data, unrelated to the geometry etc. Given CA's and everything else you've told me, I'm surprised that almost everyone doesn't use Max as a level editor.

    But in regards to coords, I guess that's what I'll have to do, write a custom exporter that stores the world coordinate before centering the mesh and exporting.

    On a complete unrelated note, I've just realised something really annoying. Tiling one section of a texture multiple times across 1 polygon isn't possible, you need to either tile an entire map, or increase the poly count to have 1 tile piece per polygon. Drat :D
  • Eric Chadwick
    I'm surprised that almost everyone doesn't use Max as a level editor.
    Well, it has its drawbacks too. Max stores some transforms and some mesh data in an odd manner, has a fair share of bugginess/crashiness, and has a bunch of controls that are extraneous to game development... if they're used on the model it can really mess it up for game export. Like non-uniform scaling, mirroring, adding modifiers on top of Skin, etc. A good Max export pipeline needs to be somewhat foolproof to avoid a lot of these gotchas, or you're going to get a lot of frustration from your users.
    Tiling one section of a texture multiple times across 1 polygon isn't possible, you need to either tile an entire map, or increase the poly count to have 1 tile piece per polygon.
    Max supports this easily, just scale the UVs larger than the 0-1 UV space. Or are you talking about your target platform?
  • renderhjs
    Offline / Send Message
    renderhjs sublime tool
    If you go for a race game engine maybe consider doing something like spline or nurbs based tracks generated in the engine instead of created beforehand in max, maya,...
    The advantage would be less of a overhead on the triangle count to clip and sort into sectors. Fzero on the n64 did it like that and many track editors work like that. Props, buidings and other environment stuff could be loaded mesh data placed around that nurbs track.

    And yes just like yiannisk said most game pipelines these days (consoles, PC,..) are driven around prefabs: detailed building blocks that are instanciated in the engine and speedup the dressing time of a level.
    I believe it was the unreal engine that made this concept more popular starting with Unreal 2 engine where they started to use more imported meshes from max as UnrealEd generated level geometry. Especially if you want to show of more complicated architecture and high detailed props there is no workaround to this anymore. In the past it was common to create the level completely in a editor alone and just use PS to create the textures and perhaps max for the characters.

    So I think you should go a similar approach: Save meshes like library items and instanciate them in your engine based on some layout map (xml, array,...). That way library items have to be loaded just once and can be used multiple times and be transformed (position, rotation ,scale) based on the map file.
    If you don't have a complicated game you could even consider saving positions and the map data just in 2d (x,y) so that you could use other tools as well to layout and export the maps.
  • renderhjs
    Offline / Send Message
    renderhjs sublime tool
    just remembered this,
    great resources for maxScript:
    1. most active maxScript forum (the official Area forums are empty compared to this one)
      http://forums.cgsociety.org/forumdisplay.php?f=98
      Best maxscript script resource:
    2. http://www.scriptspot.com/3ds-max
      If you need example scripts or existing solutions browse and search there. Most of the scripts are non encrypted which lets you study them.
    3. In the maxscript editor simply press F1 to get the official maxscript reference, its even context based if you place your cursor in a word.

    If you have any specific maxscript questions post them here in the tech section of polycount, there are quite a few scripters out here.
  • rumblesushi
    Well, it has its drawbacks too. Max stores some transforms and some mesh data in an odd manner, has a fair share of bugginess/crashiness, and has a bunch of controls that are extraneous to game development... if they're used on the model it can really mess it up for game export. Like non-uniform scaling, mirroring, adding modifiers on top of Skin, etc. A good Max export pipeline needs to be somewhat foolproof to avoid a lot of these gotchas, or you're going to get a lot of frustration from your users.


    Max supports this easily, just scale the UVs larger than the 0-1 UV space. Or are you talking about your target platform?

    Ah ok. Honestly, I like Max a lot, I find it surprisingly easy to use after only studying it for about a week. The only things I don't like are that it runs like shit on my laptops, and crashes more frequently than almost any other program I've used.

    To avoid the possible problems, maybe I shouldn't import the transforms at all, and just make sure the transforms are hardcoded before exporting.

    Actually no, on my platform I tile textures easily, but I've only experimented with tiling complete textures though - like that snow demo above. And yes, just by multiplying the UV space.

    In max, I've tried doing the same thing, tiling a complete map just by increasing the UV space, however - this is obviously for a whole texture. Correct me if I'm wrong, but there is no way to tile just part of a texture across 1 polygon? It has to be the whole map right?


    Render - thanks again for the maxScript links, I'll check those out later today.

    I considered that actually, just importing a spline, and I may still explore that option. But because I have very fast per model culling in my engine, using bounding boxes calculated from the verts before the pipeline gets to the polygon iteration - it would be just as efficient to use cut up sections like Eric did in his game, any piece that's deemed offscreen, I don't even have to loop through it's polygons. It's a good alternative to trees, for broadphase culling.

    I thought perhaps it would be easier to construct a level like that too, with varying polycounts in different sections of the track etc.

    I'll try the spline based method too, I'm pretty dilligent in regards to trying anything to see which performs better, and benchmarking.

    Oh, forgot to say - I do actually push models into an array as library items so to speak. For example this demo - http://rumblesushi.com/hachi_roku.html - after being loaded/parsed, the model is then loaded into the scene 20 times.



    By the way render - are you still using Flash, or do you use Unity these days?
  • Eric Chadwick
    Correct me if I'm wrong, but there is no way to tile just part of a texture across 1 polygon? It has to be the whole map right?
    Right. I have heard people talk about tiling internal portions of a bitmap, but I haven't seen it in action.

    Here's an interesting script. It creates a texture atlas from a tiled model, by slicing up the model, and applying portions of the atlas to each slice. Might provide some ideas...
    http://www.scriptspot.com/3ds-max/scripts/texture-atlas-generator
  • rumblesushi
    That is interesting, I just downloaded it.

    Yep see, it shouldn't be a problem, the easiest solution would be well, use a different texture on the wall or area you want tiled, with a small, specific tiling texture.

    While that is completely possible in my engine, it's not desirable. I want to use only 1 texture per model, because it uses a draw call per texture. So imagine a 500 poly model, that is reasonably intricate for the polycount - it still only has 1 drawcall for that model, as long as the Z values of it's polys aren't intertwined with another model near it. However if I use 2 textures, when the render list is sorted, the polygons from either texture would be suffled together, and could result in a draw call every one or two polygons that were rendered, so possibly 150 draw calls for that 1 model.

    It's annoying though, I'm going to have to find a way to efficiently tile parts of models.

    Eric - I forgot to ask you - you knew exactly what I was talking about, slicing up a level for per model culling, as you'd actually done it ;)

    Others seemed confused - so do you know what are common broadphase culling methods since BSP isn't really used anymore? I was under the impression it would be per model culling, with levels broken down into chunks, but seemingly not, so perhaps a quadtree or octree for mass culling?
  • Eric Chadwick
    If you want to reduce draw calls, simply use an atlas. But slice up your model intelligently, as in... by an artist at creation time. That script will likely create more slices that are really needed, so you'll end up with long thin triangles at one end of a strip. A 500 triangle model has more than enough topology to use a single atlas.

    I don't really know the best culling methods. I'd suggest asking on a game programmer mailing list, like GDAlgorithms or Sweng-Gamedev.
  • rumblesushi
    Yep, I should join gamedev actually, I'm sure there's some experienced game programmers there that could give me some tips.

    I must say, I'm plesantly surprised by the general level of technical knowledge here though, considering it's a 3D artists forum afterall. I guess the very nature of 3D means you have to be somewhat technically minded even on the arts side of things, compared to 2D.

    Using texture atlases is one of the things I'm going to do actually. But for the tiling problem I can do one of two things. If it's a LARGE tiled area like a snowscape, that would probably have a tile per polygon anyway, I can do just that, use a tile per poly.

    It's more walls/floors etc that could be tricky. I think in that situation, I would have to simply use a larger texture, section off part of the texture into a pretiled map, then use that on the floor, possibly even subdiving the surface once if the tiles need to be smaller. It would only mean adding another 6 polys to the floor of a room for example.

    Oh and renderhjs - incidentally, I was just thinking - even more games than you imagine probably do the spline method. I'm not sure about current games, but in the N64 era sure. You mentioned F Zero, but a few weeks ago I booted up MK64 in Project64, turned on wireframe to see how the track was constructed, and the road did look very much like it was extruded from a spline, especially given how every poly was exactly the same size.

    I'll have to try both methods. One of the reasons I like the idea of my segmented level method, as Eric has already done, is I can weld parts of the scenary to the track sections, to eliminate depth sorting issues with large polys, z fighting etc.
  • Eric Chadwick
    Some stuff in my portfolio about using texture atlases for floors and such. Down towards the bottom.
    http://ericchadwick.com/img/world_of_zoo.html
Sign In or Register to comment.