用Houdini实现substance的warp节点
看同事在substance演示warp节点感觉比较牛逼,推了下方程:
SDF图:
变形的图:
结果:
Houdini里实现,第一步实现二维的gradient(sdf),形成二维的梯度场,因为一定要在uv空间操作,所以得在sop映射个uv.
把求出来的梯度放到N属性上。为了方便的观看向量.节点网络:
<1>
grad节点是求二维的sdf的梯度
这里面的map 用的上面的sdf贴图.
// sample sdf texture float f_tex(string map;float u;float v){ vector ret = texture(map,u,v); return (ret.x+ret.y+ret.z)/3; } float du,dv; du = dv = 0.01; string map = chs("map"); float u = @uv[0]; float v = @uv[1]; // cal df/du float offul = clamp( u+du,0,1); float offur = clamp( u-du,0,1); float ul = f_tex(map,offul,v); float ur = f_tex(map,offur,v); float dfdu = (ur-ul)/ (2*du); // cal df/dv float offvl = clamp( v+du,0,1); float offvr = clamp( v-du,0,1); float vl = f_tex(map,u,offvl); float vr = f_tex(map,u,offvr); float dfdv = (vr-vl)/(2*du); @N = set(dfdu,0,dfdv);
这一步可以得到grad向量:
<2>
advect_warp节点 是对你的颜色贴图 执行对流变形的过程:
这里面的map用的上面的棋盘格贴图.
string map = chs("map"); float amp = -ch("amp")/100; //这里的amp是变形强度,如果过大,会跟substance一样得到uv纹理重复的效果,这个值比较敏感,毕竟uv->[0,1]区间 float u = @uv.x + @N[0]*amp; float v = @uv.y + @N[2]*amp; vector ret = texture(map,u,v); @Cd = ret;
结果: