중요했던 부분:
- 지난 시간에 배웠던 코드 복습:
eg)
float d = length (@P); // 모든 포인트에 따라 거리를 측정하여 d로 지정함
d = d*ch ("SCALE"); // d의 값의 scale을 만들어줌
d = d + (@Time*ch ("TIME_SCALE")); // 앞으로 d는 시간에 따라 계속 증가하게끔 설정함
@P.y = sin (d); // 높이값으로 sine wave의 쉐입을 적용함
- Scene view 오른쪽 위에 정육면체 모양의 아이콘
Wireframe/Wire Shaded/Smooth Shaded등의 Scene View 세팅을 담당.
- Built-In Attribute: @N
면이 붙어있을 때 point 혹은 primitive가 향하는 방향을 수치로 나타낸 Attribute.
eg) @P = @P + @N; // 면이 가지고 있는 방향으로 포인트의 위치가 팽창하거난 축소하는 것을 의미한다
eg) @P = @P + @N*ch ("PUSH"); // Normal 값에 스케일을 조정하여 geometry의 팽창 혹은 축소의 정도를 조정한다. 각각의 포인트가 가지고 있던 Normal값이 Point의 위치 정보에 더해지면 면이 가리키는 방향으로 포인트가 이동함.
eg) @P = @P + @N*sin (d*ch ("WAVELENGTH"))*ch ("WAVEHEIGHT"); // 모든 포인트가 Normal의 방향으로 팽창 혹은 축소한다. Normal에 sin() 을 곱해줌으로써 웨이브를 형성게끔 설정한다. 또한 sin()안에 들어있는 d (포인트와 원점사이의 거리)에 ch()을 곱해주면서 파장의 길이를 설정한다. 또한 sin() 바깥에 또 다른 ch()을 곱해줌으로써 웨이브의 높이 (높낮이 폭)를 설정해 준다.
eg) @Cd = sin (d*ch ("WAVELENGTH"))*ch ("WAVEHEIGHT"); // Sine wave를 기반으로 한 geometry의 파장 길이와 파형 높이를 조절한 값을 @Cd (Colour Attribute)에 지정한다.
- Attribute Delete (Vertex Attribute -> UV)
Geometry에 uv값을 지워줌. 이 노드는 특정 attribute를 지워주는 역할로써 작동됨.
- Linear Equations
eg) float d = length (@P); // 모든 포인트에 대하여 포인트의 위치까지의 거리
@P.y = d; // Variable d에 따라 @P.y (포인트 높이값)을 지정. d = length(@P)는 원점으로부터 끝쪽으로 갈수록 커지므로 grid geometry같은 경우는 깔대기 같은 모양을 형성.
eg) @P.y = @P.x; // 마치 수학식의 y = x 같은 그래프처럼 대각선을 형성
f@d = length (@P); // 원점으로부터 모든 포인트들의 위치 사이의 거리를 Float Attribute d 에 지정하여라. 음수의 거리 길이는 불가능하므로 모든 음수 위치에 있는 포인트들 까지의 거리길이는 절댓값으로 표시됨.
eg) @P.y = @P.x*2; // 포인트 사이에 있는 라인의 경사가 더욱 가파라짐. y = 2x과의 법칙과 동일함
eg) @P.y = @P.x * (-1); // 라인이 반대로 뒤집혀짐. y = -x의 식과 동일함
- fit(): Fit Function & Clamp(): Clamp Function
clamp()는 clamp (input, min, max);로 구성되어 있으며 min과 max의 수치 조절을 통해 range에 포함되지 않는 웨이브들을 납작하게 눌러버린다.
eg) @P.y = clamp (d, 0, 3); // clamp() 을 이용하여 범위안에 들지 않은 구간을 눌러버린다 (평면으로 만들어 버린다): in this case the range is between 0 and 3.
eg) float input = d*(-1); // variable d값에 음수로 변환시킨 값을 new float variable input에 집어넣음
@P.y = input; // geometry의 높이값이 위에서 declare된 input값으로 지정되면서 뒤집혀진 결과를 나오게함
@P.y = clamp (input, 0, 3); // 최솟값이 0 이므로 P.y 기준으로 0 아래로 수치를 기록하던 모든 포인드들은 clamp()에 이해 제한되므로 평평한 grid를 형성시킴. (본래는 뒤집혀진 깔때기 모양을 만들었어야 했음)
fit()은 fit (input, input_min, input_max, output_min, output_max);로 구성되어 있으며 function안에 들어가는 앞에 세개의 값들은 clamp()와 완전히 동일 하며 output_min과 output_max를 통해 웨이브의 모양은 그대로지만 높이값 (range)을 조절할 수 있다. (확대와 축소 기능).
eg) @P.y = fit (input, 1, 4, 1, 3); // 1하고 3범위에 있는 그래프로 clamp하고 output_min과 output_max의 범위안에 들어 맞게끔 stretch 할지 shrink를 할지 결정함. 이 경우에는 1과 4범위 안으로 clamp하고 1과 3안에 전체 geometry가 포함될 수 있게 끔 전반적으로 쪼그라들어야함.
Exercises:
1. Try and incorporate clamp into the above setup, see if you can make it do something interesting.
VEX I have written to create a certain shape I wanted to make
float d = length (@P); // 모든 포인트에 따라 거리를 측정하여 d로 지정함
float input = d; // 위에서 선언한 d 값을 새로운 variable input에 지정
// 보다 원활한 fit function활용을 위해 안에 들어갈 모든 값들을 variables 들로 세팅해주면서 ch()을 동시에 줌
float inmin = chf ("input_min");
float inmax = chf ("input_max");
float outmin = chf ("output_min");
float outmax = chf ("output_max");
@P.y = fit (input, inmin, inmax, outmin, outmax); // fit function을 활용하여 세팅된 값들을 geometry의 모든 포인트의 높이값으로 지정.


2. Set P based on waves generated from sin(d), but see what happens if you fit and clamp d before sin, after sine, or both before AND after sine.
VEX I have written
// 전반적인 코딩 셋업은 윗 exercise에서 가져왔다. 그렇지만 문제에 나와있듯이 clamp() or fit()를 기준으로하여 sin()을 어디다 배치하는지 큰영향을 미치는지 실험하였다.
float d = length (@P);
float input = d;
float inmin = chf ("input_min");
float inmax = chf ("input_max");
float outmin = chf ("output_min");
float outmax = chf ("output_max");
@P.y += sin (d); // fit() 이전 sin()
d = fit ((d + @Time), inmin, inmax, outmin, outmax); // fit()을 변수 d에다 설정하여 나중에 sin()이 그것을 받아들일 수 있게끔 세팅하였다.
@Cd = 0;
@Cd.r = sin (d);
@Cd.g = cos (d);
@Cd.b = sin (d)*cos (d);
@P.y += sin (d); // fit() 이후 sin()
- fit() 이전에 sin()을 배치하면 geometry의 @P.y는 아래쪽으로 튀어나온 것을 알수 있었다. 아마 내가 끄적이던 fit()의 parameter들이 @P.y 모션 이전에 적용되지 않아서 보인다.
- 반대로 fit() 이후에 sin()을 배치하면 geometry의 @P.y는 위쪽으로 튀어나온 것을 알수 있었다. 이건 또 fit()의 parameter들이 모션 @P.y 이후에 적용되어서 나타나는 결과로 보인다.
- 문제에 나와있듯이 두개 다 배치하면 geometry의 @P.y가 위 아래 둘다 튀어나와 역동적인 모션을 취하는 것을 볼 수 있었다. 두 sin() 모션들의 특징이 더해져서 만들어진 결과 같다.
솔직히 이 문제는 원인을 밝히는 것까진 너무 어려웠다. 위에 추측들이 맞는지는 확실치 않다. 문제에서 나와있듯이 이 세 개의 각기 다른 실험들이 재각기의 현상을 내놓는건 알 수 있었다.
3. waves that start from 2 points and mix with each other (remember the earlier lesson about code style, and += *= vs =, and how you can accumulate results over several lines)
나는 두개의 원점 포인트들을 만들어 꿀렁이는 웨이브가 결국에 한 지점에서 만나게 되는 모션을 구현하였다.
VEX I have written
vector center = chv ("CENTER"); // 첫번째 센터 원점
vector secondCenter = chv ("SECOND_CENTER"); // 두번째 센터 원점
float d = distance (center, @P); // 모든 포인트에 따라 유저가 지정한 첫번째 센터와 포인트 위치사이의 거리를 float d 에다 저장함
float e = distance (secondCenter, @P); // 모든 포인트에 따라 유저가 지정한 두번째 센터와 포인트 위치사이의 거리를 float e 에다 저장함
// 각각의 변수들을 ch()으로 스케일로 조정가능케함
d = d * chf ("SCALE"); // d *= chf ("SCALE"); 가능 하지만 나는 이 식을 원하지 않음
e = e * chf ("SCALE"); // 이것또한 e *=chf ("SCALE"); 가능 그치만 비추
// 위의 세팅들을 참조함
float inMin = chf ("Input_Min");
float inMax = chf ("Input_Max");
float outMin = chf ("Output_Min");
float outMax = chf ("Output_Max");
// fit안에 모든 데이터값들을 집어넣어 유저들이 직접적으로 geometry의 쉐입을 조정할 수 있게 만듦. sin과 cos를 둘다 사용하여 변칙성을 더욱이 유도함
d = fit(sin((d+@Time)), inMin, inMax, outMin, outMax);
e = fit(cos((e+@Time)), inMin, inMax, outMin, outMax);
// 변수 d와 e를 더한값이 geometry의 높이값으로 결과물을 추출할수 있게끔 @P.y와 @Cd에다 지정함.
@Cd = 0; // @Cd 기본값을 0으로 초기화
@Cd. r = d + e; // 웨이브 치는 부분들이 빨간색으로 나타날수 있게끔 식을 줌
@P.y = d + e; // 마찬가지로 웨이브 치는 부분이 높낮이로 보여질 수 있게끔 식을 적용함
4. try and build some of these examples with vops, see what feels faster.
ㅋㅋ... 지금 vex만 배우는데도 머리가 터질 지경이다.... vop은 나중에 마스터해서 둘중에 뭐가 효율적인지는 미래에 비교하기로 하겠다...
이해가 안되었던 부분:
- fit function이 대강 이해는 되어가지만 더욱 geometry가 복잡해지고 grid가 아닌 보다 입체적인 오브젝트를 다룰때 많이 햇갈릴 것 같다는 예감이 든다. 특히 fit function을 물리적인 웨이브나 쉐입의 높낮이나 한눈으로 관찰 할 수 있는 @P같은 Attribute들로 지정할때는 딱 한눈에 보여 어떤 느낌인지 이해가 가는것이 쉽지만 @Cd같이 물리적으로 한눈에 파악할 수 없는 Attribute에 fit function을 적용할때는 많이 햇갈리는 부분이 있다. 예를 들어 @Cd = fit (input, inmin, inmax, outmin, outmax); 같은 부분은 생각만해도 머리가 터질것 같다는 느낌을 받을 것 같다.
- 코드가 복잡해지면서 점점 햇갈려지는 비중이 커지는것 같다.
공부하면서 들었던 생각:
3일찬데도 벌써 어려움을 느끼기 시작한 것 같다..ㅋㅋ 대강 개념들은 이해가 가지만 정작 내가 강의 없이 코드를 쓰려고하면 생각보다 시간이 오래걸리는것 같다. 그래도 막상 뭔갈 만들고 나면 뿌듯한것도 있다. 직접 내가 계속 코드를 쓰면서 배워가는 과정이 정말 중요하다고 생각되고 완전히 한줄 한줄 코딩 문장들을 내껏으로 만드는것에 중점으로 두어야 되겠다고 생각이 든다. 막상 처음에는 어렵지만 꾸준히 반복하면 뭐든지 쉽다고 한다던데 평상시 머릿속에서도 vex를 담아두는 습관을 기르면 더욱 빠르게 익힐 수 있을거란 생각이든다.
그리고 토미는 3대 500을 넘게 칠 것같다.