Best Practices for Artists
Use proper and common scale for every model. Coordinate this with your coder. Usually 1 unit in your 3d program = 1 meter.
Keep the center of the object in the middle of the mesh or at bottom, not any arbitrary spot. Remember that rotation and moving of the model is calculated using the center point.
|You can do it automatically by clicking the "Centre" button in Editing (F9) -> Mesh tab.|
Moving, rotating and scaling is only for level making. If you are modelling a single object - do not use any transformations. Keep your object in neutral position and rotation. If you did any transformations, then use some option to apply it to the vertices positions.
|Use Transfrom -> Clear/Apply -> Clear Location and Transfrom -> Clear/Apply -> Apply Scale/Rotation (CTRL+A).|
In the front view you should see the back of your model. (The CEL camera is specific, if you use this, main characters which use the camera should be facing toward you, then).
Do not use random names like Object_031, mesh13_, blackblack_23_, 01_-_material_new2. Coordinate naming with your coder.
If your project is using the zone manager, or you are keeping all your maps loaded in memory at one time - remember, don't use duplicate names for anything in your entire project. If you use duplicate names you will have guaranteed conflicts. It's better if you use unique names for everything that you can name in your entire project, even if they're in separate maps.
|Be careful about the default naming convention that Blender uses for mesh factories.|
Use png, it's compressed, it's lossless, and it has 8bit alpha.
Do not use jpg (except for textures that really don't require a lot of detail, but note that even in this case it is best to keep the source image as png because otherwise you loose quality everytime the texture is edited). Coordinate it with your coder, he/she will decide which textures should be lossy compressed, and which not.
Between each unwrapped part of your model leave gaps of about 2 pixels wide, especially where there is stark colour changes. Otherwise you'll get colour 'leaking' at far away distances.
Usually it is best to paint textures at the target resolution you intend to use them at as they will look better- resizing does not always look optimal and can destroy details that can be done with pixel pushing.
Photograph textures usually contain too much lighting information and will most likely look odd when they conflict with the levels lighting. Imagine a cube with a the same texture on all sides with lighting info- not all the sides should have the light come from the same direction. To reduce this, take photographs during days when the sun is more diffuse and use post processing.
Also use textures that are a power of 2. For example 256x128 and not 256x130. In the latter case, CS will resize this texture internally, which sometimes can look rather ugly.
At release time, switch to DDS with dxt compression, I can't think of any case in which dxt5 is harmfull, it can handle layers/mipmaps, 8bit transparency, and more importantly, it's the same format as used by the graphics card, meaning textures load faster.
DDS compression types:
DXT1 opaque - compression ratio 8:1 - most popular for standard textures
DXT3 sharp alpha - compression ratio 4:1 - for textures with explicit alpha
DXT5 smooth alpha - compression ratio 4:1 - for textures with interpolated alpha
As of right now (march 2007), there is no graphics chip which can store a texture bigger than 4096x4096 (1024x8192 doesn't work either). Don't worry about textures that are too large -- if they don't fit in the graphics memory then CS will automatically downscale the texture.
|You can have image.png and image.dds in the same folder, use the png for blender in the viewport, at export time, b2cs will pick up the dds in order to use it in CS.|
|DDS plugin: gimp 1.2 (read only) and better one gimp 2.0.|
|DDS plugin: Nvidia Photoshop Tools|
Every per-pixel lighted material needs a normalmap. If you don't have a baked normalmap for your model, then at least use a fake plain normalmap (just a picture with the color 127, 127, 255).
You can use two transparency modes:
1. Smooth variable alpha.
- Does smoothly varying continuous alpha, but can cause ordering problems where sometimes your object will appear behind objects that should be behind it. In this case you need to set the zmode to ztest or use binary alpha instead.
2. Binary mode full opaque/full transparent.
- Binary mode is faster (use <alpha><binary/></alpha>). To tag transparent pixels you can use the transparency support in formats like png or keycolor. For keycolor, usually people are using "crazy pink" red=255 green=0 blue=255.
To avoid an ugly outline (halo effect) in transparent textures - use premultiplied alpha. Find this option in your 2d/3d program.
Transparent billboards should be rendered in per vertex light with a fixed renderstep. Also note that realtime shadows doesn't respect your alpha chanel, it will cast the whole mesh shape. Think about it before designing your game.
|If you are rendering billboards with transparency use Scene (F10) -> "Premul" button.|
Generally when building larger levels you will want to build atomized objects so that the person compositing the levels can easily fit pieces together in the level editor. This means that each object should piece together nicely (often by being a discrete size) and the object centers should be appropriate too. Textures should also tile appropriately over the object.
Be aware of holes between objects and terrain. In objects like a tree/house etc. it's a good idea to prepare an extended bottom about 0.5 m under the ground line.
|To make a tilable texture use the bulit-in "Make seamless" or better Resynthesizer plugin.|
|To make a tilable texture use the Filter > Other > Offset filter, setting horizontal and verticle to half the size of your texture and checking the Wrap Around box.|
10 objects with 10000 polygons for each - is faster than 10000 objects with 10 polygons each. The same thing applies with materials. For one object, use one big texture with many unwrapped faces, it's better than a couple of textures. Of course sometimes it's impossible because you need one shader effect for glass and another for a car body, for example.
Avoid overlapping faces. In realtime rendering it makes an ugly flickering effect called "z-fighting". Instead of intersections, it's better to add a couple of connecting faces between surfaces.
There are no double-sided surfaces. Every polygon has one side determined by its normal. Keep your normals pointing in the proper direction. If you need a double-sided surface then just copy and flip your polygons. In this case don't worry about the previous rule -- the overlapping polygons are facing in different directions and won't cause "z-fighting" problems.
|You can double all your faces automatically by setting Render -> Twosided.|
|Many times you need to have specific double sided faces on the same mesh. To do so, in edit mode select the faces you wish to make double sided, duplicate them (Shift-D) and flip the normals opposite (press W for menu-> Flip Normals). If the model is not yet finished you may wish to separate the flipped face off (P-> Separate Selected) for easier working with the geometry.|
|Blender has no support for selectively creating double-sided faces, so when you need a few faces in a mesh to be double-sided (as opposed to the whole mesh), you can triangulate the faces (CTRL+T) and then recreate the triangles on the opposite side and flip their normals if needed.|
Avoid triangle fans and thin polygons. It looks ugly in realtime rendering. The ideal shape should be close to a grid.
|You can try automatically reorganizing your faces to optimal using Edit -> Faces -> Beautify Fill (ALT, F).|
Sometimes because of optimization reasons objects need to be closed. Some shaders (real time shadows with normal maps and everything) also require closed objects to render properly. Coordinate closing objects with your coder.
|To find internal faces, switching on 'Solid' rendering mode and switching to face select mode (F) should offer some clues by shading faces gold coloured.|
If you need a visible seam on your mesh then split the polygon's vertices. But if not needed - don't double your vertices.
|To split a vertex into two use Edit -> Vertices -> Rip (VKEY). To clean doubled vertices use Edit -> Vertices -> Remove Doubles (W, 5).|
Mesh joint deformation
When modeling appendages that will need to deform in animation, remember that at least two rings that circle the entire diameter are needed to maintain volume. The first example has three rings in the front, that merge into two in the back. The top look is 100% weighted to the top bone, the bottom 100% to the bottom bone, but the middle half look is a 50/50 split between the two. This is the best solution with the lowest poly usage. If you have to go lower than that, two full rings are necessary like in the middle example. The top look is weighted to the top bone, and the bottom loop to the bottom bone. This ensures both sides of the joint maintain their volume. The last example is what to avoid. It'd two rings that merge into one in the back. The merged area is given 50/50 weighting, and you can see that it collapses the volume of the joints. Always maintain two rings if you can.
Terrain ignores your uv's. They are internally generated by the engine. Basemap and Materialmap just fully cover the terrain mesh, and for Splats, uv's make a regular grid. The scale of this grid is set in the shader variable.
If you made a terrain mesh and generated a heightmap, then the result in the game will always be a little bit different to your original mesh, especially at hill-side. Also check the bounds of your Heightmap, sometimes it has unneeded holes.
Heightmap encoding is: red * 65536 + green * 256 + blue
Use the foliage plugin to make grass, it can use a material map to choose where the grass, trees, and rocks will be. Use a material map to chose which texture will be displayed on the ground, at which place, in such a case, more than 4-5 textures will probably kill your framerate.
You can easily make your Materialmap by reducing your Basemap's colors to the number of Splats.
|b2cs automatically renders a heightmap, basing it on the mesh you tag as 'terrain'.|
For geometry Crystal Space uses it's own file format and a couple of popular formats: 3ds, cal3d, md2. If you want to use 100% of the features it's better to use the native CS format. Actually, exporting from Blender is the best supported. If you work in a team and members are using several 3d programs - exchange models between them in any popular format like Collada or Wavefront Obj.
If often switching between applications, Obj may be the best option, it's very simple, and it's supported by most applications. Collada is XML based and supports a lot of things. As a downside it is difficult to write a parser for it and, as it's quite recent, not all applications have support for it yet. However at a later point, it is supposed to be _the_ interchange format.
|Collada plugin is built-in.|
|Collada plugin: www.feelingsoftware.com.|
Darek, Genjix, Jorrit, Orogor, DistantShores