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
- Download a zip for the format that works best in your app.
- Import the models into your app. Make sure to preserve the vertex normals, and the UVs.
- Bake from BoxHigh into each of the three low boxes.
- Bake to 512x512, as a 24bit PNG.
- Make sure gamma is not applied, it must be saved in Linear color space.
- Apply the baked maps to your low boxes, using a material with a white basecolor, 1.0 metal, and 0.5 roughness.
- Screenshot them in your app's realtime viewer. If possible use this HDR for your lighting.
- Export to GLB, and include tangents/bi-tangents if you have that option. If you can't export, share the baked PNGs.
- ZIP your GLBs or PNGs, and screenshots, and drag-n-drop it into your post reply.
- Please note the software version number for the baker you used.
- 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/88Why 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
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.
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!
Plus there's a written info about the layouts in the readme:
- Go to https://github.com/KhronosGroup/glTF-Sample-Assets/pull/88
- Click on Files Changed, then the three dots, then View File.
(these steps are only needed before the submission is finalized and approved)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.
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.
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).
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.
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.
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!
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.
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
Let me know if you have any ideas what to do differently. Attached zip contains gltf file and normal map.
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 ?
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.
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:
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).
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.
It's so pretty !
@Fabi_G
thank you both for the explanations and help!
here are the output files, CC0 for Mari and Toolbag.
Baked Normalmaps.rar
@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?).
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 ...
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?
also painter 9.1.1
(both left to right: hard, soft, bevel. screenshots in app viewports. attached are the png´s)
Baked with the Blender Swizzle Preset
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!
Knald textures have an Alpha on top which hides the edge padding/dilation.
I would try to add Unreal 5 as baking tool however