I have one geometry node with 2 separate geometries inside (see image).
The left geometry has a vector attribute v0, and right geometry has a vector attribute v1.
I want to create another attribute with the dot product of v0.v1
How do I do that if I don't want to go via vopsop?
I want to use the dot() expression, but as I understand it takes the vectors as strings, so I'll have to write them string attributes, but then need to reconvert it into numbers because otherwise it'll take the whole dot expression as a string, but there it's just an expression with a string as an argument and argh… :? I think I'm overcomplicating things already.
How to take the dot product in the neatest, cleanest way possible?
dot product in string attribute
10619 13 2-
- Soothsayer
- Member
- 875 posts
- Joined: Oct. 2008
- Offline
-
- old_school
- Staff
- 2540 posts
- Joined: July 2005
- Offline
-
- Soothsayer
- Member
- 875 posts
- Joined: Oct. 2008
- Offline
jeff
dot(v0, v1) returns first component
dot(v0, v1) returns second component
dot(v0, v1) returns third component
But how do I refer to v0 and v1 as vectors? dot() doesn't seem to accept $V0 and $V1 and a point() only gives me one component.
dot() seems to want a string, for example like this: dot("“,”")
The docs aren't clear on this. I think I'm missing something really obvious here.
--
Jobless
Jobless
-
- graham
- Member
- 1926 posts
- Joined: Nov. 2006
- Offline
-
- Antoine Durr
- Member
- 321 posts
- Joined: July 2005
- Offline
SoothsayerUse a point SOP, and wire in the two attribcreates. Then, into the alpha parameter (or wherever else you want the result), enter:
The left geometry has a vector attribute v0, and right geometry has a vector attribute v1.
I want to create another attribute with the dot product of v0.v1
How do I do that if I don't want to go via vopsop?
dot(normalize(vector3($V1X,$V1Y,$V1Z)),normalize(vector3($V2X2,$V2Y2,$V2Z2)))
i.e. vector3() makes the two inputs vectors (the second vector is called V2, but it's also on the second input, hence $V2X2, i.e. V2X of the second input), then normalize() the lengths of these vectors to unit length, and then take the dot product thereof.
This is probably easier & faster than Python, but slower and way uglier than the vopsop.
-
- graham
- Member
- 1926 posts
- Joined: Nov. 2006
- Offline
I was hesitant to recommend the Point Sop because it's not really clear about the point count. If the point count between the inputs is the same then it works good.
Another thing you could do if your vectors are already normalized, or you don't care, is to just do the dot product manually. All the dot product is is v0x*v1x + v0y*v1y + v0z*v1z. You can just quickly do it yourself and not even worry about transforming them to vectors and whatnot.
Really though, unless you are doing a really large amount of points, or your calculations are time dependent you really won't notice much a difference if any at all in either hscript, python or the vop sop. Unfortunately Python seems to get a bad rap a lot for being slow and sometimes it is justified but in a most cases you don't really notice any slowdown unless you are working on extremely large data sets or cooking every frame and even then you can do things to make it much faster.
Another thing you could do if your vectors are already normalized, or you don't care, is to just do the dot product manually. All the dot product is is v0x*v1x + v0y*v1y + v0z*v1z. You can just quickly do it yourself and not even worry about transforming them to vectors and whatnot.
Really though, unless you are doing a really large amount of points, or your calculations are time dependent you really won't notice much a difference if any at all in either hscript, python or the vop sop. Unfortunately Python seems to get a bad rap a lot for being slow and sometimes it is justified but in a most cases you don't really notice any slowdown unless you are working on extremely large data sets or cooking every frame and even then you can do things to make it much faster.
Graham Thompson, Technical Artist @ Rockstar Games
-
- Soothsayer
- Member
- 875 posts
- Joined: Oct. 2008
- Offline
OK, I see. Hscript is not so good for this stuff then. Thanks for clearing that up. HOM seems the way to go.
But how about vopsop then? When I try it I get only results for as many points as there are in the geometry with the smallest amount of points. So, in this case, it only calculates one dot product, because the add1 node contains only one point.
VOPSOP loops through over all points and when there's none left in any of the inputs it just stops, right?
Can I force it to go through all the points in one input, even if it has less points than those of the second input?
But how about vopsop then? When I try it I get only results for as many points as there are in the geometry with the smallest amount of points. So, in this case, it only calculates one dot product, because the add1 node contains only one point.
VOPSOP loops through over all points and when there's none left in any of the inputs it just stops, right?
Can I force it to go through all the points in one input, even if it has less points than those of the second input?
--
Jobless
Jobless
-
- graham
- Member
- 1926 posts
- Joined: Nov. 2006
- Offline
-
- old_school
- Staff
- 2540 posts
- Joined: July 2005
- Offline
Soothsayer
But how do I refer to v0 and v1 as vectors? dot() doesn't seem to accept $V0 and $V1 and a point() only gives me one component.
dot() seems to want a string, for example like this: dot("“,”")
You can use the vector3(v1, v2, v3) function to return the correct vector component:
dot(vector3(0,1,0),vector3(1,0,0))
Btw the vector expressions are still valid in POPs where many fields can take either three discrete fields or a vector field.
There's at least one school like the old school!
-
- sparkChan
- Member
- 27 posts
- Joined: Nov. 2009
- Offline
jeffSoothsayer
But how do I refer to v0 and v1 as vectors? dot() doesn't seem to accept $V0 and $V1 and a point() only gives me one component.
dot() seems to want a string, for example like this: dot("“,”")
You can use the vector3(v1, v2, v3) function to return the correct vector component:
dot(vector3(0,1,0),vector3(1,0,0))
I think dot(vector3(0,1,0),vector3(1,0,0)) is incorrect, because the dot() expression only gets scalar value and not vector value, so you can't use the form of to get single component.
Btw the vector expressions are still valid in POPs where many fields can take either three discrete fields or a vector field.
Houdini is a big thing!
-
- Antoine Durr
- Member
- 321 posts
- Joined: July 2005
- Offline
SoothsayerIMO, trying to make the vopsop deal with an unequal number of points in each input is awkward. What happens, for example, if you have two points on the right, or N-1 points? What is the behavior of the vopsop then? Well gotta go in and dig to find out. Instead, here are two approaches I'd consider.
But how about vopsop then? When I try it I get only results for as many points as there are in the geometry with the smallest amount of points. So, in this case, it only calculates one dot product, because the add1 node contains only one point.
VOPSOP loops through over all points and when there's none left in any of the inputs it just stops, right?
Can I force it to go through all the points in one input, even if it has less points than those of the second input?
1) If the calc-dot-against input (the right hand side) is always going to be one point, rework the vopsop to take in a vector parameter that represents the calc-against vector, and thus reduce the number of inputs to one. This makes it clear: we're calculating the dot product against this given vector.
2) Duplicate the point count on the smaller input until you have a corresponding number of points. A copy SOP with an npoints() expression in the copy quantity field will duplicate the point N times and now the two inputs will be equal.
Either of these approaches are a cleaner way to deal with this scenario, especially if the setup might be handed over to someone else.
-
- Soothsayer
- Member
- 875 posts
- Joined: Oct. 2008
- Offline
-
- Soothsayer
- Member
- 875 posts
- Joined: Oct. 2008
- Offline
-
- Antoine Durr
- Member
- 321 posts
- Joined: July 2005
- Offline
SoothsayerNot sure why you're setting a string attribute to it and then eval()'ing it as you can just put dot(…) into your float channel. And while this seems verbose, realize you're grabbing what could potentially be six completely unrelated pieces of information from completely different objects/sops. Unlikely in this case, admittedly, but useful on occasion. Again, there are terser ways of doing what you want, e.g. vopsop.
Ooook, so if I wanna take the dot product of vector attributes v0 and v1 with expressions, then this is what I need to do (I tried and it works):
string variable sv0 is set to: dot("“,”")
and then:
eval($SV0)
BTW, your analogy of the lightsource is reversed – the shader is run on all the geometry, and it would do the dot-product with the one light, not the other way around. Likewise, the vopsop is run once for every point in the first input.
-
- Quick Links



