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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a way to combine PBR maps into an ORM texture for use in ORMMaterial3D #2316

Open
Tracked by #56333
Calinou opened this issue Feb 19, 2021 · 11 comments
Open
Tracked by #56333

Comments

@Calinou
Copy link
Member

Calinou commented Feb 19, 2021

Describe the project you are working on

The Godot editor 馃檪

Describe the problem or limitation you are having in your project

Creating StandardMaterial3Ds for use in Godot requires a lot of clicks. A full PBR material typically requires 5 or 6 different texture maps:

  • albedo
  • normal
  • roughness
  • metallic
  • ambient occlusion
  • (height or emission)

ORMMaterial3D improves this by only requiring 3 textures for most materials (4 if you need height or emission), but you need specially crafted ORM maps. Most websites distributing PBR materials such as CC0Textures only provide separate texture maps, not ORM maps.

Another upside of using ORM maps is that they are slightly more optimized compared to using separate texture maps, and can also be compressed in a more efficient way. Lastly, since you have less files lying around in your 3D library, it makes folders easier to browse 馃檪

ORM maps (for Occlusion, Roughness, Metallic) contain the AO map in the red channel, the roughness map in the green channel and the metallic map in the blue channel.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Add a tool in the editor to convert a set of 3 textures into a single ORM map. This would be a one-way operation. By default, the original texture maps would be kept but there could be a checkbox to remove them automatically once the operation has succeeded.

Additionally, the tool can save a .tres ORMMaterial3D resource next to the textures. This would further speed up material setup.

I don't think we can provide this feature in the Import dock since there won't be a 1:1 mapping between a source PBR map and the "final" ORM map.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

A dedicated dialog could be provided in the Project > Tools menu:

image

Here's a mockup made with Excalidraw:

image
Source: orm-material-converter-mockup.excalidraw.zip

The only required field is Albedo. All other fields will be guessed automatically, but material conversion should be functional even if only the Albedo slot is filled in. Guessing textures is based on commonly used naming pattern globs, such as {basename}*normal* for normal maps, {basename}*ao* for ambient occlusion, and so on (case-insensitive). {basename} is the name of the albedo map with the albedo*/diffuse*/basecolor* suffix, file extension and trailing dash/underscore removed.

The following name patterns can be used for guessing:

  • {basename} is determined using the albedo filename, minus the extension and any of these suffixes: _albedo, _base_color, _basecolor, _base, _color, _diffuse, _c, _d
  • Normal: {basename}_normal, {basename}_norm, {basename}_nrm, {basename}_local, {basename}_n
  • Occlusion: {basename}_ambient_occlusion, {basename}_ambientocclusion, {basename}_ambient, {basename}_occlusion, {basename}_ao, {basename}_o
  • Roughness: {basename}_roughness, {basename}_rough, {basename}_r
  • Metallic: {basename}_metallic, {basename}_metal, {basename}_m
  • Height: {basename}_height, {basename}_depth, {basename}_parallax, {basename}_h, {basename}_z
  • Emission: {basename}_emission, {basename}_emissive, {basename}_glow, {basename}_luma, {basename}_e, {basename}_g

The above list only mentions {basename}_snake_case naming conventions, but {basename}_PascalCase, {basename}PascalCase and {basename}-kebab-case would be automatically attempted as well.

To reduce UI complexity for new users, I suggest disabling all fields other than Albedo until an albedo texture has been specified.

The placeholder texts will change once an albedo texture has been specified. If no texture could be guessed for a given slot, the placeholder will change to (no [slot] texture found) instead (e.g. (no emission texture found)).

If this enhancement will not be used often, can it be worked around with a few lines of script?

This can be achieved through external programs (ImageMagick can do this in an automated way), but it's not particularly convenient, especially for people not familiar with the command line.

The following ImageMagick command can be used to combine an ambient occlusion, roughness and metallic map into a single ORM map:

convert ao.png roughness.png metallic.png -combine orm.png

To separate them back to separate maps:

convert orm.png -channel R -separate ao.png && convert orm.png -channel G -separate roughness.png && convert orm.png -channel B -separate metallic.png

Is there a reason why this should be core and not an add-on in the asset library?

See above.

@Jummit
Copy link

Jummit commented Feb 19, 2021

Tbh, my gut feeling says this should either be done with an external program or using a plugin, so I made one: https://github.com/Jummit/channel-packer
screenshot

@clayjohn
Copy link
Member

I think @Zylann also has a nice plugin to pack textures!

@NHodgesVFX
Copy link

I think @Zylann also has a nice plugin to pack textures!

https://github.com/Zylann/godot_channel_packer_plugin although it hasn't been updated in a while not sure if it still works

@Zylann
Copy link

Zylann commented Feb 20, 2021

@NHodgesVFX did you try it? Last time I checked there was an issue with the window layout due to hi-DPI displays or different font sizes (which was always an issue with almost every plugin)

Also I havent updated it in a while because the need became even more complicated when I started using texture arrays, so I implemented texture packing by creating a custom importer for a custom file format listing the packing instructions, combined with a tool to edit such files because importer dock UI sucks, which then led to this #1943

@NHodgesVFX
Copy link

NHodgesVFX commented Feb 20, 2021

Tbh, my gut feeling says this should either be done with an external program or using a plugin, so I made one: https://github.com/Jummit/channel-packer
screenshot

what happens if you have 4k+ textures and want to keep them that size or if you want to pack something into the alpha. otherwise looks good

@Calinou
Copy link
Member Author

Calinou commented Feb 20, 2021

@NHodgesVFX @Jummit The add-on should probably detect the size of all 3 textures and use the largest size for the final image. This way, the user won't have to specify the size manually and it'll work for non-square textures too.

@NHodgesVFX
Copy link

@NHodgesVFX did you try it? Last time I checked there was an issue with the window layout due to hi-DPI displays or different font sizes (which was always an issue with almost every plugin)

Just tried it, seems to have a couple issues.

  1. I couldn't find it at first top right corner is not the best place perhaps project-> tools would be better.
  2. I couldn't drag connect the points it doesn't seem to be working. So i used a preset
  3. the texture exported but didn't reimport into Godot for some reason.
  4. the dialog should probably be closed after the texture is saved

@Zylann
Copy link

Zylann commented Feb 20, 2021

I couldn't drag connect the points it doesn't seem to be working. So i used a preset

I never implemented this part because it was actually created in response to a need in my terrain plugin, so using presets was faster, while the connected points are only illustrative.

the texture exported but didn't reimport into Godot for some reason.

This is a problem I keep running into so I opened this: #1615

@alexfreyre
Copy link

alexfreyre commented Feb 25, 2021

would be great if the images to be imported has some prefix in the name and Godot convert the three images on import process, let's say

  • ao_image.png
  • rough_image.png
  • met_image.png

resulting in godot automatically:

  • orm_image.png

Godot can evaluate this on import so is up to the user if he wants to use the "tool" in any moment or to import the images directly with the prefix

@Calinou
Copy link
Member Author

Calinou commented Feb 25, 2021

@alexfreyre The issue is that there is no 1:1 mapping between an AO/roughness/metallic texture and an ORM texture. It's a 3:1 mapping, and the Godot import system isn't designed to deal with that.

@alexfreyre
Copy link

the Godot import system isn't designed to deal with that.

I mean that at import time, the import system could ideally detect the prefixes and then ask for the tool (of this PR) you want to create, then the tool do the combination to get automatically the 3:1 orm.

Either way this ends, it will be a great feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants