原文:https://www.andreaskj.com/live-pref-in-solaris/
作者:Andreas Kjær-Jensen
前半部分解释“Position Reference pass 是什么”。如果你只想直接用工具,可以跳到「在 Solaris/LOPs 中即时生成 pRef」。
什么是 Position Reference(pRef)pass?
在合成阶段,我们经常希望“在不向灯光额外要 matte 的情况下”,直接在 Nuke 里做更精细的二次选区。Point Position(pWorld)就是常见手段之一:它把每个像素在世界空间中的点位(position)编码进 AOV,合成师可以用 aPMatte 之类的工具在空间里圈选区域。
但当几何发生**变形(deform)**时,pWorld 的缺点会立刻暴露:你以为你圈的是“角色的头”,实际你圈的是“世界空间里的某个体积区域”。网格一动,遮罩就漂走了。
pWorld 在不同软件里名字可能不同;在 Houdini 的 Karma 里通常就是 AOV “P”。
下面两段视频展示了“pWorld 选区不粘住”的典型现象:
说明:pWorld 渲染结果
上面是 pWorld(Karma 里通常是 P)pass 的渲染效果。
说明:aPMatte 圈头部,但遮罩随变形漂移
因为 aPMatte 实际在“世界空间”里筛选点位,而不是绑定到角色几何上。
你可能会想到改用 Object Position(pObject):把点位存到物体空间。但如果是 deforming mesh,物体空间本身也在改变,仍然不好用(或者在很多管线里压根拿不到“稳定的 object space”定义)。
这时就需要 Position Reference pass(pRef):
- 它把点位固定在某个指定帧(例如动画开始帧、或者你挑选的 reference 帧);
- 然后在后续帧里无论网格如何变形,仍保持这组“参考点位”可用。
在 SOP 语境里,这个概念很像给几何做一个 rest 属性:用于绑定噪声、绑定程序纹理、或做稳定的空间参考。
用 pRef 后,你会得到“粘住”的遮罩:
在 Solaris/LOPs 中即时生成 pRef(无需 SOP Modify / 预烘焙)
很多做法要么要求上游在资产环节就把 reference attribute 烘焙好,要么要在 Solaris 里用 SOP Modify 去生成 rest。前者不一定做得到;后者在性能和稳定性上也常让人头疼。
原作者给出一个更“LOPs 原生”的方法:在 LOPs 里通过 Python,直接把某个 source frame 的 points 复制出来,写成一个新的 primvar(比如 pRef)。这在性能上很轻量:本质只是一次属性拷贝。
该脚本需要 Houdini 19.5+。
使用方式
- 在 LOPs 里创建一个 Python LOP 节点
- 粘贴下面脚本
- 修改三个参数:
primpattern、sourceframe、primvarname
primpattern:要生成 pRef 的 prim(支持 prim pattern,比如"/hydralisk/**")sourceframe:作为 reference 的帧号primvarname:写入 primvar 的名称(默认pRef)
node = hou.pwd()
stage = node.editableStage()
from pxr import Sdf, Usd, UsdGeom
import loputils
# Get Parameters - Replace these with your own values!
primpattern = "/hydralisk/**"
sourceframe = 140
primvarname = "pRef"
# Parse Primpattern
ls = hou.LopSelectionRule()
ls.setPathPattern(primpattern + ' & %type:Mesh')
paths = ls.expandedPaths(stage=stage)
# Compute Point Reference
for prim in paths:
prim = stage.GetPrimAtPath(prim)
primvarsapi = UsdGeom.PrimvarsAPI(prim)
points = prim.GetAttribute('points')
points_values = points.Get(sourceframe)
primvar = primvarsapi.CreatePrimvar(
primvarname,
Sdf.ValueTypeNames.Color3fArray,
UsdGeom.Tokens.vertex
)
primvar.Set(points_values)Bonus:在 Karma 中把 pRef 输出为自定义 AOV
在 Karma Render Settings:
- 打开 Image Output
- 滚到底部,展开 Extra Render Vars
- 点击
+添加一个新的 Render Var
然后按下面配置(如果你脚本里 primvar 名就叫 pRef):
Name: pRef
Format: color3f
Data Type: color3f
Source Name: pRef
Source Type: Primvar
延伸:什么是 Primvar(以及为什么它适合做 AOV)
Primvar 本质上是一套“被渲染器识别/可被着色与 AOV 访问”的特殊属性命名空间。你把数据写成 primvar,就更容易在渲染时把它作为 AOV 或 shader 输入取出来。
如果你对 primvar 还不熟,推荐读 Luca Scheller 的 USD Survival Guide(原文链接):
https://lucascheller.github.io/VFX-UsdSurvivalGuide/core/elements/property.html#attributePrimvars