Houdini 如何渲染一个20k的大图 python解决方案

在工作中碰到要渲染十几K的大图,渲染巨慢, 而且很容易崩溃

非学习版的Houdini本身是支持渲染很大分辨率的图

但是就这样默认去渲染一张超级大尺寸的图,风险就太大了,所以我这里想到一个方案就是:

把巨大的尺寸像拼图一样给拆分开,就像这样:

Houdini 如何渲染一个20k的大图 python解决方案_第1张图片

houdini的相机有这么几个参数是控制渲染裁切范围

Houdini 如何渲染一个20k的大图 python解决方案_第2张图片

python脚本解决思路:

创建一堆相机,每个相机对应的裁切范围(crop),是不一样的,相机动画等等其它参数关联到原始相机

创建一堆mantra,每个mantra取其对应的相机,然后mantra的渲染输出路径等等参数关联原始mantra

就像这样,我渲染了一张20000*20000的图做范例,这张图是拆分成100块单独渲染的:

Houdini 如何渲染一个20k的大图 python解决方案_第3张图片

nuke节点,直接将这个100个2000*2000的图merge起来,就变成了20k*20k

Houdini 如何渲染一个20k的大图 python解决方案_第4张图片

houdini里面主相机窗口是这样的:

Houdini 如何渲染一个20k的大图 python解决方案_第5张图片

脚本工具点击之后,弹出UI,设置横竖分块数,并选择是否串联mantra节点

点击脚本工具会创建camera节点阵列,和mantra节点阵列,每个的位置和crop裁切的位置是一一对应的的,就像这样:

Houdini 如何渲染一个20k的大图 python解决方案_第6张图片

因为点击的按钮是串联,这个10*10的100个mantra是串起来的,渲染最后以后红色的就行

Houdini 如何渲染一个20k的大图 python解决方案_第7张图片

渲染路径是自动关联到原始mantra节点的,接下来是此工具的python源代码,有兴趣的朋友可以改改代码让实用性符合自己的习惯,要使用此脚本,直接copy到工具架上建个工具按钮即可使用:

import hou,re
def new_cam(i, j, cam, crop):
    root = hou.node("/obj")
    name = "Jigsaw_Camera_%d_%d" % (i,j)
    new_cam = root.createNode('cam',name)
    new_cam.move((i*4,j))
    for parm in cam.parms():
        parm_name = parm.name()
        if parm_name == "cropl":
            new_cam.parm(parm_name).set(crop[0])
        elif parm_name == "cropr":
            new_cam.parm(parm_name).set(crop[1])
        elif parm_name == "cropb":
            new_cam.parm(parm_name).set(crop[2])
        elif parm_name == "cropt":
            new_cam.parm(parm_name).set(crop[3])
        elif parm_name in ["tx","ty","tz","rx","ry","rz","sx","sy","sz","px","py","pz","iconscale","resx","resy","aspect","projection",
                           "focal","aperture","orthowidth","near","far","winx","winy","winsizex","winsizey",
                           "shutter","focus","fstop"]:
            exp = 'ch("%s/%s")' % (cam.path(), parm_name)
            new_cam.parm(parm_name).setExpression(exp)
    return new_cam

def new_mantra(i, j, mantra, cam):    
    root = hou.node("/out")
    name = "Jigsaw_Mantra_%d_%d" % (i,j)
    new_mantra = root.createNode('ifd', name)
    new_mantra.move((i*4,j))
    new_mantra.parm("camera").set(cam)
    
    mantra_name = mantra.name()
    code = mantra.parm("vm_picture").asCode()
    val = code.split('hou_parm.set("')[1].split('")')[0]
    #正则匹配($F4.exr)
    reg = re.compile("\$F[1-9]?\.[A-Za-z]{3}")
    piclst = re.findall(reg,val)
    if piclst is not None:
        tmp1 = re.split(reg,val)
        tmp2 = tmp1[0]
        if '$OS' in tmp2:
            tmp2 = tmp2.replace('$OS',mantra_name)
        vm_pic_path = tmp2 + ("Jigsaw_%d_%d." % (i,j)) + piclst[0]
        new_mantra.parm("vm_picture").set(vm_pic_path)
    return new_mantra
    
def main():
    try:
        nd = hou.selectedNodes()[0]
        cam = None
        try:
            cam_path = nd.parm("camera")
            cam_path = cam_path.eval()
            cam = hou.node(cam_path)
            if cam == None:
                hou.ui.displayMessage(text="Mantra相机参数无效,请指定一个有效相机")
                return
        except:
            hou.ui.displayMessage(text="请选择一个Mantra节点")
            return
    except:
        hou.ui.displayMessage(text="请选择一个Mantra节点")
        return
    else:
        shutter = hou.ui.readInput('设置相机拼图方式\n横向分段-竖向分段', buttons=('串联', '不串连', '取消'), title='多相机渲染',
                                      initial_contents='2-2', close_choice=1, default_choice=0)
        x = (int)(shutter[1].split('-')[0])
        y = (int)(shutter[1].split('-')[1])
        x_mv = 1.0/x
        y_mv = 1.0/y
        camfllow = []
        fllow = []
        for i in range(0,x):
            for j in range(0,y):
                lc = x_mv*i
                rc = x_mv*(i+1)
                bc = y_mv*j
                tc = y_mv*(j+1)
                lst = (lc,rc,bc,tc)
                cam_pth = new_cam(i, j, cam, lst)
                camfllow.append(cam_pth)
                mantra = new_mantra(i, j, nd, cam_pth.path())
                fllow.append(mantra)
        #设置最后一个manta节点颜色为红色
        last_mantra_color = hou.Color()
        last_mantra_color.setRGB( (1, 0, 0) )
        fllow[-1].setColor(last_mantra_color)
        
        #如果点的按钮是串联,则串联mantra节点
        if shutter[0] == 0:
            for m in fllow:
                if m==fllow[0]:
                    continue
                i = fllow.index(m)
                m.setInput(0,fllow[i-1])
        #创建out下的stickyNote
        pos1 = fllow[0].position()
        pos2 = fllow[-1].position()
        size = abs(pos2[0] - pos1[0]),abs(pos2[1] - pos1[1])
        out = hou.node("/out")
        note = out.createStickyNote()
        color = hou.Color()
        color.setRGB( (0.03,0.04,0.1) )
        note.setColor(color)
        note.setPosition( (pos1[0]-1, pos1[1]-1) )
        note.setSize( (size[0]+5, size[1]+3) )
        color1 = hou.Color()
        color1.setRGB( (1, 0.8, 0.3) )
        note.setText("Render Jigsaw puzzle")
        note.setTextColor(color1)
        #创建obj下的stickynote
        pos1 = camfllow[0].position()
        pos2 = camfllow[-1].position()
        size = abs(pos2[0] - pos1[0]),abs(pos2[1] - pos1[1])
        obj = hou.node("/obj")
        note1 = obj.createStickyNote()
        note1.setColor(color)
        note1.setPosition( (pos1[0]-1, pos1[1]-1) )
        note1.setSize( (size[0]+5, size[1]+3) )
        note1.setText("Jigsaw Cameras")
        note1.setTextColor(color1)
main()

你可能感兴趣的:(Houdini,python,Houdini,Python,小工具)