Material export Blending mode support

What is current state of supporting the export of blend modes for materials. I am aware that I could adjust the blending mode at start of the component but that just doesnt really fit my use case. Is there any way to export this information from Unity without adding additional components to the gameobject?

Hi Martin,

Currently the export pipeline for Unity materials doesn’t automatically transfer the blend mode settings directly into the exported asset. Even though recent updates have improved material handling – for example, fixes that add values like AlphaToMask and BlendModePreserveSpecular to the material setup (see at UnityGLTF-changelog.md) – these improvements primarily work around specific issues with Unity’s runtime material keyword management. They do not provide full, ā€œplug‐and‐playā€ blend mode export directly from Unity’s material data.

At the moment the only reliable way to ensure that the blend mode is set as needed in the running Needle Engine project is to adjust it in code (or via a helper component) after exporting. If you require the blend mode information to be part of the exported asset without having to add extra components, this isn’t fully supported yet.

If your use case is critical, I’d recommend sharing your requirements with the Needle team. That input helps drive future improvements so that a more seamless solution might be available down the line.

Let me know if you need further clarification or assistance with a workaround!

1 replies left - Become PRO for more replies.
thread_tEcqPXOf17pBScPz9C7vXTp1
Reply to this post directly if you need further help (bottom right button)

Hi! You mean blend modes that go beyond the glTF blend modes ā€œblendā€, ā€œmaskā€, and ā€œopaqueā€, right?

There is some discussion on agreeing on a glTF extension here:

Would be great if you could chime in there with your use cases!

Yeah this is indeed the issue. The use case is somewhat simple its just that we are migrating all of data (models, textures, shaders, materials) (something over 400+GB) to Unity and Needle in both large batches and make new ones. It would be possible to make editor script, pre processing before export and some export checks but I was just hoping for a fix that would take the least ammount of time and be somewhat foolproof.

For that amount of assets maybe it makes sense to automate things with a custom extension?

That’s rather easy to do and gives you a lot of flexibility on how to handle custom things (like blend modes in materials).

It’s basically the same as we would do when we ultimately implement material blend modes, just that when we would do it it would ship at the core of Needle and thus ā€œjust workā€ everywhere Needle is used, whereas when you define custom extensions they only work where your code runs.

Here’s a full example:

Needle Engine plugin for loading material extension data

import { addCustomExtensionPlugin, Context, INeedleGLTFExtensionPlugin } from "@needle-tools/engine";
import { AdditiveBlending, Material } from "three";
import { GLTFParser, GLTFLoader, GLTFLoaderPlugin } from "three/examples/jsm/loaders/GLTFLoader.js";

// Needle Engine plugin to register plugins with all GLTFLoaders
class MyMaterialExtensionPlugin implements INeedleGLTFExtensionPlugin {
    /** @readonly */
    name = "MY_material_extension_Plugin";

    // Whenever a glTF file is imported (from <needle-engine>, DropListener, etc.),
    // this callback will be called before the import starts, and can be used to
    // extend the GLTFLoader with custom plugins.
    onImport = (loader: GLTFLoader, url: string, context: Context) => {
        loader.register((parser) => {
            return new MyMaterialExtensionLoaderPlugin(parser);
        });
    }
}

// three.js plugin to extend the three.js GLTFLoader
// See {@type {GLTFLoaderPlugin}} for more information on other available callbacks.
class MyMaterialExtensionLoaderPlugin implements GLTFLoaderPlugin {
    /** @readonly */
    name = "MY_material_extension";
    parser: GLTFParser;

    constructor(parser: GLTFParser) {
		this.parser = parser;
	}

    loadMaterial(materialIndex: number): Promise<Material> | null {
        const materialDef = this.parser.json.materials[materialIndex];

        // If the material does not have this extension, we can just let the parser handle it
        if (!materialDef.extensions || !materialDef.extensions[this.name])
            return null;

        // Load the material, so that we can modify it
        return new Promise(async (resolve, reject) => {
            const mat = await this.parser.loadMaterial(materialIndex);

            // Access the glTF material definition and extension data
            if (materialDef.extensions && materialDef.extensions[this.name]) {
                const extension = materialDef.extensions[this.name];
                // TODO access extension properties here...
                // Here we can modify the created material, e.g. set custom uniforms or properties.
                mat.blending = AdditiveBlending;
                mat.transparent = true;
                console.log("Loaded material with MY_material_extension", extension, mat);
            }
            resolve(mat);
        });
    }
}

addCustomExtensionPlugin(new MyMaterialExtensionPlugin());

Needle Engine for Unity plugin to export material extension data

using System;
using UnityEngine;
using Needle.Engine.Gltf;

[Serializable]
class MyMaterialExtension
{
	public string hello = "world";
	public int number = 42;
}

class MaterialExtension: GltfExtensionHandlerBase
{
	public override void OnAfterMaterialExport(GltfExportContext context, Material material, int materialId)
	{
		base.OnAfterMaterialExport(context, material, materialId);
		context.Bridge.AddMaterialExtension(materialId, "MY_material_extension", new MyMaterialExtension()
		{
			hello = "world 2",
			number = 100,
		});
	}
}

Hope that helps!

1 Like

Thanks for the example the only issue I am facing that I cant seem to load Needle.Engine.Gltf. I am on Needle Engine 4.7.4. Which package includes these classes?

I don’t think you need all of these but here’s glTF classes across Needle + UnityGLTF:

1 Like

Everything seems to be working great thanks once again.

That’s great to hear – wish you all the best!

1 Like

This topic was automatically closed 13 days after the last reply. New replies are no longer allowed.