복습한 내용과 다시봤더니 이해되는 부분:
Day 9-1: normalize(), dot(), and cross()
Day 9-1에는 각기 다른 Function. normalize()와 class() 그리고 dot()에 대해 기본적인 원리를 배웠다. normalize()는 방향은 같지만 크기가 1인 vector값으로 vector값을 전환해주는 Function으로써 하나의 vector 수치가 들어가고 vector값을 반환해준다. class()는 두 vector가 공유하고 있는 평면에 수직이 되는 방향으로 vector값을 돌려받는다. class()는 기본적으로 두 vector값을 받아 하나의 vector값을 되돌려준다. dot()은 두 vector가 있을때 그 사이의 각도를 나타내 준다. 이때 식은 dot(A, B) = length (A)*length (B)*cos(θ)으로써 나타나지고 두 vector값을 받아 float값으로 cos()이 적용된 각도값을 나타내준다. 이는 수학에서의 내적 식과 완전히 동일한데 이 function의 특징을 이용하여 geometry가 특정 광원 주위에 있을때 어떠한 부분이 밝아지고 어두워질지 색깔 값으로 지정해주는 역할을 한다. 간단히 설명하자면 geometry에서부터 광원으로 향한 vector값과 geometry의 normal의 vector값 사이의 각도가 커질 수록 더욱 dot()에서의 결과는 낮아져 어두워지는 결과를 낳게되고 그와반대로 각도가 좁아질수록 dot()의서의 결과가 커져 색이 밝아지는 결과를 낳게 된다. 이때 dot()의 정확한 각도 (degree)의 결과를 알려면 normalize()을 활용하여 각각의 Vector input A와 B의 크기값을 1로써 바꿔주어야 한다.
- TWA선생님께서 설명을 너무 잘해주셔서 이번엔 어려웠던 부분이 많이 없던 것 같다. 수학을 좋아한편은 아니라 생각했는데 그래도 오랜만에 다시 배워보니까 재미가 있었던것 같다. 문제는 이 방식을 이용해서 어떻게 응용하고 코드가 많아질 때 이것들을 하나하나 어떻게 꾸려 나가가고 해석을 해야할 지 많은 연습이 필요하다는 것을 느꼈다. 이 부분에 대해선 본강의를 봐야 할 것 같다.
1. 코드가 많아지고 하나하나 꾸리는 것은 반복과 연습이 필요한건 사실이다. 다음 강의에서부터 디테일하게 라이팅과 function들의 관계에 대해 깊게 파고들어 그리 계속 햇갈리는 점들이 지속되지는 않았지만 확실하고 확실한 상기를 위해 주기적으로 개념과 응용해 대해 생각해보는 것이 중요한 것 같다.
Day 9-2: dot and cross product, fake lighting combing normals to a surface, vector maths primer
Day 9-2에는 본격적으로 Joy of Vex 커리큘럼으로 들어가 지난 강의때 배운 내용을 좀 더 심화적으로 응용해보는 시간을 가졌다. 지난번에 언급해보았던 것처럼 geometry가 광원 옆에 있을때 geometry의 normal값과 광원으로 향하는 vector값 사이의 각도가 커질수록 dot()의 파형에서 cosine wave에 따라 180도까지로 보았을때 y값이 내려가기 때문에 밝기가 전체적으로 어두워진다. 반대로 각도가 작을수록 cosine wave의 y값은 1과 가까워저 색이 밝아지는 효과를 낸다. 만약 dot()을 적용한 값에 상수를 더해준다면 밝기가 전체적으로 모두 밝아지게 조절 할 수 있고 반대로 곱해준다면 파형의 높이값이 커져 더욱 밝은 색과 어두운 색을 심하게 대조시킬 수 있다. 광원의 위치에 따라 geometry에서 나타나는 색깔의 위치가 바뀌며 이는 만약 광원이 2개 이상일때 geometry상에서 그 수의 맞는 광원의 빛들을 반사 시킬 수 있는 것 처럼 보이게 할 수 있다. 또한 광원을 향한 방향vector값을 Geometry의 모든 포인트로부터 광원까지로 (목적점 - 시작점) 구해준다면 Geometry의 모든 포인트가 마치 빛을 반사시키는 것처럼 보이게 할 수 있다. cross()는 geometry의 normal값들을 정해주며 geometry를 구성하는 vector값과 Vector값의 수직 방향을 가리켜 normal값들을 새롭게 조정 할 수 있게 한다. 이는 오른손 법칙을 통해 손쉽게 어느 방향으로 향할지 예측 할 수 있다. 그리고 normal값에 여러가지 상수를 더해보아 normal의 방향을 조절 시킬 수 있고 곱해보아 normal의 스케일을 조절 시킬 수 있다.
- 위에 첫번째와 두번째 exercise에서 cross()를 @N과 noise를 사용하여 새로운 Normal을 생성할때 어떤 방식으로 normal이 그런 방향으로 생성되었는지 이해가 잘 되지 않았다. noise()의 방향은 많이 랜덤하게 지정되어있는데 어떠한 과정을 통해 한쪽 방향으로 Normal이 쏠리는지에대해 정확한 이유는 내 머리로는 한계에 왔던것 같다. noise(@P)를 하면 정확히 어떠한 방향으로 vector가 지정되는지 그런 흐름이 있는지에대해 복습할때 다시 한 번 살펴봐야 겠다고 느꼈다. 그 문제만 파악하면 만능의 오른손 법칙을 이용하여 어떠한 방향으로 cross()결과 vector값이 나타날지 유추할 수 있기 때문이다.
vector noise1 = noise (@P);
vector temp = cross (@N, noise1);
@N = temp;
1. noise()를 활용하면 보통 모든 값들이 양수의 값을 가진 Vector으로 나타나게 되어 기본적으로 top view에서 보았을때 the 4th quadrant 쪽으로 수치가 향하는 것을 알 수 있다. 이를 유추하자면 @P 포인트 위치가 noise()으로 적용되어 갖게된 모든 포인트들의 vector값들이 모두 양수의 수치를 가져 원점으로부터 오른쪽 아래를 향하는 방향으로 구성이 되었을때 오른손 법칙을 사용하여 cross()의 첫번째 인풋인 @N값은 검지로써 grid상에서 모두 위를 향하게 될 것 이고 이는 검지로 표현하고 , noise()가 포함된 noise1변수는 아까도 말했듯이 오른쪽 아래쪽으로 수치가 향하게 되어 이는 중지로 표현했을때 normal값이 오른쪽 윗방향을 가리키는게 가능하다는 결론이 나온다. 하지만 Noise()의 특성상 전체적으로 일정하지만 세부적으로 불규칙한 파형을 가져 grid의 normal값이 일반적으로 한 방향을 가리키고 있지만 사소하게 불규칙한 방향을 띄는것을 관찰 할 수 있다.
Day 10: relpointbbox
Day 10에는 우선적으로 코드를 예쁘게 쓰는 방법과 relpointbbox()에 대해 중심적으로 알아 보았다. 우선 코드를 예쁘게 쓰는 방법중에 모든 효과들을 따로 따로 float variable에 적용함으로써 각각에 geometry에 적용되는 각기 다른 효과들을 직관적으로 뭐가 뭔지 알 수 있게 하는 방법이 있다. 이는 총 네 단계로 이루어져 있으며 이로인해 순차적으로 effect들을 geometry에 더해가면서 점진적으로 쉐입이 바껴지는 단계들을 한 눈에 알아 볼 수 있다.
1. 변수 생성 (float variable fx도 선언)
2. 효과 생성 (effect의 특징을 만들어 어디에 어떻게 저장할 지 지정)
3. 효과를 택 (변수 fx에 effects를 추가)
4. 원본에 저장 (결과로 보는 것)
또한 relpointbbox()은 지금까지 chramp()같은 function을 geometry에 적용하여 쓸 때 특정 사이즈가 1보다 클 경우 chramp()에서 만들어진 Ramp의 모양이 attribute로써 반복되는 형상을 관찰 할 수 있었다. 지금까지 입체적인 geometry가 아닌 라인같은 포인트들의 수치들을 0에서 1까지의 range로 바꾸어주기 위해 @ptnum/@numpt와 같은 방식을 이용해주었지만 3상에서의 부분에서는 불가능 하다는 한계가 있었다. relpointbbox()은 이를 방지하기 위해 Geometry에서 가장 큰 x/y/z값을 각각 1미만의 값으로 설정하고 제일 작은 값을 0이상의 값으로 설정하여 모든 포인트들의 새로운 @P 포인트 위치값을 얻어낼 수 있다. Relpointbbox()에는 윗 geometry의 노드가 몇번 wrangle 노드의 인풋 넘버에 들어갔는가와 어떠한 attribute를 0에서 1까지의 range값으로 반환해 줄 지 인풋으로 지정해주어야 하며 이는 나중에 chramp()같은 Function을 적용하였을때 ramp의 모양이 반복되지 않고 Geometry상에서 전체적으로 ramp의 모양을 담아주는 그런 효과를 줄 수 있다. 이러한 특성을 이용해 Relpointbbox()가 적용된 Geometry의 특정 부위만을 ramp값으로 조절해줌으로써 fx효과를 다른 부위의 비해 덜 아니면 더 줄건지 ramp graph와 함께 손쉽게 작업하게 할 수 있다.
- 의외로 길었던 강의와는 대조되게 엄청나게 어려웠던 부분은 이번강의에서는 없었던 것 같다. 오히려 지난번 chramp()을 배웠을때 찜찜했던 궁금증을 해소시켜주었던 것 같다. relpointbbox()의 첫 인상은 매우 어려울 것 같았지만 bounding box를 통해 시각적으로 보니 이해가 바로 되었던 것 같다. 그리고 또한 코드를 예쁘게 쓰는 방법을 알고 나니 effect마다 햇갈리지 않고 구분지어 특정 Geometry를 구현할 수 있겠다는 생각이 들었다.
- Exercise 1에 나왔던 taper effect가 정확이 무엇을 의미하는 건지 확실치 않은 것 같다.
1. 그랬다. 매우 어려울 것 같았다. 그치만 알고나니 생각보다 쉽고 정말 쓸모있겠다는 생각이 들었다. 또 코드를 예쁘게 쓰는 방법은 좀더 후디니 스럽게 FX방식 스럽게 코드를 전반적으로 작성하는 방식을 알고 나니 정말 유용하겠다는 생각이 들었다.
2. 아직도 확실치는 않지만 내가 Day 10에 Exercise를 풀 때 인터넷에서 찾아보았던 내용이 정답일 것 같다.
Day 11: if statements
Day 11에는 if statement 조건문을 활용하여 후디니에게 판단의 기회를 내려주는 방식에 대해 공부 하였다. if (A) { B; }와 같이 만약 A라면 B를 수행해 주어라 라는 방식처럼 작동한다. if statement에서 같다라는 의미로는 등호를 두번써 넣어주어야 하며 하나밖에 없다면 성립이 되지 않아 제대로 수행되지 않는다. if statement에는 부등호와 등호를 전부 다 쓸 수 있으며 이를 응용해 총 여섯번의 경우로 만들어 줄 수 있다.
== -> equal
!= -> not equal
> -> greater than
< -> less than
>= -> greater than or equal to
<= -> less than or equal to
또한 if statement를 한문장에 두번 쓰고 싶을때 두 개의 조건을 모두 달성해야만 아랫 공식을 적용시킬 수 있게 하려는 AND의 의미로써 사용하고 싶다면 "&&"을 조건 사이에 써넣어야 하며 반면 두 개의 조건중 하나만 달성해도 아랫 공식을 적용시킬 수 있게 하려는 OR의 의미로써 사용하고 싶다면 "||"을 조건 사이에 써 넣어야 한다.
- 처음에 쉬웠다가 Joy of Vex 11일차 마지막의 rubbertoy를 사용한 예제에서 if statement안에 들어가는 식이 복잡해지면서 뇌정지가 오기 시작하였던것 같다. dot()을 이용해 내적각도를 구하든가든지 특정 포인트들에만 effect를 준다는지의 식은 쉬웠지만 그런 식들이 전부 짬뽕이 되기 시작하면서 왜 rubbertoy의 색깔이 시간이 지나며 저리 변하였는지 확실히 이해가 되지 않았다. if statement안에 식이 여러개 섞였을때 어떠한 포인트들이 정확히 효과를 행하기 시작할 것인지 예상하는 실력을 더욱 키워야 할 것 같다.
- Exercise 1에서 동일한식에 @Time만 바꾼체 @Frame에서 2*24를 하여 48프레임으로 맞추어 실행해보면 eg) @Frame >= 2*24 이렇게 적용하면 @Time때와는 다르게 (@Time은 49프레임부터 시작함) 48프레임때부터 웨이브가 작동되는것을 알 수 있었다. 식은 같고 내가 알기론 @Time에서 1이 24프레임으로 알고있는데 그렇다면 방금전 처럼 @Frame만 동일하게 바꿔준다면 똑같은 프레임부터 작동되어야 하는거 아닌가라는 의구심이 들었다. 1프레임 차이지만 무척 궁금하였다. 설명이 어려워 동영상을 첨부해야겠다.
/*원점으로부터 @P 모든 포인트까지의 거리길이를 두 배로 곱해주고 각 @ptnum 포인트 넘버에서 5를 나눈값의 나머지를
더하여 float variable a에 저장하여라*/
float a = length (@P)*2 + @ptnum%5;
/* 광원에서 수직이 되는 vector값과 Normal값을 가진 Vector값의 내적 각도를 구하여 @Time을 곱해 움직이는 결과를
생성하고 Float variable b에 저장하여라*/
float b = dot (@N, {0, 1, 0})*@Time;
if (a > b) { // 만약 a값의 수치가 b값의 수치보다 크다면
@Cd = {1, 0, 0}; // Geometry의 그 부분은 빨간색으로 칠하여라
}
1. 모든 포인트에 대하여 원점으로 부터 포인트 사이의 거리값과 dot()을 이용하여 rubbertoy의 바로 위에 위치하는 광원까지의 vector값과 normal값의 각도를 비교하였을때 만약 dot()을 이용한 float variable b값은 @Time이 곱해졌으므로 프레임이 올라갈 수록 계속 수치가 변할 것이다. 그렇다면 광원과의 vector값과 rubbertoy의 normal값의 내적각도를 구하였을때 90도를 기준으로 90도 보다 작은 값은 cosine 파형에서의 y값이 양수로 지정되어 @Time이 곱해졌을때 값이 계속 증가될 것이고 반면 90보다 높은 값은 cosine 파형에서 y값이 음수로 지정되어 값이 계속 감소 할 것이다. 즉 값이 계속 증가하는 float variable b의 수치를 가진 포인트는 float variable a의 수치를 임계점으로 넘어가면 색깔이 희게 변하고 그렇지 않은 감소하는 float variable b의 수치를 가진 포인트는 float variable a의 수치의 임계점을 넘지 못해 빨간 색을 유지하게 된다. 그러므로 광원 (0, 1, 0)에서 geometry의 방향과 Geometry의 normal의 방향들이 서로 직접 마주할 수록 수치가 늘어나 더욱 a의 임계점을 넘게되어 조건문안에 있는 조건을 수행하지 못하고 희게 변하게 되는 것을 알 수있다. 그래서 마치 빨겠던 Rubbertoy의 등 부분이 시간이 지날 수록 하얗게 뒤덮히는것을 볼 수 있다.
if (@Time >= 2) { // @Time이 2보다 크다면
fx += fxA*chf ("HEIGHT"); // effect가 생성되게끔 하여라
}
if (@Frame >= 24*2) { // @Time이 2보다 크다면
fx += fxA*chf ("HEIGHT"); // effect가 생성되게끔 하여라
}
// 이 두 식 모두 웨이브가 48프레임부터 effect가 작동되어야 하는 것 아닌가?
// 왜 @Time >= 2로 하면 48프레임이 아닌 49프레임부터 effect가 작동되어지는 것이 궁금하였다
2. @Frame에서 임계점을 2*24이렇게 설정하면 말 그대로 48 프레임부터 이 식을 수행하여라 이러한 식이 되어 위 식으로 vex를 작성하였을때 정확히 48프레임부터 effect가 나타나게끔 한다. 반대로 @Time은 24프레임까지 완전한 1초라 생각하여 2에서부턴 25 프레임으로부터 48 프레임까지 기준으로 여긴다. 그렇게 되어 2보다 크다고 if statement를 써 넣었을때 @Time기준으로는 3초가 되어 48프레임이 아닌 49 프레임부터 effect가 geometry에 생성되게끔 세팅해주는 것이다. 즉 @Frame은 후디니 인터페이스 아래 있는 프레임 바 그 수치 자체를 기반으로 움직이며 @Time은 24fps로써 1초가 1부터 24프레임을 모두 가지는 것으로 계산이 되어 2초부터 25프레임부터 48프레임 그리고 3초부터 49 프레임부터 72 프레임까지의 간격을 가지고 있는 것을 알 수 있다.
다시봐도 모르겠는부분:
- 다행히 이번 윅의 복습을 통해 생각보다 아직도 이해가 안되는 부분은 찾을 수 없었던 것 같다. Week 3까지 공부하면서 점차 계속 똑같은 것을 저절로 반복해서 익히게 되어 기초는 튼튼해지는 동시에 새로운 것을 응용하다 보니 기초적인 면들은 이제 확실하게 자리를 잡아가는 것을 느낄 수 있었다. 모든 Exercise를 한번 전부 풀어보고 알아보는 시간을 가져보아 이제 내가 직접 응용하고 effect들과 Function들을 적용해 보는 시간을 가져야 겠다. 그리고 그때 안풀리는 문제들은 또 다음에 배우는 커리큘럼들의 과정들과 함께 다시 연구해 보아 새로운 솔루션들을 찾을 수 있는지 고찰 해야 겠다는 생각이 들었다. 이제 벌써 3주차가 지났다. Joy of Vex 커리큘럼 시점으로는 벌써 딱 반이 지난거다. 이제부터 중후반까지의 과정만 남았다. 더욱 독하게 마음먹어야 겠다는 생각이 든다. 솔직히 고백하자면 주말에 나태해지고 딴 생각을 계속 하게 됬던 것 같다. 후디니에 미치도록 초심을 가졌었는데 중반까지밖에 안와서 이런 안일하고 쓸데없는 생각을 가지니 내 자신이 정말 부끄러웠던 것 같다. 또한 아직까지 후디니로써 무언갈 증명할 작업물이 없기 때문이거와 그러한 걱정들 때문에 괜히 남들과 비교하면서 그시간을 보냈던 것 같다. 그치만 Joy of Vex를 마치고 나면 만들수 있는 응용력이 향상된다는 말이 정말 매력적으로 다가오는 것같다. 내 개인적인 희망은 후디니를 배움에 있어 마치 지수함수처럼 달성해 보고싶다. 초반에는 고통스럽지만 그 고통들을 버티고 나면 새로운 세상을 얻는것 처럼 내 전반적인 모든 VFX 여정도 그렇게 진행됬으면 좋겠다고 느낀다. 밤 중에 쓰다보니 괜히 이런 글이 길어진것 같다...ㅋㅋ 어쨌든 항상 느끼는데 무엇을 하든 초심을 잃지 않는 것이 정말 중요하게 생각되는 이번주의 주말이었다. 이런 나를 바로잡고자 오늘의 복습일기를 완성하였고 다시한번 기강을 잡아 내일부터 다시 진행해나가야 겠다는 생각이 든다. 아직 끝나지는 않았지만 최선을 다해 스터디 그룹을 관리하시는 TWA님과 스앵님께 진심으로 항상 감사드리고 싶다.
- 그리고 조금은 오글거리지만 오늘만큼은 뭔가 마음가짐을 하기 위해 내가 제일 좋아하는 이 문장으로써 오늘의 복습일기를 마무리 하고 싶다.
THE ONLY EASY DAY WAS YESTERDAY.
'FX > Houdini_Joy of VEX' 카테고리의 다른 글
Joy of Vex - Day 12-2: overlapping effect (0) | 2022.07.13 |
---|---|
Joy of Vex - Day 12-1: ripple effect (0) | 2022.07.13 |
Joy of Vex - Day 11: if statements (0) | 2022.07.08 |
Joy of Vex - Day 10: relpointbbox (1) | 2022.07.07 |
Joy of Vex - Day 9-2: dot and cross product, fake lighting combing normals to a surface, vector maths primer (0) | 2022.07.06 |