트위터


2017/03/16 02:08

후디니 Houdini Vex vex

==원문서 : CGwiki
==짬짬이 번역해보는중


Wrangle Sops는 작은의 Vex 코드를 작성하고 사용하기에 빠르고 효율적으로하기 위한 몇 가지 UI가 잘 갖춰져 있습니다. 그들은 다양한 특징 (포인트, 프림, 디테일, 속성) 들이 '모두 같은' 메뉴에 포인트/프림/디테일 로 전환된 것들입니다.

Wrangle nodes에 접근하는 가장 좋은 방법은, 40x40 그리드를 생성후, point wrangle을 붙여 주는 것으로 시작됩니다.



Contents

1 Create a new attribute
2 Get existing attribute values
3 Implicit vs explicit attribute type
4 Create UI controls
5 Customise the UI elements
6 Common functions
7 Built-in attributes
8 Example: Random delete points by threshold
9 Example: Wave deformer
10 Attributes vs variables
11 Example: Rotation
11.1 Rotate a single point with sin and cos
11.2 Rotate geometry with sin and cos
11.3 Rotate into a twirl or spiral
11.4 Rotate with a matrix
11.5 Rotate prims around an edge
11.6 Rotate prims around an edge, alternate version
12 Wrangles vs hscript vs vops vs everything else
13 Mixing vex and vops with snippets
14 Get values from other points, other geo
15 Blurring attributes with vex and point clouds
16 Get attributes from other inputs
17 Arrays
18 Search an array with find
19 Access group names procedurally in vex
20 Solver sop and wrangles for simulation
21 Solver and wrangle for branching structures
22 Get transform of objects with optransform
23 optransform to do a motion control style camera
24 More on rotation: Orient, Quaternions, Matricies, Offsets, stuff
25 ZOMG more rotation: Convert N to Orient with dihedral
26 Convert N and Up to Orient with maketransform
27 Remove points that don't have normals directly along an axis
28 Scaling with vex and matrices
29 xyzdist to get info about the closest prim to a position
30 Rubiks cube
31 Vex vs Vops
32 Vex snippet cheat sheet
33 Further learning





-[ 1 Create a new attribute ]-

새로운 플롯 속성의 'foo' 를 정의하고 싶다면, 그냥 입력하세요

@foo;

ctrl+Enter 키를 눌러서 geometry Spreadsheet를 보면서 하면 새롭게 foo 속성이 생긴 것을 볼 수 있습니다.
이 @ 는 후디니에게 '이것을 속성으로 해달라' 는 것을 알려주며, 기본적으로는 float(플롯) 유형으로 입력됩니다.

initialized를 하고 싶나요?

@foo=1;

벡터 속성이 필요한가요? '@' 앞에 'v' 를 추가하는 것으로 가능합니다. intialise 하려면, 중괄호 안에 숫자를 넣거나, 함수나 다른 속성으로 뭔가 하고 싶다면 'set()' 을 사용하세요.

v@myvector = {1, 0, 3};
v@other = set(0, @P.x, 1);

'v' 와 같이, 적절한 접두사를 사용하여 속성 유형을 설정할 수 있습니다.

// common ones 주로 쓰는 것들
f@foo = 12.234; // float 플롯
i@foo = 5; // int 인티저
v@myvector={1,0,3}; // vector 벡터

// less common ones그외 기타
p@george;  // quaternion, a 4 value vector 사원수 혹은 4벡터
3@transform; // a 3x3 matrix 3-3행렬
 
// there's more, see below. :) 나머지는 아래를 참고하세요 :)

이곳에 전체 리스트가 있습니다





-[ 2 Get existing attribute values ]-

myvector 속성이 각 포인트들의 위치값으로 가져오길 원한다면

v@myvector = @P;

@라는 기호는 속성을 가져와 설정하는 것에 주로 사용됩니다.
지오메트리 스프레드 시트에 표시되는 모든 속성은 이름 앞에 @를 붙임으로써 엑세스(접근/불러오기)할 수 있습니다.

만약 각 포인트에 있는 N의 1.5배를 원한다면
(기본 그리드에서는 스프레드 시트에 N이 숨어있습니다. 씬 뷰에서는 Display Normal 을 켜는 것으로 시각화 할 수 있음)

v@myvector = @N * 1.5;

벡터 또는 색상의 개별 속성에 엑세스하려면, @attribute.channel 을 사용합니다.
예를 들어 각 점의 y 값을 구하여 반으로 나눕니다.

@foo = @P.y / 2;

비슷한 방법으로, 각 점의 컬러 Red채널을 X위치의 2배인 sin으로 설정하려면

@Cd.r = sin( @P.x * 2 );

Cd 또는 P 와 같은 벡터 속성을 사용하려면 여러가지 방법으로 구성요소를 참조 할 수 있으므로 편리하게 사용할 수 있습니다.
구성요소는 r, g, b / x, y, z / [0], [1], [2] 가 가장 많이 사용됩니다.

// These all do the same thing, set the first component of the vector:
// 이것들은 모두 같은 역할을 합니다. 벡터의 첫 번째 요소를 설정합니다.
@Cd.r = 1;
@Cd.x = 1;
@Cd[0] = 1;

// As are these, all setting the third component:
// 물론 이것들은 모두 세번째 요소를 설정합니다.
@P.z = 6;
@P.b = 6;
@P[2] = 6;





-[ 3 Implicit vs explicit attribute type ]-

Wrangles 은 특정 공통 속성들의(@P, @Cd, @N, @v, @orient) 유형(Float,Vector,Integer등)을 따로 지정하지 않아도 됩니다만,
본인이 따로 만든 속성이 있다면, 달리 지정하지 않는한 앞서 말한 기본인 플롯으로 간주합니다.

후디니가 생각한대로 작동하게 하기 위해선 그 유형을 앞에 붙여줘야 합니다. 예를들어 @mycolur를 벡터로 설정한 다음, 이를 회전목마에 사용하려고 합니다.

// BAD
@Cd = @mycolour; // This will treat it as a float and only read the first value (ie, just the red channel of @mycolour)
// 이렇게 되면 float으로 간주되어 첫번째 값만 읽게됩니다 (즉, @mycolour의 red 채널만입니다. RGB)
 
// GOOD
@Cd = v@mycolour; // Explicitly tells the wrangle that its a vector.
// wrangle의 대상인 벡터를 정확히 명시해뒀습니다

모든 작업을 마친 뒤, 이러한 유형을 지정해 주지 않아 문제가 발생 할 수 있습니다.
잊지마세요. 자신이 만든 속성값 앞의 유형을 확실히 지정해주세요.





-[ 4 Create UI controls ]-

먼저 이렇게 해줍시다.

@Cd.r = sin( @P.x * 5 );

하지만 여기서 5 를 다른 번호로 변경하려고 합니다. 다른 번호로 코드를 계속 변경하거나 5 를 ch('scale') 로 바꿀 수 있습니다.

@Cd.r = sin(  @P.x * ch('scale')  );

ch() 는 후디니가 UI 구성요소(보통 슬라이더입니다)를 호출하는 채널을 찾도록 지시합니다.
텍스트 편집기의 오른쪽에 있는 작은 플러그 아이콘을 누르면 후디니가 vex 코드를 스캔하고, 아직 존재하지 않는 채널을 참조했다는 것을 알게됩니다. 그리고선 Wrangle 의 하단에 'scale' 이라는 채널이 만들어지고 이 슬라이더를 조절함으로써 색상이 업데이트 되는 구조입니다.

사용할 수 있는 몇가지 채널 유형이 있습니다. ch() 및 chf() 는 모두 float 채널을 만듭니다. 그 외에도

// An int channel
// INT 유형의 채널
i@myint = chi('myint');
 
// A vector channel
// Vector 유형의 채널
v@myvector = chv('awesome');
 
// A ramp channel
// 램프 유형의 채널
f@foo = chramp('myramp',@P.x);


마지막의 램프 유형은 정말 편리합니다.
먼저 하나의 값(@P.x)들을 모두 읽어들인 뒤, UI 램프 위젯을 통해 다시 매핑한 다음 @foo 를 통해 피드값을 가져옵니다.
나는 결국 내 설정을 통해 이들 중 많은 것을 사용하게 됩니다. 들어오는 값이 0부터 1까지의 범위에 있다고 가정할 때, 램프로 공급하기 전에 값을 맞춰야 합니다. 이땐 fit 함수가 적합합니다 작성방법은 if(value, oldmin, oldmax, newmin, newmax) 입니다.
예를들어 X를 -0.5와 6 사이로 다시 매핑한 다음 램프를 사용하여 해당값을 적색 채널에 공급해보겠습니다.

float tmp = fit(@P.x, -0.5,6,0,1);
@Cd.r = chramp('myramp',tmp);

(**)호기심으로 fit함수를 사용하지 않고 바로 넣어봤습니다. @P.x 가 전체적으로 -5부터 5까지 분포되어 있고, 램프를 0에서 1까지 단순히 증가하는 그래프로 지정한 상태로 스프레드시트를 봤을때, [0 to 5], [0 to -5] 로 나뉘어서 0 이 0으로, 5와 -5가 1 로 변환되었습니다. 이 원인이 무엇인지는 저도 잘 모르겠습니다.


자, 이제 Ui슬라이더에 기존 값의 시작점과 끝점까지 정의합시다.

float min = ch('min');
float max = ch('max');
float tmp = fit(@P.x, min,max,0,1);
@Cd = 0;  // lazy way to reset the colour to black before the next step 다음과정을 준비하기 위한 검정색만들기 과정.
@Cd.r = chramp('myramp',tmp);






-[ 5 Customise the UI elements ]-

플러그 버튼은 편리한 기능이며 모든 채널 값들을 검색하고, 기본값들과 함께 기본 유형을 만듭니다.
일단 채널이 만들어지면 Wranlge 노드에서 우클릭하여 'edit parameter interface'(혹은 우측상단 톱니바퀴 메뉴의 parameter panel)에 들어가서 플롯의 범위나 기본값, 레이블 등을 원하는대로 변경할 수 있습니다.

이중에서 보통 기본적인 벡터 채널을 컬러채널로 변환하는게 많이 쓰입니다.
한번 해봅시다. vex에서 필요한 만큼 많은 벡터 채널을 만들었습니다. 예를들어,

v@colour1 = chv('col1');
v@colour2 = chv('col2');
v@colour3 = chv('col3');
v@colour4 = chv('col4');

그런 뒤 플러그 버튼을 클릭, 톱니바퀴의 edit the parameter interface 에 들어가서, shift-select로 만들었던 4개를 모두 선택하고, type을 'color' 로 변경합니다. 그 다음 민감한 변화를 최소화 하기 위해 show color as 를 HSV slider로 변경해주세요. 이게 제일 다루기 편합니다.






-[ 6 Common functions ]-

이외에도 wrangle로 vex를 사용할 때 99%로 나오는 것들입니다.

fit()
최대와 최소값 사이의 숫자들을 받아들어, 다른 2개의 값 (보통 0부터 1까지로) 을 넣으세요.
예를들어 -5에서 20까지의 @u 를 0에서 1로 다시 매핑하고 싶을땐
foo = fit(@u, -5, 20, 0, 1);

rand()
0과 1사이의 임의의 숫자를 생성합니다. 일반적으로 포인트 ID를 제공하므로, 각 포인트는 임의의 숫자를 얻습니다.
foo = rand(@ptnum);

sin() , cos()
사인과 코사인입니다. 다만 radian 안에서.

radians()
각도에서 라디안으로 숫자를 변환합니다
foo = radians(90);

length()
벡터의 길이를 측정합니다. 예를들어 원점에서 한 점까지의 거리를 측정할 때
dist = length(@P);

distance()
두 점 사이의 거리를 측정합니다.
dist = distance(@P, v@mypoint);






-[ 7 Built-in attributes ]-

사용할 수 있는 변수가 몇가지 있습니다. 가장 쉽게 볼 수 있는 방법은 point vop을 만들어서 global params를 보는 것입니다.
다음은 일반적인 것들입니다.

@ptnum : 포인트 id
@numpt : 총 포인트 수
@Time : 현재 시간 (초)
@Frame : 현재 프레임
@primnum : 프리미티브 ID
@numprim : 총 프리미티브 수






-[ 8 Example: Random delete points by threshold ]-

Matte Ebb 씨께서 이것을 보여준 뒤로 나는 이것을 하루에 수백만번 사용하고 있습니다. Scatter의 일부 point들에 아래의 wrangle을 함께 사용합니다.

if ( rand(@ptnum) > ch('threshold') ) {
   removepoint(0,@ptnum);
}

이제 플러그 버튼을 눌리고 새로 생긴 threshold 의 슬라이더를 움직이면, 슬라이더의 0 과 1 사이에서 무작위로 포인트들이 사라지는 것을 볼 수 있을 것입니다.

rand(@ptnum)
// 각 점은 ID를 기반으로 0과 1사이의 무작위 난수를 얻습니다.

> ch('threshold')
// 만들어진 난수를 threshold(뜻:임계) 값의 슬라이더와 비교하여 임계값 보다 큰 경우..

removepoint(0,@ptnum)
// 포인트를 삭제합니다. 여기서 0은 input1 을 의미합니다. 즉, 이 wranlge 에 연결된 모든 모든것을 말하며, @ptnum은 포인트를 대상으로 삼을 참조값입니다.






-[ 9 Example: Wave deformer ]-

먼저 40x40의 그리드를 준비합니다.
중심에서 방사되는 동심원 Sin파동을 만들겠습니다. 즉, 각 점의 원점까지의 거리를 측정해야 합니다.

@d = length(@P);

그리고 그것들을 sin()으로 보내고, 이를 이용해 각 점의 Y위치를 직접 설정합니다.

@P.y = sin(@d);

하지만 여기서는 이를 슬라이더로 사용하도록 만들겠습니다.

@P.y = sin(@d * ch('scale'));

플러그버튼을 눌린 뒤 슬라이더를 직접 조작해보세요. (값이 1을 넘도록 조작해보세요)
슬라이더를 움직일때마다 파도가 움직일 것입니다.
이제 파도가 애니메이션 되도록 time값을 추가합니다.

@P.y = sin(@d * ch('scale') + @Time);

다만 우리는 파도를 밖으로 보낼것이기 때문에 시간은 반대로 줍시다.

@P.y = sin(@d * ch('scale') - @Time);

이제 속도를 조절하기 위한 슬라이더도 추가합시다.

@P.y = sin(@d * ch('scale') + (ch('speed') * @Time) );

지저분하네요. 잠시 정리를 하겠습니다.
Wranlges 에서 좋은점은 가독성을 위해 여러 줄로 나눌 수 있다는 것입니다.

@d = length(@P); // 'd' 속성은 현위치에서 0점까지의 거리값으로 생성됩니다
@d *= ch('scale'); // 'd' 속성은 슬라이더(name:scale)값을 곱하여 생성됩니다
@speed = -@Time*ch('speed'); // 'speed' 속성은 슬라이더(name:speed)값에 시간을 곱하여 생성됩니다
@P.y = sin(@d+@speed); // y위치는 d 속성과 speed 속성을 더한값의 Sin 값으로 생성됩니다

여기에 몇가지 더 더해봅시다. 최대높이와 거리에 따른 감쇠값을 만들겠습니다.
최대 높이는 간단합니다. 최종 결과가 무엇이든 채널값을 참고삼아 추가로 값을 곱해버리면 됩니다.
물론 1을 곱하면 바뀌지않을것이고, 0을 곱하면 높이는 없어지겠죠. 다른숫자도 적절하게 조절됩니다.

@P.y *= ch('height');

마지막으로 감쇠값을 제어하는 Ramp입니다. Ramp는 0과 1사이의 변수값을 가져오도록 하기 위해 우선 만들어진 ramp 값을 참고하여 fit()을 사용해 0과 1사이로 다시 매핑합니다.

@falloff = fit(@d, ch('start'), ch('end'), 1, 0);
// falloff 속성은 'd' 값을 최대값 start 와 최소값 end 를 최대 1과 최소 0사이로 다시 매핑한 값입니다

램프채널에는 이름과 변수가 필요하며, 변수는 램프의 곡선을 통해 다시 매핑됩니다. 이 결과를 P에 직접 곱합니다.

@P.y *= chramp('falloff', @falloff);
// y위치값은 falloff를 참조삼아 만들어진 Ramp채널(name: falloff) 을 곱한값으로 만들어집니다

여기서 약간 사소한 문제는, 시작과 끝이 전체의 공간(월드 스페이스) 단위가 될 것으로 예상했지만, 예상외로 'end' 가 커졌습니다.
우리가 이미 파동의 횟수를 제어하기 위해 Scale 채널을 d 에 곱해버렸기 때문에 된 것 같습니다.
아래는 이를 개편한 수정판입니다.

@d = length(@P); // d는 현위치에서 0점까지의 거리값
@speed = @Time * ch('speed'); // speed 는 시간에 채널'speed'를 곱한 값
@falloff = fit(@d, ch('start'), ch('end'),1,0); // falloff 는 d의 최대(start)와 최소(end)를 1과 0으로 매핑한 값
 
@P.y = sin(@d*ch('scale')+@speed); // y위치는 d와 채널'scale' 와 speed 를 모두 더한 값의 sin 값
@P.y *= ch('height'); // y위치는 여기서 채널'height'를 곱한 값
@P.y *= chramp('falloff', @falloff); // y위치는 여기서 falloff값의 참조로 만들어진 램프채널'falloff' 을 곱한 값






-[ 10 Attributes vs variables ]-

앞서 주어진 예제는 모두 @ 구문을 사용하여 포인트의 속성을 가져오거나 설정했습니다. 
만약 wralnge이 많지 않거나, wranlge 밖에서는 속성을 필요로 하지 않는다거나,
지오메트리 시트가 지저분해지는게 싫다거나, 모든 포인트의 데이터들이 메모리를 차지할 수 있습니다.
특히 복잡한 장면일 경우엔 더더욱이요.

이를 대신해 wrangle 내에서만 존재하는 변수를 만들 수 있습니다.
구문은 다른 C-style의 언어와 유사합니다.
전반적인 단어로 유형을 정의하되, 변수 앞에는 아무것도 붙이지 않습니다.

float foo;
vector bar = {0,0,0};
matrix m;

foo = 8;
bar.x += foo;

포인트 변수와 vex 변수는 각각 별개로 분리되어 있기 때문에 각각 동일한 이름으로 설정할 수 있으며,
이들은 상호 공존할 수도 있게 됩니다. 
의미하지 않았던 곳을 쉽게 추가하거나 필요로 하는 곳에 하나를 쉽게 제거할 수 있게 됩니다.

float dist = length(@P);
// 이 wrangle 내에서만 존재하는 로컬 변수

@dist = dist
// 새로운 point 속성 @dist를 생성하고, 로컬변수 'dist' 를 할당합니다.

변수를 사용하는 예제활용을 위해 앞의 예제를 다시 작성해보겠습니다.
물론 이번엔 변수를 선언하는 일을 먼저 합니다.

float d;
float speed;
float falloff;

d = length(@P);
speed = @time * ch('speed');
falloff = fit(d, ch('start'), ch('end'), 1, 0);

@P.y = sin(d*ch('scale')+speed);
@P.y *= ch('height');
@P.y *= chramp('falloff', falloff);






-[ 11 Example: Rotation ]-



2016/12/31 23:59

프롤로그 - (Update 20150304) 메인카테고리



닉네임 . Dsharp [D#, 디샵]

직업. 대학생

할줄 아는것. 숨쉬기

모자란것. 숨쉬기 (?!)


능력없는 한 학생이 넷상에서 개인자료 관리하고 주변 네티즌들과 소통하기 위해 생성된 이글루스의 한 이용자의 블로그입니다.
일단 나름 영상관련쪽으로 배우고는 있는데, 하라는 연습은 안하고 머릿속 자작영상에 대한 스토리 망상만 가득한 놈입니다.
생각만 해야지해야지. 몸은 어그적어그적. 이러면 안되는걸 알면서도 어그적어그적.

아래는 기본 스팩입니다.

 나름 규칙적인 생활중.
 일단 학생이다보니 평일 기상시간과 취침시간은 거의 비슷한 편.
 문제라면 취침시간이 되게 늦는데 그 원인은 컴퓨터와 스마트폰.

 다섯가지 항마력을 지니고 있음.
 하지만 그다지 전문적이진 않은 일상계 잡덕
 

 살짝 감성적 (이라 쓰고 남들보기 쓸데없는 눈물이 많다고 해석) 임.
 애니로 봤을 때 제일 많이 울었던 것은 "클라나드"
 영화로 봤을 때 제일 많이 울었던 것은 "각설탕"
 (이게 지금 몇년째 바뀌지 않고 있다..)

 장난기가 꽤 있음.
 오프라인상에서도 사람 낚는걸 즐김.
 물론 어느정도 수위는 지켜가면서.
 그래도 뭐 할려고 하면 최선을 다하는 쪽으로. (문제라면 한다는게 단기간 스퍼트의 경우이다..)

 고지식 (이라 쓰고 애늙은이라 해석) 적인 면이 좀 있음.
 심지어는 얼굴도 노안이어서 여친이나 결혼같은건
 일찍 포기한 채 생활중. (물론 생길지도 모른다는 희망도 있지만..)


 로리만세.



트위터 아이디 : @dsharp_ (update : 15.03.04)



이글루스 접속 일정

'앱게임해봤습니다' 쓰고 싶을때만..


앱해봤

- 도쿄카지노
- 각의 이슈타리아
- 닌쯔쿠 (nintsuku)


2016/10/11 02:20

후디니 소형 물 이펙트 영상제작


(번역문입니다)
원문은 일본의 cgworld 에 수록된 내용이며, 저작권 또한 집필자인  cai inc. 에 있습니다.
어느쪽이든 삭제 요청이 확인되는대로 즉시 해당게시물을 내립니다.
© cai inc. All Rights Reserved.




Topic 01. FLIP Solveer의 설정.



Houdini 15에서 추가 된 Swirly Kernel을 사용

기본적인 FLIP 설치를 진행하면 FLIP Solver의 Velocity Transfer Swirly Kernel로 변경합니다.
Swirly Kernel은 기존의 Splashy Kernel 이외에 Houdini 15에서 추가되었습니다. 이것은 2015 년에 발표 된 The Affine Particle- in- Cell Method라는 논문을 기초로하고 있으며, 소용돌이가 손실되지않고 안정된 계산을 할 수 있습니다. Houdini 도움말에서 Splashy Kernel은 바다와 강 등의 대규모 것, Swirly Kernel은 작은 것들과 용암 같은 시뮬레이션에 적합하다고 설명되어 있습니다. 또한 FLIP Solver의 Use Preconditioner은 기본으로 ON으로되어 있습니다만, 도움말에서는 여러 코어 CPU로 계산하는 경우는 OFF가 더 좋은 성능이 나온다고 설명하고 있기 때문에 OFF로 해봅니다.


그림A : Swirly Kernel과 Use Preconditioner 설정. 설정 항목이 많은 찾기가 힘들지만 매번 전부를 만지는 것은 아니기 때문에 자신의 즐겨 찾기 장소는 눌러 둡시다
그림B : 위가 Swirl Kernel, 아래가 Splashy Kernel의 계산 결과. Splashy Kernel에서는 액체 에서 입자가 튀어 나올 것 같은 거동을 확인할 수 있지만 Swirly Kernel에서는 그것이 부족합니다.


--




Topic 02. 표면장력을 구현하자.


작은 규모의 물 표현에 필수적인 표면 장력

작은 규모의 경우 큰 장면에서는 눈에 띄지 않는 특징이 잘 나타나 있습니다. 그 중 하나가 표면 장력입니다. 표면 장력은 액체가 표면을 가능한 한 작게하려고하는 성질의 것으로, 일상 생활에서도 흔히 볼 수있는 현상입니다. 예를 들어 RealFlow는 처음부터 Surface Tension 매개 변수가 포함되어있어 이를 높임으로써 표면 장력을 강하게 할 수 있지만, Houdini의 FLIP Object와 FLIP Solver에 비슷한 매개 변수는 없습니다. Houdini에서 가장 쉽게 Surface Tension을 추가하려면 Gas Surface Tension DOP를 사용합니다. Gas Surface Tension는 microsolver 노드의 하나로, FLIP Solver에 기능 추가 같은 일을 할 수 있습니다. 이를 FLIP Solver의 Velocity Update에 추가하여 표면 장력의 효과를 만들 수 있습니다.

그림A,B : 표면 장력의 이미지. 컵에서 물이 쏟아져 나오지 않는 것도 마찬가지. 작은 스케일의 액체에서는 이러한 성질이 표정을 갖게하기에 매우 중요한 역할을합니다
그림C : 아주 간단한 FLIP 설정에 Gas Surface Tension을 추가 한 예. 다른 부분에 연결해서 생각 결과를 얻을 수없는 경우가 있으므로 요주의
그림D : 시간에이 표면 장력이없는 경우, 아래가 표면 장력을 추가했습니다. 입자가 모여 물방울과 같은 형상이 형성되어 있습니다




--


Topic 03. microsolver란?



개별 microsolver을 함께 해법을 구축한다.


방금 FLIP Solver에 추가 한 Gas Surface Tension는 micro solver의 하나로, microsolver은 FLIP Solver와 Pyro Solver 같은 큰 해법을 만들기위한 부품입니다. 시뮬에 FLIP Solver 속을 열어 보면 엄청난 수의 노드를 확인할 수있을 것입니다. 이들 대부분이 microsolver이며, 각각 FLIP Solver 처리 부분을 담당하고 있습니다.

FLIP Solver는 4 개의 input이 여기에 노드를 추가하여 중간 처리를 끼울 수 있습니다. 이들은 각각 평가되는 타이밍이 다르기 때문에 잘못된 곳에 노드를 꽃을 경우 결과가 나오지 않을 수 있으므로주의가 필요합니다. microsolver와 접촉하여 방금 전의 표면 장력을 Gas Surface Tension을 사용하지 않고 추가해봅시다.

먼저 오른쪽의 그림과 같이 노드를 짭니다. 사용하는 노드는 Gas Match Field. Gas Analysis. Gas Field Wrangle의 3 종류입니다. Gas Match Field는 참조에 지정된 필드를 기반으로 새로운 필드를 생성 할 수있는 노드입니다. 기타 크기 조정이나 리샘플링 등의 기능도 갖추고 있습니다 만, 주로 필드를 복제하는 데 사용하는 경우가 많습니다.

Gas Match Field에서 만드는 필드는 density. temperature, vel 등의 유체 자체를 나타내는 중요한 데이터와는 달리 임시 데이터로 사용되는 경우가 대부분입니다. 여기에서는 surface와 vel를 복제하고 각각 curvature. gradient했습니다. curvature는 float를 저장하기 때문에 surface를 gradient는 vector를 저장하기 때문에 vel를 참조했습니다.

Gas Analysis는 Source Field에 지정된 필드를 분석하고 Dest Field에 지정된 필드에 그 결과를 저장합니다. SOP에서도 Volume Analysis와 VDB Analysis 등에서 같은 처리 할 수 ​​있습니다. 이번에는 Surface의 Gradient을 gradient에 Surface의 Curvature를 curvature에 저장했습니다. Gradient는 Surface의 기울기를 가져옵니다. 이것은 액체 표면의 법선에 해당합니다. Curvature 곡률입니다. 이것을 사용하면 액체의 계면 부분이 얻을 수 있습니다. 기울기는 3 차원적인 정보이므로 vector 곡률은 1 차원적인 정보이므로 float입니다. 이렇게 만들어진 curvature. gradient 값은 Gas Field Wrangle에서 vel 필드에 표면 장력을 추가 할 때 사용됩니다.

마지막으로 Gas Field Wrangle을 사용하여 직접 필드에 액세스하고 vel 값을 편집합니다. Gas Field Wrangle는 Volume Wrangle의 DOP 버전에서 필드의 값을 편집 할 때 사용합니다. 비슷한 노드에서 Geometry Wrangle이라는 것이 있는데, 이것은 Point Wrangle SOP 등에 해당하는 것으로, 필드의 값을 만지는 것은 불가능하므로주의하십시오. POP Wrangle도 내용은 Geometry Wrangle가 사용되고 있기 때문에 마찬가지로주의가 필요합니다.

또한 이번 예에서는 사용하지 않지만 Gas Blur 등을 사용하여 gradient 필드에 블러를 걸어 구배의 변화를 완만하게 해 준다 것도 더 매끄러운 표면 장력의 결과를 얻으려면 유효합니다. 마찬가지로 Gas Blur를 vel 대해 조금 걸어주는 것이 viscocity을 준 같은 결과를 얻을 수 있습니다 FLIP의 viscocity 조금 값도 상당히 강하게 작용 해 버리는 경우가 많기 때문에 조금 점성라면 Gas Blur 분들이 부담없이 처리 할 수 ​​있습니다.




그림 상 : FLIP Solver의 내용. FLIP Solver는 다수의 microsolver로 만들어진 Digital Asset. 오른쪽 클릭 메뉴에서 Allow Editing Contents를 실행하면 내용을 편집 할 수 있습니다.

그림 중 : gradient, curvature의 각 필드의 데이터를 가시화 한 예. 설명을 위해 더미 객체를 사용하고 있습니다. 상단 왼쪽에서 원래의 형상 형상을 SDF 변한 것, 시각화를위한 포인트 클라우드. 하단 2 개는 이들을 이용하여 gradient. curvature를 시각화 한 것으로, 왼쪽이 gradient, 오른쪽이 curvature. gradient는 형상의 법선을 나타낸 같은 데이터가 있습니다 만, 지오메트리의 뒷면에 법선과 반대 측의 방향에 경사가 부여되어 있습니다. 사진에서 희미하게 확인할 수있는 검은 성분이 그것입니다 curvature은 곡률이 높은 곳에서 큰 값을 확인할 수 있습니다. 어둡고 우울 곳은 음수가있는 곳에서 curvature가 작다는 것은 아닙니다. 또한 둘 다 표면 근처에만 값이 존재하고 볼륨 내부는 거의 제로 또는 그것에 가까운 값으로되어있는 것을 알 수 있습니다.

그림 하 : Gas Match Field에서 추가 된 데이터는 Geometry Spreadsheet의 Solver 다음의 깊은 곳에서 확인할 수 있습니다 density나 vel 등 Flip Object에서 만들어진 필드처럼 알기 쉬운 장소에 존재하는 것은 아니지만뿐만 아니라 데이터 가 존재하고있는 것을 알 수 있습니다. 자주 확인해야 할 부분은 아니지만 스스로 해법을 생성하거나 수정 등하고 싶을 때 특히 지식으로 기억해두면 안심입니다.

그림 결과 : mlcro solver를 사용하여 구축 한 표면 장력 설정. 앞의 예와 비교하면 매우 많은 노드를 사용하고 있습니다 만, 처음부터 모든 것을 스스로 구축 할 수 있기 때문에 자신의 방법을 구축하는 것도 가능합니다.






---


Topic 04. SOP Solver를 사용하자


microsolver없이 표면 장력의 추가 방법.

앞 페이지에서 microsolver를 사용하여 표면 장력의 추가를 실시했지만, SOP Solver를 사용하면 익숙한 SOP에서 필드를 편집 할 수 있습니다. SOP Solver의 장점은 SOP에서 할 수있는 일은 무엇이든 할 수 있다는 것입니다. Geometry VOP. Wrangle 등의 등장으로 활약의 장소는 이전보다 다소 줄어든 것도 사실이지만, 역시 SOP Solver 없어서는 안될 존재입니다. 생각했던 방법을 사용할 수 없을 때 등 만일의 경우에 의지합니다.


그림 좌 : SOP Solver를 사용하여 Surface Tension을 추가 surface 필드를 가져오고 VDB으로 변환 한 후 VDB Analysis에서 gradient와 curvature를 만듭니다. 마지막으로 Volume Wrangle를 사용하여 다른에서 가져왔다 vel 필드를 편집. 일반적으로 만지고있는 SOP에서 데이터를 편집 할 수있을뿐만 아니라 값의 시각화 등을 쉽게 할 수 있기 때문에 사용이 편리합니다




---


Topic 05. 수막 (물의 막) 을 만들자


간이 Sheeter 추가하여 원하는대로 막을 만들자

시뮬레이션을 행하고 있다고 막처럼 번지고 원하는 장소에 본래 싶지 않아 구멍이 뚫려 버리거나 근육처럼 뻗어 원하는 곳에이 분단되고, 레 솔루션을 아무리 올려도 해결 않은 문제가 나타납니다.

RealFlow는 Sheeter 데몬이라는 것이 있는데, 이것을 사용하면 얇은 막 같은 것 같은 얇은 근육을 만들거나 할 수 있습니다. Houdini는 기본적으로 Sheeter 같은 것은 존재하지 않습니다 만, Geometry VOP wrangle을 사용하여 자기 부담의 Sheeter을 만들 수 있습니다. 그러나 실제로 Sheeter 상당의 물건을 만드는 것은 매우 어렵 기 때문에 이번에는 간단한 구현 예를 소개합니다.

액체 표면에 구멍이 교련은 구멍을 채울 정도로 입자가 없기 때문입니다. 그러나 이것은 레졸루션을 올렸 더니에서 충돌 객체의 형상 등에 의해 어쩔 도리가없는 경우가 있습니다. 그래서 간단하게 구멍이 있으면 묻어 버리는 작전을 취합니다. 주위의 파티클을 찾고 일정거리 내에 파티클이 존재하지 않으면 그 중간에 새로운 파티클을 추가하는 아주 간단한 방법을 시도합니다.

이번 편집하는 것은 필드가 아닌 Geometry이므로 Geometry Wrangle을 사용합니다. 사용법은 Point Wrangle과 거의 동일합니다. 추가 한 Geometry Wrangle은 FLIP Solver의 Input에 연결합니다. 이번에는 맨 오른쪽 Input4 : Sourcing으로 이었고요.



그림 상 : 상단이 그대로 시뮬레이션을 행한 것, 하단이 간이 Sheeter을 추가 한 것입니다. 아주 간단한 방법이지만 잘 막이 생성되어 있습니다. 또한이 예제에서는 Reseeding를 OFF. Separation를 ON으로하고 있습니다 Separation를 사용함으로써 입자가 균등하게 배치되어 매끄러운 표면이 만들어집니다.

그림 하 : 파라미터는 정상에서 검색하는 파티클의 최대 수와 범위, 포인트를 추가하는 거리의 임계 ​​값 Max Radius는 FLIP Object의 Particle Separation의 4 배, Max Gap Distance는 1.5 배 정도가되도록 설정되어 있습니다.


---


Topic 06. Collision의 설정



두 가지 방법을 경우에 따라 구분


FLIP에서 충돌을하려면 Source Volume을 사용하는 방법과 Static Object를 사용하는 방법이 일반적입니다. 게다가 Source Volume을 사용하여 Collision 필드를 설정하는 방법도 있지만 이것이라고 파티클과 개체의 충돌이 가미되지 않기 때문에 또는 정밀도가 좋지 않습니다. Collision 같은 분위기가 나와 있으면 OK라고하는 것이면 충분히 사용할 수 있다고 생각 합니다만, 기본적으로 Static Object를 사용하는 것이 쉽게 정밀한 충돌이 될 수 있습니다.

일반적 FLIP Solver는 Particle Separation에서 지정한 값에서 각종 필드의 해상도가 결정되지만 Collision Separation를 ON으로하여 collision 필드의 해상도는 별도로 설정할 수 있습니다. 여기의 값을 충분히 작게 해 준다하여 FLIP의 해상도를 높일 수없이 충돌의 정확도를 높일 수 있습니다.

Source Volume에 충돌 할 때 FLIP Solver의 Particle Collision을 Move Outside Collision로 설정합니다. 기본 Particle은 실제로 존재하는 DOP Object에서만 의미가 없기 때문에 필드 만 충돌하는 경우에는 빠른 Move Outside Collision를 추천합니다.



그림A : 위가 Source Volume에서 collision을 가져온 경우, 아래가 Static Object를 작성한 결과입니다. 대략적인 충돌 판정은 할 수 있지만 엄격한 것을 다루는 것은 어려울 것

그림B : Collision Separation을 설정하면 Particle Separation와 관계없이 collision Field의 해상도를 결정 할 수 있습니다. 고해상도되면 시뮬레이션 시간은 늘어나므로 요주의





--


총괄

microsolver을 사용하여 자신이 만든 싶은 결과를 위해 매우 유연한 접근 방식을 취할 수있게됩니다. 이번에 소개 한 두 일례에 지나지 않지만 microsolver에 그다지 익숙하지 않은 분들이 도전하기에 좋은 소재가 아닌가 생각합니다. 사실 Surface Tension는 다음 버전의 Houdini에서 지원 예정임을 SIGGRAPH 2016 SideFX 부스 표명했습니다. 그래서 타이밍으로이 재료를 채택하는 것은 사실 미묘한 뻔 했습니다만, microsolver에 닿는 소재로 뛰어 때문에 다루기로했습니다.

microsolver 아무것도 FLIP 만의 것이 아닙니다. Pyro Solver 등으로도 사용 가능하며, 극단적 인 이야기 Pyro의 계산에 표면 장력을주는 것도 가능합니다. 자신이 얻고 싶은 결과를위한 방법이 생각 나면, 나머지는 구현하면됩니다. 기타 도구는 그렇게 간단한 이야기는 아닐지 모르지만, Houdini는 그 환경이 준비되어 있습니다. 꼭 요청에 따라 시뮬레이션을 사용자 정의하여보십시오. 만약 너무 해 버려서 결과에서 멀어져 버린 경우에도 Houdini는 바로 이전 상태로 돌아갈 수 있기 때문에 안심하고 시행 착오를 겪어봅시다.

1 2 3 4 5 6 7 8 9 10 다음