FX/Houdini_Houdini 1

Starter - Ep 0: Summary of Open the Houdini & Joy of VEX

Gamestonk118 2022. 12. 5. 13:27

이번 시간에는 본격적인 Houdini 1에 들어가기 앞서 기존에 배워왔던 기본적이고 핵심적인 내용들을 가볍게 훑어보는 시간을 가졌다. 지금까지 최초 입문 강의와 Joy of Vex 강의를 통해 배워왔던 부분들 중에서 merge node로 각기 다른 두 Object들을 묶었을 때에 경고등이 표시되는 것을 볼 수 있었을 것이다. 이는 각각의 Object들이 가지고 있는 Attribute의 Type이 서로 일치하지 않았을 때에 나타남으로써 다음과 같이 Clean Node를 통해 고쳐볼 수 있다.

 

A Mis-match of Attibutes

Box Object에는 Point Attribute의 정보들만 담고 있는 상태이고 Normal Attribute의 대한 정보를 담지 않고 있다.

 

Box Object의 Attribute 정보들을 Geometry Spreadsheet으로 확인하였다.

 

Rubbertoy Object에는 Point Attribute와 함께 Normal Attribute의 대한 정보도 담고 있다.

 

Rubbertoy Object의 Attribute 정보들을 Geometry Spreadsheet으로 확인하였다.

 

이러한 상황에서 두 각기 다른 Object들을 Merge Node로 연결하였을 시에 다음과 같이 경고등이 뜸과 동시에 Geometry Spreadsheet에서 Box의 Normal Attribute를 계산하여 0번부터 7번까지의 Point들의 Position과 Normal값들을 제시한것을 알 수 있다.

 

Merge Node에서 경고등이 뜨면서 각기 Attribute들이 일치하지 않아 경고등이 뜬다고 알려준다.

 

이 때 Clean Node를 활용하여 Rubbertoy에 있는 Normal Attribute를 없애주면 각기 내포하고 있는 Attribute들은 Position만 있게 되어 경고등이 더이상 뜨지 않고 Geometry Spreadsheet에서는 Position의 정보들만 디스플레이 하게 된다.

 

더이상 Merge Node에 경고등이 뜨지 않으면서 Geometry Spreadsheet에 Normal Attribute의 정보들이 없어진 것을 알 수 있다.

 

Animation in Houdini

그렇다면 Object에 Animation을 구현하는 방법들은 무엇들이 있을까? 크게 세 가지 방법들이 있다.

 

  1. 특정 Frame에 Option + Parameter Value 값을 좌클릭 하여 Keyframe을 생성하여 Animation을 구현하는 방법.
  2. HScript로 파라미터를 작성하여 원하는 수식에 맞게끔 Animation을 구현하는 방법
  3. point() Function을 활용하여 파라미터를 작성하여 다른 Object의 Position 정보 값들을 불러와 똑같이 원하는 Animation에 적용될 수 있게끔 하는 방법. Point() Function에는 각각 다음과 같은 값들이 들어가야 한다.
point ("Surface Node", Point Number, "Attribute", index)

// Example:
point ("../MOVE", 0, "P", 0)

 

https://www.sidefx.com/docs/houdini/expressions/point.html

 

point

point("/obj/geo1/facet1", 3, "P", 0) Returns the X component of point 3 of the facet1 surface node in geo1. point("/obj/geo1/facet1", 3, "N", 2) Returns the Z component of the normal attribute of point 3 in the facet1 surface node of object geo1.

www.sidefx.com

 

point() Function

그렇다면 Vex 상에서 point() Function을 이용하여 각기 다른 Object들을 이루는 Point들의 거리 사이의 값을 구하고 싶으면 어떻게 하면 될까? 이는 지난 Joy of Vex에서 다루었듯이 각기 Object을 해당하는 Wrangle Node의 Input에 연결해준 다음에 각각의 값을 불러와 distance() Function을 사용하여 각 두 Vector 값 사이의 거리 길이 값을 구해주면 된다. 만약 length() Function을 사용하여 거리의 값을 만들어 주고 싶으면 두 Point들의 Vector 값의 차를 구한 다음에 그 값을 Length() Function에 넣어주어야 한다는 특징이 있다. 이는 왜냐하면 Length() Function은 원점으로부터 Vector값의 거리를 구해주기 때문에 한가지의 값만 받아들이기 때문이다.

 

만일 다음과 같이 Node들이 구성되어 있고 add4와 add5의 길이를 구하고 싶으면 다음과 같이 코드를 작성해주어야 한다.

 

add4와 add5의 거리 길이 값을 구해주기 위해 wrangle node안에서 코드를 작성해야 한다.

 

// Vex에 작성되는 point() function은 Vector 값을 반환하며 일반적인 Expression Function과는 다르게 작성된다.
point (Geometry, "Attribute", Point Number);

vector c = point (2, "P", 0);
vector d = point (3, "P", 0);

// dist() Function을 사용할 시
float dist = distance (c, d);
f@DIST = dist;

// length() Function을 사용할 시
vector sub = d - c;
float length = length (sub);
f@LENGTH = length;

 

https://www.sidefx.com/docs/houdini/vex/attrib_suite#point

 

Reading attributes

These functions take an additional argument. The functions will overwrite the integer variable you pass to this argument with 1 if the read succeeded or 0 if it failed. This lets you distinguish when the function returns 0 because the attribute value is ac

www.sidefx.com

 

Clamp() Function

clamp() Function과 fit() Function을 다시 상기시켜 보자면 clamp()는 말 그대로 한계 지점을 정하여 Function 안에 들어가는 값을 넘어가는 Point들의 정보들이 있을 경우 더이상 넘어가지 못하게끔 한계 지점을 만들어주는 Function 이다. 

 

@P.y = @P.x;
@P.y = clamp (@P.y, chf("MIN"), chf("MAX"));

 

다음과 같이 @P.y값을 @P.x값과 동일하게 만들어 대각선 모양의 라인을 만들어주었을 때에 clamp()를 활용하여 각각의 한계지점을 넘어가는 Point들의 Position값을 눌러주었다.

 

https://www.sidefx.com/docs/houdini/vex/functions/clamp.html

 

clamp

vector4  clamp(vector4 value, vector4 min, vector4 max) Returns a new vector containing the clamped value of each component.

www.sidefx.com

 

Fit() Function

fit()은 clamp()로 정해진 한계 지점이 포함된 상태에서 최솟값과 최댓값을 설정해줌으로써 값들을 최솟값과 최댓값 사이에 맞게끔 확대 혹은 축소시켜주는 Function이다. fit()의 두번째와 세번째로 들어가는 값들은 clamp()와 동일하다.

 

@P.y = @P.x;
@P.y = fit (@P.y, chf("INPUTMIN"), chf("INPUTMAX"), chf("OUTPUTMIN"), chf("OUTPUTMAX"));

 

다음과 같이 이미 한계지점이 정해진 라인들이 fit()으로 인해 확대되어 Y값과 함께 확대된것을 알 수 있다.

 

https://www.sidefx.com/docs/houdini/vex/functions/fit.html

 

fit

fit( value, omin, omax, nmin, nmax) Takes the value in the range (omin, omax) and shifts it to the corresponding value in the new range (nmin, nmax). The function clamps the given value the range (omin, omax) before fitting, so the resulting value will be

www.sidefx.com

 

chramp() Function

chramp() Function은 각각의 Point의 값을 원하는 대로 Ramp로써 파라미터 안에서 설정할 수 있게끔 만들어주는 Function으로써 Range가 1일때 까지의 범위에게만 적용되고 그 이상 넘어가는 Object들은 Ramp의 형태가 반복되게 된다.

 

@P.y = @P.x;
@P.y = chramp ("MYRAMP", @P.y);

 

chramp()로 설정된 ramp의 형태의 맞게끔 Point들의 @P.y 값들이 ramp에 일치하는 값으로 설정된 것을 알 수 있다.

 

https://www.sidefx.com/docs/houdini/vex/functions/chramp.html

 

chramp

float  chramp(string channel, float ramppos) float  chramp(string channel, float ramppos, float time) vector  chramp(string channel, float ramppos) vector  chramp(string channel, float ramppos, float time) Evaluates a ramp parameter and retur

www.sidefx.com

 

If Statement

그리고 If Statement에 대해서도 상기해보았는데 이는 다음과 같은 원리로 작동되는 것을 알 수 있다. 만일 어떠한 Point들을 각기 다른 색으로 만들어 주고 싶을때 If Statement를 통해 간단하게 구현시켜줄 수 있다. 만약 아래에서 처럼 Point의 @P.x의 값이 a보다 작으면 빨간색, 혹은 a보다 크지만 b보다 작으면 초록색, 전부 다 해당하지 않는다면 파란색 이러한 식으로 If Statement를 구성할 수 있다. 

 

float a = chf ("A");
float b = chf ("B");

if (@P.x < a) {
    @Cd = {1, 0, 0};
} else if (@P.x > a && @P.x < b) {
    @Cd = {0, 1, 0};
} else {
    @Cd = {0, 0, 1};
}

 

다음과 같이 Object이 있을시에 If Statement에 일치하게끔 값을 설정시켜주어 원하는 부분만 적용시켜줄 수 있다.

 

https://www.sidefx.com/docs/houdini/expressions/if.html

 

if

When the current frame number ($F) is less than 12, returns the current frame number, otherwise returns 75.

www.sidefx.com

 

normalize() Function

그리고 마지막으로 Joy of Vex에서 배웠던 심화 과정들을 빠르게 훑어보는 시간을 가져보았다.

 

normalize() Function은 어떤 Vector값이든지 간에 Vector값의 크기를 1로 만들어주는 Function이다. 값으로는 크기를 1로 만들어주려는 Vector값을 집어넣는다.

 

// Example
vector a = {10, 34, 634};
vector normA = normalize (a);
v@NORMA = normA;

 

윗 코드로 계산하게 되면 다음과 같은 결과값들이 나오게 된다.

 

https://www.sidefx.com/docs/houdini/vex/functions/normalize.html

 

normalize

normalize( v) Returns the normalized version of v.

www.sidefx.com

 

minpos() Function

minpos() Function은 두 Object들이 하나의 Wrangle Node로 연결되었을시에 기준이 되는 Object에서로부터 Reference가 되는 Object 정보중 가장 가까운 Point의 Vector값을 반환해주는 Function이다. 값으로는 반환하려는 Reference가 되는 Object이 Wrangle Node의 어떤 Input에 연결되었는지에 대한 번호값과, 불러올 Point들의 Attribute Type을 작성한다.

 

// Example

// 1번 input으로 들어간 geometry를 구성하는 포인트들 중 가장 가까운 포인트의 위치값을 좀 알려달라
vector pos = minpos (1, @P);
v@POS = pos;

 

https://www.sidefx.com/docs/houdini/vex/functions/minpos.html

 

minpos

If specified, only report points on You can also use group specification syntax like @Cd.x>0, but note that the @ may need to be escaped with a backslash in a Wrangle snippet. An empty string matches all primitives.

www.sidefx.com

 

nearpoint() Function

nearpoint() Function은 두 Object들이 하나의 Wrangle Node로 연결되었을시에 기준이 되는 Object에서로부터 Reference가 되는 Object 정보중 가장 가까운 Point의 Point Number (Integer)값을 반환해주는 Function이다. 값으로는 반환하려는 Reference가 되는 Object이 Wrangle Node의 어떤 Input에 연결되었는지에 대한 번호값과, 불러올 Point들의 Attribute Type을 작성한다.

 

// Example

// 1번 input으로 들어간 geometry를 구성하는 포인트들 중 가장 가까운 포인트의 포인트 넘버값을 좀 알려달라
int pos = nearpoint (1, @P);
i@POS = pos;

 

https://www.sidefx.com/docs/houdini/vex/functions/nearpoint.html

 

nearpoint

When running in the context of a node (such as a wrangle SOP), this argument can be an integer representing the input number (starting at 0) to read the geometry from. Alternatively, the argument can be a string specifying a geometry file (for example, a .

www.sidefx.com

 

dot() Function

dot() Function은 두 Vector의 값 사이의 내적 각도를 구해주는 Function이다. 값으로는 두 Vector의 값들이 들어간다.

 

// Example

float angle = dot (@P, @N);
f@ANGLE = angle;

 

 

https://www.sidefx.com/docs/houdini/vex/functions/dot.html

 

dot

int  dot(int a[], int b[]) Returns the sum of dot products i.e. dot(a, b) = dot(a[0], b[0]) + ... + dot(a[n-1], b[n-1]) where n = min(len(a), len(b)).

www.sidefx.com

 

cross() Function

cross() Function은 두 Vector에서 수직이 되는 Vector값을 구해주는 Function이다. 값으로는 두 Vector의 값들이 들어간다.

 

// Example

vector vec = cross (@P, @N);
v@VEC = vec;

 

https://www.sidefx.com/docs/houdini/vex/functions/cross.html

 

cross

vector  cross(vector a, vector b) Returns the cross product between the two vectors.

www.sidefx.com

 

Array & nearpoints() Function

Array는 여러개의 정보들을 하나의 Variable로써 만들어주는 역할을 해주며 nearpoints() Function과 같이 nearpoint()와 동일하지만 여러개의 Reference Object에서 가장 가까운 Point들의 Integer 정보들을 반환하는데 array의 형태로써 하나의 Variable안에 저장될 수 있다. nearpoints() Function은 값으로는 반환하려는 Reference가 되는 Object이 Wrangle Node의 어떤 Input에 연결되었는지에 대한 번호값과, 불러올 Point들의 Attribute Type을 작성하고, 얼마만큼의 범위만큼 가까운 Point들을 찾을지에 대한 Float 값과, 얼마나 많은 Point들의 정보들을 불러올지에 대한 Integer값을 입력한다.

 

// Example

// 1번 input으로 들어간 geometry를 구성하는 포인트들 중 3.5만큼의 범위 안에서 가장 가까운 10개의 포인트들의 포인트 넘버값을 좀 알려달라
int[]pos = nearpoints (1, @P, 3.5, 10);
i[]@POS = pos;

 

https://www.sidefx.com/docs/houdini/vex/functions/nearpoints.html

 

nearpoints

The name of the geometry file to reference. Inside Houdini, this may be “op:full_path_to_sop” to reference a SOP.

www.sidefx.com

 

Loops - foreach & for

Loops는 각각 두가지의 형태가 있는데 foreach는 array안에 값들을 전부 열거해주는 Loops로써 값으로는 반환을 하려는 variable값과 array variable을 집어넣어주면 된다.

 

 // 이 값을 가지고 있는 array variable twa생성
int twa[] = {2, 7, 3, -2, 8};

foreach (int x; twa) { // array twa안에 있는 모든값들에 대해
    addpoint (0, set (x, 0, 0)); // array안에 있는 각각의 수치에 따라 생성되는 포인트들의 x값이 정해진다
}

 

점들이 위와 같이 여러개 분포되어 있는 것을 알 수 있다.

 

https://www.sidefx.com/docs/houdini/vex/functions/foreach.html

 

foreach

foreach ([element_type] value; array) { } This loops over the members of array. For each iteration, it copies the current member to value and then executes statement. For example: int an_array[] = {1, 2} foreach (int num; an_array) { printf("%d", num); }

www.sidefx.com

 

for Loops는 Array 안에서 원하는 범위의 값들을 전부 인식하게끔 만들어주는 Loops로써 값으로는 Variable, Conditional, 그리고 Calculation이 들어간다. 즉 예시를 들면 다음과 같다.

 

 // 이 값을 가지고 있는 array variable twa생성
int twa[] = {2, 7, 3, -2, 8};

for (int i = 0; i < len(twa); i++) { // i가 0일 때부터 array안에서의 값들의 수만큼 까지 1씩 늘어났을때
    addpoint (0, set(i, 0, 0)); // x값이 i일 경우의 포인트들을 모두 생성하여 보여주어라
}

 

CopyToPoints Node

CopyToPoints Node는 첫번째 Input에 복사하고자 하는 Object을 연결해준 다음 두번째 Input에 어떤 Point들에게 복붙하려는지 설정해줄 수 있게 할 수 있다. 이 때 두번째 Input에 연결하기전에 Wrangle Node를 달아두어 @N과 @up (바라보는 방향과 머리가 들려있는 방향을 정해주는 Attribute)혹은 @pscale (Object이 얼마나 확대되거나 축소될지 정해주는 Attribute)과 같은 Attribute를 세부적으로 설정하여 원하는 Rotation혹은 Scale으로 해당 Object이 각각의 Point에서 바라보게끔 만들어 주었다.

 

https://www.sidefx.com/docs/houdini/nodes/sop/copytopoints

 

Copy to Points

 

www.sidefx.com

 

quaternion() Function

Quaternion() Function 은 어떠한 Axis를 중심으로 얼마만큼의 Angle로 돌려줄지 결정해주는 Function으로써 @orient값을 반환하여 준다. 값으로는 3x3 Matrix의 형태인 Rotation (matrix3) 값을 집어넣을 수 도 있고, 또는 기본적으로 Radians로 단위가 설정된 Angle (float)값과 Axis (vector)값을 집어넣어 줄 수 있다. 또는 Radians의 단위인 Angle값과 Normalized된 Axis값을 곱하여 한가지의 Angleaxis (vector)값을 집어넣어줄 수 있다.

 

// Example
float angle = radians (chf ("ANGLE"));
vector axis = chv ("AXIS");
@orient = quaternion (angle, axis);

 

https://www.sidefx.com/docs/houdini/vex/functions/quaternion

 

quaternion

vector4  quaternion(matrix3 rotations) Creates a vector4 representing a quaternion from a 3×3 rotational matrix. vector4  quaternion(float angle, vector axis) Creates a vector4 representing a quaternion from an angle and axis. The angle is specified

www.sidefx.com

 

여기서부턴 Joy of Vex 내에서도 심화과정에 속하는 내용인지라 예시와 더욱 깊은 설명을 위해서 전에 작성하였던 링크를 대신해서 달아두기로 하였다.

 

primuv() Function & xyzdist() Function

primuv() Function는 원하는 특정 primitive에서 primitive의 u값과 v값을 토대로 원하는 정보를 받아와주는 Function이다. primuv()에는 wrangle노드에 연결된 input의 넘버, 어떠한 정보를 불러오고자 하는지, 몇번 primitive, 그리고 uv를 vector값으로 입력해주어야 한다. 

 

https://www.sidefx.com/docs/houdini/vex/functions/primuv.html

 

primuv

The name of the attribute to read. For point and vertex attributes, the value will at the given UV coordinates will be interpolated from the surrounding points/vertices.

www.sidefx.com

 

xyzdist() Function는 minpos()/nearpoint()/nearpoints() 와 비슷하게 하나의 geometry에서 가장 가까운 geometry의 대한 정보를 가져다 주는데 세개의 정보를 가져다 준다. 이는 float값인 두 geometry의 사이의 거리값, 그리고 가장 가까운 프리미티브가 몇번인지 (integer value), 그리고 가장 가까운 부분의 uv값이 어떤 값인지 vector값으로 가져와 준다. 이때 xyzdist()에는 네개의 값을 입력해주는데 wrangle의 몇번 인풋에 연결되었는지, 어떤 Attribute정보를 불러오고 싶은지, 어떤 프리미티브 값을 불러오고 싶은지, 그리고 uv값을 뭘 불러오고 싶인지 입력해야 한다. 

 

https://www.sidefx.com/docs/houdini/vex/functions/xyzdist.html

 

xyzdist

The name of a primitive group or a pattern to generate a primitive group. Uses the same semantics as a SOP group, so empty strings will match all primitives. Attribute groups like @Cd.x>0 can also be used, but note that the @ may need to be escaped with a

www.sidefx.com

 

primuv()와 xyzdist()의 대한 예시들과 더욱 자세한 설명들은 아래의 링크를 통해 알아볼 수 있다.

 

https://davidhoudinistudy.tistory.com/30

 

Joy of Vex - Day 19: primuv, xyzdist

중요했던 부분: - uv uv는 primitive상에서 가로값과 세로값을 1로써 비율을 맞추었을때 그 비율을 알려준다. 아래의 그림을 하나의 프리미티브라고 가정하고 가로값을 v 세로값을 u이라고 가정했을

davidhoudinistudy.tistory.com

 

Pointclouds

pointclouds는 각각의 위치에 해당하는 Point들의 형태를 부분 부분적을 표현하여 마치 구름이 있는 것처럼 3D의 형태를 만들어주는 집합체이다. 이 또한 여러개의 Function들과 심화적인 내용들을 포괄함으로써 다음 링크를 통해 해당 내용을 대변하도록 하였다.

 

https://davidhoudinistudy.tistory.com/31

 

Joy of Vex - Day 20: pointclouds, further learning

중요했던 부분: - nearpoints() & foreach 복습 우선적으로 nearpoints()와 foreach를 활용하여 pointclounds와 같은 형상을 만들어 보았다. 이는 box안에서의 랜덤한 위치의 7개의 점들로부터 box안을 꽉꽉이루는

davidhoudinistudy.tistory.com

 

Conclusion

지금까지 최초 입문 강의와 Joy of Vex의 간략한 복습들을 진행하였다. 오랜만에 다시 시작해보는 후디니 과정이었지만 다행히 지난번에 필기를 열심히 한 덕분인지 전부 다 확실하게 넘겨 집고갈 수 있었던 것 같았다. 다음 시간부터 본격적인 Houdini 1을 배워볼 예정으로써 지금까지의 내용을 확실하게 숙지해야 할 것 같다. 앞으로 배울 Houdini 1 Starter 과정을 더욱 나아감으로써 후디니에 대한 자신감을 더욱 상승시켰으면 하는 바람이다.

'FX > Houdini_Houdini 1' 카테고리의 다른 글

Starter - Ep 1: Group  (0) 2022.12.06