Q Manual GLB Material Modifier
Fixing Hunyuan 3D GLBs the manual way
- texture_image
- normal_texture
- modified_glb_path
- emissive_mask_preview
- normal_map_preview
Hunyuan 3D 2.0 is great at giving you a textured model fast, but that texture is plastic. Everything comes out looking like a shiny toy. This node is the band-aid: it takes the GLB and the diffuse texture, re-tints the material, generates real normal maps, and optionally burns bright spots into emissive. You get a .glb that actually reads as metal, hull, or sci-fi paneling instead of "3D print in a museum."
It's from the Q GLB Material Modifier pack by angree, a small one-file utility that exists for exactly one workflow: after Hunyuan 3D 2.0 spits out a model, before you drop it into a game engine or a render. It does not call any API, needs no key, and touches no weights - it's pure post-processing on files that already exist.
What it actually does
Under the hood it's pygltflib plus OpenCV. The node loads your GLB, and for every material in the file it sets a baseColorFactor, a metallicFactor, and a roughnessFactor (which it computes as 1 - smoothness, since the input is named like Unity's smoothness). Then it builds an emissive texture and a normal texture, embeds them as base64 PNG data URIs right inside the GLB, and saves a new file next to the original with your chosen suffix. Nothing in-place, nothing destructive - the source file is never touched.
The two clever bits:
- Emissive detection converts your diffuse texture to luminance, finds the brightest pixels (a percentile threshold plus an absolute minimum brightness), smooths the mask with a Gaussian, and uses it to make a colored emissive texture that preserves the original pixel colors - so glowing engine parts actually glow their own color.
- Normal generation treats the diffuse as a heightmap and runs either a Sobel filter or a simple gradient, then normalizes and packs the result into a normal map. The
AutoGen Subtle → Dramaticmodes are just different strength/blur/contrast presets, andnormal_noiseadds multi-octave procedural detail for surface roughness.
The inputs that matter
You wire in two things: texture_image (the diffuse texture from Hunyuan 3D 2.0) and glb_path - which is a string with a file path, not a file upload widget. Paste the path to the GLB on disk, or just the filename and let its search logic hunt through output/ and ComfyUI/output/.
metallic_factor(default 0.85) andsmoothness(default 0.5) - the two knobs that kill the plastic look. High metallic + medium-to-high smoothness = metal; low smoothness = matte.base_color_r/g/b- a tint that multiplies the existing diffuse texture. Leave near 1.0 unless you want a color shift.emissive_mode-No Emissive,With Emissive, orBoth Versions(writes one with and one without the glow).normal_mode_1/normal_mode_2- pick normal presets; if both are on, you get two variants per emissive mode (up to 4 GLBs per run).Use Input Textureneeds the optionalnormal_textureinput.render- this is the "test mode" toggle. When off, it skips all GLB work and just returns placeholder previews, so you can tune without generating files.
The three outputs: modified_glb_path (a string - see the gotcha below), emissive_mask_preview, and normal_map_preview (both images you can save or preview in ComfyUI).
Installing it
cd ComfyUI/custom_nodes
git clone https://github.com/angree/ComfyUI-Q_GLB_Material_Modifier
cd ComfyUI-Q_GLB_Material_Modifier
pip install -r requirements.txt
Then restart ComfyUI. ComfyUI Manager can also find it if you search "Q GLB Material Modifier". The dependencies are light - pygltflib, opencv-python, pillow, numpy - no models to download, no CUDA-specific install beyond whatever you already have for Hunyuan 3D. (The README's clone URL has a YOUR_USERNAME placeholder in it - that's a typo; the real repo is angree/ComfyUI-Q_GLB_Material_Modifier.)
Gotchas worth knowing
- The
modified_glb_pathoutput is just the filename, not the full path - the code returnsos.path.basename(...). The file is written next to your source GLB. If a downstream node needs a real path, prepend the source directory. - If pygltflib isn't installed, the node doesn't crash - it returns the literal string
PYGLTFLIB_NOT_INSTALLEDand blank previews. Same pattern forRENDER_DISABLED,NO_PATH_PROVIDED, andFILE_NOT_FOUND. If you see one of those strings on the output, that's your diagnosis. - It rewrites every material in the GLB with the same values. Multi-material models get flattened to one look. For Hunyuan 3D 2.0's single-texture outputs that's fine; for anything fancier, this node is the wrong tool.
- The source GLB is never modified - look in the same folder for
_modifiedfiles, or whateveroutput_suffixyou set.
Inputs (21)
| Name | Type | Default | Description |
|---|---|---|---|
| glb_path | STRING | — | |
| texture_image | IMAGE | — | |
| output_suffix | STRING | _modified | — |
| metallic_factor | FLOAT | 0.850–1 | — |
| smoothness | FLOAT | 0.500–1 | — |
| base_color_r | FLOAT | 0.700–1 | — |
| base_color_g | FLOAT | 0.800–1 | — |
| base_color_b | FLOAT | 0.900–1 | — |
| emissive_brightness_threshold | FLOAT | 0.200.05–0.5 | — |
| emissive_percentage | FLOAT | 0.050.01–0.15 | — |
| absolute_min_brightness | INT | 12850–200 | — |
| emissive_strength | FLOAT | 0.80–2 | — |
| emissive_mode | COMBO | With Emissive | 3 options: No Emissive, With Emissive, Both Versions |
| render | BOOLEAN | true | — |
| normal_mode_1 | COMBO | No Normal Map | 7 options: No Normal Map, Use Input Texture, AutoGen Subtle, AutoGen Normal, AutoGen Enhanced, AutoGen Dramatic, +1 |
| normal_mode_2 | COMBO | Disable | 8 options: Disable, No Normal Map, Use Input Texture, AutoGen Subtle, AutoGen Normal, AutoGen Enhanced, +2 |
| normal_algorithm | COMBO | Sobel Filter | 2 options: Sobel Filter, Simple Gradient |
| normal_scale | COMBO | 1x (Original) | 3 options: 1x (Original), 2x (Half Size), 4x (Quarter Size) |
| normal_compression | BOOLEAN | true | — |
| normal_noise | FLOAT | 0.250–0.5 | — |
| normal_textureopt | IMAGE | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| modified_glb_path | STRING | — |
| emissive_mask_preview | IMAGE | — |
| normal_map_preview | IMAGE | — |