Jump to content
The Dark Mod Forums

Exporting models from Blender into TDM


Recommended Posts

edit: TL;DR: I've tweaked the .lwo exporter to preserve autosmooth angle


When I started writing this post a couple of days ago, it was supposed to be a "please help me, models won't smooth" kind of thing, but as I started taking screenshots and such for a comprehensive view of the problem, the question morphed into a "is there a hack to get .lwo's to export the way .ase's do", then to "how to get the same surface smoothing from Blender as you can get from Lightwave" and eventually to "does anyone around know python and blender enough to fix the export plugin". But then I fixed the addon myself, so it was almost as if there's no point to the thread.

However, while googling around for a solution I stumbled upon a whole bunch of incomplete (1,2) or outright wrong (1,2) information, and whenever the question came up the issue was never really resolved completely. That might be because the problem isn't obvious, since a lot of exported models will actually end up correctly smoothed on export, leading one to believe wrong shading in rare cases is due to modeling mistakes / bad shadowmesh / etc. Point is, having the definitive .lwo smoothing post seems useful.

Identifying the problem:

Here's the mesh. I add an 'edge split' modifier (I use sharp edges while modeling the low poly, so I can uncheck the 'edge angle' option).
I can now apply the modifier(s) and export to .ase (triple the mesh either in export options or in modifiers beforehand). The .ase looks alright in-game:
Now I'll export it to .lwo using this script. Depending on export options, here are the results:
If I also check "remove doubles", I'll lose all of the split (sharp) edges:
(recalculating normals on export can be unpredictable as well, so clean up the model beforehand instead)

Right about this point I start searching for a solution online, stumble upon this and try the renderbump hack. However, all it seems to do is weld all of the vertices back together at runtime and attempt to smooth the whole surface, similarly to "remove duplicates", but with no upper threshold. (to anyone possibly reading this in the future: don't forget to revert your changes to the materials!)

Source of the problem:

At this point I still wasn't sure if it's even possible to get .lwo's identical to .ase's, so I installed Lightwave. Naturally, it took some time to eventually stumble upon Surface Editor (F5), and the "smoothing threshold" contained therein. But then I just had to crank it up to 180 and export to "LWO2". That fixes everything in-game:

So the issue is trivial, I just have to find a way to somehow pass on a smoothing angle through the exporter. However, the "auto smooth" option on the object data tab doesn't seem to affect anything regardless of angle.

Long story short, after some hex-comparison magic, I home in on SMAN block in the exporter script:
So what it actually does is set your smoothing angle to either 90°, 86°(??), or 0°, depending on whether you've chosen "idtech compatible", "smoothed", or neither.

The solution:

Now, I don't know Python and I don't know Blender scripting, so I can't say with full certainty that I didn't break anything. But I did cobble together a version of the script that seems to do the job. Here it is, mirror / do whatever you want with it.

If your mesh has autosmooth enabled, and you've checked "idtech" or "smoothed" on export, your chosen autosmooth angle will now transfer to the surface in .lwo:
I took the liberty of changing the default export options to what seems to suit TDM the best, you can just open the script in notepad and edit them to your taste.

Wrapping up, there are still some mysteries I didn't solve, such as "idtech compatible" models taking up only half the size of models exported otherwise (including from Lightwave itself), there doesn't seem to be any visible difference in-game, at least in TDM. That "1.5 radian" in the code still makes me scratch my head. And I still don't know if the 4-8x size savings over .ase matter for in-game memory at all (but at least I know I won't have to edit the *BITMAPs manually anymore). Even after all this, the .ase still has just slightly better shading, but since the outputs of the exporter and Lightwave itself are now identical, seems safe to say it's as good as it gets.

Edited by chedap
  • Like 3
Link to comment
Share on other sites

Is this model properly unwrapped? It looks so. IMO the best solution would be to use one smoothing group for the final model, and using UV islands to define where you want to have hard edges, along with different smoothing groups but only for baking normals. This way you both save up on vertices (not sure why model DR model viewer also says I have less triangles) and benefit from better shading. In general I try to use as few smoothing groups as I can, so normalmaps can do their work.

Edited by Judith
Link to comment
Share on other sites

Is this model properly unwrapped?

I mean, it's not some masterpiece of packing and alignment or anything, but it does its job:


(on the right: same mesh (via .fbx) and textures (legacy specular shader) dropped into unity)


If I unwrapped the whole thing like you say, without any splits, the normal map would have to compensate for the entire mesh.



In theory, the engine then applies the normal map on a fully smoothed mesh and flat surfaces go back to being flat, but in practice it can't quite hit the mark:


Note how the flat surface now has some waviness. Didn't get the screenshot, but the holes look bad as well. Maybe I did some mistake along the way, but I think I understand the process enough to at least avoid the obvious ones.

Also, I don't know how/if TDM creates mipmaps for .tga normalmaps, but there is another known problem with entire meshes using averaged normals: when compressed, the skewing will get exaggerated, so even with a perfect rendering process there are pitfalls.

Edited by chedap
Link to comment
Share on other sites

Yeah, the first setup isn't perfect, but doesn't waste the texture space as much as the second one. Besides, it doesn't match SGs you set up on the model in the first post, if I see correctly? Btw. you can use uv mirroring for the same parts that aren't in view simultaneously. Anyway I'd go back to the first setup and use SGs on the low res model to define hard egdes for baking normals, that should have some effect too. Averaged normals is a problem regardless of engine, AFAIK. In 3dsmax I switch between using cage and averaged normals to see what looks best.

Edited by Judith
Link to comment
Share on other sites

Apart from one extra uv seam along the horn, sharp edges match uv islands exactly. By SGs you mean max smoothgroups, right? Unless you bake with explicit normals, smoothgoups/hard edges don't affect baking, and it's a bad idea to bake with explicit normals anyway - in case of distortions it's always better to just subdivide the low-poly mesh (without smoothing) a bunch of times before baking. In max, you'd select the faces and press "tesselate" iirc. Try it, you probably won't tinker with the cage ever again.

Link to comment
Share on other sites

Yup, I use SGs for short :) If I'm not mistaken, you have hard edge on that round part of the base of the anvil in the first post, while UVs have that base stitched to the rest of the model (in the second set of UVs).


In 3dsmax cage still has important uses, i.e. when hi-res mesh intersects the surface of your low-res mesh, averaged normals will often will give you errors. It's also useful for stuf like floaters, as averaged normals tend to skew them quite noticeably. I use low-res mesh subdivisions mostly when I encounter wavines, typical example being low-res cyliders.


In general I follow guidelines found here: https://www.dropbox.com/s/tps4jagkzbemg9w/A%20Practical%20Guide%20On%20Normal%20Mapping%20for%20Games.pdf?dl=1

Edited by Judith
Link to comment
Share on other sites

Figured I'd post a useful batch script as well. This one is unrelated to Blender, but I don't know where to post it instead.

It creates a generic material definition based on the name of a file you've selected, then moves the related textures from your current location to your FM folder.
Download the .bat and put it anywhere on your PC. Type "shell:sendto" in the explorer address bar. Put a shortcut to the batch file you've downloaded here. Now you can right-click any file, "send" it to the script, and if all goes well, your material is immediately ready to use.

Caveats: made it for personal use, and the whole point is to save time, so it won't ask anything, you should change path vars beforehand (just right click > edit). It won't give warnings about overwriting an existing .mtr. It handles spaces in filenames and paths, but you probably should avoid them anyway. It will automatically add normal/specular stages if it finds _local.tga or _s.tga in the same folder.

Working with just .tga's is (imo) easier while working, but you should convert them before shipping the FM. If you prefer to work with .dds/.jpg right away, you should edit that into the script. And don't forget to eventually change the surface type (wood by default).


In general I follow guidelines found here

Well, that guide mentions same kind of non-deforming tesselation I meant. It is especially useful when dealing with skewed floaters.

Did anyone manage to get custom normals working in TDM?

Per-vertex? I don't think they show up in TDM, but they do get exported to .lwo as a "vertex normal map".

Link to comment
Share on other sites

I don't quite follow what's being said here, but when I want a face to have sharp edges, I select it and press Y to separate its vertices (which could be thought of as the opposite of remove doubles). When exporting the .lwo, I have the 'smoothed' box is checked, and 'remove doubles' and 'recalculate normals' are unchecked.

Edited by R Soul
Link to comment
Share on other sites

Yes, you're effectively splitting the edges around. Before I tweaked the exporter, checking "smoothed" on export would result in 86° smoothing threshold on the rest of the surface (parts you haven't split). Which is fine for a lot of cases, but in edge cases like with the anvil, thats not enough: you'd want 180°, otherwise there will be unintended sharp edges.

It's not just for edge cases though. Before, you had to split the edges manually, otherwise your only choice of autosmooth was 86° or 0° with nothing in-between. However, since the custom exporter will now respect your autosmooth angle, it's more wysiwyg: for simpler objects it might be enough to just set an appropriate angle inside Blender, with no manual splits needed.


edit: I realized I assume some not-too-obvious blender knowledge on the part of the reader, so here's a quick rundown on smooth shading. Once you switch from default flat (faceted) shading, it'll attempt to smooth the whole mesh regardless of angles and hard edges. To make use of those you'll have to turn on autosmooth. Now you can mark edges as sharp (ctrl+e) and they will display as such in blender. However, they will not transfer to TDM, so you'd need to split these hard edges before export ('edge split' modifier).

Edited by chedap
Link to comment
Share on other sites

Even after all this, the .ase still has just slightly better shading, but since the outputs of the exporter and Lightwave itself are now identical, seems safe to say it's as good as it gets.


Hello, thank you for this updated script. On this point, in particular, is this what you mean?






Right side is the .lwo, left is the .ase. I've overridden the materials to something more consistent than default textures for this model. It must be something to do with the edge or face normals, but I'm not knowledgeable enough to guess. It's a little irksome, but it's near invisible with real, detailed textures.

My FMs: The King of Diamonds (2016) | Visit my Mapbook thread sometimes! | Read my tutorial on Image-Based Lighting Workflows for TDM!



Link to comment
Share on other sites

Without seeing the geometry that's a bit too non-specific to get anything out of.

What I meant is that if you open both images (1, 2) and switch between them, you'll notice that a thin triangle at the horn's base gets smoothed slightly better in .ase. It's a fairly extreme case though.

Link to comment
Share on other sites

Well I've run into a snag and need to report it. chedap, I know you just fixed up the existing script, but this is related to smoothnig, so perhaps you, or someone else who works with Blender can offer any ideas on what's causing this.




This is what's happening to one of my models after exporting. Two are tiled together, and you can clearly see that the smoothing is going along the triangles' edges instead of being constant. (it looks the same in-game, but this is a screenshot Springheel took in Lightwave). In Blender, the problematic part looks just fine:





I tried all combinations of export options, recalculating the normals (of course), even made a custom plane inside Blender (since this is a .lwo import) and that exported with the same problem, too. So, it's got to be something with the exporter... .ase, in the meantime, has even normals.

My FMs: The King of Diamonds (2016) | Visit my Mapbook thread sometimes! | Read my tutorial on Image-Based Lighting Workflows for TDM!



Link to comment
Share on other sites

Tried replicating: a/b, three spans are separate models. There's a bit of a step in shading at the bottom-right junction, and it isn't there with .ase (a/b). Seems to be related to triangulation, and is only visible under certain lighting. But it's definitely not nearly as severe as in your case. Your example isn't capped at both ends or anything, right? Can you post the mesh? Feel free to PM.

Link to comment
Share on other sites

  • 2 weeks later...

Investigating the problem raised by Spooks has lead me down a rabbit hole, but I'm not coming back from it emptyhanded.


So, the good news first: I've rewritten parts of Blender .ase exporter to expand its functionality and make it work better with TDM.

Get the updated version here.

Main changes are:

Vertex-per-face normals support. This means you don't have to split your sharp edges anymore, and makes custom vertex normals a viable workflow.

Material bitmap assignment is now based on the material's name instead of image filepath. This possibly breaks workflow with some other engines, but for us this means that as long as your material name in Blender matches a valid TDM material, you won't have to edit anything manually. Get R Soul's material manager to have the name match a valid material automatically.

File size decrease by about 20%, achieved by only storing unique vertex UVs. This doesn't affect anything visually, it's just a slight data rearrangement (20% compared to using the older Blender exporters, 3dsmax already exports .ase's this way). UVs for meshes with "collision_" and "shadow_" in their name are not stored. I've cleaned up file formatting to remove whitespace spam and generally be more max-like.

Extra options on export: you can now automatically apply modifier stack or separate the meshes by material. The latter is a requirement for TDM, since submaterials are not supported. But in case they ever are, I've added a missing brace to enclose the submaterial block.

• All export-related operations are now done on temporary clones of the objects being exported, so you can continue working on a model afterwards without triangulation getting in your way.



- It appears that TDM doesn't take smoothgroups into account, all it cares about are the vertex normals. And since previously the exporter was effectively averaging the normals on all the vertices, if you wanted to have sharp edges on your mesh, your only choice was to split them before exporting. Vertex normals are now based on how the model is smoothed in Blender, so hopefully it's wysiwyg. I'm also hoping I'll get it to work both ways: have an importer get it back into Blender with no data loss.

- Smoothing groups are still derived from sharp edge "islands" - meaning, unlike 3dsmax, multiple smoothgroups per face are not supported. Again, this shouldn't matter to TDM at all since they seem to be ignored, but combined with custom normals it might look wrong in other engines.

- I called custom normals a "viable workflow", but don't expect miracles. Because of the way the engine decides whether a light contributes to any particular face's shading, you get these. A sphere is almost the best case scenario compared to a 45° bevel, so if you couldn't wait to use those, it's only going to work half the time. Could work if you're careful with the lighting though.

- At the moment, Blender likes overwriting your custom vert-per-face normals. In particular, during triangulation. There's no nice way around it: either you triangulate the mesh before hand-tweaking the normals, or you data-transfer them onto a triangulated mesh from a non-triangulated clone. Either way, you'll have to triple before exporting.

- I didn't know a thing about Python a week ago, so it's the usual: no warranty, etc. I don't know the proper etiquette for releasing such things (and don't really care). This is based on the exporter made by Mike Campagnini and Richard Bartlett (our very own rich_is_bored).

Edited by chedap
  • Like 3
Link to comment
Share on other sites

On to the bad news.
From what I currently understand, it is impossible for .lwo models to be smoothed independently of the way they are triangulated. The effect is hard to notice when a detailed material is applied on top, but once replaced with a flat smooth one, it becomes easier to spot (though still not obvious):
This is (most likely) caused by vertex normals being derived from face normals. In the image above, vertex V1 derives the direction of its normal by averaging the normals of faces F1, F2, F3 - leading to it being skewed towards F2 and F3. Assuming the triangulation maintains the same direction, adjacent quads compensate for this skewing on a continuous surface. This means most models will look mostly right. However, where it will become visible is at the edges, where there are no faces to balance out the smoothing, and especially whenever such edges meet a/b.

I still can't claim to understand exporter script completely, but vertex and vert-per-face normals seem to actually get exported to .lwo file*. However, they don't seem to have any effect whatsoever, not in TDM, not in vanilla Doom3. And yet, in both, vertex normals from .ase files are being read and applied correctly**.

Meshes most affected by this are modular pieces that have smoothed shapes at the junctions: pipes, walls with railings, vertically-tiled columns, etc. However, EVERY mesh that has any sort of edge splits or holes is affected, just to a lesser extent. Bottom line is: while .lwo's are "good enough" once you apply the materials and light the scene, .ase seems to be the more reliable format. I'd still like to learn how the formats differ in performance impact, if at all. If it's just a console command away and not deep in the scary stuff, please let me know.

* Previously, in the first post of this thread I claimed there was no visible difference between "smoothed" and "idtech-compatible" exported .lwo's. While this is true, vertex normals WILL NOT get exported to an "idtech" file at all (leading to the decrease in file size). Making it the default option was a bit hasty on my part, but, to reiterate, currently for TDM it doesn't matter.
** If I apply "renderbump" parameter to the material, the engine will weld all of the vertices together, average all of their normals (discarding the ones from the file). This will bork .ase smoothing and make it look
identical to .lwo.

  • Like 4
Link to comment
Share on other sites

I shall be testing these with some moderately heavy tree models Im working on, and Im grateful you were able to reduce ASEs size, since it was always my favourite format (maybe because it was my first, and is always reliable). Sadly, they have a tendency to become exponentially big when the tris count increases, so going for LWOs was basicly a necessity (they seem to create smaller files). Never thought about a performance difference between them. I wonder if its a noticeable effect...


Either way, thanks a lot for your work and the care you are putting on those normals issues.

Edited by RPGista
Link to comment
Share on other sites

You made tremendous work here, no doubt about that.



Bottom line is: while .lwo's are "good enough" once you apply the materials and light the scene, .ase seems to be the more reliable format.


I've been working with .ase format exclusively because max doesn't support .lwo. I haven't encountered any problems with it, TDM recognizes max's smoothing groups as it should, although I'm doing my best to use just one SG and leverage unwrapped normalmaps fo better look. The downside is size of the models, as it grows expotentially with more polygons per model, but I haven't encountered any negative impact from that. First, people should have like 2 GB VRAM cards by now, and this generation of of GPUs doesn't go below 3 GB, so you should be able to use both .ase and 2k textures everywhere, without much worry. Second, .ase has very nice compression ratio in .pk4 package, even with the good old deflate method (the only one recognised by the engine).

Edited by Judith
Link to comment
Share on other sites

TDM recognizes max's smoothing groups as it should

Try editing them manually after the mesh is already working in-game: set all SGs the same where sharp edges should be, or set some differently on a completely smooth surface. From what I tried it doesn't change how it looks at all. The actual part that seems to matter is these. Max bases them on SGs, theyaren't the averaged normals, though I'm not sure they are verts-per-face either.

First, people should have like 2 GB VRAM cards by now, and this generation of of GPUs doesn't go below 3 GB, so you should be able to use both .ase and 2k textures everywhere, without much worry. Second, .ase has very nice compression ratio in .pk4 package, even with the good old deflate method (the only one recognised by the engine).

See, that's why I'm saying I'm curious, the fact that the archive is compressed doesn't at all mean the models in the memory are. And vice versa, the fact that .ase files are so big may also be irrelevant once the model is loaded and processed once. I kind of know how engines handle texture compression, but I've not a clue about models. Also 2GB seems like an overkill when TDM runs on a 512MB laptop cards. I get what you're saying, technology moves etc, but in a hypothetical case where one could choose to convert hundreds of .lwo's to .ase for slightly better shading and a 800% memory imprint, let's say it's debatable.

Edited by chedap
  • Like 1
Link to comment
Share on other sites

Yeah, I agree. In my case, I just have no choice but to use .ase. The thing with better shading is kind of nice bonus, although you're right: while I can control SGs via max EditPoly options, EditNormals modifier has no effect, whether I change normals per vertex or polygon. As for potential memory problems, Unreal engines (2, 3) used .ase for years, so their impact must be manageable. Especially since those engines use lightmaps, so they require even more texture memory. For now can I only suspect that TDM should handle that pretty well too.

Link to comment
Share on other sites

This might be a dumb question but is that edge merged or disconnected from the other Spooks? Cause that shouldn't happen if that is one (not two) edges.

Modeler galore & co-authors literally everything



Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recent Status Updates

    • The Black Arrow

      I was playing Skyrim, got bored fast. Got back to The Dark Mod just for one mission, played "Somewhere above the City" which is not really a great mission but still good, as in above-average.
      My biggest regret is living in this country, where there's a heat wave, I am sweating at 20c and I really wish for temperatures below 5c.
      · 10 replies
    • Skaruts

      Is there something wrong with the forums lately, or is it my browser? I've been having trouble formatting posts, and just now I couldn't format anything at all.
      I'm using Vivaldi.
      Usually I have to: select text, click bold, nothing happens, select again, click bold, then it works. 
      Same for other stuff, like creating spoilers, bullet points, links. Nothing works the first time. 
      · 1 reply
    • STiFU

      Back from a spontaneous 1-week trip to Lanzarote with wife and son. I hope beta testing has been going well...
      · 1 reply
    • datiswous

      Whenever I eat fried chicken these days I think of this scene in The Black Mage..

      · 1 reply
    • Mortem Desino

      Even though I've been absent a long while, I still find myself dreamily wishing for the free time to do TDM mission development. When working on new research projects I'll find myself involuntarily thinking, "hee hee this could be a fun texture or readable or bit of map architecture." Or I find myself absentmindedly responding out loud to odd noises with a drunkguard-like "must've been rats!"
      · 3 replies
  • Create New...