Lightmap with 3Dstudio
by Toni Doublet · in Torque Game Engine Advanced · 01/31/2007 (3:20 am) · 16 replies
Hi everybody!
I want to know if it is possible to bake my lightmap on a 2nd UV channel in TSE
I know it's impossible in TGE but is there any solution like a Pixel or Vertex Shader to create my own backing channel
I already try to bake my lightmap on the 1st UV channel and then create a detail map but it seem to be impossible to export my DTS in this config under a 3dsmax environment...
Thanks for your help !
I want to know if it is possible to bake my lightmap on a 2nd UV channel in TSE
I know it's impossible in TGE but is there any solution like a Pixel or Vertex Shader to create my own backing channel
I already try to bake my lightmap on the 1st UV channel and then create a detail map but it seem to be impossible to export my DTS in this config under a 3dsmax environment...
Thanks for your help !
#2
01/31/2007 (2:51 pm)
I suppose you could also write a shader that loaded a second image and blended it on top of the texture map
#3
02/12/2007 (1:24 am)
I think Manoel put it really well. My preference would be for #3 too. Mainly because I think the DTS format sucks.
#4
02/12/2007 (2:00 am)
Out of interest Manoel, why not collada?
#5
Actually, we're using FBX (which is similar to collada) to build a custom polysoup-based interior format. It's working well: collision, culling, dynamic lighting are working well but our lightmapping pipeline still need work, but the results are clearly showing up since the offline-rendered lightmaps are of a far greater quality (ambient occlusion FTW).
Other advantages:
- Knowing exactly how much RAM the lightmaps will eat;
- Using DXT1 compressed lightmaps (they compress very well);
- Using baked vertex colors on some areas (like small objects).
FBX ain't perfect, though. It's data is structured in away that is different from the one used by the GPU, so you need to do some work to get vertex buffers and index buffers out of the file. Right now we are reading the file during load time, but I intend to do an offline converter in the future, and load the data are it'll be rendered from custom files.
02/12/2007 (6:40 am)
@Phil:Actually, we're using FBX (which is similar to collada) to build a custom polysoup-based interior format. It's working well: collision, culling, dynamic lighting are working well but our lightmapping pipeline still need work, but the results are clearly showing up since the offline-rendered lightmaps are of a far greater quality (ambient occlusion FTW).
Other advantages:
- Knowing exactly how much RAM the lightmaps will eat;
- Using DXT1 compressed lightmaps (they compress very well);
- Using baked vertex colors on some areas (like small objects).
FBX ain't perfect, though. It's data is structured in away that is different from the one used by the GPU, so you need to do some work to get vertex buffers and index buffers out of the file. Right now we are reading the file during load time, but I intend to do an offline converter in the future, and load the data are it'll be rendered from custom files.
#6
Yeah, I think that pretty much sums up the benefits very nicely! :)
I did take a look at the FBX format docs a couple of months back and had a thought of making a FBX scene loader.
I think both FBX and Collada are the main formats I'd go after. In fact, if I remember rightly, the FBX SDK actually handles collada? (I seem to remember a discussion with Logan about using the FBX libs from Discreet to handle collada content).
Out of interest, how do you generate the lightmaps? Is it a commercial product you are using? How about the ambient occlusion?
The place I want to get to, is where the engine is capable of producing nicely lit environments, which can have static meshes placed inside, which work with a common format and which are rendered as optimally as possible.
I take your point on transform on load issues with FBX, but lets face it, how hard is it to write a serialiser for your in-engine classes that simply stores a cache'd version of the post-transformed data you got out of the FBX/Collada file. Ideally, you'd have an asset hook that allowed you to reload and re-serialise the data when the FBX file changes.
Anyway, nice work! hope you release it (but I know its a lot of effort and commercially probably not a good move to do so).
02/12/2007 (7:44 am)
Thanks Manoel,Yeah, I think that pretty much sums up the benefits very nicely! :)
I did take a look at the FBX format docs a couple of months back and had a thought of making a FBX scene loader.
I think both FBX and Collada are the main formats I'd go after. In fact, if I remember rightly, the FBX SDK actually handles collada? (I seem to remember a discussion with Logan about using the FBX libs from Discreet to handle collada content).
Out of interest, how do you generate the lightmaps? Is it a commercial product you are using? How about the ambient occlusion?
The place I want to get to, is where the engine is capable of producing nicely lit environments, which can have static meshes placed inside, which work with a common format and which are rendered as optimally as possible.
I take your point on transform on load issues with FBX, but lets face it, how hard is it to write a serialiser for your in-engine classes that simply stores a cache'd version of the post-transformed data you got out of the FBX/Collada file. Ideally, you'd have an asset hook that allowed you to reload and re-serialise the data when the FBX file changes.
Anyway, nice work! hope you release it (but I know its a lot of effort and commercially probably not a good move to do so).
#7
Then, when working on larger structures, we started to hit walls with Gile[s]. It started to become unreliable and the render times got massive on more complex scenes, creating bottlenecks in our pipeline. We decided to modify the code to load from FBX files as well and move our lightmapping pipeline into Maya (which we use for our models).
We are evaluating Turtle for baking lightmaps and occlusion, but we're not certain on it yet (there are a few stability and pipeline issues). But the normal lightmaps are rendered in the engine, using custom shader-based code. It's not a 100% viable solution, since right now it requires shader 3.0 hardware to render them (on lower GPUs a cached version is used) and we do some guesswork to handle indirect lighting. We should either move it into software (like the interior relight) or find a way to render them offline (it might be possible to create a custom Maya shader to render the normals - that would be ideal, since it could deal with indirect lighting).
As for caching, yeah it isn't that hard (we had a partial geometry cache for Giles files), but it's easier to debug and add support for loading more features without the cache for now.
I can't make any promises about releasing this. It plays a big part in our company's future strategy, making it a touchy subject. Also, the code still gets major changes from time to time, the pipeline is not usable for artists without close support. Even so, we'll use it in our next commercial project (alongside with a fixed-function enabled TGEA), and it should mature a lot after that.
02/12/2007 (8:36 am)
Initially, we started our custom object as a Gile[s] loader (Gile[s] is a lightmapping tool, it's cheap and did good results). We downloaded the format specs and wrote a loader, the lightmaps came inside the giles file.Then, when working on larger structures, we started to hit walls with Gile[s]. It started to become unreliable and the render times got massive on more complex scenes, creating bottlenecks in our pipeline. We decided to modify the code to load from FBX files as well and move our lightmapping pipeline into Maya (which we use for our models).
We are evaluating Turtle for baking lightmaps and occlusion, but we're not certain on it yet (there are a few stability and pipeline issues). But the normal lightmaps are rendered in the engine, using custom shader-based code. It's not a 100% viable solution, since right now it requires shader 3.0 hardware to render them (on lower GPUs a cached version is used) and we do some guesswork to handle indirect lighting. We should either move it into software (like the interior relight) or find a way to render them offline (it might be possible to create a custom Maya shader to render the normals - that would be ideal, since it could deal with indirect lighting).
As for caching, yeah it isn't that hard (we had a partial geometry cache for Giles files), but it's easier to debug and add support for loading more features without the cache for now.
I can't make any promises about releasing this. It plays a big part in our company's future strategy, making it a touchy subject. Also, the code still gets major changes from time to time, the pipeline is not usable for artists without close support. Even so, we'll use it in our next commercial project (alongside with a fixed-function enabled TGEA), and it should mature a lot after that.
#8
I did have a look at Giles a while ago and didnt really like its interface. One tool I've been looking at recently is IrrEdit, which is a map editor based on Irrlicht. It seems to be getting some nice tools for Global Illumination lightmap baking and works with plenty of file formats, which is good.
Ideally, I'd like to find a distributed lighting solver that can use multiple machines to speed up the solution (similar to zoners tools for halflife).
Another possible alternative is FSRad, but I havent looked at it yet.
I am also hoping to see if we can bake the lighting from within max, maybe using VRAY or Mental Ray, but I've not seen any good discussions on how to use that in a game engine, so I'm a bit wary of it.
I'll have to have a look at the various solutions available.
Out of curiosity, how did you handle rendering? Did you define all of the materials etc and let the material manager decide on render ordering and batching? Or define your own render path for the scene?
02/12/2007 (8:54 am)
Yeah, I understand completely that this is a commercial asset, so its fine you dont release it. But thanks for the info anyway.I did have a look at Giles a while ago and didnt really like its interface. One tool I've been looking at recently is IrrEdit, which is a map editor based on Irrlicht. It seems to be getting some nice tools for Global Illumination lightmap baking and works with plenty of file formats, which is good.
Ideally, I'd like to find a distributed lighting solver that can use multiple machines to speed up the solution (similar to zoners tools for halflife).
Another possible alternative is FSRad, but I havent looked at it yet.
I am also hoping to see if we can bake the lighting from within max, maybe using VRAY or Mental Ray, but I've not seen any good discussions on how to use that in a game engine, so I'm a bit wary of it.
I'll have to have a look at the various solutions available.
Out of curiosity, how did you handle rendering? Did you define all of the materials etc and let the material manager decide on render ordering and batching? Or define your own render path for the scene?
#9
02/12/2007 (11:15 am)
I'd like to know how well FSRad handles arbitrary geometry (high poly, curved surfaces, etc).
#10
In Maya, we're associating the baked lightmaps manually in the ambient color field of each material. They can't be properly previewed in Maya this way, but it was the fastest way we found to do the lightmap linking using the UI. Seems we'll have to roll out some scripts if we want everything done cleanly. The good thing is that the renderer does support farming, and will take full advantage of whatever monster multi-core computer we throw at it.
For rendering, it was easier than expected. TGEA do makes it a lot easier to get your own stuff rendered properly once you get the procedure down, that's for sure. When the geometry is loaded, it's organized into primitives blocks. Each block knows it's material, vertex buffer and has a GFXPrimitive associated with it, and has a bounding box.
We register all these primitives with a r-tree (which is also used for collision), and during prepRenderImage we do a frustum search on the tree. For each visible primitive a render instance is created and added to the render instance manager as... a RIT_Interior! We then just let the RenderInteriorMgr handle the rest. It renders our stuff without any changes, and with a small modification the RenderTranslucentMgr takes care of rendering translucent lightmapped primitives. And it's all nicely batched to boot.
For dynamic lights, I based the code on the interior's renderLights function, with an added twist: I use sgCanIlluminate to check if a primitive's bounding box can be lit by each light before creating a new render instance for it. That boosted performance for dynamic lights.
There are further optimizations that must be done, mostly doing better geometry batches and implementing a LOD system. I'm also considering using the polysoup resource for collision instead of the Atlas-style tetrahedron hack we're using right now.
Even if this doesn't get released to public, I'm willing to provide advice and help to anyone who's going a similar route, since I find it very healthy for the community to develop alternatives for core features, like the DIFs. Who knows, maybe a robust polysoup-based level/interior implementation might even make it into the codebase.
02/12/2007 (11:43 am)
I know your pain about Mental Ray and baking directly from within the modeling program. There isn't a clear, definite way for getting your lightmaps properly associated with their geometry/materials. In Maya, we're associating the baked lightmaps manually in the ambient color field of each material. They can't be properly previewed in Maya this way, but it was the fastest way we found to do the lightmap linking using the UI. Seems we'll have to roll out some scripts if we want everything done cleanly. The good thing is that the renderer does support farming, and will take full advantage of whatever monster multi-core computer we throw at it.
For rendering, it was easier than expected. TGEA do makes it a lot easier to get your own stuff rendered properly once you get the procedure down, that's for sure. When the geometry is loaded, it's organized into primitives blocks. Each block knows it's material, vertex buffer and has a GFXPrimitive associated with it, and has a bounding box.
We register all these primitives with a r-tree (which is also used for collision), and during prepRenderImage we do a frustum search on the tree. For each visible primitive a render instance is created and added to the render instance manager as... a RIT_Interior! We then just let the RenderInteriorMgr handle the rest. It renders our stuff without any changes, and with a small modification the RenderTranslucentMgr takes care of rendering translucent lightmapped primitives. And it's all nicely batched to boot.
For dynamic lights, I based the code on the interior's renderLights function, with an added twist: I use sgCanIlluminate to check if a primitive's bounding box can be lit by each light before creating a new render instance for it. That boosted performance for dynamic lights.
There are further optimizations that must be done, mostly doing better geometry batches and implementing a LOD system. I'm also considering using the polysoup resource for collision instead of the Atlas-style tetrahedron hack we're using right now.
Even if this doesn't get released to public, I'm willing to provide advice and help to anyone who's going a similar route, since I find it very healthy for the community to develop alternatives for core features, like the DIFs. Who knows, maybe a robust polysoup-based level/interior implementation might even make it into the codebase.
#11
What about ambient occlusion? PRT?
What I've been thinking about, is maybe loading up a Collada/FBX and split it up into a quadtree, then call a PRT process on that quadtree'd mesh to generate a lighting solution. Finally, cache the PRT solution and the quadtree'd mesh.
I'm not sure its a good idea to let the render instance batch the geometry. Surely you are better of batching by shader with some kind of lightmap atlas? Actually, thinking about that, how do you actually generate the lightmaps in terms of unique lumels? Does it have to have no overlapping UV's in the original mesh?
02/12/2007 (4:13 pm)
Did you say you had support for vertex lighting too?What about ambient occlusion? PRT?
What I've been thinking about, is maybe loading up a Collada/FBX and split it up into a quadtree, then call a PRT process on that quadtree'd mesh to generate a lighting solution. Finally, cache the PRT solution and the quadtree'd mesh.
I'm not sure its a good idea to let the render instance batch the geometry. Surely you are better of batching by shader with some kind of lightmap atlas? Actually, thinking about that, how do you actually generate the lightmaps in terms of unique lumels? Does it have to have no overlapping UV's in the original mesh?
#12
02/12/2007 (6:32 pm)
Hey Neto - check your inbox. :)
#13
I got it, the reply might be hitting your inbox soon. :)
@Phil
The render instance manager does batch by shader and vertex buffer (via qsort). It doesn't batch by lightmap, but since the lightmaps are specified per-material on the FBX file, all models using the same material actually use the same lightmap, so that's not an issue right now.
I was a bit sad that none of the baking solutions we tried featured proper lightmap UV generation, so we ended up having to do it by hand. In Maya, our artists create a new UV set, name it "lightmap" (that's the magical word our loader looks for) and use a combination of the Maya's automatic UV tool and UV layout tool to generate non-overlapping UVs. Sometimes we do a few manual tweaks, like increasing the UV area of very small objects to better use the texture space.
I can't show screenshots of the actual assets we are creating right now due to NDAs. But I can show the model I used to test the system (do not mind the GG bump all over the place - it was sued to test if the normal lightmap directions were all OK):
Screenshot 1
Screenshot 2
Screenshot 3
The whole model uses a 512x512 lightmap.
02/13/2007 (4:32 am)
@Ben:I got it, the reply might be hitting your inbox soon. :)
@Phil
Quote:Did you say you had support for vertex lighting too?Yes, geometry without lightmaps is assumed to have baked vertex colors. The shaderGen was modified to support this too.
Quote:Surely you are better of batching by shader with some kind of lightmap atlas?
The render instance manager does batch by shader and vertex buffer (via qsort). It doesn't batch by lightmap, but since the lightmaps are specified per-material on the FBX file, all models using the same material actually use the same lightmap, so that's not an issue right now.
Quote:Actually, thinking about that, how do you actually generate the lightmaps in terms of unique lumels? Does it have to have no overlapping UV's in the original mesh?
I was a bit sad that none of the baking solutions we tried featured proper lightmap UV generation, so we ended up having to do it by hand. In Maya, our artists create a new UV set, name it "lightmap" (that's the magical word our loader looks for) and use a combination of the Maya's automatic UV tool and UV layout tool to generate non-overlapping UVs. Sometimes we do a few manual tweaks, like increasing the UV area of very small objects to better use the texture space.
I can't show screenshots of the actual assets we are creating right now due to NDAs. But I can show the model I used to test the system (do not mind the GG bump all over the place - it was sued to test if the normal lightmap directions were all OK):
Screenshot 1
Screenshot 2
Screenshot 3
The whole model uses a 512x512 lightmap.
#14
Although, its not fully within the interface yet, it seems that they are looking to make it available, so it might be a useful option at some point. Definitely worth investigating further I think.
02/13/2007 (12:23 pm)
One thing that I found the other night, was that Nvidia's "Gelato" GPU based renderer apparently does lightmap baking.Although, its not fully within the interface yet, it seems that they are looking to make it available, so it might be a useful option at some point. Definitely worth investigating further I think.
#15
02/14/2007 (12:38 pm)
That would be very cool. DirectX has some nice utilities like PRT and texture atlas functions, but they aren't open source. It would be awesome for nVIDIA or ATI to set up and make some good tools.
#16
02/14/2007 (1:45 pm)
Yep, I have worked with an Engine which used PRT and some of the texture atlas stuff from DirectX and it did a good job in most cases. There were always cases where things need to be modified in certain ways to make it look 100% like you wanted... but at least you could bake the PRT out to a separate file and easily keep up with what has PRT and what doesn't.
Associate Manoel Neto
Default Studio Name
1) Use a large texture with lightmap+diffuse baked into a single texture (looks blurry, but you could thrown in detail textures using a shader)
2) Modify the DTS structure to store a 2nd uv layer per vertex (you'll also need to modify the exporter for the 3D modelling program you use)
3) Create your own object type which loads from a custom format or from a format which supports multiple UVs (lots of work, you need to roll up many things like collision, culling and so on)
4) Go with DIFs (and deal with the usual limitations)
Our company decided to go with #3 and we're using FBX files. It was quite some work and it's far from complete. I'm also not sure if/when/how it'll be made available to others.