多变量插值-houdiniUE
 Houdini UE特效学习站|houdiUE节点、工程、插件、资产世界

{{ tags.important.name }}多变量插值

{{ tag.name }}
优惠前:
已售{{ sales_count }}
原价:
已售{{ sales_count }}
{{ important_discount.small_badge }}
倒计时00分00秒
{{ important_discount.desc }}
{{ opt.name }}
{{ opt.view_mode === 'img' ? '列表' : '图片' }}
{{ item.name }}
{{ item.name }}
{{ item.value }}
{{ item.name }}

使用多变量插值法,使用 Python 模块 Numpy / Scipy,使网格流经导引点。

f@height 属性将根据网格与导点之间的常见 X 和 Z 位置进行插值。

// Grid
f@px = v@P.x;
f@pz = v@P.z;

f@height = 0.0;
// Guide points
f@px = v@P.x;
f@pz = v@P.z;

f@height = v@P.y;

插值

Python 的 NumPy/SciPy 库支持多变量插值。它确保网格即使不规则地排列,也能始终顺畅地通过我们的引导点。

提供了多种插值方法:多二次插值、 逆多二次插值、高斯插值、线性插值、三次插值、五次插值和薄板插值。

import numpy as np
from scipy.interpolate import griddata
import scipy.interpolate as interp

node = hou.pwd()
geo1 = node.geometry()
inputs = node.inputs()
geo2 = inputs[1].geometry()

method_nr = node.evalParm('method')
method_names = 'multiquadric,inverse_multiquadric,gaussian,linear,cubic,quintic,thin_plate'.split(',')
method_str = method_names[method_nr]

grid_x = np.array(geo1.pointFloatAttribValues('px'))
grid_z = np.array(geo1.pointFloatAttribValues('pz'))
pos_x = np.array(geo2.pointFloatAttribValues('px'))
pos_z = np.array(geo2.pointFloatAttribValues('pz'))
height = np.array(geo2.pointFloatAttribValues('height'))

rbf_height = interp.Rbf(pos_x, pos_z, height, function=method_str)
smooth_rbf_height = rbf_height(grid_x, grid_z)

geo1.setPointFloatAttribValuesFromString("height", smooth_rbf_height.astype(np.float32))
v@P.y = f@height;

Scipy.插值中的  径向基函数(RBF) 在插值不规则点之间表现出色。RBF 看起来比属性转移标准作程序(SOP )更流畅。

VEX 版本

int mode = chi('mode');
float k = chf('radius');

float w    = 0.0;
vector clr = 0.0;

for(int i = 0; i < npoints(1); i++){
    vector pos = point(1, 'P', i);
    float d = distance2(v@P, pos);
    vector clr_pt = point(1, 'Cd', i);
    
    float weight = 0.0;
    if     (mode == 0) weight = 1.0 / sqrt(d);                // inverse multiquadratic
    else if(mode == 1) weight = pow(1.0 + (d * d), -0.5) / d; // multiquadric
    else if(mode == 2) weight = exp(-d / (2.0 * k * k));      // gaussian
    else if(mode == 3) weight = 1.0 / (d * d * d);            // cubic
    w += weight; 
    
    clr += clr_pt * weight;
}

v@Cd = clr / w;