Home General Discussion

Help people with normal map baking methods?

I'd like some help from the community, if you have a minute!



Could you bake normal maps from these models in the software you're familiar with? 
  • 3ds Max [done]
  • Maya
  • Blender
  • Substance [done]
  • Toolbag
  • 3D-Coat
  • Cinema 4D
  • Houdini
  • Modo
  • Xnormal [done]
  • Knald
  • (others?)

The intent is to show the baked result in a glTF binary file (GLB), viewable in Babylon.js Sandbox.

How To Bake

  1. Download a zip for the format that works best in your app.
  2. Import the models into your app. Make sure to preserve the vertex normals, and the UVs.
  3. Bake from BoxHigh into each of the three low boxes.
  4. Bake to 512x512, as a 24bit PNG. 
  5. Make sure gamma is not applied, it must be saved in Linear color space.
  6. Apply the baked maps to your low boxes, using a material with a white basecolor, 1.0 metal, and 0.5 roughness.
  7. Screenshot them in your app's realtime viewer. If possible use this HDR for your lighting.
  8. Export to GLB, and include tangents/bi-tangents if you have that option. If you can't export, share the baked PNGs.
  9. ZIP your GLBs or PNGs, and screenshots, and drag-n-drop it into your post reply. 
  10. Please note the software version number for the baker you used.
  11. Please indicate what license you want to use (see below).

The Box Models

The models (attached in ZIPs at the bottom here, choose whichever format works best in your app):

  • boxhard = cube with hard edges
  • boxsoft = cube with soft edges
  • boxbevel = cube with beveled edges and face-weighted normals
  • boxhigh = subdivision surface model to bake normals from

License

I will need you to release your output with a license, so I can share it in the repo. I'd recommend either using CCBY4 (attribution required, include your name for the attribution) or CC1 (public domain). I donate my work as either of those two, pretty much depending on how much work I put into it, if it takes me a lot of work or I do it on behalf of my employer then it's CCBY4. But if it's a quickie I just do public domain.

I'll also need the software version number you used to bake it with. For example, 3ds Max 2024.2.

Results

I'll compile all the results and publish them in the glTF Sample Assets repository, as a public resource for people to learn from. The first step is here, with maps baked in 3ds Max with V-Ray: https://github.com/KhronosGroup/glTF-Sample-Assets/pull/88

Why do this?

By the way, donating models like this has strongly helped my career. People across 3D industries know of me directly from my efforts adding to these repositories, which in turn benefit the whole 3d ecosystem of tools, renderers, and content makers. So, it's worth the time, in my opinion!

Thanks a ton!  =)

Replies

  • Fabi_G
    Options
    Offline / Send Message
    Fabi_G insane polycounter
    Hi! In Blender, baking to boxsoft and boxbevel in their original state, the resulting the normal maps don`t look as intended. Blender seems to ignore the modified vertex normals when baking. If I discard the custom split normals data on those meshes, they become hard shaded. If I set their shading to auto smooth with 180° (so essentially smooth), the baking result is more as expected, without the visual of the mesh changing. Is it ok to make that modification? But I might be missing something - happy to learn.

    And is it ok to bake boxhard using a cage?

    Attached are my Blender 4.0.2 bakes as gtlf files. I included both unmodified (unintended normal map) and modified soft and beveled boxes. Boxhard was baked using a cage. Let me know if it works.
  • Eric Chadwick
    Options
    Offline / Send Message
    Thanks for these!

    The original vertex normals are very important for all three, especially for boxbevel because it has face-weighted normals. However, if you can recreate the vertex normals in your software, feel free to do so.


    Your modified GLBs look great. Vertex normals look like they're aligned the right way... hard, soft, bevel:


    It looks like Blender uses Mikktspace for the tangent basis and OpenGL for the normal map standard (red +X, green +Y), which is great because glTF also uses these.

    Thanks again for the tests, this is great!
  • pior
    Options
    Offline / Send Message
    pior grand marshal polycounter
    Nice initiative. Please make sure to show the actual UV layout (with overlaid wireframes) in the final presentation, especially for boxhard ...
  • Eric Chadwick
    Options
    Offline / Send Message
     Thanks! The full asset has snapshots of the UV layouts included.


    Plus there's a written info about the layouts in the readme:
    1. Go to https://github.com/KhronosGroup/glTF-Sample-Assets/pull/88
    2. Click on Files Changed, then the three dots, then View File.
    (these steps are only needed before the submission is finalized and approved)


     
  • myclay
    Options
    Online / Send Message
    myclay polycounter lvl 10
    I get really wacky results + no self shadowing as in your results.
    For now it´s just a video since I obviously have done something wrong !?
    (previewed ingame)

    https://www.youtube.com/watch?v=Wvr2AYAcr6g

    Mari 7.0v1.
    Is there even a gltf exporter in Mari?
    Hard edges are visible on the hard mesh.


    Toolbag 4.06;
    Spheres look unlike Spheres and seem clipped in Bevel and Hard.

    No idea on the export as gltf part since Toolbag gives some cryptic information;
    texture quality settings are Full, High, Medium, Low as well as Metalness Threshold set to 0.8.



    In both (Mari and Toolbag) results, on one side for Bevel and Hard, the normals Y is the opposite. Is this intentional?
    I only did the bake procedures, no other changes done whatsoever. Only used 16bit.
    couple questions;

    Mari has no obvious way of exporting a gltf, would the textures alone be enough?
    Is the 24bit export mandatory? I can only generate 8, 16 and 32bit images.










  • Fabi_G
    Options
    Offline / Send Message
    Fabi_G insane polycounter
    Hi! Attached are box bakes created with xNormal v3.19.39669[x64] and Substance3DPainter v8.3.1, exported through Blender.

    In xNormal, didn`t find an option to save as 24bit, just 32 bit (alpha channel). I used the default settings mainly, except for BoxHard, which I baked with a cage, because the use average normal setting resulted in a normal map fit for the smooth shaded lowpoly. Antialiasing was set 1x.

    Painter: left everything pretty much default, except adjusting the ray distances: average vertex normals, antialiasing none.

    Bakes done to the best of my knowledge, don`t want to spread misinformation or misrepresent a baker, happy to be corrected/learn if there is something off.
  • Fabi_G
    Options
    Offline / Send Message
    Fabi_G insane polycounter
    @myclay Hi! I assume to remove the normal map clipping of the protruding sphere shapes in Toolbag, you would have to increase the cage offset, ensuring it incapsulates the high poly.

    In regards to the 24bit, my understanding is that it's consistent with the 8bit export option in some applications (8bit per r, g and b channel, resulting in 24bit total). At least when I double-checked the properties of the exported normal maps in the Windows explorer, it said 24bit (except for the xNormal ones, which are 32bit, because of the included alpha channel I imagine).
  • Eric Chadwick
    Options
    Offline / Send Message
    Thanks for the examples!!

    Right, 24 bits per pixel (bpp) is the same as 8 bits per channel (bpc). It's confusing since some apps don't specify when it's per-channel vs. per-pixel. 
    • 8 bits can mean either 8 bits per channel (3 channels = 16.7 million colors, JPG for example), or 8 bits per pixel (1 channel = only 256 colors, GIF for example).
    • 16 bits can be 16 bits per channel (3 channels = 48 million colors, commonly used for displacement maps or normal maps) or 16 bits per pixel (1 channel = 65536 colors, not used very often at all).
    • 24 bits always means bits per pixel, 16.7 million colors, which is the same as 8 bits per channel, so that's easy.
    • 32 bits can mean either 32 bits per channel (4.2 billion colors, often used in film compositing), or it can mean 32 bits per pixel (4 channels, 16.7 million colors + 256 grays for alpha).

    If your export options are only 8,16,32 then that likely means bits per channel, so in our case 8 would be the right choice (8 bits per channel = 24 bits per pixel).

    You can just share the baked maps, as 512x512 24bit PNG.
    As Fabi_G mentioned though, you'll need to fix the clipping first.

    Which game engine is shown in the Youtube video? If you have glTF files, the best bet is to drag-and-drop them into the Babylon.js Sandbox.
  • Eric Chadwick
    Options
    Offline / Send Message
    The results so far, in Babylon.js Sandbox. Pretty good, we knew soft edges would be problematic in most cases.

    However, I think recreating the normals in Blender might have altered the bakes. I've attached more formats for the raw meshes: FBX, GLB, and the original OBJ. Choose whichever works best in your app. You just want to make sure to use the existing vertex normals, and existing UVs.




    Thanks again for your help, this is great!
  • pior
    Options
    Offline / Send Message
    pior grand marshal polycounter
    Heya -
    Without even attempting to understand the reason(s) why, I find it odd that all the "BoxSoft" results shown in the above picture are all showcasing incorrect shading (since the faces should appear completely flat, yet they all display some amount of shading artefacts). So perhaps it could be interesting to also show the results as displayed in the native environments things have been baked in (like for instance the Blender Eevee viewport, or the Toolbag viewport), even if it is just as temporary screenshots to help with debugging.
  • Fabi_G
    Options
    Offline / Send Message
    Fabi_G insane polycounter
    Happy new year!
    The issue I encounter when importing and baking the boxes in Blender, is that the shading is stored as custom split normal data. If I were to remove the data, the underlying shading is hard (Auto Smooth 30°). During the bake the custom split normal data gets ignored, which is a nuisance. When searching for the issue, I came across similar reports. Am I missing an import option? Any idea how to work around this? Maybe you, @pior (or anyone else)? Would transferring the original mesh normals with a data transfer modifier make any difference? Comparisons of normal map applied in Blender and Sandbox below.

    Some screenshots to illustrate:
    BoxSoft imported - Auto Smooth 30°, Custom Normal Data


    original BoxSmooth baked - custom split normal data is ignored


    I set the Auto Smooth value to 180°, all smooth mesh, when baking the normal map is now as I would expect.


    Closeup of BoxSoft with normal map applied:


    The gltf export settings I set.
    Notable changes: ticked apply Modifiers (although the object uses none), ticked Tangents, increased Image quality from 75 to 100, disabled animation. 
     

    The result in the sandbox, the shading surely looks different compared to the one Blender.

    Apologies for the image heavy post :sweat_smile:
     Let me know if you have any ideas what to do differently. Attached zip contains gltf file and normal map.
  • pior
    Options
    Offline / Send Message
    pior grand marshal polycounter
    Hi there Fabi, Eric - personally I am getting this out of a bake with a manually defined cage, done on a freshly imported unmodified boxsoft with the "custom split normals" left as they were on import therefore overriding the default 30 degrees smoothing. That's blender 3.1.0.



    From what I understand/guess, Blender is not making any decision about the state of its own flag for an object being set to "soft" or "hard" on FBX import, hence (likely) setting as off. And since smoothing is 30 by default (probably following a request from artists ?) this result in the model becoming facetted as soon as the Custom Normals Data is deleted. (Still not sure why they still call it "Custom "Split" Normals Data" BTW, as the "split" part makes no sense to me).
    I think it would be much more clear for the "smoothing angle" to have a more explicit UI, perhaps displaying "undefined" as opposed to a a grayed out 30 by default. But I guess there are justified reasons for this current UX.

    The resulting shading in motion for this boxsmooth bake : 

    I think it's great that at least the results are internally consistent when displayed in the native Eevee viewport ; but loading this model+texture re-exported from Blender as .glb in the provided sandbox does look wrong (for lack of a better word). So there's definitely something suspicious going on somewhere between the Blender GLTF exporter, and what the sandbox does with it.

    If anything, the fact that all Boxsoft bake results from the various tests so far all have shading issues would logically indicate that the problem likely comes from the sandbox itself, or perhaps the GLTF format, or the various importers/exporter skipping something ...


    [edit] I've since then tried about 6 or so various GLTF viewers and none of them displays this one specific Blender export properly, all showcasing some slight bending on the faces of the cube, that should be perfectly flat.

    Is there an official GLTF baker out there ?
  • Fabi_G
    Options
    Offline / Send Message
    Fabi_G insane polycounter
    Hi, thanks for your bake and comment @pior. Following your steps, I baked to the original BoxSoft with a cage in Blender 4, sadly with same result as before. To double check, I then downloaded Blender 3.1, baked highpoly to un-modified BoxSoft - and it looks good! This makes me assume things in that regard have changed between Blender versions, for the worse sadly imo.

    Bake with cage in Blender 4


    Bake with Blender 3.1


    After this test, I went ahead and baked the unmodified boxes with Blender 3.1.2 and exported as gtlf files, to be found in the attached zip (+ separate normal maps).

    Edit: Added Painter BoxBakes: Loaded the fbx directly in Painter and baked, setup material and exported in Blender 3.1.2. Zip also contains separate Normal maps.
  • Eric Chadwick
    Options
    Offline / Send Message
    I wonder why you're using the Auto Smooth option in Blender? That would seem to be overwriting the incoming vertex normals? 


    About synching:

    The glTF specification says renderers should use MikkTSpace tangent space with the OpenGL X-right Y-up convention to render a model with normal maps on it. Which means the baker needs to also use MikkTSpace X-right Y-up when it creates the normal map.

    3ds Max can be set to use MikkTSpace, Blender defaults to MikkTSpace since version 2.57, and xNormal defaults to it since version 3.17.5.

    However, each baker has other differences in rendering which will not guarantee a perfect synch in arbitrary realtime renderers. Morten talks about that here. Each baker has its own method to shoot rays from the low to the high for example, there's not a single well-defined method for this. The baker has to make a new averaged cage to bake the boxhard mesh, since it has split normals. So the directions of those rays are likely a bit different between bakers.

    There is no single "approved" glTF baker; it is an application-independent specification. There is (supposedly) a reference renderer in the glTF Sample Viewer, and even though the Khronos Group funds its development there are unfortunately many problems with this renderer, and development has remained fairly slow. Babylon.js Sandbox is the closest I've seen to an accurate renderer.

    Also the BoxSoft example is an extreme case, not a production asset. Artists should know not to build their meshes like this because there are likely to be errors. Both in synching, and with increased errors in compression from those extreme gradients. It's good to have as a stress test, an illustration of what not to do and why, as it's not meant to resolve itself perfectly. Artists should be using hard edges, or bevels and face-weighted normals.

    Screenshots:

    I agree it would help to screenshot the native realtime renderer, since each baker is supposedly synched with it's native renderer.

    As a start I've captured screenshots in several glTF renderers, in the \screenshot folder here: https://github.com/KhronosGroup/glTF-Sample-Assets/pull/88/files#diff-1032f75f08f1d2ba7261d67ee2e785eb9a9fbcdde529ce3f55ab7dfe17f3f3d2 

    Gamma

    Gamma is also really important. You need to make sure the normal map is baked and saved in Linear color space, and it must also be set to Linear when loaded in the material on the low-res model. The last Blender screenshot has a flat view of the normal map at lower left, and that's showing with Gamma 2.2 which is bad. The thumbnails above that are showing Linear though.

    Here's a visual example of gamma:
  • pior
    Options
    Offline / Send Message
    pior grand marshal polycounter
    Heya Eric,

    The Blender terminology is a bit unclear, probably coming from earlier legacy development. "Autosmooth" simply means that smoothing is applied to the object with an optional threshold for hard edge shading from 0 to 180 degrees (30 being the default). First and foremost this requires the model to being flagged as "smooth shaded". And this "Autosmooth" shading does respect explicit hard edges manually marked as hard.

    Therefore a regular game asset produced in Blender would have "Autosmooth" enabled and set to 180, with manually marked hard edges where needed. "Custom Split Normals" wouldn't not be needed, since the shading and hard edges all derive from the aforementioned Autosmooth setting and/or manual hard edges. But locked "Custom Split Normals" would become relevant as soon as shading information is being transferred from one model to another (for instance for neck seams and for props with destruction splits). In a sense that's similar to the green/yellow normals states in Maya.

    When an asset is imported from an external source (FBX or GLTF) into Blender, it needs to have its normals and tangents read from file. Hence "Autosmooth" being greyed out, since "Custom Split Normals" are being taken into account.

    Thankfully (at least in Blender 3.x), Boxsmooth behaves exactly the same baking-wise if left as is, or if manually set as 180 autosmooth with hard edges, since the hard edge data is being properly read.

    It's still surprising to me that GLTF (and the various viewers) don't seem to have a reference point allowing this extreme case, when various internal bakers/renderers do. I'll run the Blender boxsmooth case through UE4 later to see if it can be imported in there without glitches.

    (The Blender texture preview is certainly misleading, but the gamma calculation is correct and very explicitly set in the texture node. There's an added level of complexity coming from the fact that Blender doesn't allow input on this setting as long as the texture has not been explicitly embedded into the scene or saved out to disc. You can see this two different states by looking at the screenshots provided by Fabi and myself. In one case the gamma setting of the texture node is editable, and in the other it is greyed out. Neither is right or wrong, they are just two different states of the baking process really.
    The TLDR is that the "unnecessarily corrected" preview of Blender normalmaps isn't as problematic as it may be usually in other contexts. It doesn't mean that the texture is being badly processed - from what I understand it's just that the texture preview does color correction within its own UI/window, which is *not* indicative of what the texture node itself is doing).

  • Eric Chadwick
    Options
    Offline / Send Message
    OK I've updated the first post to include instructions, and attached ZIPs for different mesh formats. Hopefully this helps.
  • pior
    Options
    Offline / Send Message
    pior grand marshal polycounter
    Here's some more data FWIW. The pipeline I am currently the most familiar with involves bakes in either Blender or Toolbag3, for a display in UE4 and UE5. So here is the result of the Boxsoft blender bake in that context (obviously imported with Tangents and Normals read from file). The shading is ever so slightly different between SMs and skelmeshes, with skelmeshes being IMHO acceptable (albeit just a little bit warped), and static mesh looking a tad worse, probably requiring some extra work to be flawless (hard edges, bevels, and so on). A small but noticeable difference. There's also a noticeable mysterious shading seam appearing on the top face of the skelmesh version which would makes that one asset not usable. Hence neither would be acceptable without some reasonable extra work making them less extreme cases.
     UE4 doesn't seem to have a GLTF importer by default hence these were imported from Blender FBX exports.




    This is of course a bit of a tangent (!) since these results are not shown in the intended GLTF sandbox, but I think it does have some importance still, since at the end of the day people will want to have their assets in game.
  • pior
    Options
    Offline / Send Message
    pior grand marshal polycounter
    Oh the irony - after enabling both GLTF import plugins available and dropping in a Blender-baked and -exported GLTF (defaulting as static mesh) and doing the necessary texture re-plugging (as the importer assigned some nonsensical texture presets by default) ... the result of a Boxsoft bake is perfectly flawless, with flat faces appearing perfectly flat.





    It's so pretty !



  • myclay
    Options
    Online / Send Message
    myclay polycounter lvl 10
    @Eric Chadwick
    @Fabi_G
    thank you both for the explanations and help!
    here are the output files, CC0 for Mari and Toolbag.
    Baked Normalmaps.rar

    The video was just the provided meshes imported and baked textures slapped on it.
    Gameengine is Godot. As of now webexport is complicated since it requires a lot of necessary elevated sandboxing to let projects run on the web.
  • Eric Chadwick
    Options
    Offline / Send Message
    Congrats @pior w00t! Can you share the GLB files? Also I wonder what happens if you disable exporting with tangents/bi-tangents? That would be a good test of Unreal shader's ability to generate proper MikkTSpace.

    @Fabi_G and @myclay Thanks for the updates!

    I thought it would be good to make direct comparisons, so I'm swapping out the baked PNGs into my existing comparison scene, and making screenshots in Babylon.js. Also, I had to disable "Horizon Occlusion" in Babylon since this only applies to the normal maps and makes it harder to compare to the boxhigh. For Mari7 and Toolbag and V-Ray I had to flip the green channel, because glTF uses the OpenGL convention (green/y = up). If you open in the Forum "lightbox" view, you can arrow between them to compare, which is nice.

    None of them are 100% correct, could be I need to export the glTF with the tangents & bi-tangents from the bakes (like I think pior did for Unreal?).











  • pior
    Options
    Offline / Send Message
    pior grand marshal polycounter
    Sure thing, I am attaching the result of the Blender 3.1.0 boxsoft bake exported as .glb. I'd expect it to be exactly the same as Fabi's contributions though.

    The UE4.27 GLTF import plugin (or rather pluginS, are both seem to behave exactly the same way...) doesn't expose the usual FBX normals/tangent and Mikkt options at all. The only user input is a scale override.

    Loading the file in the Khronos online viewer still reveals the slight warping that UE doesn't seem to exhibit. Wouldn't that mean that the various online viewers all skip something about the model data that UE does manage to take into account ?



    Of course and as you rightfully point out this kind of warping would not be an issue in practice with more dense meshes/bevels. But still there's something puzzling about UE being able to display such a good result - I've tried a few setups (image-based, point light, directional light) and I just can't seem to make any warping show up ...
  • Fabi_G
    Options
    Offline / Send Message
    Fabi_G insane polycounter
    Hi! Unfortunately takes me longer to respond currently. In regards to what pior replied about "Auto Smooth" and baking/textures in Blender, can`t add anything. I appreciate the information, this thread revealed things I should read up on or refresh memory :D

    Since my last post, I re-baked the boxes in Painter 8.3.1 with "Compute tangent space per fragment" enabled. I don`t know if the option makes a difference in this case. I´ll attach the boxes baked in Painter that way with a screenshot and separate normal maps. The BoxSoft gtlf still shows gradients viewed in the Sandbox, I don`t know what I can do export-wise to reduce those.



    As visible in the screenshot, the xNormal bake of BoxSoft shows some gradient in my test scene. Didn`t manage to get a better bake. Maybe someone more familiar with xNormal can get a better result?
  • seb3d
    Options
    Offline / Send Message
    seb3d polycounter lvl 11
    Baked the fbx files in maya2020 + 2024. unlike 2020 maya 2024 can use mikk tangent space now which gives an obvious difference in the box soft bake normal map. bake settings are identical. top 2020, bottom 2024.
    also painter 9.1.1

    (both left to right: hard, soft, bevel. screenshots in app viewports. attached are the png´s)

  • myclay
    Options
    Online / Send Message
    myclay polycounter lvl 10
    Results from 3DCoat 2023.41
    Baked with the Blender Swizzle Preset



  • Eric Chadwick
    Options
    Offline / Send Message
    pior said:
    Loading the file in the Khronos online viewer still reveals the slight warping that UE doesn't seem to exhibit. Wouldn't that mean that the various online viewers all skip something about the model data that UE does manage to take into account ?
    Thanks for this! The official glTF Sample Viewer currently has some problems with rendering normal maps properly, I suspect their shader just needs to flip the green channel, but there are a number of other rendering bugs there so I've simply stopped using it as a source of truth.

    I suspect Unreal could be spending a bit more shading calculations on generating rock-solid tangent space conversions, while the WebGL based viewers could be more conservative with their shaders to keep performance fast. There are some pathtracers that support glTF, and they also render these flawlessly. I'll try to dig into this a bit more.

    Thanks @Fabi_G @seb3d and @myclay for the updates!


  • myclay
    Options
    Online / Send Message
    myclay polycounter lvl 10
    Topogun and Knald results

    Topogun and the cube with hard edges gave some problematic output.
    Knald textures have an Alpha on top which hides the edge padding/dilation.


  • Shrike
    Options
    Offline / Send Message
    Shrike interpolator
    Cinema 4D has no baking of normal maps that is even remotely usable so you can put it off the list
    I would try to add Unreal 5 as baking tool however
Sign In or Register to comment.