Skip to content

Import custom attributes with GLTFDocumentExtension#97756

Open
huwpascoe wants to merge 1 commit intogodotengine:masterfrom
huwpascoe:custom_attrib
Open

Import custom attributes with GLTFDocumentExtension#97756
huwpascoe wants to merge 1 commit intogodotengine:masterfrom
huwpascoe:custom_attrib

Conversation

@huwpascoe
Copy link
Contributor

@huwpascoe huwpascoe commented Oct 3, 2024

Proposal

Import ARRAY_CUSTOM# attributes with GLTFDocumentExtension using a function to specify layer name. Also added "Export Attributes" checkbox to the blender importer.
godotengine/godot-proposals#10892

Test Project

image
custom_attrib_test.zip

changes

  • Ability to combine 2 attributes per CUSTOM
  • Created new GLTFAttributeMap resource to deal with the sheer number of possibilities
extends GLTFDocumentExtension

func _import_get_attribute_map(state: GLTFState, mesh_index: int) -> GLTFAttributeMap:
	var attrmap := GLTFAttributeMap.new()

	var mesh_name: String = state.json["meshes"][mesh_index]["name"]
	match mesh_name:
		"mesh_1": attrmap.color = "COLOR_1"
		"mesh_2": attrmap.color = "_MY_DATA"
		"custom":
			attrmap.custom0 = "_ROCK"
			attrmap.custom1 = "_MUD"
			attrmap.custom2 = ""
			attrmap.custom3 = "_GRASS"
			attrmap.custom3_mux = "_SNOW"

	return attrmap

Supported attributes

  • Mesh.ARRAY_TEX_UV (vec2)
  • Mesh.ARRAY_TEX_UV2 (vec2)
  • Mesh.ARRAY_COLOR (vec3, vec4)
  • Mesh.ARRAY_CUSTOM# (scalar, vec2, vec3, vec4)

@fire
Copy link
Member

fire commented Oct 3, 2024

I'm having a hard time understanding the extension. Can you link or write a proposal in https://github.com/godotengine/godot-proposals?

Something like: I have a game workflow that uses blender I want the vertex attributes to import from blender, but it needs this pr. I can use the attributes for a shader effect.

@huwpascoe
Copy link
Contributor Author

godotengine/godot-proposals#10892

@huwpascoe
Copy link
Contributor Author

Refactored and removed like a hundred duplicate lines of code.

_decode_accessor_as_floats();
_decode_accessor_as_ints();
_decode_accessor_as_vec2();
_decode_accessor_as_vec3();
_decode_accessor_as_color();
_decode_accessor_as_quaternion();
_decode_accessor_as_xform2d();
_decode_accessor_as_basis();
_decode_accessor_as_xform();

// VVV

_decode_accessor<T>();

Multi-element scalars are now decoded with _decode_accessor<T, N>()

array[Mesh::ARRAY_TANGENT] = _decode_accessor<float, 4>(p_state, a["TANGENT"], true, indices_mapping);

@aaronfranke
Copy link
Member

Since this PR alters the accessor code, it will have to wait until after #94165 which also touches this code.

@Flynsarmy
Copy link
Contributor

Since this PR alters the accessor code, it will have to wait until after #94165 which also touches this code.

PR in question was just merged so we should be good to continue here.

@fire
Copy link
Member

fire commented Nov 6, 2024

@huwpascoe Many people think this is a good enhancement. Would you happen to have time to rebase it? <3

@huwpascoe
Copy link
Contributor Author

huwpascoe commented Nov 7, 2024

@fire

Would it be better to keep as an extension or promote it to import options?
https://github.com/user-attachments/assets/52dc1357-7b32-49c2-a2ce-216343f69d60

There are trade-offs for each.

@fire
Copy link
Member

fire commented Nov 7, 2024

I am trending towards promoting it to import options

@Flynsarmy
Copy link
Contributor

Remember to take this PR out of draft if it's ready :)

@huwpascoe
Copy link
Contributor Author

Remember to take this PR out of draft if it's ready :)

Don't worry! I haven't forgotten.

I am trending towards promoting it to import options

Right, I've determined that the UI approach is just too much of a mess for what is a technical feature. So I'll be moving forward with the original plan to add the method to DocumentExtension.

@huwpascoe huwpascoe force-pushed the custom_attrib branch 2 times, most recently from fd4dff7 to 4db4bdb Compare December 15, 2024 05:59
@huwpascoe huwpascoe marked this pull request as ready for review December 15, 2024 06:46
@huwpascoe huwpascoe requested review from a team as code owners December 15, 2024 06:46
@huwpascoe huwpascoe force-pushed the custom_attrib branch 3 times, most recently from 8921298 to e429182 Compare November 29, 2025 00:13
@huwpascoe huwpascoe force-pushed the custom_attrib branch 2 times, most recently from f0f9cd4 to 6848be9 Compare November 29, 2025 15:59
@huwpascoe
Copy link
Contributor Author

I've updated the test scene for the name change (_import_get_attribute_for_mesh_array)

@aaronfranke aaronfranke self-requested a review November 30, 2025 22:54
Copy link
Contributor

@lyuma lyuma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some comments about the design that I'd like a chance to discuss.

Firstly, I have concerns about the usability of depending on a customized GLTFDocumentExtension to perform the remapping... it certainly could work, but document extensions are registered globally (project-wide), so any attempt to use this feature would have to condition the remapping on some condition or add a setting to the import dock. If I were to copy the sample code as written, it would break all other glTF models in my project, even if they do not have that custom attribute. But explaining all this is probably too much for a method description, so I'm not sure how to clarify this.

Second, as I noticed, if I use this to override any custom attributes, then I can no longer combine two UV channels into one custom channel which limits the number of custom 2-channel UVs I can import. I feel like maybe something simple like "TEXCOORD_1,TEXCOORD_2" could work to handle that case. I think it only needs to support 2 x vec2 or 1 x anything cases , so no need to handle every combination.

Basically the usecase is for compacting multiple 2-channel UVs into a CUSTOM, and this is Godot's current behavior so it would be nice to support it for that reason without needing a whole special case. At a minimum, it should be possible to return "" for an individual custom channel to get the current behavior without losing all the other custom channels.

@huwpascoe
Copy link
Contributor Author

If I were to copy the sample code as written, it would break all other glTF models in my project, even if they do not have that custom attribute. But explaining all this is probably too much for a method description, so I'm not sure how to clarify this.

That's why GLTFState is provided to determine if changes apply. If this method needs explaining, then every other method of GLTFDocumentExtension would require the same explanation. So that's out of scope, I think.

At a minimum, it should be possible to return "" for an individual custom channel to get the current behavior without losing all the other custom channels.

That sounds reasonable, I'll see if I can get it working efficiently.

@huwpascoe huwpascoe requested a review from a team as a code owner December 2, 2025 03:54
@huwpascoe huwpascoe force-pushed the custom_attrib branch 2 times, most recently from f564792 to 0db8539 Compare December 2, 2025 04:05
@huwpascoe
Copy link
Contributor Author

Individual attribute querying is gone, now extensions only need to return a GLTFAttributeMap resource. With defaults set to how texture UVs were originally handled.

Any 2 attributes can combine into a CUSTOM provided they fit within a vec4. For example, vec3+scalar is valid.

image

@PurpBatBoi
Copy link

updates?

@fire fire requested a review from a team February 17, 2026 21:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants