3ds max

Last week I digged into the topic of exporting a lightmapped, vertex-colored scene from 3ds max to Unity. Unity3D does not come with special exporters but exports to standard formats like FBX and COLLADA. When exporting to FBX, 3ds max Shell Materials do not get converted automatically to a lightmapped shader upon import. No wonder as FBX (= Filmbox which became later MotionBuilder) is not specially targeted towards game content. Therefore you have to manually assign the shader and the second texture. Of course it would better if this could be automatized!

Here are two pictures from a test scene with vertex-colored houses we created once for Virtools-based projects. The houses are currently using only dummy lightmaps, but that's the result without any manual shader or texture assignments.

Raw 3ds max scene Result in Unity 3D

So, here is how I do it.

Preparations inside 3ds max with Maxscripting (MXS)

Unity allows to hook into the assets import pipeline via custom scripts. This is very cool concept and is similar to something we did for our Virtools Assets&Build pipeline which we called BogBuilder btw. The key concept is therefore to *somehow* pass hints to a assets post processor script. What I do is to tag material names inside 3ds max, for example using __lm__ to indicate that the material is a lightmapped one. I use two underscores on each side because it reduces the probability that the original name accidentally contains such a sequence of letters.

I did not found a way to extract the names of lightmap texture from FBX files inside a Unity post processor script. So I actually add the texture name to the material name itself too! Here is an example of how a material inside 3ds max can look like after preprocessing

wandputz-tex__lm__S_4_WaendeCompleteMap_ambient-schlagschattenMulti100.tga

Pretty long, hehe. But it helps!

The custom maxscript does thus the following for every shell material

  • take the texture from baked material and put it into the original material's self-illumination slot
  • add the lightmap tag to the original material name (if it's not already there)
  • add the lightmap texture filename (including extension) to the material name
  • assign the original material back onto the geometry

Don't forget to check if the original or baked material is of type multi-material and handle it accordingly. Another issue I *sometimes* have is with special German characters like öäü. Unity sometimes replaces those upon import with some other symbols and may therefore break your postprocessor scripts when they will look for the lightmap textures. I created two more custom maxscripts that check and replaces those characters in material and texture names. (For object names it would be good, too, I guess). As a little hint, in order to access easily all bitmap-materials inside 3ds max you can use the following maxscript snippet:

local maps = getClassInstances bitmaptexture

Using enumerateFiles or usedMaps() only gives you strings and might turn things more complicated. As some of our meshes use Vertex Colors, I check that too and tag material then with __lmc__ instead of __lm__. To detect the use of vertex colors you can do the following

local tmesh = snapshotAsMesh myObjectNode
if ( getNumCPVVerts tmesh > 0 ) then

Using AssetPostprocessor

There are several types of asset postprocessors. To create one, you have to place/create your script inside a project folder called "Editor". It's not created by default, so create one if you can't find it. Using Javascript you usually start like this

class AssetPost_ShadersByPostfix extends AssetPostprocessor
{    …

and then you implement a static function depending into which kind of event you want to hook into.

OnAssignMaterialModel gets triggered each time a material has to be imported. In this callback you have the control if, where and how you create the new material. If you organize your project in a way that you cluster all materials in specific directories rather to have them close to the geometry assets, then this works fine. Otherwise this isn't the best callback to use as you don't get any hint where, inside the project directory hierarchy, the imported FBX is. Usually on FBX import a "Materials" folder is created on the same level, something you can't do easily with OnAssignMaterialModel. Alternatively you can use

OnPostprocessAllAssets: The benefit of this callback hook is, that the assets creation is automatically done for you and you get the target directory paths as array. To detect materials you can simply do something like this

        for (var aFile: String in importedAssets)
        {
            // identify materials by .mat extension
            if( aFile.ToLower().EndsWith(".mat") )
            {
               …

This works pretty good. But also with this there is a scenario where it's not the best fit. If you use the FBX exporter option "embed Media" that includes all textures inside the FBX file, then it does not import the lightmap textures during the first import/refresh activation. They get imported if you do a refresh or if you switch to another app and back. As result, your OnPostprocessorAllAssets may not find the lightmap textures because it's called during the first run, when the materials are created (and only diffuse textures get imported) and the lightmaps are added in the second run to the project.

So what I do is calling manually a custom ScriptableWizard inside Unity after import. It's therefore not totally automatic, but quite robust and only something like 3 clicks.

Somehow I miss some built-in functionality to deal with project things inside Unity but you can parse through all material assets inside your project using standard DotNet, like this

import System;
import System.IO;

var matFiles : String[] = Directory.GetFiles(Application.dataPath, "*.mat", SearchOption.AllDirectories);

for(var aMatFile : String in matFiles)
{     …

The rest is quite straight forward: the Wizard iterates through all project materials, checks if they contain any shader tags in their names, assigns the corresponding shader, extracts the lightmap texture name, finds the texture and assigns it as second texture to the shader.

Well, that's it. I hope this helps you to setup a better pipeline for importing assets with lightmaps from 3ds max. Of course the key concept can be used for anything else too! 

CGGenie did an interesting survey called "Upgrades09". After having published the results (see previous link), they also added a very interesting article about how to interpret the results!

It's title: "CG Survey: a question of cost and satisfaction".

To resume the article and the survey, one could say: professional users are less satisfied with their tools than hobbiest or casual users.

Here some extracts:

3ds Max's users have invested a large amount of money, are likely to be professionally pressured in their usage and timescales and also are likely to be pushing the software to its limits every day.

[…] in more challenging ways and those little niggles might become major blockers, those quirky crashes become fundamental cash burners – even though the actual reality of the event, the flaw or the software limitation wouldn't have changed, the user requirements would have.

This helps to understand why a diversified, professional user/customer base might seem always as unhappy grumbler. They use the tools under tight time-frames and budgets. Working with their tool everyday they see what works efficiently and what not. Moreover, they want to push it to it's edges. They want to be fast(er). And if the tool improves, they move fast towards the new 'edge' … pushing it some more! And moreover not necessarily everybody is pushing it into the same direction …

Obviously it's "a far greater challenge" to satisfy those people. 

Puppetshop, the rigging and animation toolkit from Kees Rijnen, is now available for free!!!

Aaaaand … ShaderFX is free for …

[…] individuals and companies smaller than 2 employees

:woot:

Wow ! Pretty cool !

[It's at the bottom of the page, where it says: download.]

In addition to that, as result of the Softimage acquisition by Autodesk, CAT, another rigging, muscle and animation toolkit, is now available as extension download for 3ds max subscription customers. Here is an old review of the 'Character Animation Toolkit'

 puppetshop Character Animation Toolkit ShaderFX

I never had a look at these animation packages… what about you?

Autodesk released a new SDK which allows you to customize the DCC FBX exporters and importers for 3ds max and Maya.

On the Autodesk website it says:

Autodesk FBX 2009.3 technology now includes published source code for the FBX and COLLADA readers and writers, enabling developers to extend and adapt the code for use in custom pipelines.

[…] and thus protect their investment in their FBX plug-ins.

And the docs specify:

  • Extend the FBX and/or Collada file format to support additional kinds of data.
  • Extend the functionality of the FBX plugins for 3ds Max/Maya to support the reading and writing of files that use your file format.
  • Use FBX SDK directly to read and write files that use your file format, without passing through 3ds Max or Maya.

You can download this SDK which is entitled as "FBX Extensions Software Development Kit". The size of the download is 298 MB. 

Today I was on a local IDGA event and this news was mentioned. Initially I thought that the FBX format itself has become open but this seems not to be the case, unfortunately

😐

Still, it's good that now one can extend the file format and those plugins. 8)

Eye.I.It's already old news but I just came across it. Boy, there are many acquisitions lately!!

Some RealViz products will be discontinued. One of them is Matchmover of which we have a license… Surprised
I guess if it gets integrated into 3ds max, we won't mind at the end.

(…) 

Autodesk intends to develop and sell REALVIZ’s Stitcher Unlimited, Stitcher Express, ImageModeler and Movimento software as standalone products. Matchmover, Retimer and VTour will no longer be available as standalone products; core technology from these REALVIZ products will be integrated into future versions of Autodesk’s existing products, enabling customers to bring the real world into design environments.

The following REALVIZ offerings have been discontinued: Stitcher Pro, Stitcher Unlimited DS, StoryViz, and hardware and software product bundles. Education versions of ImageModeler and Stitcher continue to be available.  Student versions of ImageModeler and Stitcher are no longer available.

(…) 

Source: Autodesk Press Release  

Also take note of the part I highlighted. This probably means image-based modeling/lightning and pathfinding+traffic modules for Max, Maya etc. 

(…)

where it's easy to build 3D environments or virtual sets by stitching pictures together or derive 3D models very quickly from set photos using image-based modeling. Games now require a lot of facial animation. Animators can rough out facial animations using a webcam and optical motion capture.

(…)

We have plans to use these technologies across a wide spectrum of industries… Every country in the world is starting to model their cities in 3D, and the Kynapse technology offers some very relevant potential for these applications. The path-finding and AI technology can be used to do simulations of crowds inside of buildings or stadiums or to model and simulate car traffic in digital models of cities.

Source:  VFX World Interview

The short answer is: no!

The long answer is:  3ds max hides complexity. Before per-pixel handling via programmable pixel-shaders became available on consumer gfx cards, shading components across the triangle were mainly calculated by interpolating the value between the three vertices. A triangle is flat and thus you can interpolate in a linear/straight way. For example the vertex colors and normals.

Now, if you have a mesh inside 3ds max – let's say a cube in it's default state. It has 6 smoothing groups, because there are hard edges between each face. How many normals do you need for each corner vertex? Each corner has 3 faces – each of them pointing to another direction and having "hard" seams at it's borders.

We need 3 normals for all 8 corners … that's 24 vertices. Ok, now convert it to an 'editable poly', go into the face sub-level and hit CTRL+a to select all faces. Hit "clear all" and then smoothing group "1" in order to assign a single smoothing group to all faces. Export this one and load it into Virtools. And?

Oh, it ain't 24 anymore but not 8 neither? Yes! That's because there are not only normals stored in the vertices but also UV coordinates and color/material information. In 3ds max do then the following:

  • add the "UV Unwrap" modifier to the cube
  • go into face sub-level mode
  • select all
  • open the "Edit…" dialog
  • select Mapping -> Unfold Mapping ('walk to closest face') -> Ok
  • You now have a cross-like UV layout
  • go into vertex sub-level mode
  • select through each vertex and notice that sometimes another one is highlighted in blue
  • right click and select "target weld" form the context menu
  • now weld each vertex to it's "blue partner" in case it has one

Import the smoothed cube that has no UV seams into Virtools … … … what does the mesh setup say? 8 vertices, finally !!!

Cool

I hope this little tutorial has shed some light on the topic therefore you should now be able to understand better why there might be differences in vertex count between Virtools and 3ds max.

3ds max 2008 is announced. Something interesting is the GPU shadowing system for the viewport. Checkout the video about the "review rendering" feature. It does support up to 64 lights.

 3ds max 2008 preview - gpu based review rendering for shadows

I also like the new working-pivot and the new LOD options. The ability to UV unwrap multiple objects manually at the same time also sounds very useful.

And … finally … a better maxscript editor!! Yay :)