godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.42k stars 20.24k forks source link

OBJ import not working correctly in Godot v4.0.beta12.mono.official #71342

Open ghost opened 1 year ago

ghost commented 1 year ago

Godot version

v4.0.beta12.mono.official [3c9bf4bc2]

System information

Windows 10 Home 64 bit, NVIDIA GeForce GTX 1070, 31.0.15.1748 (NVIDIA 517.48), forward_plus

Issue description

I try to import an OBJ file with MTL file and all required textures. This OBJ file is imported correctly in Blender so it's correct.

Correctly render in Blender: notice all textures are present and the arcade stick at the right is YELLOW

afbeelding

Problems in Godot: notice there are no textures at all and the arcade stick at the right is RED! It should be yellow as in Blender

afbeelding

In attachment the OBJ, MTL and texture files to test. Also the .blend file for comparison

simpsonsmodel v1.zip

Steps to reproduce

Minimal reproduction project

N/A

ghost commented 1 year ago

I imported to OBJ model into Blender and exported to GLTF (using Blender). Then I imported this GLTF model into Godot.

afbeelding

The result here is correctly loaded with all textures and also the arcade stick is yellow! So there is a problem in the OBJ loader of Godot.

Attached is the GLTF file

GLTF.zip

akien-mga commented 1 year ago

Likely a regression from #71033, CC @scurest @fire.

ghost commented 1 year ago

Is it correct the right way to import OBJ is just to copy the OBJ file to your Godot project folder (including textures and MTL file) and drag and drop it into the scene?

clayjohn commented 1 year ago

Likely a regression from #71033, CC @scurest @fire.

The model looks the same in earlier betas (I tested in master and in Beta 10 and the result is the same) The model isn't using vertex colours so #71033 is likely unrelated.

This appears to be an issue with how we parse MTL files. The material in question is simpsonsorange (despite the name I guess it is intended to be yellow:

newmtl simpsonsorange
Ka 0.509804 0.501961 0.000000
Kd 1.000000 0.376471 0.000000
Ks 0.152941 0.152941 0.152941
Ns 34.559998
d 1.000000

It looks like Godot is only using Kd while blender is combining Ka, Kd, and Ks (ambient color, diffuse color, specular color). Since Godot uses a PBR pipeline, we don't have multiple types of color, so we need to combine those three into one "albedo" colour I guess.

Calinou commented 1 year ago

It looks like Godot is only using Kd while blender is combining Ka, Kd, and Ks (ambient color, diffuse color, specular color). Since Godot uses a PBR pipeline, we don't have multiple types of color, so we need to combine those three into one "albedo" colour I guess.

Could we treat Ka as emission, Kd as albedo and ignore Ks? That said, we may want to ignore Ka as well.

clayjohn commented 1 year ago

Could we treat Ka as emission, Kd as albedo and ignore Ks? That said, we may want to ignore Ka as well.

We should just do whatever blender does.

Comparing the GLTF material and the MTL material

GLTF albedo: 1.0, 0.65, 0.0 MTL albedo: 1.0, 0.38, 0.0

So indeed, Godot is taking the MTL value as is. However, it looks like all Blender is doing for the value is taking the diffuse component and converting from linear to sRGB. We probably just need to do the same in our importer

edit: to make the model in this issue match the GLTF exported model we just have to change this: https://github.com/godotengine/godot/blob/7aeccad7737c1a6c8b841870905a1a91462c2439/editor/import/resource_importer_obj.cpp#L76 to

current->set_albedo(c.linear_to_srgb());

That being said. I'm not sure if we should actually do that. The MTL specification doesn't appear to require colours be in one space or another. Currently we are effectively assuming the color is in sRGB space, while the change above assumes that colors are in linear space. I'm not sure which assumption is more likely to be true. Looking online (in particular on Blender Q&As) it seems most people recommend changing the color type to "Raw" on the blender side to deal with this issue.

It would be good to have input from people with more experience using the .obj/MTL file formats with multiple tools.

Perhaps @fracteed can help

scurest commented 1 year ago

Currently we are effectively assuming the color is in sRGB space, while the change above assumes that colors are in linear space. I'm not sure which assumption is more likely to be true.

I can confirm Blender reads/writes MTL colors in linear space. Unfortunately my impression is everyone else uses sRGB (a fair assumption for a format from the 80s).

See

Not sure if there's a good solution.

scurest commented 1 year ago

(Btw the reason the images don't work is because they're TIFFs; for that see https://github.com/godotengine/godot-proposals/issues/4620)

ghost commented 1 year ago

Hi

Since there could be an endless discussion for this and I really would love to have a 1:1 match with Blender, would it be possible to add an option in the editor settings, under "import"?

afbeelding

There could be made for each supported format (OBJ, Collada and gLTF) a section with settings. For OBJ you could have 2 radio buttons in order to choose loading the OBJ with color space:

In this way people can choose what space they want. I don't think the MTL file really forces you to use one space or not and it's up to the application to decide this (I'm not an expert).

My proposal is a good solution I think. The user can choose and all problems are solved.

ghost commented 1 year ago

(Btw the reason the images don't work is because they're TIFFs; for that see godotengine/godot-proposals#4620)

Thanks! I finally understand now. The gLTF file has working textures in Godot. Does this mean the textures are INSIDE the gLTF file and are converted by Blender to another format (not TIFF) when exporting to gLTF? Because the model was originally imported into Blender using OBJ, MTL and TIFF textures. (and I didn't convert the TIFF files myself to another format)

Thanks

clayjohn commented 1 year ago

The gLTF file has working textures in Godot. Does this mean the textures are INSIDE the gLTF file and are converted by Blender to another format (not TIFF) when exporting to gLTF?

Yes, Blender is likely converting the images to PNG or JPEG.

fracteed commented 1 year ago

I think in general it is best to use GLTF to get fully textured pbr assets from Blender to Godot. If you are using third party obj format assets, then use Blender to convert them to GLTF.

Mtl files tend to be a nightmare in all 3d packages and I avoid them if possible. My only use of them between Blender and Godot is if I need multiple material selections on a mesh. If I need the material selections, then I export with a mtl from blender but then delete it, since Godot really only looks at the obj file for the material selections anyway (even though it spits out an error, it is fine to use it regardless).

One of the big issues using mtl in Godot is that if you delete or move an obj. the related mtl file sticks around, as it is not seen by the Godot file browser.

fire commented 1 year ago

There used to be a dependent filepaths array, but not sure if it's still here.