FX/Houdini_Joy of VEX

Joy of Vex - Assignment #1

Gamestonk118 2022. 7. 3. 19:55

중요했던 부분:

우선 해설강의 없이 만들려고 하였지만 포인트들 하나씩 각기 개별로 날라다니게 하는 이펙트와 더불어 도저히 addpoint()로 minpos()로 생성된 여러개의 포인트들을 생성하는것이 불가능 하다고 생각하고 또 무엇보다도 primitive없이 minpos()를 통해 포인트를 생성시킬 수 없다는 사실을 몰라 어쩔 수 없이 해설강의를 참조하여 만들어보고 그다음엔 해설 없이 혼자서 직접 만들어보았다. 근데 그러다보니 졸지에 선생님의 방식을 따라한게 된것 같다... 죄송합니다...ㅠ 

첫번째 노드블럭 더미들

우선 sphere 두개로 두 세력들의 기반이 되는 geometry들을 생성해준뒤 add 노드들을 연결하여 포인트들만 남겨둔채 geometry의 메쉬들을 모두 삭제하였다. 그리고 Point Jitter을 통해 포인트들 사이의 간격을 적당한 만큼 벌려주었고 Attribute VOP을 통해 noise를 적용함으로써 파티클들이 동선없이 자유롭게 단독적으로 날아다닐 수 있도록 설정하였다.

이러한 VOP의 노드들을 연결하여 VEX의 역할을 대신할 수 있게 하였다. 이는 anti-aliased noise를 활용하여 @P값이 인풋으로 들어 갈수 있게 하였고 @Time에 flow를 연결하여 움직이는 파티클 세력들을 만들어 보았다. 그리고 noise노드를 복하하여 더욱 역동적인 파형을 구축하려 고 하였다.

그 다음 attribute wrangle을 연결하고

@Cd = 0; // 색상을 0으로 초기화
// 색상값을 chf()으로 조정 가능케함
float redscale = chf ("REDSCALE");
float greenscale = chf ("GREENSCALE");
float bluescale = chf ("BLUESCALE");
// 설정한 값을 @Cd에 저장함
@Cd = set (redscale, greenscale, bluescale);

과 같은 vex를 입력하여 각기 세력들의 색상을 조절하였다. Wrangle안에 chf()를 통해 유동적으로 유저가 색상을 조절 할수 있게 세팅하였다.

그리고 transform노드를 연결하여 두 sphere다 (0, 0, 0)에 고정되어있는 것을 각기 양옆으로 옮겨주어 두 세력들이 일정한 간격을 두고 휘날리는 것을 구현하였다.

*특히 minpos()로 생성하게 될 포인트들은 reference가 되는 geometry에 primitive의 존재를 요구한다. 이미 add노드로 primitive들이 전부 사라진 세력들에게 primitive를 부여하기위해 Copy to Point노드를 사용하여 각각의 포인트가 sphere로 변하게끔하였다. 

두번째 노드블럭 더미들

우선적으로 왼쪽의 세력을 wrangle노드의 0번 input으로 넣어 기준 geometry로 설정하고 오른쪽의 세력을 1번째 input으로 넣어 reference로 활용하였다.

우선적으로 아래와 같이 세팅하여 왼쪽의 세력에서부터 오른쪽 세력을 이루는 가장 가까운 포인트들의 위치값을 v@newPos에 저장하였다.

/* 0번인풋으로 들어간 geometry에서부터 1번 인풋으로 들어간 geometry를 이루는 포인트들중
가장 가까운 포인트들을 찾아 @P값으로 반환시켜 주세요*/
// 그리고 그 @P값들을 vector varaible pos에 저장시켜라
vector pos = minpos (1, @P);
// 저장시킨 variable pos를 v@newPos에 저장시켜 수치들을 geometry spreadsheet에 디스플레이하라
v@newPos = pos;

그리고 For Each Point 노드들을 사용하여 왼쪽세력의 모든 포인트에 대하여 minpos()가 적용된 포인트들을 scene view에 디스플레이 할 수 있도록 세팅하였다.

기본적으로 기존에 했던 것처럼 오직 @newPos 수치들중 단 하나의 vector값 (모든 변화에 기준이 되는 포인트) 만 가져와 나중에 for each end노드에서 설정될때 전부 다 적용될 수 있도록 하였다

// run over가 detail (only once)로 세팅되어 있는 상태에서
vector a = point (1, "newPos", 0); /* 윗 노드 1번 인풋으로 연결된 노드에서로부터 0번포인트의 대한 @newPos
수치를 가져와 vector variable a에 저장하여라.*/
addpoint (0, a); // 방금전 선언한 vector variable a를 포인트로 만들어 주어라

merge노드를 통해 각기 세력의 두 점들을 함께 볼 수있게하고 add 노드를 통해 그 점들을 선으로 연결 시켜주었다.

그리고 wrangle노드를 다시 추가하여 점들을 연결한 선이 일정 거리 사이에서만 나타날 수 있도록 조건문을 추가해주었다.

// 위에서 만들어진 두 점들의 위치 수치정보를 point()로 이 노드에 가져옴
vector a = point (0, "P", 0);
vector b = point (0, "P", 1);
// 두 vector값들 사이의 거리 길이를 float variable d에 저장
float d = distance (a, b);
// 윗 변수의 값을 볼 수 있게 f@d에 다시 또 저장
f@d = d;

// 조건문
// if 만약 a와 b (두 포인트들)의 사이의 거리가 chf()으로 설정한 값보다 높다면
if (d > chf ("LIMIT")) {
// 두 포인트들을 지워라
    removepoint (0, 0);
    removepoint (0, 1);
}

이렇게 하여 파티클들이 휘날릴때 세력간의 점들의 거리가 LIMIT값안에만 들어올 경우 선으로써 나타날 수 있게 하였다.

그다음 선에 chramp()을 적용시키기위해 resample노드를 사용하여 선들을 여러 단위의 포인트들로 쪼게주었고 그 포인트들이 할당하는 attribute를 새롭게 만들어 a 부터 b까지 0에서 1까지의 수치를 가지도록 만들어 주었다.

// float값으로 다시 type casting을 해준 @ptnum에 @numpt를 나누어 0에서 1까지의 결과를 가지게 설정하였다
// 그 결과들은 float variable pointRange에 저장하였다
float pointRange = float (@ptnum)/(@numpt - 1);
// 방금전 선언된 float variable pointRange를 attribute으로 저장하였다
f@pointRange = pointRange;

그리고 본격적으로 라인에 색상을 더해주는데 양 끝의 색상을 약간 다르게 하게 위해 chramp()을 설정하여 직접적으로 포인트들의 위치에 대한 색상을 조절 할 수 있게끔 하였다.

float ramp = @pointRange; // 위에서 선언된 f@pointRange를 float variable ramp에 저장
// float color을 chramp()으로 설정하여 유저가 직접 색상의 농도를 위치에 따라 결정하도록 만듬
float color = chramp ("COLOR", ramp); // ramp: 0에서 1까지의 range
@Cd = 0; // @Cd값을 0으로 초기화
// 컬러값을 유저가 직접 파라미터로 조절할 수 있게 chf()으로 만들어줌
float redscale = chf ("REDSCALE");
float greenscale = chf ("GREENSCALE");
float bluescale = chf ("BLUESCALE");
// 설정된 값들을 @Cd값에다 저장하여 색깔로 보이게함
@Cd = set (redscale, greenscale, bluescale);
/* @Cd에 방금 선언된 chramp()가 적용된 float variable color을 집어넣어 유저가 생성한 ramp의 모양이 
@Cd 컬러값으로 나타나게함*/
@Cd *= color;

그 다음 for each end노드로 닫아주니 기준이 되는 포인트가 모든 왼쪽 세력의 모든 포인트들에 적용되기 시작하여 왼쪽과 오른쪽의 점들과 사이의 라인들이 모두 scene view에 나타나기 시작하였다.

 

세번째 노드블럭 더미들

그리고 그 라인들에게 모두 noise 파형을 적용시켜 찌글찌글 거리는 모양의 라인들을 생성시키기 위해 아까 파티클 때와 같이 Attribute VOP을 사용하였다. 

아까 파티클때와 같이 anti-aliased noise를 적용하여 랜덤한 모양의 파형을 가지도록 설정하였다. 자세한 설정들은 dimension, frequeny, offset, 그리고 amplitude과 같은 세부적인 파라미터들을 Tweak하여 더욱이 전기 스파크와 가까운 모양의 쉐입을 형성하도록 하였다.

문제는 이렇게 Noise를 라인들에게 적용하고 나니 라인들을 구성하는 점들의 위치값이 모두 랜덤으로 설정이 되어 파티클들과 연결되지 않았다. 이러한 문제를 해결 하기위해 위에 VOP node위에 chramp()을 포함하는 wrangle node를 달아주어 라인의 처음과 끝의 포인트들은 noise가 적용되지 않게끔 세팅하였다. 

// @pointRange (0과 1사이의 range)값을 chramp()으로 설정해주어 직접 파형을 조절 가능케함
/* chramp()을 접목시키고 noise()을 적용하면 chramp()으로 설정된 파형의 세로 y-값이 noise()로 설정된 
파형의 가로 x-값으로 변환되어 일반적인 noise()로 적용할때와 다른 양상의 쉐입을 띈 파형을 생성하게됨*/
f@newPointRange = chramp ("RAMP", @pointRange);

위의 ramp모양과 같이 처음과 끝점은 0으로 설정되어 noise()가 이 점들에는 적용이 안되게끔 설정하였다.

그리고 이렇게 생성된 라인과 두 세력들을 담당하는 첫번째 노드 더미들을 merge노드에 전부다 묶어주어 두 파티클 세력과 라인들이 전부 나타나게끔 세팅하였다. 

*그리고 직접 CONTROL 노드에서 각각의 세팅된 중요 파라미터들을 조절할 수 있도록 null노드에 모든 파라미터들을 복사시켜 손쉽게 조절 가능하게끔 세팅하였다.

쉽게 파리미터들을 조절 가능하게끔 만든 파라미터들. Null노드에 복사하여 여기서 조절 가능하게 했다.

Result:

파티클 세력 (본 숙제) 결과물

방금 위의 방식을 다른 방식으로 geometry의 위치와 쉐입을 조절하여 Plasma Globe의 모양도 만들어 보았다.

Plasma Globe
두 개의 이펙트들을 동시에 보았을때

이해가 안되었던 부분:

정확히는 해설강의를 보기전 이해가 안되었던 부분:

- geometry를 add나 scatter노드로 점으로 변환시키면 두 세력간의 minpos()가 적용되지 않는다. 당시 이유를 몰라 nearpoint()도 써보고 다른 시도들도 해보았지만 도저히 minpos로 생성되는 점들을 정확한 위치에 만들 수 없어 애먹었다.

Solution: Copy To Point노드와 같이 primitive를 reference가 되는 geometry안에 무조건 생성해주어야 minpos()가 적용되는 포인트가 정확하게 생성된다.

- Attribute Wrangle을 사용하여 minpos()로 생성된 점들의 위치 수치들을 정확히 wrangle로 scene view에서 포인트로 나타내주려하였지만 도저히 모든 포인트에 대해 점들을 addpoint()로 만드는 건 불가능 하다고 생각하였고 이 점도 어렵게 만드는 원인중 하나였다.

Solution: For Each Point와 같은 노드를 사용하여 기준이 되는 포인트들을 만들어 놓고 For Each End노드로 확인해 봤을때 모든 포인트에 대해 minpos()로 생성되는 포인트들의 위치값을 scene view에서 포인트로써 생성할 수 있게 할 수 있다.

- If 조건문을 사용하여 어떠한 거리값을 임계점으로 라인이 나타날지 안나타날지 조절할 수 있다는것은 예상을 하였지만 라인을 안나타낼때 어떤 식을 써야 라인이 사라질지 도저히 몰랐었다.

Solution: removepoint()와 같은 Function을 사용하여 라인에 두개의 포인트들밖에 없을때 양쪽 끝의 점들을 없에 줌으로써 라인을 없앨 수 있다. removepoint()는 인풋에 (0이라 쓰는데 뭘 의미하는지 확실치 않음, 지울 포인트 넘버)으로 생성하면된다.

- 어떠한 방법으로 scatter로 만들어둔 세력의 파티클들을 하나하나씩 지들끼리 (한꺼번에가 아닌) 자율적으로 떠돌아다닐지 생각이 나지 않았다.

Solution: Attibute VOP을 사용하여 noise()를 적용시켜주면 점들간의 위치가 파형적으로 랜덤적으로 지정되어 점들이 개별적으로 움직이는 세력을 만들어 줄 수 있다.

- @ptnum/@numpt를 하니 1로써 딱 range가 끝나지 않는다. 어떻게 해야할까?

Solution: @numpt에 -1를 해준값을 division식에 적용시키면 1로 끝나는 range의 값을 만들 수 있게 된다.

- Attribute VOP에 노드를 결합하는 방식이 많이 햇갈린다. Attribute VOP을 성공적으로 공부를 해야할 것 같다. 

- Plasma Globe를 만들 때 바깥의 sphere를 투명으로 만들어야 안에 이펙트가 보일텐데 도저히 geometry network view상에서 투명으로 만드는 방법을 찾지 못했다. Template Flag를 켜봤지만 이것으로 만족하지 못하였다.

 

공부하면서 들었던 생각:

ㅋㅋㅋ... 솔직히 앞서 말한 것처럼 막혔던 부분이 너무 많기도 하였고 구글링을 해보더라도 어떻게 검색을 해야 나올지 감이 안나와 해설강의를 참조해야 했었다...ㅠ 최대한 도움을 받지 않고 해결하려고 했었지만 유혹을 뿌리치지 못하고 강의를 보고나서야 이해가 된 나를 약간 원망하기도 하였다. 그래도 강의를 보고난다음 한번더 따라할때는 강의 1절없이 직접 손수 제작하려고 했고 이는 성공적으로 결과가 나오는 계기가 되었다. 최대한 내가 포기했던 이유들을 적고 솔루션들을 따라적어 내가 잘 모르는 부분이 어디쯤인지 한눈에 알수 있게끔 공부일지에 작성하였다. 드디어 100퍼센트 내 머리에서 나온건 아니지만 처음으로 내 손으로 무언가 후디니 프로젝트를 만든것 같아 뿌듯하다. 후디니는 공부하면 공부할수록 정말 수치 그리고 수치 그리고 수치를 위한 것이라고 생각이 든다. 나는 이 점이 이상하게도 맘에 드는것 같다. 내가 만들어둔 미리 만들어둔 알고리즘을 통해 파라미터들을 원하는 값으로 조절만 시키면 어떻게든 수정이 가능하다는 것이 정말 신기 한것 같다. 어쨋든 벌써 2주가 지나고 3주째를 바라보니 아직도 넘어야 할 산이 많지만 조금만 더 더 버티면 언젠간 Joy of Vex를 전부 끝낼것이라는 생각에 설레기도 한다. 앞으로도 계속 열심히 꾸준히 해야 할 것 같다.