Other combinations are not supported. I’m not sure about the support but there might be glTF exporter which can automatically merge these textures during the export. Otherwise, you have to do this by yourself.
Thank you, Mugen87. I read about that before posting and I think it is a good option.
However, I don’t understand why the AO occupies a channel when, IMHO it can easily be blended to the base/albedo map, which would free a black/white channel for a bump. Sure bump maps are not as good as Normal maps, but they are good enough. It’s not about best results but about efficiency.
I know you’re knowledgeable and it may mean that there might not be another option.
There is an issue when baking the AO into the diffuse texture: Many professional assets put every surface color of an asset into a single texture. That means certain parts of the texture are sampled multiple times at different places of the geometry. However, the ambient occlusion is often different at these places. In order to decouple the pure surface color from the lighting data, you use two different maps (diffuse map and ambient occlusion map) with two different set of texture coordinates.
Blender 2.8 or Substance Painter should be able to do this.
IMHO it can easily be blended to the base/albedo map, which would free a black/white channel for a bump.
You can do this for a cheap effect, but it doesn’t look as good. The renderer will be simulating ambient and direct lighting on a dark surface, which looks quite different than a brightly colored surface that’s actually receiving less ambient light. Ambient occlusion is supposed to affect only indirect light, not point lights etc. Baking it to the color map is OK in some cases (especially unlit materials), but often looks dirty instead of shadowed and isn’t correct for PBR.
glTF doesn’t support bump maps, by design, it’s better practice to use a normal map. But you can always bring in a bump map separately of course.
You usually don’t need a metalness map. Materials are either metal, or not metal, so you can set this material.metal to 1 or zero accordingly and avoid this map. The exception is if you’re making a single material for an object that’s part metal and part non-metal, in which case your map will be pure black and white (with maybe 1 or 2 pixels of grey padding between) and will compress to a tiny size. The only common exception is something like rusty metal which you’ll need to ‘cheat’ with a greyscale metalness map.
Do you know how Jpeg compression will affect a combined map like this? Jpeg is highly tuned for lossy compression that looks good visually. From what I’ve heard it’s not a good idea to Jpeg compress images that store other kinds of data, such as normal maps.
Normal maps are better but more expensive, difficult to create
Blending AO onto Albedo may lead to some artifact
glTF is built this way and good luck for changing that.
The idea behind my original post was that, in my day-to-day job, I have scenes with 20+ materials and transferring them to the web is challenging in terms of bandwidth. Web users don’t have a Nvidia 2080 RTX Ti as I do, they may run on a CPU-embedded GPU and they still expect to use a page in 3sec max/target.
I am a 3D Artist not a programmer although I’m learning Lit-Element/Polymer because of its small footprint and lazy-loading capabilities. Downloading and loading 20 images or 60 is not the same and I’m trying to find a balance because waiting for 30sec looking at a loading bar is not sexy.
IMHO, Three.js holds a different place than UE4 (HTML export footprint is 120MB) or Godot (footprint may be 20MB) or even the up-coming Google’s Stadia platform (that will be costly). Three.js strength? It makes 3D ubiquitous, it feels like another img/text on the page. That’s why I’m training to make my 3D scenes lightweight and I won’t be using a 20MB Hero Tree.
If you don’t know how I could replicate the node tree shown in the screenshot, it’s ok. It may be a good feature request. Anyway, thank you for your interest in this topic.
That happens because many compression algorithms like JPG do not judge color channels individually but as a whole. That works well for color information but not for packed data like normals. Of course it highly depends on the compression ratio how visible compression artifacts are going be.
In any event, certain texture compression formats like ASTC provide special modes or pre-defined encoding settings in order to produce an optimized output for data-source textures (like normal maps). For example -normal_psnr or -normal_percep.
Since the usage of texture compression formats in WebGL is a bit inconvenient, I would still compress normals maps with JPG rather than PNG. The difference in size is still worth it.
By hand in Photoshop, yes. But baking a bump map to a normal map is easy in a program like Blender. In general glTF focuses on what is best practice for the renderer, and requires export tools to do more up front. And bump maps are pretty old school these days, for games and such. From Unity docs:
Modern realtime 3D graphics hardware rely on Normal Maps, because they contain the vectors required to modify how light should appear to bounce of the surface. Unity can also accept Height Maps for bump mapping, but they must be converted to Normal Maps on import in order to use them.
For hard surfaces you might get better compression with PNG
It’s true, I was thinking about this in ‘worst case’ mode. In general, if your texture is mainly single blocks of color with a couple of lines (tiled walls, for example), then compression is not a problem for you anyway. Maybe PNG will be better, but when it’s 10kb vs 15kb that’s not really important. I’m thinking about high frequency normals (lots of tiny details), where a 1024x1024 PNG may be >1mb and jpg compression will kill the details.
Still, I’m willing to accept that bump maps are a thing of the past and we’ll have to accept these annoyances
Looking forward to the time when we can use proper compressed textures on the web. @Mugen87 I think calling the current situation ‘a bit inconvenient’ is quite an understatement!
I have faked bump/metal/roughness maps with just two nodes (ColorRamp and Bump). Is it possible to do this in Three.js? How?
Back to the original question
I’d say that you could do this fairly easily for the color ramp, since that’s just a simple gradient mask. You could write a custom function in JS to achieve this.
As I mentioned above, for a wood texture you don’t need a metalness map, you just set metal to zero. Or you could create a 1x1 black texture if you really want that map!
That just leaves the bump node. It looks like blender’s bump node is creating a normal map from a height map, the same as Unity does per @Mugen87’s comment above. I have no idea how hard that would be to implement, but I guess Sobel operators are going to feature somewhere. Blender is open source so you could check out what they’re doing there. Check out these links too:
There’s two approaches you could take here, either you could pre-process the textures in JS, which I guess would be easier to implement, but less flexible. Or, you could try adding these as nodes in the (currently experimental) node-based material system. I’m not sure how much processing is required for the height -> normal map, it may not be feasible to do in real-time. But the color ramp should work well as a node.