4.8 KiB
4.8 KiB
Documentation
- Class name: ConvertNormals
- Category: image/filters
- Output node: False
- Repo Ref: https://github.com/comfyanonymous/ComfyUI
ConvertNormals节点专门用于转换法线贴图的格式,调整其比例,并可选择性地进行归一化或填充缺失区域。它支持多种输入和输出模式,能够灵活地调整法线贴图以适应不同的渲染或处理需求。这个节点在图形和图像处理流程中特别有用,尤其是在需要将法线贴图转换或调整以满足特定用途时。
Input types
Required
- normals
- 需要转换的输入法线贴图张量。这是节点操作的核心参数,它会根据其他输入参数进行各种转换。
- Comfy dtype: IMAGE
- Python dtype: torch.Tensor
- input_mode
- 指定输入法线贴图的格式,影响其初始处理方式。该参数决定了在进行进一步转换之前,对法线贴图进行的初始调整。
- Comfy dtype: COMBO[STRING]
- Python dtype: str
- output_mode
- 定义输出法线贴图的期望格式,指导对张量进行最终调整。此参数确保转换后的法线贴图满足特定的格式要求。
- Comfy dtype: COMBO[STRING]
- Python dtype: str
- scale_XY
- 应用于法线贴图X和Y分量的缩放因子,影响其整体外观。此参数允许微调法线贴图在表面上的视觉效果。
- Comfy dtype: FLOAT
- Python dtype: float
- normalize
- 一个布尔标志,指示是否在转换后对法线贴图进行归一化。归一化确保法线贴图的向量为单位长度,这通常是为了保证一致的光照效果。
- Comfy dtype: BOOLEAN
- Python dtype: bool
- fix_black
- 一个布尔标志,当启用时,会对法线贴图中的黑色区域进行修正,可能会基于optional_fill参数填充这些区域。这对于修复或增强具有缺失数据的法线贴图很有用。
- Comfy dtype: BOOLEAN
- Python dtype: bool
Optional
- optional_fill
- 一个可选的张量,用于在启用fix_black时填充法线贴图中的黑色区域。此参数允许应用自定义填充模式或颜色,增强了节点的多功能性。
- Comfy dtype: IMAGE
- Python dtype: torch.Tensor
Output types
- image
- 转换后的法线贴图张量,根据指定的输入和输出模式、缩放、归一化和可选填充进行调整。这个输出可以直接用于后续的处理或渲染步骤。
- Comfy dtype: IMAGE
- Python dtype: torch.Tensor
Usage tips
- Infra type:
GPU - Common nodes: unknown
Source code
class ConvertNormals:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"normals": ("IMAGE",),
"input_mode": (["BAE", "MiDaS", "Standard"],),
"output_mode": (["BAE", "MiDaS", "Standard"],),
"scale_XY": ("FLOAT",{"default": 1, "min": 0, "max": 100, "step": 0.001}),
"normalize": ("BOOLEAN", {"default": True}),
"fix_black": ("BOOLEAN", {"default": True}),
},
"optional": {
"optional_fill": ("IMAGE",),
},
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "convert_normals"
CATEGORY = "image/filters"
def convert_normals(self, normals, input_mode, output_mode, scale_XY, normalize, fix_black, optional_fill=None):
t = normals.detach().clone()
if input_mode == "BAE":
t[:,:,:,0] = 1 - t[:,:,:,0] # invert R
elif input_mode == "MiDaS":
t[:,:,:,:3] = torch.stack([1 - t[:,:,:,2], t[:,:,:,1], t[:,:,:,0]], dim=3) # BGR -> RGB and invert R
if fix_black:
key = torch.clamp(1 - t[:,:,:,2] * 2, min=0, max=1)
if optional_fill == None:
t[:,:,:,0] += key * 0.5
t[:,:,:,1] += key * 0.5
t[:,:,:,2] += key
else:
fill = optional_fill.detach().clone()
if fill.shape[1:3] != t.shape[1:3]:
fill = torch.nn.functional.interpolate(fill.movedim(-1,1), size=(t.shape[1], t.shape[2]), mode='bilinear').movedim(1,-1)
if fill.shape[0] != t.shape[0]:
fill = fill[0].unsqueeze(0).expand(t.shape[0], -1, -1, -1)
t[:,:,:,:3] += fill[:,:,:,:3] * key.unsqueeze(3).expand(-1, -1, -1, 3)
t[:,:,:,:2] = (t[:,:,:,:2] - 0.5) * scale_XY + 0.5
if normalize:
t[:,:,:,:3] = torch.nn.functional.normalize(t[:,:,:,:3] * 2 - 1, dim=3) / 2 + 0.5
if output_mode == "BAE":
t[:,:,:,0] = 1 - t[:,:,:,0] # invert R
elif output_mode == "MiDaS":
t[:,:,:,:3] = torch.stack([t[:,:,:,2], t[:,:,:,1], 1 - t[:,:,:,0]], dim=3) # invert R and BGR -> RGB
return (t,)