newbie question about grid planes / moving points on normals

   2183   11   1
User Avatar
Member
73 posts
Joined: April 2020
Online
I started learning Houdini two days ago, and although I've done a lot of 3D modeling in Rhino, there's much about the Houdini world that is fascinating but also quite different for me. I think I've boiled my first confusions down to the following very simple example, and I'd greatly appreciate any insights anyone can offer.

One thing to note: in the viewport preferences, I have set the Z direction to be up, and perhaps that is part of my problem? I'm not sure.

I start with a grid node (primitive type polygon, connectivity quadrilaterals, orientation YZ plane). I've attached a screen shot of the grid parameters and the scene with visibility set to the next node – a pointvop.

Inside the pointvop I am attempting to move the points of the grid along their normals by varying amounts. I'm using a unifiednoise node whose position input I connect to the point location input of the vop. I then multiply the normal input of the vop with this noise and add it to the point locations. I attach a screen shot of that setup and also the parameter settings of the unified noise node.

At least two things confuse me about the results. First, when I look at the permutation of the grid, it seems that the points aren't just being lifted along their normal directions. They are also slanting off in the y/z direction.

Section, I tried to do this with the grid set to the XY plane, but when I do that, no permutations show up from the pointvop at all. It is just a flat grid in the XY plane. I'm confused about why what I've done wouldn't work with that grid orientation.

Thanks again for any help you can offer.

Mary



Attachments:
normals question1.png (3.0 MB)
normals question2.png (614.4 KB)
normals question3.png (258.6 KB)

User Avatar
Member
683 posts
Joined: Feb. 2017
Offline
Hey mgbaker,

your setup looks right. It might be the multiply node as it has the wrong noodle color. try to replace it with a new one. Also, give the aanoise a try as it is much faster than the unified noise.

Cheers
CYTE
User Avatar
Member
480 posts
Joined: July 2005
Offline
Hi,

Is it working, if you change the order of the inputs for “multiply” (N as first input and noise as second input)?
User Avatar
Member
73 posts
Joined: April 2020
Online
Dear CTYTE and Aizatulin,

Thank you so much! Switching the order of the inputs to the multiply node fixes the problem. I hadn't realized that the color of the “noodle” (that's a great term) is supposed to match up – now I know to look for that. This also fixes my problem with plane orientation – the XY plane works fine now. If I switch the wires back again, the same problem occurs, so it truly seems to be the choice of which wire goes to which input. When I try a new multiply node, I get the same problem.

I wonder why the order of inputs to the multiply node makes a difference – I've always thought of multiplication as being commutative :-)

Thanks again,
Mary
User Avatar
Member
480 posts
Joined: July 2005
Offline
Usually it should be commutative, but it looks like, that the multiply node is implemented in a way, that the first input dominates

the types of other inputs (which can be used). If you use a point wrangle, you can use the “*” operator, which can be

applied from both sides. For example

@P += v@N * noise(@P);

or

@P += noise(@P) * v@N;

will have the same results.
User Avatar
Member
7803 posts
Joined: Sept. 2011
Online
Aizatulin
Usually it should be commutative, but it looks like, that the multiply node is implemented in a way, that the first input dominates

It's different because VOPs is not doing `@P += v@N * noise(@P);`

VOPs store the result of each operation in a temp variable. The first input determines the result variable's type.

So the addition and multiplication happens as follows:

float output1, output2, output3;
vector N1 = N;
vector P1 = P;
float product;
vector sum;

// from autoconvert
vop_vectofloat(N1, output1, output2, output3);

// From multiply1
product = noise * output1;

// from add1
sum = P1 + product;

P = sum;

product gets its type from noise and sum is from P1. Because noise of a shorter type than N, an automatic conversion to float is applied, so only the x component of the normal is used. Since the grid is on the YZ plane, it happens not to be 0. When adding the result to P, the float is cast to a vector using the same value for all components giving a skewed effect.

Putting it all in one line in a wrangle has the benefit of using the return type of P which happens to be long enough to store the result. Keep in mind it is also used for the type of the function calls on the right as well. When calling noise(@P) on the right side of assignment, it's calling vector(noise(@P)), which may or may not be desired. float(noise(@P)) can be used to force float signature noise for this case.
User Avatar
Member
8595 posts
Joined: July 2007
Offline
mgbaker
I wonder why the order of inputs to the multiply node makes a difference – I've always thought of multiplication as being commutative :-)
multiplication is not necessarily commutative even if you are not mixing types
float*float is for example
matrix*matrix is not

when you start mixing types then not only doesn't have to be commutative, it may not even be defined in both ways within the programming language
not that that's this case, but in general
Tomas Slancik
FX Supervisor
Method Studios, NY
User Avatar
Member
73 posts
Joined: April 2020
Online
Thank you, Aizatulin and jsmack – this answers all the next questions I was about to follow up with. You've been extremely helpful, as this would have taken me ages to dissect and understand.
User Avatar
Member
340 posts
Joined: June 2017
Offline
Quaterion multiplication is not commutative.
Edited by Island - May 7, 2020 18:56:09
User Avatar
Member
73 posts
Joined: April 2020
Online
Thanks, Tomas and Island – this is making sense now. Clearly I have a long ways to go here…

Mary
User Avatar
Member
480 posts
Joined: July 2005
Offline
In addition to @jsmack's statement: The noise function in VEX is an overloaded function, which has a multi signature. It can have

different types of outputs (even for the same input type). In our case it can have a float or vector output. The problem is, that

both types can be used for multiplication, but the results are different. But for displacement it might be more intuitive (as

@jsmack already mentioned) to use a float type. So the displacement direction is always along the normal.

Here is another comparison between the results.

// noise A
//@P += noise(@P) * v@N;
// same result (A)
//@P += vector(noise(@P)) * v@N;

// noise B
//@P += float(noise(@P)) * v@N;
// same result (B)
//@P += vector(noise(@P)).x * v@N;

You can also check this link:

https://www.sidefx.com/docs/houdini/vex/functions/noise.html [www.sidefx.com]
User Avatar
Member
73 posts
Joined: April 2020
Online
Thanks, Aizatulin, for the very clear examples and link to all the info on different kinds of noise and randomness. I've switched to treating this as a programming language with function overloading rather than whatever it is I was treating it as in my mind before!
  • Quick Links