Interested in writing my own RBF node. Any info helpful!


#1

I’m interested in writing my own RBF node, more for gaining the knowledge of creating it than the use of it. I’ve tried digging around online and have only found this description(http://www.marcuskrautwurst.com/2017/12/rbf-node.html) which brought me a lot of insight but following it along the matrix math does not come out as described. Others seem to have the same issue judging from the comment section. If anyone would be willing to direct me to other resources for digging into this, I would be most grateful.


#2

#3

Super helpful! Thanks!!!


#4

This is a link to the entire course the linked video is taken from at Caltech. http://work.caltech.edu/telecourse.html#lectures


#5

Take some inspiration from Ingos RBF.


#6

I had the same thing - the math didn’t work out. From my understanding, RBF is just another interpolator who’s weights are solved based on the radial distance. So you need to build a coefficients matrix of the distance of the targets with respect to each other using one of the RBF functions. The values you drive can be anything. Ive built solvers before but I used non-negative least squared for it using the scipy library - which is VERY fast :slight_smile:

I always go to wiki first as it tends to be devoid of any varitation of the math:

Now there are several versions of the RBF interpolator - Guassian, Multi-Quadratic, Linear etc… Anything other than Linear will require a epsilon variable. Here’s a graph I made showing Gausian and the epsilon c value - which is a constant across the system. It basically describes the falloff the poses will start to blend with each other.

https://www.desmos.com/calculator/ulmpwhvjcj

Approximation

So you have a bunch targets A, B, C and, from which you build a coefficients matrix (left side) of their distance to all the rest using a given RBF interpolation.


RBF(0)      RBF(|A-B|)   RBF(|A-C|)        1 ...
RBF(|B-A|)  RBF(0)       RBF(|B-C|)        2 ...
RBF(|C-A|)  RBF(|C-B|)   RBF(0)            3 ...

The zero’s are because its the distance of a target to itself. On the right side you have your values - these can be anything. So you then solve this matrix with least squares (numpy and scipy solve this).

So once you have your solved matrix of weights- all you’re doing is sum’ing the RBF interpolated poses using the distance between your driver and target multiplied by the solved weight for that target/pose.

I was very confused about RBF for ages because I saw the function and spent a long time trying to understand how it works for many poses. When I realized its just the interpolation e.g. (b-a) * t + a you’re just using to interpolate poses using the weights from a solved matrix.

This paper is excellent - A Radial Basis Function Approximation for Large Datasets:

There is a regularization multiplication you can add - I don’t understand this that well other than adding some evenness to the approximation. This is generally noted as g.


#7

Git project for RBF node for Maya 2016.


#8

Oh neat, I was just about to add my github link that Riggity posted. I used C++ and the Eigen library to solve. It’s been a minute but I’m happy to answer what questions I can


#9

Thanks so much for joining the thread. I’ve been going through your git code trying to get a better handle on how to set up the math for RBF solving. The Krautwurst how-to described setting up matrices in prep for a Ax=b solve which sounds like it makes sense…setting up relationships based on on distances between the end targets.
I need to dig into things a little more this weekend… I guess I’m still not sure what questions to ask.
I first thought of setting up rotation values correlated to a pose weight matrix. Each pose being fully dialed in and all others dialed out… but was told Euler rotation values are not the way to go…gimbal problems, etc.

If you could help me get a sense of how you set up relations to start the solution that would be really helpful.

How are you using Eigen values?


#10

ah just to clarify Eigen library is used like scipy, it’s an library for C++ that I use to solve Ax=b, there are no eigenvalues / eigenvectors (lowercase e) used in my code

i’ll try and dig back in thursday night, been meaning to revisit this code anyway. iirc i did extract and blend using individual euler rotations, but used an up vector/object to stabilize. hm don’t quote me though. meanwhile it’ll probably be easier to start with blendshapes, rgb, or translation values, ie channels you can blend to independently


#11

Ah…gotcha.
I have been using both numpy and linalg.py as suggested in the Krautwurst steps feeding it Ax=b setups. They solved correctly but I’m hazy on how to set up the matrices to feed into that scheme meaningfully.