You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Maya Python及Nuke中HDRI亮斑坐标提取与2D转3D方法咨询

问题1:Maya中通过Python提取穹顶灯HDRI亮斑3D坐标

是可以实现的,核心逻辑是读取HDRI像素筛选亮斑,将2D纹理坐标映射到穹顶灯的球面坐标后转换为3D笛卡尔坐标,参考实现步骤如下:

  • 首先获取当前场景中Arnold穹顶灯绑定的HDRI文件路径
  • 读取HDRI文件的像素亮度信息,设置阈值筛选高亮区域,计算亮斑质心的2D纹理坐标
  • 将2D UV坐标转换为球面经纬度,再映射为3D坐标,同步对齐穹顶灯的世界变换参数
  • 最终将坐标导出为CSV/JSON等格式即可

简化实现代码示例:

import maya.cmds as cmds
import imageio
import numpy as np

# 替换为实际场景中的穹顶灯节点名
DOME_LIGHT_NAME = "aiDomeLight1"
# 亮斑亮度阈值,取最高亮度的80%作为筛选标准
BRIGHT_THRESHOLD_RATIO = 0.8
# 穹顶灯自定义半径
DOME_RADIUS = 10

# 1. 获取HDRI文件路径
file_node = cmds.listConnections(f"{DOME_LIGHT_NAME}.color", source=True, destination=False)[0]
hdri_path = cmds.getAttr(f"{file_node}.fileTextureName")

# 2. 读取HDRI并筛选高亮像素
hdri_data = imageio.imread(hdri_path, format="HDR")
h, w = hdri_data.shape[:2]
# 计算像素亮度,可根据需求替换为更准确的亮度公式
brightness = np.mean(hdri_data, axis=-1)
threshold = brightness.max() * BRIGHT_THRESHOLD_RATIO
bright_pixels = np.argwhere(brightness >= threshold)

export_coords = []
# 3. UV转3D世界坐标
for (y, x) in bright_pixels:
    u = x / w
    v = y / h
    # UV转球面经纬度
    azimuth = u * 2 * np.pi
    elevation = (v - 0.5) * np.pi
    # 球面坐标转笛卡尔本地坐标
    local_x = DOME_RADIUS * np.cos(elevation) * np.sin(azimuth)
    local_y = DOME_RADIUS * np.sin(elevation)
    local_z = DOME_RADIUS * np.cos(elevation) * np.cos(azimuth)
    # 若穹顶灯有位移/旋转/缩放,在此处乘上穹顶灯的世界变换矩阵即可得到世界坐标
    export_coords.append((local_x, local_y, local_z))

# 4. 导出坐标到CSV
np.savetxt("dome_bright_spots.csv", export_coords, delimiter=",")
问题2:Nuke中亮斑2D坐标转3D坐标

可以实现,分为两种常用场景:

  • 场景带对应渲染相机:获取最亮斑2D坐标后,通过相机的逆投影矩阵计算3D坐标
  • 仅匹配Nuke环境球:和Maya的逻辑一致,将2D图像坐标映射到环境球球面得到3D坐标

简化实现代码示例(带场景相机场景):

import nuke
import numpy as np

# 替换为实际的输入节点、相机节点名
SRC_NODE = nuke.selectedNode()
CAM_NODE = nuke.toNode("Camera1")
# 环境球/深度值自定义
DEFAULT_DEPTH = 10

current_frame = nuke.frame()
w = SRC_NODE.width()
h = SRC_NODE.height()

# 1. 遍历像素找到最亮斑点坐标
max_bright = 0
bright_x, bright_y = 0, 0
for x in range(w):
    for y in range(h):
        r = SRC_NODE.sample("r", x, y, current_frame)
        g = SRC_NODE.sample("g", x, y, current_frame)
        b = SRC_NODE.sample("b", x, y, current_frame)
        # 人眼感知亮度计算公式
        bright = r * 0.299 + g * 0.587 + b * 0.114
        if bright > max_bright:
            max_bright = bright
            bright_x, bright_y = x, y

# 2. 2D坐标转标准化设备坐标
ndc_x = (bright_x / w) * 2 - 1
ndc_y = (1 - (bright_y / h)) * 2 - 1

# 3. 逆投影计算3D世界坐标
proj_mat = np.array(CAM_NODE["projection_matrix"].getValueAt(current_frame)).reshape(4, 4)
inv_proj_mat = np.linalg.inv(proj_mat)
world_mat = np.array(CAM_NODE["world_matrix"].getValueAt(current_frame)).reshape(4, 4)

pos_ndc = np.array([ndc_x, ndc_y, DEFAULT_DEPTH, 1])
pos_cam = inv_proj_mat.dot(pos_ndc)
pos_cam /= pos_cam[3]
pos_world = world_mat.dot(pos_cam)

x3d, y3d, z3d = pos_world[:3]
print(f"最亮斑对应3D世界坐标:{x3d}, {y3d}, {z3d}")

内容的提问来源于stack exchange,提问作者Arnov Chaudhury

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 23:54:00