Initial commit

This commit is contained in:
angree
2025-05-23 17:55:53 +02:00
commit 03f0bc14da
9 changed files with 6026 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+190
View File
@@ -0,0 +1,190 @@
# ComfyUI-Q_GLB_Material_Modifier
A ComfyUI custom node for enhancing GLB 3D models generated with Hunyuan 3D 2.0. This module helps solve the common "plastic look" problem by adding realistic materials and smart emissive elements.
## Features
- Transforms the default "plastic" appearance of Hunyuan 3D 2.0 models into realistic materials
- Automatically detects bright areas in textures and converts them to emissive parts
- Preserves the original colors of the emissive areas
- Properly embeds emissive textures directly into the GLB file
- Easy to use with presets for common materials
- Works with any GLB model from Hunyuan 3D 2.0
## Installation
1. Clone this repository into your ComfyUI's `custom_nodes` directory:
```bash
cd ComfyUI/custom_nodes
git clone https://github.com/YOUR_USERNAME/ComfyUI-Q_GLB_Material_Modifier.git
```
2. Install required dependencies:
```bash
pip install -r requirements.txt
```
or install manually:
```bash
pip install pygltflib>=1.16.1 opencv-python>=4.8.0 pillow>=10.0.0 numpy>=1.24.0
```
3. Restart ComfyUI
## Dependencies
This module requires the following Python libraries:
- **pygltflib**: For GLB/GLTF file manipulation
- **opencv-python**: For image processing operations
- **pillow**: For image loading and conversion
- **numpy**: For array operations
A `requirements.txt` file is included for easy installation.
## Usage with Hunyuan 3D 2.0
The extension provides two main nodes specifically designed for enhancing Hunyuan 3D 2.0 outputs:
### Q Manual GLB Material Modifier
This node provides full control over material parameters:
- **glb_path**: Path to your Hunyuan 3D 2.0 GLB file
- **texture_image**: Input texture from Hunyuan 3D 2.0
- **output_suffix**: Suffix to add to the output filename (default: "_modified")
- **metallic_factor**: How metallic the surface should be (0-1)
- **smoothness**: How smooth the surface should be (0-1)
- **base_color_r/g/b**: Base color tint
- **emissive_brightness_threshold**: Threshold for detecting bright areas
- **emissive_percentage**: Percentage of the brightest pixels to make emissive
- **absolute_min_brightness**: Minimum brightness to consider emissive
- **emissive_strength**: Brightness multiplier for emissive areas
- **enable_smart_emissive**: Enable/disable emissive effect
- **render**: Enable/disable processing (when disabled, skips GLB generation)
### Q Preset GLB Material Modifier
This node provides convenient presets specifically designed for Hunyuan 3D 2.0 models:
- **glb_path**: Path to your Hunyuan 3D 2.0 GLB file
- **texture_image**: Input texture from Hunyuan 3D 2.0
- **preset**: Choose from predefined material presets:
- Spaceship Metal
- Brushed Steel
- Chrome Hull
- Titanium
- Combat Metal
- Alien Tech
- **output_suffix**: Suffix to add to the output filename (default: "_modified")
- **emissive_mode**: Smart Auto, Force On, or Force Off
- **absolute_min_brightness**: Minimum brightness to consider emissive
- **render**: Enable/disable processing (when disabled, skips GLB generation)
## Hunyuan 3D 2.0 Workflows
In the `workflows` subfolder, you'll find example ComfyUI workflows specifically for Hunyuan 3D 2.0:
### Fixing the "Plastic Look" Problem
Hunyuan 3D 2.0 models (using DIT 2.0 fp16) typically have a default "plastic" appearance:
- The preset modifiers are specifically designed to transform this plastic look into realistic materials
- Chrome Hull preset works well for sci-fi and mechanical objects
- Brushed Steel creates a more industrial look
- Titanium is good for high-tech and aerospace models
- Adjust the metallic_factor and smoothness in the Manual modifier for fine control
### Batch Generation
Generate multiple variants of a Hunyuan 3D 2.0 model with different materials:
- Connect multiple Q Preset GLB Material Modifier nodes to the same texture
- Set different output_suffix values for each variant (e.g., "_chrome", "_steel")
- Use the render parameter to selectively enable only the variants you want to generate
- This workflow is efficient for testing different material looks without regenerating the 3D model
### Emission Map Generation
Create glowing elements in your Hunyuan 3D 2.0 models:
- Adjust emissive_brightness_threshold to control which areas will glow
- Use emissive_percentage to fine-tune the amount of emissive areas
- The emissive texture preserves the original colors from the Hunyuan texture
- For sci-fi models, try the "Alien Tech" preset with emissive_mode set to "Force On"
## License
[MIT License](LICENSE)
# ComfyUI-Q_GLB_Material_Modifier
A ComfyUI custom node for adding smart emissive materials to GLB 3D models. Perfect for adding glowing elements to your 3D models based on the brightest parts of textures generated with AI.
## Features
- Automatically detects bright areas in textures and converts them to emissive parts
- Preserves the original colors of the emissive areas
- Properly embeds emissive textures directly into the GLB file
- Easy to use with presets for common material types
- Works with any GLB model and any texture
## Installation
1. Clone this repository into your ComfyUI's `custom_nodes` directory:
```bash
cd ComfyUI/custom_nodes
git clone https://github.com/YOUR_USERNAME/ComfyUI-Q_GLB_Material_Modifier.git
```
2. Install required dependencies:
```bash
pip install pygltflib pillow opencv-python
```
3. Restart ComfyUI
## Usage
The extension provides two main nodes:
### Q Manual GLB Material Modifier
This node provides full control over material parameters:
- **glb_path**: Path to your GLB file
- **texture_image**: Input texture (e.g. from AI generation)
- **output_suffix**: Suffix to add to the output filename (default: "_modified")
- **metallic_factor**: How metallic the surface should be (0-1)
- **smoothness**: How smooth the surface should be (0-1)
- **base_color_r/g/b**: Base color tint
- **emissive_brightness_threshold**: Threshold for detecting bright areas
- **emissive_percentage**: Percentage of the brightest pixels to make emissive
- **absolute_min_brightness**: Minimum brightness to consider emissive
- **render**: Enable/disable processing (when disabled, skips GLB generation)
- **emissive_strength**: Brightness multiplier for emissive areas
- **enable_smart_emissive**: Enable/disable emissive effect
- **render**: Enable/disable processing (when disabled, skips GLB generation)
### Q Preset GLB Material Modifier
This node provides convenient presets for common materials:
- **glb_path**: Path to your GLB file
- **texture_image**: Input texture (e.g. from AI generation)
- **preset**: Choose from predefined material presets:
- Spaceship Metal
- Brushed Steel
- Chrome Hull
- Titanium
- Combat Metal
- Alien Tech
- **output_suffix**: Suffix to add to the output filename (default: "_modified")
- **emissive_mode**: Smart Auto, Force On, or Force Off
- **absolute_min_brightness**: Minimum brightness to consider emissive
## Example Workflow
1. Generate a texture using your favorite image generation node
2. Connect the generated image to the `texture_image` input of the Q Preset GLB Material Modifier node
3. Set the path to your GLB file
4. Choose a preset that matches your desired look
5. Run the workflow to get a modified GLB with emissive materials
## License
[MIT License](LICENSE)
+11
View File
@@ -0,0 +1,11 @@
from .q_glb_material_modifier import QManualGLBMaterialModifier, QPresetGLBMaterialModifier
NODE_CLASS_MAPPINGS = {
"QManualGLBMaterialModifier": QManualGLBMaterialModifier,
"QPresetGLBMaterialModifier": QPresetGLBMaterialModifier,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"QManualGLBMaterialModifier": "Q Manual GLB Material Modifier",
"QPresetGLBMaterialModifier": "Q Preset GLB Material Modifier",
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
+430
View File
@@ -0,0 +1,430 @@
import json
import os
from pathlib import Path
import shutil
import numpy as np
from PIL import Image, ImageEnhance, ImageFilter
import cv2
import torch
from io import BytesIO
import base64
class QManualGLBMaterialModifier:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"glb_path": ("STRING", {"default": "", "multiline": False}),
"texture_image": ("IMAGE", {"forceInput": True}),
"output_suffix": ("STRING", {"default": "_modified", "multiline": False}),
"metallic_factor": ("FLOAT", {"default": 0.85, "min": 0.0, "max": 1.0, "step": 0.01}),
"smoothness": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
"base_color_r": ("FLOAT", {"default": 0.7, "min": 0.0, "max": 1.0, "step": 0.01}),
"base_color_g": ("FLOAT", {"default": 0.8, "min": 0.0, "max": 1.0, "step": 0.01}),
"base_color_b": ("FLOAT", {"default": 0.9, "min": 0.0, "max": 1.0, "step": 0.01}),
"emissive_brightness_threshold": ("FLOAT", {"default": 0.2, "min": 0.05, "max": 0.5, "step": 0.01}),
"emissive_percentage": ("FLOAT", {"default": 0.05, "min": 0.01, "max": 0.15, "step": 0.01}),
"absolute_min_brightness": ("INT", {"default": 128, "min": 50, "max": 200, "step": 1}),
"emissive_strength": ("FLOAT", {"default": 0.8, "min": 0.0, "max": 2.0, "step": 0.1}),
"enable_smart_emissive": ("BOOLEAN", {"default": True}),
"render": ("BOOLEAN", {"default": True}),
}
}
RETURN_TYPES = ("STRING", "IMAGE")
RETURN_NAMES = ("modified_glb_path", "emissive_mask_preview")
FUNCTION = "modify_material_smart"
CATEGORY = "3d/q_material"
def create_emissive_texture(self, original_image, emissive_mask, emissive_strength):
"""
Creates a proper colored emissive texture that preserves original colors in emissive areas
"""
# Convert mask to 3-channel if needed
if len(emissive_mask.shape) == 2:
# Create a mask with 3 channels
emissive_mask_3d = np.stack([emissive_mask, emissive_mask, emissive_mask], axis=-1)
else:
emissive_mask_3d = emissive_mask
# Normalize mask to [0,1]
mask_normalized = emissive_mask_3d.astype(np.float32) / 255.0
# Create colored emissive texture that preserves original colors in bright areas
# Use original colors where mask is bright, black where mask is dark
emissive_texture = original_image * mask_normalized * emissive_strength
# Clip to valid range
emissive_texture = np.clip(emissive_texture, 0, 1)
return emissive_texture
def analyze_texture_brightness(self, image_tensor, brightness_threshold, percentage, absolute_min_threshold=128):
"""
Analyzes texture and creates smart emissive mask
"""
# Check if it's a tensor or already a numpy array
if hasattr(image_tensor, 'cpu'):
image_np_raw = image_tensor.cpu().numpy()
else:
image_np_raw = image_tensor
# Remove batch dimension if it exists
if len(image_np_raw.shape) == 4:
image_np_raw = image_np_raw[0]
# Convert from float [0,1] to uint8 [0,255]
image_np = (image_np_raw * 255).astype(np.uint8)
# Create PIL Image
pil_image = Image.fromarray(image_np)
# Convert to grayscale for brightness analysis
gray = pil_image.convert('L')
gray_np = np.array(gray)
# Calculate brightness statistics
mean_brightness = np.mean(gray_np) / 255.0
# Find percentile for brightest pixels
bright_threshold_value = np.percentile(gray_np, (1.0 - percentage) * 100)
# Use higher value from two thresholds
final_threshold = max(bright_threshold_value, absolute_min_threshold)
# Check if brightest pixels are significantly brighter than average
brightness_contrast = (final_threshold / 255.0) - mean_brightness
# Create emissive mask only if contrast is sufficient
if brightness_contrast >= brightness_threshold:
# Create mask for brightest pixels
emissive_mask = (gray_np >= final_threshold).astype(np.uint8) * 255
# Optional: slight blur of mask for smoother transition
emissive_mask = cv2.GaussianBlur(emissive_mask, (3, 3), 0)
# Normalize mask
if np.max(emissive_mask) > 0:
emissive_mask = (emissive_mask / np.max(emissive_mask) * 255).astype(np.uint8)
else:
emissive_mask = np.zeros_like(gray_np, dtype=np.uint8)
return emissive_mask, False
return emissive_mask, True
else:
return np.zeros_like(gray_np, dtype=np.uint8), False
def image_to_data_uri(self, image_array, format='png'):
"""Convert image array to data URI"""
if len(image_array.shape) == 3:
# Convert to PIL Image
if image_array.dtype == np.float32 or image_array.dtype == np.float64:
# Convert float [0,1] to uint8 [0,255]
image_array = (image_array * 255).astype(np.uint8)
pil_image = Image.fromarray(image_array)
# Save to BytesIO
buffer = BytesIO()
pil_image.save(buffer, format=format)
buffer.seek(0)
# Convert to base64
mime_type = f"image/{format}"
encoded = base64.b64encode(buffer.read()).decode('ascii')
return f"data:{mime_type};base64,{encoded}"
return None
def modify_material_smart(self, glb_path, texture_image, output_suffix, metallic_factor, smoothness,
base_color_r, base_color_g, base_color_b,
emissive_brightness_threshold, emissive_percentage, absolute_min_brightness,
emissive_strength, enable_smart_emissive, render):
try:
from pygltflib import GLTF2, TextureInfo, Image as GLTFImage, Texture, Sampler
except ImportError:
print("ERROR: pygltflib not installed. Install with: pip install pygltflib")
black_mask = np.zeros((512, 512, 3), dtype=np.float32)
return ("PYGLTFLIB_NOT_INSTALLED", torch.from_numpy(black_mask[None, ...]))
# Check if rendering is disabled
if not render:
print("Rendering disabled, skipping GLB processing")
# Return only the filename and a black preview
if hasattr(texture_image, 'cpu'):
shape = texture_image[0].cpu().numpy().shape
else:
shape = texture_image[0].shape if len(texture_image.shape) == 4 else texture_image.shape
black_mask = np.zeros(shape, dtype=np.float32)
return ("RENDER_DISABLED", torch.from_numpy(black_mask[None, ...]))
# Path validation and clean-up
if not glb_path or glb_path.strip() == "":
print("ERROR: No GLB file path provided")
black_mask = np.zeros((512, 512, 3), dtype=np.float32)
return ("NO_PATH_PROVIDED", torch.from_numpy(black_mask[None, ...]))
# Clean up path - remove quotes and whitespace
glb_path = glb_path.strip().strip('"\'')
# First check if the path exists directly as provided
if os.path.exists(glb_path) and os.path.isfile(glb_path):
actual_glb_path = glb_path
else:
# Check if this is a relative path or just a filename
if os.path.dirname(glb_path) == "":
# This is just a filename, check in output directories
possible_paths = [
os.path.join(os.getcwd(), glb_path), # Current dir + filename
os.path.join("output", glb_path), # output/ + filename
os.path.join("ComfyUI", "output", glb_path), # ComfyUI/output/ + filename
os.path.join("..", "output", glb_path), # ../output/ + filename
]
else:
# This is a path with directories, just normalize it
normalized_path = os.path.normpath(glb_path)
possible_paths = [normalized_path]
# Also try some variations with .glb extension if not already there
if not normalized_path.lower().endswith('.glb'):
possible_paths.append(f"{normalized_path}.glb")
# Check all possible locations
found_path = None
for path in possible_paths:
if os.path.exists(path) and os.path.isfile(path):
found_path = path
break
if found_path:
actual_glb_path = found_path
else:
# Wait a bit and try again
import time
time.sleep(2)
# Check again
for path in possible_paths:
if os.path.exists(path) and os.path.isfile(path):
found_path = path
break
if found_path:
actual_glb_path = found_path
else:
print(f"File not found: {glb_path}")
black_preview = np.zeros((1, 512, 512, 3), dtype=np.float32)
return ("FILE_NOT_FOUND", torch.from_numpy(black_preview))
# Create a new path for the modified file
base_path, ext = os.path.splitext(actual_glb_path)
modified_glb_path = f"{base_path}{output_suffix}{ext}"
# Load the GLB file
print(f"Loading GLB file: {actual_glb_path}")
gltf = GLTF2().load(actual_glb_path)
# Process emissive map
emissive_mask = None
has_emissive = False
emissive_data_uri = None
if enable_smart_emissive:
# Generate emissive mask
emissive_mask, has_emissive = self.analyze_texture_brightness(
texture_image, emissive_brightness_threshold, emissive_percentage, absolute_min_brightness
)
if has_emissive:
print(f"Creating emissive texture")
# Get original texture for color reference
if hasattr(texture_image, 'cpu'):
original_rgb = texture_image[0].cpu().numpy()
else:
original_rgb = texture_image[0] if len(texture_image.shape) == 4 else texture_image
# Create colored emissive texture
emissive_texture = self.create_emissive_texture(
original_rgb, emissive_mask, emissive_strength
)
# Convert to 8-bit for saving
emissive_texture_8bit = (emissive_texture * 255).astype(np.uint8)
# Convert emissive texture to data URI
emissive_data_uri = self.image_to_data_uri(emissive_texture_8bit)
# Save for preview - use the colored emissive texture, not just the mask
emissive_preview = emissive_texture[None, ...] # Add batch dimension
else:
print(f"No emissive areas detected")
emissive_preview = None
else:
print(f"Smart emissive disabled")
has_emissive = False
emissive_preview = None
# Update materials in the GLTF
roughness_factor = 1.0 - smoothness # Convert Unity smoothness to glTF roughness
# Add emissive texture to glTF if needed
emissive_texture_index = None
if has_emissive and emissive_data_uri:
# Create an image for the emissive texture
emissive_image = GLTFImage()
emissive_image.uri = emissive_data_uri
emissive_image.mimeType = "image/png"
emissive_image_index = len(gltf.images)
gltf.images.append(emissive_image)
# Make sure we have a sampler
if not gltf.samplers:
default_sampler = Sampler()
default_sampler.magFilter = 9729 # LINEAR
default_sampler.minFilter = 9987 # LINEAR_MIPMAP_LINEAR
default_sampler.wrapS = 10497 # REPEAT
default_sampler.wrapT = 10497 # REPEAT
gltf.samplers.append(default_sampler)
# Create a texture referencing the image
emissive_texture = Texture()
emissive_texture.source = emissive_image_index
emissive_texture.sampler = 0 # Use first sampler
emissive_texture_index = len(gltf.textures)
gltf.textures.append(emissive_texture)
print(f"Added emissive texture at index {emissive_texture_index}")
# Update all materials
for i, material in enumerate(gltf.materials):
# Set base PBR properties
if not hasattr(material, 'pbrMetallicRoughness'):
from pygltflib import PbrMetallicRoughness
material.pbrMetallicRoughness = PbrMetallicRoughness()
material.pbrMetallicRoughness.baseColorFactor = [
base_color_r, base_color_g, base_color_b, 1.0
]
material.pbrMetallicRoughness.metallicFactor = metallic_factor
material.pbrMetallicRoughness.roughnessFactor = roughness_factor
# Set emissive properties if we have them
if has_emissive and emissive_texture_index is not None:
# Create a TextureInfo for the emissive texture
emissive_texture_info = TextureInfo()
emissive_texture_info.index = emissive_texture_index
material.emissiveTexture = emissive_texture_info
# Set emissive factor to white (1,1,1) to show full texture colors
material.emissiveFactor = [1.0, 1.0, 1.0]
print(f"Applied emissive texture to material {i}")
else:
# No emissive
material.emissiveFactor = [0.0, 0.0, 0.0]
# Save the modified GLB file
print(f"Saving modified GLB to {modified_glb_path}")
gltf.save(modified_glb_path)
# Return only the filename of the modified GLB (not the full path)
output_filename = os.path.basename(modified_glb_path)
# Return preview of emissive texture if available
if emissive_preview is not None:
return (output_filename, torch.from_numpy(emissive_preview))
else:
# Create a black preview image
if hasattr(texture_image, 'cpu'):
shape = texture_image[0].cpu().numpy().shape
else:
shape = texture_image[0].shape if len(texture_image.shape) == 4 else texture_image.shape
black_mask = np.zeros(shape, dtype=np.float32)
return (output_filename, torch.from_numpy(black_mask[None, ...]))
# Simplified presets for Unity-style
class QPresetGLBMaterialModifier:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"glb_path": ("STRING", {"default": "", "multiline": False}),
"texture_image": ("IMAGE", {"forceInput": True}),
"preset": (["Spaceship Metal", "Brushed Steel", "Chrome Hull", "Chrome Hull Lite", "Titanium", "Combat Metal", "Alien Tech"], {"default": "Spaceship Metal"}),
"output_suffix": ("STRING", {"default": "_modified", "multiline": False}),
"emissive_mode": (["Smart Auto", "Force On", "Force Off"], {"default": "Smart Auto"}),
"absolute_min_brightness": ("INT", {"default": 128, "min": 50, "max": 200, "step": 1}),
"render": ("BOOLEAN", {"default": True}),
}
}
RETURN_TYPES = ("STRING", "IMAGE")
RETURN_NAMES = ("modified_glb_path", "emissive_mask_preview")
FUNCTION = "apply_material_preset"
CATEGORY = "3d/q_material"
def apply_material_preset(self, glb_path, texture_image, preset, output_suffix, emissive_mode, absolute_min_brightness, render):
# Unity-style presets
presets = {
"Spaceship Metal": {
"metallic": 0.85, "smoothness": 0.5,
"color": [0.7, 0.8, 0.9], "emissive_strength": 0.8,
"brightness_threshold": 0.2, "percentage": 0.05
},
"Brushed Steel": {
"metallic": 0.9, "smoothness": 0.3,
"color": [0.8, 0.8, 0.8], "emissive_strength": 0.6,
"brightness_threshold": 0.25, "percentage": 0.03
},
"Chrome Hull": {
"metallic": 1.0, "smoothness": 0.9,
"color": [0.95, 0.95, 0.95], "emissive_strength": 0.9,
"brightness_threshold": 0.15, "percentage": 0.08
},
"Chrome Hull Lite": {
"metallic": 1.0, "smoothness": 0.72,
"color": [0.95, 0.95, 0.95], "emissive_strength": 0.9,
"brightness_threshold": 0.15, "percentage": 0.08
},
"Titanium": {
"metallic": 0.8, "smoothness": 0.4,
"color": [0.6, 0.6, 0.7], "emissive_strength": 0.7,
"brightness_threshold": 0.22, "percentage": 0.04
},
"Combat Metal": {
"metallic": 0.7, "smoothness": 0.2,
"color": [0.5, 0.5, 0.6], "emissive_strength": 1.0,
"brightness_threshold": 0.18, "percentage": 0.06
},
"Alien Tech": {
"metallic": 0.6, "smoothness": 0.7,
"color": [0.4, 0.8, 0.6], "emissive_strength": 1.2,
"brightness_threshold": 0.12, "percentage": 0.1
}
}
settings = presets[preset]
enable_emissive = emissive_mode != "Force Off"
# Use the main node - pass all parameters
modifier = QManualGLBMaterialModifier()
return modifier.modify_material_smart(
glb_path=glb_path,
texture_image=texture_image,
output_suffix=output_suffix,
metallic_factor=settings["metallic"],
smoothness=settings["smoothness"],
base_color_r=settings["color"][0],
base_color_g=settings["color"][1],
base_color_b=settings["color"][2],
emissive_brightness_threshold=settings["brightness_threshold"],
emissive_percentage=settings["percentage"],
absolute_min_brightness=absolute_min_brightness,
emissive_strength=settings["emissive_strength"],
enable_smart_emissive=enable_emissive,
render=render
)
+4
View File
@@ -0,0 +1,4 @@
pygltflib>=1.16.1
opencv-python>=4.8.0
pillow>=10.0.0
numpy>=1.24.0
File diff suppressed because it is too large Load Diff