Skip to content

Filter or exclude by custom material properties in toktx#1779

Open
FrostKiwi wants to merge 1 commit intodonmccurdy:mainfrom
FrostKiwi:custom_properties
Open

Filter or exclude by custom material properties in toktx#1779
FrostKiwi wants to merge 1 commit intodonmccurdy:mainfrom
FrostKiwi:custom_properties

Conversation

@FrostKiwi
Copy link
Contributor

This PR allows for to include or exclude textures from toktx in the document.transform step. It works specifically with blender custom properties (extras in gltf lingo) and assumes them to be booleans.

eg.:

toktx({
    encoder: sharp,
    mode: Mode.ETC1S,
    slots: /baseColor|emissiveTexture|metallicRoughnessTexture/,
    excludeCustomTextureBool: "palletize", /* Exclude textures marked as palletized */
    compression: 3,
    filter: Filter.BOX,
}),

I copied the code from

const isAnimated = node.listParents().some((p) => p instanceof AnimationChannel);
to do the matching. I don't expect this PR to be merged as is, this is to kick-off a train of thought on how to include custom properties in the filtering. Thus also no tests yet in this PR.

Motivation

Similar to the palletize function, I already pre-palletize in Blender and tag those materials for exclusion in texture compression and setting those to Nearest Neighbor, similar to function pallete. But gltf-transform toktx has no way to check for custom properties, so right now I have to do some gymnastics with checking custom property with the JS API, then adding a Texture name & URI prefix only then to have the pattern RegEx do the exclusion.

Right now I mark palletized materials:

if (extras.palletized !== true) continue;

to then prefix them with this cursed setup:

const PALLETIZED_PREFIX = "PALLETIZED_";
...
if (!currentURI.startsWith(PALLETIZED_PREFIX)) {
    /* Ensure URI has an extension so toktx can infer mime type */
    const uriWithExt = currentURI || "texture.png";
    texture.setURI(PALLETIZED_PREFIX + uriWithExt);
}
if (!currentName.startsWith(PALLETIZED_PREFIX))
    texture.setName(PALLETIZED_PREFIX + currentName);

only to then exclude them from the processing

/* ETC1S compression for color textures (excluding palletized) */
toktx({
    encoder: sharp,
    mode: Mode.ETC1S,
    slots: /baseColor|emissiveTexture|metallicRoughnessTexture/,
    pattern: /^(?!PALLETIZED_)/, /* Exclude textures marked as palletized */
    compression: 3,
    filter: Filter.BOX,
}),

Either way, filtering by custom property seems like a natural extension to anything gltf processing related.

Issues

  • Technically, what is needed is to match by custom property of the texture, not the material. But even though according to the Blender wiki "All data-blocks types can have custom properties" and according to the data-block type wiki page Image is a data-block type, there exists no way in the Blender UI to set custom properties and setting it via the API doesn't work either, as the gltf exporter ignores it. Both things I'll try to look into
  • toktx already has RegEx in the form of pattern, so maybe that feature could be connected to custom property things, but I didn't come up with a good way and resorted to excludeCustomTextureBool and matchCustomTextureBool
  • I assume it to be a boolean, but really ideally we should be able to match strings and numbers for whatever other use-cases are doing

@donmccurdy
Copy link
Owner

Hi @FrostKiwi! The discussion in #1650 might be relevant, specifically adding a callback to the toktx() function...

toktx({
  filter: (texture) => checkSomeCondition(texture),
  ...
})

... and compressing a texture only if the callback returns true. Most transforms use the pattern (regexp) option today, but I'm open to adding the filter (callback) option in more places when it makes sense. For an example, see:

@donmccurdy donmccurdy added feature New enhancement or request package:cli labels Dec 9, 2025
@donmccurdy donmccurdy added this to the 🗄️ Backlog milestone Dec 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New enhancement or request package:cli

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants