Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GLTFLoader+GLTFExporter: Initial support for 'EXT_materials_bump' #27036

Merged
merged 2 commits into from
Nov 23, 2023

Conversation

bhouston
Copy link
Contributor

@bhouston bhouston commented Oct 23, 2023

Description

This PR adds support for the EXT_materials_bump extension via the pre-existing ThreeJS MeshStandardMaterial bumpMap and bumpScale factor.

It is a straight forward extension that represents both the bumpScale and bumpMap. I've added import/export support to ThreeJS. It works in the editor as well as the examples.

What is great is that if you don't have a bump map, it isn't used. Thus it is 100% backwards compatible with all glTFs.

Screenshot 2023-10-23 at 1 00 29 PM

Benefits of bump maps are primarily these two:

  1. Bump maps are much more compact that normal maps and lead to smaller glTF files as well as less GPU memory requirements. This is because the normal map has to store a full 3D vector per texel, while the bump map only needs to store a single scalar value per texel. Thus bump maps require 3 times less data than normal maps for transmission and GPU storage. Normal maps are also very sensitive to texture compressions methods, while bump maps are less sensitive.

  2. Bump maps are useful for capturing small details in combination with a normal map for large scale structures. For example, when rendering human faces, there are usually two layers of surface pertubation detail, the unwrapped normal map is used for representing wrinkles, and then a repeating bump map is used for skin pore details. This is also the case for many other materials such as wood, metal, and stone, where there is both macro and micro details.

Also I should note that many engines already support both a bumpMap and a normalMap, including both ThreeJS as well as Sketchfab and Threekit (my company.) I think being able to save and load this data from glTFs makes a lot of sense and doesn't really hurt anyone.

This contribution is funded by Threekit

@bhouston
Copy link
Contributor Author

Example glTF that uses this extension exported via ThreeJS's glTF exporter is here: https://drive.google.com/file/d/1NX_LGF0Yp_F5ceWhStcoYbH_UGpuhFqz/view?usp=share_link. You can also import it into the ThreeJS editor via the ThreeJS glTF importer.

@donmccurdy
Copy link
Collaborator

donmccurdy commented Oct 23, 2023

Note to reviewers — EXT_materials_bump is a proposal, until it is implemented by at least two vendors. If we feel .bumpMap would be a valuable addition to glTF for three.js users, we can merge this PR and be one of those vendors. If we have concerns about supporting .bumpMap in glTF, now would be a good time to raise them. In the linked pull request, @bhouston gives use cases for the extension.

@bhouston
Copy link
Contributor Author

@donmccurdy I can confirm that Threekit will support this extension.

@bhouston bhouston changed the title initial support for EXT_materials_bump Oct 24, 2023
@mrdoob
Copy link
Owner

mrdoob commented Oct 26, 2023

Lets hope Khronos approves this one soon 🤞

@mrdoob mrdoob added this to the r159 milestone Oct 26, 2023
@donmccurdy
Copy link
Collaborator

donmccurdy commented Oct 26, 2023

Usually EXT_ extensions are not subject to any Khronos approval – they're added to the repository and considered out of the proposal stage if >=2 vendors have added support. EXT_ extensions are less 'official', which can be a good thing if there are important limitations associated with the extension, or a concept just needs to be proved.

Perhaps Khronos may express support or concerns, but many PRs just sit without responses, and I do not expect an official response here. If we feel this will benefit three.js users then that is enough, and we can ship it I think. Though if it's only three.js and ThreeKit for now, perhaps the extension should be THREE_* rather than EXT_* unless/until other vendors add support.

@bhouston
Copy link
Contributor Author

@donmccurdy here is the list of other EXT_ extensions that ThreeJS supports:

	EXT_TEXTURE_WEBP: 'EXT_texture_webp',
	EXT_TEXTURE_AVIF: 'EXT_texture_avif',
	EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression',
	EXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing'

https://github.com/mrdoob/three.js/blob/dev/examples/jsm/loaders/GLTFLoader.js#L494

@bhouston
Copy link
Contributor Author

BTW Alban over at Sketchfab liked the extension when I mentioned it to him - finally all those models over at Sketchfab that have bumps can actually export that info: https://twitter.com/benhouston3d/status/1716640855455412305

@donmccurdy
Copy link
Collaborator

donmccurdy commented Oct 26, 2023

@bhouston Understood! I have no objection to EXT_ extensions in general. Our policy has been to implement them on a case-by-case basis, if we feel they're good for our users. We do not support EXT_lights_image_based or EXT_lights_ies – and with reason. If EXT_materials_bump benefits three.js and its users, we should support it. Unlike some engines, loading a bump map at runtime does not cost three.js anything.

Positive interest from Sketchfab is encouraging. 👍🏻

@bhouston
Copy link
Contributor Author

@donmccurdy why don't we support the IES extension? I figured it was just because we never got around to it. We technically have an IES loader (which I provided the initial code for) as well as an IES light type. Our code base aligns well with that extension.

@bhouston
Copy link
Contributor Author

Also we could likely support the EXT_lights_image_based as well. While I am not a complete fan of its dual cube map + SH approach, we could do it anyway. It is a major limitation that we can not pass around HDR files in glTFs.

@donmccurdy
Copy link
Collaborator

donmccurdy commented Oct 26, 2023

Perhaps we should support EXT_lights_ies. Mostly it's newer, nothing exports it, and I don't care to lead the charge on more complexity in GLTFLoader at this time.

I don't view EXT_lights_image_based as a production-ready approach to IBL. KhronosGroup/glTF#1956 may be better. If we want to nudge things along I'd sooner ship an implementation we like under THREE_*, than promote the wrong EXT_* extension toward becoming the de facto standard.

But we can have a new issue for either, if that's of interest.

@mrdoob
Copy link
Owner

mrdoob commented Oct 27, 2023

@elalish Any thoughts about EXT_materials_bump?

@elalish
Copy link
Contributor

elalish commented Oct 27, 2023

A few things:

here is the list of other EXT_ extensions that ThreeJS supports

These are actually EXT extensions that have since been ratified, so more like KHR now.

It is a major limitation that we can not pass around HDR files in glTFs.

I would disagree, especially considering how huge HDR files are (we really need a better image format). Packing the lighting into the file removes much of the point of PBR (separation of object from lighting), especially since it means you can't easily reuse the lighting for multiple models. For scenes where you want the lighting packaged with the model, a NeRF-style system would be much better anyway. I'm sure when that settles down a bit a format standard will be developed for that too.

Any thoughts about EXT_materials_bump?

I've put my opinions here and here. I'm concerned about artist workflow fragmentation mostly, but I don't have a very strong opinion. It would help to know a bit more about the state of the industry.

@donmccurdy donmccurdy changed the title initial support for glTF EXT_materials_bump via StandardMaterial.bumpMap Oct 29, 2023
@donmccurdy donmccurdy changed the title GLTFLoader: Initial support for 'EXT_materials_bump' via StandardMaterial.bumpMap Oct 29, 2023
@Mugen87
Copy link
Collaborator

Mugen87 commented Nov 22, 2023

I would like to have some additional (more general) information about bump and normal maps.

I have often read that bump maps are considered as a predecessor of normal maps. And that means if a system supports normal maps, there is no reason for using bump maps since you can do the same with normal maps. Is that actually true? In other words: Is there a use case that can be implemented with bump maps but not with normal maps?

If not, I wonder why having both map types? Wouldn't it be more intuitive and simple to just have one solution that covers all use cases? Supporting EXT_materials_bump somewhat means breathing new live into something that felt obsolete, imo.

@bhouston
Copy link
Contributor Author

somewhat means breathing new live into something that felt obsolete

@Mugen87 if bump maps are obsolete then maybe we should remove bump map support from ThreeJS?

@mrdoob
Copy link
Owner

mrdoob commented Nov 23, 2023

I think being able to combine bumpMap and normalMap is powerful. Specially now that we support multi uvs and multi transforms.

@mrdoob
Copy link
Owner

mrdoob commented Nov 23, 2023

Okay, let's give it a go 👌

@mrdoob mrdoob merged commit b2741ea into mrdoob:dev Nov 23, 2023
19 checks passed
AdaRoseCannon pushed a commit to AdaRoseCannon/three.js that referenced this pull request Jan 15, 2024
…doob#27036)

* initial support for EXT_materials_bump

* fix typo: EXR_ -> EXT_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
5 participants