Difference between revisions of "Houdini Octane"
| Line 15: | Line 15: | ||
import hou | import hou | ||
def chooseRTdialog(buttons): | def chooseRTdialog(buttons): | ||
buttons.append('Cancel') | buttons.append('Cancel') | ||
| Line 30: | Line 29: | ||
else: | else: | ||
menu.set(1) | menu.set(1) | ||
rts = [] | rts = [] | ||
RT = None | RT = None | ||
| Line 38: | Line 39: | ||
names = [x.name() for x in rts] | names = [x.name() for x in rts] | ||
if len(rts) == 1: | if len(rts) == 1: | ||
RT = rts[0] | RT = rts[0] | ||
| Line 45: | Line 46: | ||
chosenRT = chooseRTdialog(names) | chosenRT = chooseRTdialog(names) | ||
if chosenRT is not False: | if chosenRT is not False: | ||
RT = chosenRT | RT = rts[chosenRT] | ||
if RT: | if RT: | ||
| Line 84: | Line 85: | ||
hdri.setComment(RT.path()+'\n'+RT.parm('textureEnvironmentFilename').eval().split('/')[-1]) | hdri.setComment(RT.path()+'\n'+RT.parm('textureEnvironmentFilename').eval().split('/')[-1]) | ||
#hou.nodeEventType.FlagChanged | |||
#hdri.addEventCallback(hou.nodeEventType.FlagChanged,print("hi")) | |||
#RT.parm('environmentMenu').eval() | |||
hdri.addEventCallback((hou.nodeEventType.FlagChanged,),linkDispFlag) | hdri.addEventCallback((hou.nodeEventType.FlagChanged,),linkDispFlag) | ||
</pre> | </pre> | ||
Revision as of 17:45, 10 October 2025
Octane
Python tools
HDRI in the viewport control
It's a pain in the ass to go to the rendertarget each time, this acts like a normal environment preview. Barebones but works.
'''
links a null with some parameters to a chosen Rendertarget texture.
Display flag sets texture on/off just like for lights.
No error checking.
'''
import hou
def chooseRTdialog(buttons):
buttons.append('Cancel')
dialog = hou.ui.displayMessage('Choose which RTarget HDRi to link to', buttons=buttons)
if dialog == len(buttons)-1:
dialog = False
return dialog
def linkDispFlag(node,event_type):
RT = hou.node(node.parm('RT').eval())
menu = RT.parm('environmentMenu')
if node.isDisplayFlagSet() == 1:
menu.set(6)
else:
menu.set(1)
rts = []
RT = None
for node in hou.node('/').allSubChildren():
if 'octane_mat_renderTarget' in node.type().name():
rts.append(node)
names = [x.name() for x in rts]
if len(rts) == 1:
RT = rts[0]
else:
chosenRT = chooseRTdialog(names)
if chosenRT is not False:
RT = rts[chosenRT]
if RT:
hdri = hou.node("/obj").createNode("null", "hdri")
hdri.setSelectableInViewport(True)
hdri.useXray(True)
hdri.setDisplayFlag(True)
hdri.hide(False)
hdri.setSelected(True)
hdri.parm('geoscale').set(10)
hdri.parm('controltype').set(1)
hdri.setUserData("nodeshape", "circle")
hdri.setColor(hou.Color([0.976, 0.78, 0.263]))
hdri.setGenericFlag(hou.nodeFlag.DisplayComment,True)
ptg = hdri.parmTemplateGroup()
slider = hou.FloatParmTemplate("hdripower", "Hdri Power", 1, default_value=(0.0,))
exr = hou.StringParmTemplate("exr", "HDRI", 1, string_type=hou.stringParmType.FileReference, file_type=hou.fileType.Image)
path = hou.StringParmTemplate("RT", "RTarget", 1, string_type=hou.stringParmType.NodeReference,default_value=(RT.path(),))
ptg.insertBefore((0,0),path)
ptg.insertBefore((0,0),exr)
ptg.insertBefore((0,0),slider)
hdri.setParmTemplateGroup(ptg)
parmsFrom = 'tx ty tz rx ry rz sx sy sz exr hdripower'
parmsTo = 'translation121 translation122 translation123 textureEnvTilt textureEnvLeftRight textureEnvRoll textureEnvScale1 textureEnvScale2 textureEnvScale3 textureEnvironmentFilename textureEnvPower'
parmsFrom = parmsFrom.split(' ')
parmsTo = parmsTo.split(' ')
for i in range(len(parmsFrom)):
hdri.parm(parmsFrom[i]).set(RT.parm(parmsTo[i]).eval())
RT.parm(parmsTo[i]).set(hdri.parm(parmsFrom[i]))
hdri.setComment(RT.path()+'\n'+RT.parm('textureEnvironmentFilename').eval().split('/')[-1])
#hou.nodeEventType.FlagChanged
#hdri.addEventCallback(hou.nodeEventType.FlagChanged,print("hi"))
#RT.parm('environmentMenu').eval()
hdri.addEventCallback((hou.nodeEventType.FlagChanged,),linkDispFlag)
Shading Guide
For C4D, still good: https://www.behance.net/gallery/102948251/Octane-Universal-Material-Guide-Starter-File
Shading instances with custom colors
Is a little more hands on than getting custom attributes
If you have a single object that you want to instance but have it have a random shader (in my example, using color), you can use a trick/weird workaround.
To make it work:
- in your scattered points (the ones that hold @instance, @orient, @pscale, @Cd) /obj/ level geo, make sure you choose 'Packed RGBA Values from 'Cd' Point Attribute'.
- in your instance shader, you need to grab 'Texture Instance Color' and go pick a .ppm texture that sits in the install directory of octane under the /tex folder called rgb4k_map.ppm
- plug it in directly your diffuse or use it to drive other textures like a ramp in my example
Shadow catcher with diffuse bounce
I think default shadow catching doesn't get the bounce so you can whip it up with a rayswitch. I sort of plugged stuff into stuff for it to work (topright pigheads -- bottom left is normal shadowcatcher,plane grid is a green material):
(also i cropped the rayswitch like an idiot but camera ray is at 0 the rest at 1
Double sided material in Octane
You can use tool_polygon_side to drive a material mixer:
Arnold
Weird render procedural stuff: https://arnoldsupport.com/2018/11/21/backdoor-setting-visibility/