Skip to content

Instantly share code, notes, and snippets.

@lcrs
Last active November 29, 2017 21:55
Show Gist options
  • Save lcrs/acb4e0caff9a09c9baa8c66c37ff51dd to your computer and use it in GitHub Desktop.
Save lcrs/acb4e0caff9a09c9baa8c66c37ff51dd to your computer and use it in GitHub Desktop.
# Creates perspective projection in a shader without UVs on the geo
# Select the camera to project from, run this, two nodes appear in /mat
# [email protected]
import hou, math
cam = hou.selectedNodes()[0]
world2cam = cam.worldTransform()
world2camvex = str(world2cam).replace('[', '{').replace(']', '}')
aspect = float(cam.evalParm('resx')) / float(cam.evalParm('resy'));
haperture = cam.evalParm('aperture')
vaperture = haperture / aspect;
focal = cam.evalParm('focal')
fovx = 2.0 * math.atan(haperture / (2.0 * focal));
fovy = 2.0 * math.atan(vaperture / (2.0 * focal));
proj = hou.Matrix4((1.0/math.tan(fovx/2.0), 0.0, 0.0, 0.0, 0.0, 1.0/math.tan(fovy/2.0), 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0))
projvex = str(proj).replace('[', '{').replace(']', '}')
rp = hou.node('/mat').createNode('restpos')
i = hou.node('/mat').createNode('inline')
i.setFirstInput(rp)
i.moveToGoodPosition()
i.parm('outtype1').set('vector')
i.parm('outname1').set('uv')
i.parm('outtype2').set('float')
i.parm('outname2').set('facing')
i.parm('outtype3').set('float')
i.parm('outname3').set('dist')
i.setName('UVlessProjection', True)
i.setComment('From %s\nat frame %d' % (cam.path(), hou.frame()))
i.setGenericFlag(hou.nodeFlag.DisplayComment, True)
i.parm('code').set("""// Outputs perspective projection UVs calculated from rest position and camera matrix
matrix world2cam = %s;
matrix proj = %s;
vector objp = $restP;
vector worldp = ptransform('space:object', 'space:world', objp);
vector4 camp = invert(world2cam) * worldp * set(1.0, 1.0, -1.0, 1.0);
vector4 clipp = proj * camp;
vector4 ndcp = clipp / clipp.w;
$uv = ((vector)ndcp / 2.0) + set(0.5);
vector projworld = world2cam * set(0.0);
vector projdir = normalize(projworld - worldp);
vector worldN = ntransform('space:camera', 'space:world', N);
$facing = dot(worldN, projdir);
$dist = length(projworld - worldp);""" % (world2camvex, projvex))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment