# Welcome to NoSleepCreative

<figure><img src="/files/ABh4DxYzMUonTTKqmSaO" alt=""><figcaption></figcaption></figure>

## About NoSleepCreative

Hello! I'm [**Desmond Du**](https://www.duitbetter.com), a Motion Designer/Creative Technologist based in New York City.&#x20;

Welcome to NoSleepCreative Wiki. I established this platform in late 2019 as a complement to my [NoSleepCreative YouTube Channel](https://www.youtube.com/c/NoSleepCreative). Here, my focus is on curating knowledge related to Motion Design, with a particular emphasis on JSX expression coding and creative technology. I occasionally update this wiki when I get some free time or actively use the site for new expression snippets.

## Origins

This wiki project started in 2015. After experimenting with platforms like WordPress, Notion, Google Docs, and Mediawiki for about four years, I finally found what I was looking for in 2019 with GitBook, which offered the ideal interface and design for curating knowledge while honing my artistic skills. I was very much inspired by Matt and his [cgwiki](http://www.tokeru.com/cgwiki/index.php?title=Main_Page) database explains the importance and structure of the wiki:

> Rather than keep it in a paper notebook I've stored it online in a wiki, which you're looking at now., it's a little disorganised and messy, you'll find things scribbled in the margins, sketches of ideas, shopping lists etc. It's not a manual, it's not official software documentation, quality varies depending on my stress levels at the time of writing. Hopefully most of it is interesting and/or useful.

## Changelog

* **2024.02.21:** Added new page Formulas to Cinema 4D Section
* **2023.10.04:** Created Cinema 4D>Cookbook, added Python terms table to Cheat Sheet
* **2023.10.01:** Added profile photo, while loop to JSX Cheatsheet
* **2023.09.16:** Added GIFs for snippet and rewrote expressions for clarity, added change log, clean up Welcome page
* **2020.10.12:** Some of my content here are disappearing as I am migrating them into my private Notion database for easier curation. Not to worry, everything related to Motion Design will remain here.

## Support

This website is a non-profit, and made based on my willingness to share knowledge and help anyone I can. If you find this helpful, please consider donating to keep the website running and buy some coffees and ~~beer~~ to keep this community of sharing going. Thank you very much.

* [PayPal](https://www.paypal.com/donate/?cmd=_donations\&business=8ED65L9C5DK3C\&currency_code=USD\&source=url)
* Buy my ["Advanced After Effects: Coding for Motion Design" Domestika Course](https://www.domestika.org/en/courses/3818-advanced-after-effects-coding-for-motion-design)


# Getting Started with Expressions

Last update: 19 January 2024

## Introduction

Welcome to my comprehensive guide on JavaScript and After Effects Expressions! This page is designed to be your one-stop resource for learning, enhancing, and mastering the art of JavaScript, particularly in the context of Adobe After Effects.&#x20;

## Reference Library

### **Javascript**

* [Javascript, w3schools](https://www.w3schools.com/js/js_object_definition.asp)
* [Javascript ES6, The Coding Train](https://thecodingtrain.com/Tutorials/16-javascript-es6/)
* [ECMAScript 6 updates, lukehoban](https://github.com/lukehoban/es6features)

### Expressions

* **Documentation**
  * [Adobe User Guide - Expression Basics](https://helpx.adobe.com/after-effects/user-guide.html/after-effects/using/expression-basics.ug.html)
  * [Expression guide](https://readthedocs.org/projects/after-effects-expressions-guide/downloads/pdf/latest/) (PDF)
  * [Aenhancers — Expressions](http://expressions.aenhancers.com/)
* **Tutorials**
  * [Animoplex](https://www.youtube.com/channel/UCbfz_keteqaKbpiRiS95Dqg)
  * [Motionscript ](http://www.motionscript.com/)by Dan Ebbert
    * [Mastering expressions](http://www.motionscript.com/mastering-expressions/table-of-contents.html)
* **Francois Lefebvre**
  * [After Effects Incredible Expressions Challenge](https://www.youtube.com/playlist?list=PLZAr8tT8TcsRj62nIO7ILCMitj5RKjsMf)
  * [The Power of Expression Book](https://aescripts.com/the-power-of-expression/)
* **Resources**
  * [**JR Canesto AE Tricks Google Sheets**](https://docs.google.com/spreadsheets/d/1a3ArTUHAJwVi-ObZofvz6IfrKbSGSENlaTIRTs8pAJU/edit#gid=0)

### **Industry tools**

* [Templater](https://dataclay.com/templater/)
* [CompsFromSpreadsheet](https://aescripts.com/compsfromspreadsheet/)

### Source cited

* [UI (Window, dialog, palette etc) reference info for AI scripting](https://forums.adobe.com/thread/1238745)
* <https://zacklovatt.com/tutorials>

## NoSleepCreative Expression Starter Pack

* [JSX Cheatsheet](/after-effects/expressions/jsx-cheatsheet)
* [Basic Expression Workshop](https://youtu.be/aZ5F1eCm428), NoSleepCreative&#x20;
* [Expression snippet library](/after-effects/expressions)
* &#x20;["Advanced After Effects: Coding for Motion Design" Domestika Course](https://www.domestika.org/en/courses/3818-advanced-after-effects-coding-for-motion-design)

## FAQs

<figure><img src="/files/GVedE323wL8A2pNbLhr9" alt=""><figcaption></figcaption></figure>

### How do I get started with coding and expressions?

The key to mastering coding expressions lies in consistent practice within your projects. A fondness for math can be a significant advantage, as coding often resonates with those who enjoy mathematical concepts and organized thinking.&#x20;

To kickstart your journey, here's a structured learning path I recommend:

1. **Start with my** [**Expression workshop video**](https://youtu.be/aZ5F1eCm428)**: T**his will give you a quick introduction to the basics of expressions.
2. **Dive into** [**Animoplex tutorials**](https://www.youtube.com/c/Animoplex/playlists)**:** Progress to learning how to implement expressions into your animations in various ways.
3. **Practice Writing Your Functions:** Challenge yourself by writing your own functions/code solutions, applying the concepts you've learned.
4. **Refine Your Code**: Aim to write cleaner, more efficient code. Practice using advanced array methods like map, reduce, and filter, and familiarize yourself with arrow functions for more concise code.

### Do I need to know Javascript before I get into expressions?

Not necessarily,  while a foundation in JSX helps, you can **easily learn that as you are learning expressions.** I often refer to [w3schools](https://www.w3schools.com/js/) to look the the functions documentation. There are a lot of them but you only need a handful eg. variables, arrays, string, operators, loops, conditional, function, math, or random. If you can understand these concepts, writing expressions can be a breeze.&#x20;

### Do I need to be good at expressions to be a better Motion Designer?

Absolutely NO. You do not have to be good, you just need to know the important ones (eg. Ignore Scale inheritance from Parent). Most of my [master-studies tutorials ](https://www.youtube.com/playlist?list=PL1TQbviAEvf3C_W2K-PE8mpOys2n9BDch)(with the exception of Ordinary Folk's ones) uses basic expression to do make things look "complex". Here are some examples:

* [**Flatwhite Motion wOo video**](https://www.youtube.com/watch?v=cLr1YDdqVxg\&t=16s)**:** uses single expression of valueAtTime
* [**Flatwhite Motion Aicy Flying Orb**](https://www.youtube.com/watch?v=HswPRuVbeSM\&t=80s)**:** uses a detailed wiggle function&#x20;
* [***Creativity***](https://vimeo.com/424805218) by Jose Pena 32-36s: uses "Ignore scale rom parent"

**Your main goal when learning expressions is not mastery but**[ **fluency and comprehension**](https://www.optilingo.com/blog/general/the-difference-between-proficiency-and-fluency/)***.*** Just like learning a foreign language, the goal is not spew out fanciful words but rather to understand and communicate with one another. In our context, we want to be able to read expression code or algorithms, understand their functions, and modify them. You may not necessarily write intricate functions yourselves, but you can at least know how to source expressions online and utilize them for your projects, or communicate to a more code-savvy artist what you are trying to develop.

### Are there any paid training courses you recommend?

I do recommend my "[Advanced After Effects: Coding for Motion Design](https://www.domestika.org/en/courses/3818-advanced-after-effects-coding-for-motion-design/thedesmonddu)" course on Domestika. It offers specialized training in coding within After Effects, tailored for those keen on mastering advanced motion design techniques.

An alternative course to consider is the School of Motion's Expression course, although I haven't personally taken it. Notably, my improvement in expressions largely came from a scripting course from FXPHD.

### Best way to learn expressions

#### Play

Personally, I really enjoyed Mathematics, it was my strongest and favorite subject in school. I love solving riddle and discovering patterns and that is how I see expressions: They are just are fun riddles. Usually I would get an idea about an expression to animate or design something, and **I would spend lots of time and effort figuring it out even if I was not going to use for any current projects.** Sometimes, I am unable to sleep because i'm thinking of coding ideas. Hence, fun is an element when it comes to learning!

<div align="left"><img src="/files/-M_qPpqu2rp8vFbzqleT" alt=""></div>

#### Make your expression library

There are just way too many expressions to write or remember, that is why I have this wiki site to house everything. I recommend anyone who want to get good at expression to start their own wiki page and curate your own code snippets you found or wrote yourself. You can use Gitbook like me or Google Sheets like JR Canesto/Ordinary Folk.

<figure><img src="/files/dHtP2zmwg3l39LPTchfU" alt=""><figcaption></figcaption></figure>

#### **Just do it**

When I first started, I would type out expressions from tutorial and avoid copying and pasting. Even if I do not understand what I am typing, I am building the coding ability into my subconscious.&#x20;

<div align="left"><figure><img src="/files/ktXVJHXVB2iZBy0jmhaS" alt=""><figcaption></figcaption></figure></div>

## Tips

### Complex expressions ≠ amazing animation

I sensed that people think that writing long lines of complex expression code will yield amazing animation and design. In truth, that is not the case. The adage "Less is More" still applies when it comes to programming and coding. What we should aim for instead when writing expressions  (or anything actually) is **Profound Simplicity (James Clear) or Informed Simplicity (architect Matthew Frederick) .**&#x20;

**Basically, Everything should be made as simple as possible, but no simpler (Albert Einstein).** &#x20;

### **Focus on problem solving, not improving at writing expressions**

{% embed url="<https://youtu.be/QMbx0dTWJIQ?list=PLpdAX8PTk5ao41zZpFEs1DOl_JQCPqLJf>" %}


# Expressions & Snippets

Here are list of useful expressions I curated and written. This page is currently being sorted into the pages under Cookbook & JSX Cheatsheet

## Transformation

<figure><img src="/files/l7RzET46Yp2s3k9wNiZQ" alt=""><figcaption></figcaption></figure>

### **Constant Value Drift and Motion**

#### 1. Linear Value Drift Over Time

```javascript
value + time * 50;
```

#### 2. Apply Value Drift to Array Element eg. Position Y

```javascript
value + [0, time * 5];
```

**3. Constant Horizontal Motion From Layer's Start Point**

<pre class="language-javascript"><code class="lang-javascript"><strong>offset = (time - inPoint) * -10;
</strong><strong>x = position[0] + offset;
</strong>y = position[1];
[x, y]
</code></pre>

### Align to X-axis or Y-axis

### X-Axis

<figure><img src="/files/YHOVxGCv6zk2bZ06bkLu" alt=""><figcaption><p>This expression references the X position of the layer above in the Composition panel and adds a fixed increment, resulting in a row of evenly spaced child layers.</p></figcaption></figure>

```javascript
var xOffset = 350;
var prevLayerX = thisComp.layer(index - 1).transform.position[0];
[xOffset + prevLayerX, value[1]];

```

### Y-Axis&#x20;

```javascript
var yOffset = 350;
var prevLayerY = thisComp.layer(index - 1).transform.position[1];
[value[0], yOffset + prevLayerY];

```

### Changing anchor point

```javascript
var s = sourceRectAtTime();

// Top left ↖
[s.left, s.top] // 

// Top center ↑
[s.left, s.top] + [s.width / 2, 0];

// Top right ↗
[s.left, s.top] + [s.width, 0];

// Center left ← 
[s.left, s.top] + [0, s.height / 2];

// Center
[s.left, s.top] + [s.width, s.height] / 2;

// Center right → 
[s.left, s.top] + [s.width, s.height / 2]

// Bottom left ↙

[s.left, s.top] + [0, s.height]

// Bottom center ↓ 
[s.left, s.top] + [s.width / 2, s.height]

//Bottom right ↘
[s.left, s.top] + [s.width, s.height]
```

### Random positioning XYZ

![A series of duplicated layers with random position values](/files/-LvuSO0lKmXxPkXip0IV)

```javascript
// Seed for randomization
var seed = 20;

// Define the minimum values for randomization
var minX = 25;
var minY = 25;
var minZ = -1900; 

// Define the maximum values for randomization
var maxX = thisComp.width;
var maxY = thisComp.height;
var maxZ = 50;

// Set the random seed
seedRandom(seed, true);

// Generate random values within the defined ranges
var randomX = random(minX, maxX);
var randomY = random(minY, maxY);
var randomZ = random(minZ, maxZ);

// Create an array with the random values
[randomX, randomY, randomZ];

```

Alternatively, you can use array variables for a preferred and shorter expression.

```javascript
// Seed for randomization
var seed = 20;

// Define the minimum and maximum values for randomization
var minValues = [25, 25, -1900]; 
var maxValues = [thisComp.width, thisComp.height, 50];

// Set the random seed
seedRandom(seed, true);

// Create an array with the random values
random(minValues,maxValues)

```

## Scale

### Maintain Scale When Parented&#x20;

{% tabs %}
{% tab title="Both" %}

```javascript
var scaleFactor = [];
var parentScale = parent.transform.scale.value;

for (var i = 0; i < parentScale.length; i++) {
    scaleFactor[i] = (value[i] * 100) / parentScale[i];
}

scaleFactor;
```

{% endtab %}

{% tab title="uniform" %}

```javascript
arr = value;
ps = parent.transform.scale.value;
ratio = 100/ ps[0];

arr*ratio;
```

{% endtab %}
{% endtabs %}

**Implementation**

* [Scaling Radial Grid Expression · After Effects Tutorial · Master study: José Peña's "Creativity"](https://youtu.be/8BeI1qXzysU?t=122)

## Rotation

### [Aim constraint](https://creativecow.net/forums/thread/aim-constraint/) by Kevin Camp / Dan Ebberts

{% tabs %}
{% tab title="no parent" %}

```javascript
target = thisComp.layer("Null 1"); // set this to the layer to aim at
p = position - target.position;
radiansToDegrees( Math.atan2( p[1], p[0] ) )- 90
```

{% endtab %}

{% tab title="w/ parent" %}

```javascript
target = thisComp.layer("controls"); // set this to the layer to aim at
p = thisLayer.toWorld(anchorPoint) - target.position;
radiansToDegrees(Math.atan2(p[1], p[0])) - 90
```

{% endtab %}

{% tab title="3D layers" %}

```
target = thisComp.layer("Null 1");// set this to the layer to aim at
lookAt( position, target.position )
```

{% endtab %}
{% endtabs %}

### [Retrieving auto-orientation rotation value](https://forums.creativecow.net/docs/forums/post.php?forumid=227\&postid=15409\&univpostid=15409\&pview=t)

```javascript
L = thisComp.layer("Null 1");
v = L.toWorldVec([1,0]);
radiansToDegrees(Math.atan2(v[1],v[0]))
```

### Auto-orient along path by [Videolancer](https://videolancer.net/expressions/)

```javascript
try{
cornerEase = 3;
p = transform.position;
t = Math.min(Math.max(time,p.key(1).time+.001),p.key(p.numKeys).time);
pre = position.valueAtTime(t-thisComp.frameDuration*cornerEase);
post = position.valueAtTime(t+thisComp.frameDuration*cornerEase);
delta = post-pre;
orient = radiansToDegrees(Math.atan2(delta[0],-delta[1]));
value+orient+180
}catch(err){value}
```

### Ignore Parent Rotation

```javascript
value – parent.transform.rotation
```

## Opacity ✅

### Flickering / Strobe

![](/files/-Lvzv6zr3sH_kO9D4HI-)

```javascript
// VARIABLES
    minSeg = 1.5; //minimum interval (must be > 0) 
    maxSeg = 2.5; //maximum interval (must be > minSeg) 
    
    // flickering duration
    minFlicker = .5; //must be less than minSeg 
    maxFlicker = 1; // must be less than minSeg 
    flickerDur = random(minFlicker,maxFlicker);
    
    //initial conditions
    segEndTime = 0; 
    i = 1; 

// Continuous loop: create a fixed random segment value and add to segEndTime
while (time >= segEndTime){ 
    i += 1; 
    seedRandom(i,true); 
    segEndTime = segEndTime + random(minSeg,maxSeg); 
} 

// Switch back to use the current time as input to the random seed.
seedRandom(1,false); 

// As time > threshold, flicker
if (time > segEndTime - flickerDur){random(0,100) }else{ 100 }

// Source: http://www.motionscript.com/expressions-lab-ae65/swinging-light.html
// Also see: http://www.motionscript.com/mastering-expressions/random-3.html
```

### Random opacity wiggle&#x20;

![](/files/-LxgTeeafXFWIXSvUAVz)

```javascript
// control = thisComp.layer("control"); // connect to null layer with sliders
freq = 1;
amp = 100;
octave = 1;
amp_mult = 3;

wiggle(freq, amp, octave, amp_mult, time)
```

### Random opacity wiggle with flicker&#x20;

![](/files/-LxgTee_fD3Lkg-RBd8A)

```javascript
// control = thisComp.layer("control"); // connect to null layer with sliders
freq = 1;
amp = 100;
octave = 1;
amp_mult = 3;

opacity = wiggle(freq, amp, octave, amp_mult, time)


// VARIABLES
minSeg = control.effect("minSeg")("Slider"); //minimum interval (must be > 0) 
maxSeg = control.effect("maxSeg")("Slider");; //maximum interval (must be > minSeg) 

// flickering duration
minFlicker = control.effect("minFlicker")("Slider");; //must be less than minSeg 
maxFlicker = control.effect("maxFlicker")("Slider");; // must be less than minSeg 
flickerDur = random(minFlicker, maxFlicker);

//initial conditions 
segStartTime = 0;
segEndTime = 0;
i = 1;

// Continuous loop: create a fixed random segment value and add to segEndTime
while (time >= segEndTime) {
    i += 1;
    seedRandom(i, true);
    segStartTime = segEndTime;
    segEndTime = segEndTime + random(minSeg, maxSeg);
}

// Switch back to use the current time as input to the random seed.
seedRandom(1, false);

// As time moves threshold, flicker
if (time > segEndTime - flickerDur) {
    random(0, 100)
} else {
    opacity
}
```

### Random opacity with sin function

![](/files/-LvzqIqZjkIfnahiz4Xp)

```javascript
// Mass flickering
vel = 50;
seedRandom(0,true);
Math.sin(time*vel+random(index))*100;
```

![](/files/-LvzqOfKOBy4vOe8vqGz)

```javascript
// 'Wave flickering'
vel = 50;
seedRandom(0,true);
Math.sin(time*vel+index)*100;

// Combining 
bool = 1;
vel = 50;
seedRandom(0,true);
wave=Math.sin(time*vel+index)*100;
rand =Math.sin(time*vel+random(index))*100;
bool==0 ? wave : rand;
```

### Random opacity turn on

![](/files/-LvuSGW8ej9Hcu5gPtMv)

```javascript
seed = 29;
threshold = linear(time,0,thisComp.duration,0,100); // or Connect to slider to animate switch on & off

seedRandom(seed,true);
randValue = random(0,90);

if(randValue < threshold){
    100;} else 0
```

### Random opacity fade on&#x20;

![](/files/-LvuSL9ktGztg6U8qnuQ)

{% tabs %}
{% tab title="v1" %}

```javascript
seed = 29;
seedRandom(seed,true);
delay = random(0,1);
t = framesToTime(20) // or usethisComp.duration

linear(time, 0+delay,t+delay,0,100)
```

{% endtab %}

{% tab title="v2" %}

```javascript
//VARIABLES
fadeDuration = 1;
maxDelay = .5

//SETUP
seedRandom(index,true);
delay = random(maxDelay);
t = time -(inPoint + delay);

// EXECUTION
linear(t,0,fadeDuration,0,100);
```

{% endtab %}
{% endtabs %}

### Distance-based opacity fade by Animoplex

```javascript
// Distance Based Opacity Fade
// Original: https://helpx.adobe.com/after-effects/using/expression-examples.html
// Full Tutorial: https://www.youtube.com/watch?v=I-Acdl_l9G0&t=14s

startFade = 500;
endFade = 3000;
try {
    C = thisComp.activeCamera.toWorld([0,0,0]);
} catch(err) {
    w = thisComp.width * thisComp.pixelAspect;
    z = (w / 2)/Math.tan(degreesToRadians(19.799));
    C = [0,0,-z];
}
P = toWorld(anchorPoint);
d = length(C, P);
linear(d, startFade, endFade, 100, 0)
```

### Transparent backside of 3D layer

<figure><img src="/files/fhVeoZaN2ajTZwXgwW7h" alt=""><figcaption></figcaption></figure>

```javascript
if (toCompVec([0, 0, 1])[2] > 0 ) value; else 0;
```

## Colour

### [Hexcode from text to color](https://forums.creativecow.net/docs/forums/post.php?forumid=227\&postid=36789\&univpostid=36789\&pview=t)

```javascript
txt = thisComp.layer("Text").text.sourceText;
c = parseInt(txt,16);
r = c >> 16;
g = (c & 0x00ff00) >> 8;
b = c & 0xff;
[r,g,b,255]/255
```

### Random fill

```javascript
// Apply on Color Controls
seed = 20;
seedRandom(seed,true); // change true to 0 for constant change
random([0,0,0,1],[1,1,1,1])
```

## Camera

### [Smoothing rotation of auto-orient along path](https://creativecow.net/forums/thread/smoothing-rotation-of-auto-orient-along-path/)

{% tabs %}
{% tab title="x-rot" %}

```javascript
f = 2; // number of frames before and after to average
v = [0,0];
for (i = -f; i <= f; i++){
v += position.velocityAtTime(i*thisComp.frameDuration + time);
}
v /= (f*2+1);
a = Math.atan2(v[1],v[0]);
radiansToDegrees(a)

// turn off auto-orient
```

{% endtab %}

{% tab title="y-rot" %}

```javascript
//y-rotation for 3d layers

f = 2; // number of frames before and after to average
v = [0, 0, 0];
for (i = -f; i <= f; i++) {
    v += position.velocityAtTime(i * thisComp.frameDuration + time);
}
v /= (f * 2 + 1);
a = Math.atan2(v[0], v[2]);
radiansToDegrees(a)
```

{% endtab %}
{% endtabs %}

## Motion

### Wiggle

![](/files/-LxgwCQvpQ2zgLp0L3b-)

```javascript
// frequency by amplitude = how fast by how much
wiggle(20,30);

[value[0], wiggle(20,30)[1]] // wiggle y-axis only 


// Smooth wiggle — freq,amp,octave,amp_mult
wiggle(20,30,1,2,time)


// Jumpy Wiggle 1 (moves at a random FPS) Makes wiggle skip and hold rather than move fluidly.

v=wiggle(5,50);
if(v < 50)v=0;
if(v > 50)v=100;
v;

// Jumpy Wiggle 2 (moves at a defined FPS)
fps=5; //frequency
amount=50;  //amplitude
wiggle(fps,amount,octaves = 1, amp_mult = 0.5,(Math.round(time*fps))/fps);
```

* [Looping wiggle](https://www.motionscript.com/design-guide/looping-wiggle.html)

### Inertial Bounce / Overshoot

```javascript
// Inertial Bounce (moves settle into place after bouncing around a little)
// // Source: https://forums.creativecow.net/docs/forums/post.php?forumid=227&postid=19145&univpostid=19145&pview=t
amp = .05;
freq = 4.0;
decay = 2.0; // springyness
n = 0;
if (numKeys > 0){
n = nearestKey(time).index;
if (key(n).time > time){
n--;
}
}
if (n == 0){
t = 0;
}else{
t = time - key(n).time;
}

if (n > 0){
v = velocityAtTime(key(n).time - thisComp.frameDuration/10);

value + v*amp*Math.sin(freq*t*2*Math.PI)/Math.exp(decay*t);
}else{
value;
}
```

### Constant move in either x or y axis / Random walker

```javascript
WIP---
choice = Math.floor(random(0,2));
seedRandom(0,false);
stepx = random(0,50);
stepy = random(0,20);
if(choice ==0){
	value + [stepx,0];} else if( choice ==1){
	value +[0,stepy];}
```

## Carousel

### 2D

### 3D&#x20;

![](/files/-LvfBiUXsAJ1IE2haa_y)

```javascript
/*  There needs to be two layers named 'startCard' & 'endCard'
    This allows rotation value to dynamically change when layers are inserted or removed.
    All duplicates need to be placed within these two layers
*/

//anchor point
radius = 500
value+[0,0,radius]

// Y rotation

startIndex=thisComp.layer("startCard").index; 
endIndex = thisComp.layer("endCard").index;
numpt = startIndex-endIndex+1; // total number of layers
myIndex = index-startIndex;
angle = 360/numpt

myIndex*angle+
```

#### Linking layers' rotation with opacity

#### Using distance & vector position

![](/files/-LvfB_ueezf9KXCBgUob)

```javascript
// Make sure there is a camera 

//Opacity
startVal = 0;
endVal = 100;
fadeAngle = 180;

v = toCompVec([0,0,1]); // layer position to comp position in Z
d = length(toWorld(anchorPoint),thisComp.layer("Camera 1").toWorld([0,0,0]));
c = v[2]/d;
ease(c,Math.cos(degreesToRadians(fadeAngle)),1.0,startVal,endVal)

```

#### Using rotation

{% code title="" %}

```javascript
angle = transform.yRotation%360;
minAngle = 0;
maxAngle = 360;
mid = (maxAngle+minAngle)/2;
if (angle < mid)
  linear(angle,minAngle,mid,100,0)
else
  linear(angle,mid,maxAngle,0,100)
```

{% endcode %}

## Responsive Systems / Setups

### Dynamic-sizing text box / lower-third (depreciated, [see new code](broken://pages/-M2US1FizeipgA17SSOy#2-liner-with-conditional-sizing-left-aligned-text))

```javascript
// Create two text layers named "DATA1" & "DATA2"
// Variables
pad = 50;
xPad = 15;
yPad = 15;

seed = 1 // allow you to change between two text layers

// Making it work
if(seed==1){	
    src = thisComp.layer("DATA1")
    }else {		
        src = thisComp.layer("DATA2")		
        }; 

box = src.sourceRectAtTime(time-src.inPoint); 
[box.width + pad + xPad, box.height+pad +yPad];
```

### Slider with center fade on

![](/files/-Lvk7fplz1EScrLfOht_)

```javascript
v = transform.position[0] // x 
d = length(v,thisComp.width/2);
maxDist= 960;

ease(d,0,maxDist,100,0)
```

## Time Remapping / Playback ✅

![](/files/-LvkAgiEDExUK4lfIkT6)

### Random frame playback

```javascript
// Source Dan Ebbert

fr = 12; // frame rate;

numFrames = 8;

seedRandom(index,true);

seg = Math.floor(time*fr);

f = Math.floor(random(numFrames));

for (i = 0; i < seg; i++)

  f = (f + Math.floor(random(1,numFrames)))%numFrames;

framesToTime(f);
```

### Random delayed/advanced layer playback

```javascript
seedRandom(index,true);
myDelay = random(1,10);
time + myDelay;
```

### Play one frame at a time (without 'float time')

```javascript
fps = 1;
x = framesToTime(Math.round(time*fps))
//There probably is a better way but I cannot figured it out right now.
```

### Random still frame (Good for spriting)

```javascript
//Apply this to a composition with a image sequence inside
seedRandom(0,true);
t= random(0,72);
framesToTime(t);
```

### Playback at every nth frames&#x20;

```javascript
n = 3 // frames
time*n
```

### Hold and play every nth frames \[[source](https://www.reddit.com/r/AfterEffects/comments/59h2v0/is_there_a_way_to_render_every_nth_frame_in_after/?utm_medium=android_app\&utm_source=share)]

```javascript
n = 3;  // play every __ frames
m = 3; // hold each frame ___ times 

f= timeToFrames(timeRemap);

p=Math.floor(f/m);

framesToTime(p*n);
```

## Triggering animations with marker

#### Workflow

1. Create a preComp with all the different types of animation
2. In the main Comp, put an expression on the time remapping of that preComp&#x20;
3. Add markers to trigger animations
4. Learn more
   * [Animoplex tutorial](https://www.youtube.com/watch?v=B_3XS2-VWOM\&t=698s)

```javascript
//https://gist.github.com/animoplex/cecf1c64aec4f2733ecd0edbebf4786d
```

## Staggering animations&#x20;

![](/files/-Lvuf4jS4Nc5XQANBNQg)

```javascript
// Copying animation of a layer, and start it at inPoint of layer
thisComp.layer(index+1).transform.position.valueAtTime(time-inPoint)

// Using delay
offset = 1;
thisComp.layer(index+1).transform.position.valueAtTime(time-offset)    
```

### Radial scale up staggering ✅

![](/files/-Lvud2TcyFlQGLkBX6FC)

{% tabs %}
{% tab title="nsc" %}

```javascript
// VARIABLES + SETUP
target = thisComp.layer("master").transform.scale; 
maxDist = 1000;
maxDelay = 1;

dst = length(transform.position,[thisComp.width/2,thisComp.height/2]);
delay = linear(dst,0,maxDist,0,maxDelay);

// EXECUTION
target.valueAtTime(time-delay)
```

{% endtab %}

{% tab title="OF" %}

```javascript
//apply to scale
target = thisComp.layer("fade");
fade = target.effect("scale")(1);
delay = target.effect("delay")(1)*thisComp.frameDuration;
dist = length(thisLayer.toWorld(thisLayer.anchorPoint), target.toWorld(target.anchorPoint));
seed = seedRandom(15, true)
randomRange = target.effect("random")("Slider");
rand = (random(-randomRange, randomRange))*thisComp.frameDuration;
offset = delay/dist;
s = fade.valueAtTime(time - offset - rand);
[s,s]
```

{% endtab %}
{% endtabs %}

### Effector opacity fade on ✅

![](/files/-LwnI2-VTH1AOJCZ-3JC)

{% tabs %}
{% tab title="nsc" %}

```javascript
//Create a null named "EFFECTOR" 
//Add 2 Slider Control Effects renamed to "maxDist" and "delay"


// EXECUTE
target = thisComp.layer("EFFECTOR").transform
maxDist = thisComp.layer("EFFECTOR").effect("maxDist")("Slider");
maxDelay = thisComp.layer("EFFECTOR").effect("delay")("Slider");

dst = length(transform.position, target.position);
delay = linear(dst, 0, maxDist, 0, maxDelay);

// EXECUTION
target.opacity.valueAtTime(time - delay)
```

{% endtab %}

{% tab title="OF" %}

```javascript


```

{% endtab %}
{% endtabs %}


# JSX Cheatsheet

<figure><img src="/files/v1WsgiEJbVl4jWGJUHLs" alt=""><figcaption></figcaption></figure>

If you're just starting to learn JSX and expressions for After Effects, it can be overwhelming to remember all the syntax and concepts involved. That's why I've created this JSX cheatsheet as a quick reference guide to help you when you get stuck.

## Declaration

In programming, a *declaration* is a statement that tells the computer what a particular variable or function is going to be named and what type of value it will hold or return. To declare a variable in JavaScript, use the `var` keyword followed by the variable name. You can declare multiple variables in one line by separating them with a comma.&#x20;

```javascript
var myVariable;
var x,y,c
```

## Initialization

*Initialization* is the process of giving a variable its first value when it is created. When you declare a variable, the computer sets aside a specific amount of memory to store its value. Initialization is the act of assigning a value to that memory location. To initialize a variable, assign a value to it using the = operator. You can initialize an array with multiple values using square brackets \[] and separating the values with commas.

```javascript
var myVariable = 5;
var myArray = [a,b,c,d,h,i,j,k];
```

## String

Strings are used to represent text in JavaScript.

```javascript
"string is text"
```

## For-Loops

For-loops are used to iterate over a block of code multiple times.

```javascript
for (var i = 0; i < value; i++) {
  // statement
}
```

## While Loops

While-loops are used to iterate over a block of code as long as a particular condition remains true.

```javascript
while (i < 20) {
  // statement
  i++
}
```

## If/Else Statements&#x20;

If/else statements are used to execute different blocks of code depending on whether a condition is true or false.

```javascript
if (x==20) {
  statement
} else {
  statement
}
```

### Shorthand If Statement

The shorthand if statement is used when you want to return a value based on a condition.

```javascript
if (x == 1) 10;
```

### Ternary

Ternary operations are a shorthand way to write if/else statements and return a value based on a condition.

```javascript
x = (y >= 5) ? 20 : 50;
```

## Function

A function is a block of code in programming that performs a specific task or set of tasks. It's like a reusable mini-program within a larger program. Imagine them as a pre-compositions in After Effects.

Functions are designed to take some input (known as **arguments** or parameters), process that input, and then **return** an output or perform an action.

Similar to variables, functions must be declared. In the below example, a function `double` that accepts an **argument** called `x` and **returns** the double of x :

```javascript
function double(x) {
  return 2 * x;
}
```

## Object

Objects in JavaScript are used to store collections of key/value pairs.

```javascript
var x = { firstName "John", lastName "Doe" };
```

## Single Line Comment

Single line comments are used to add comments to your code that will not be executed.

```java
// This is a single line comment
```

## Multi-Line Comment

Multi-line comments are used to add comments to your code that span multiple lines.

```javascript
/* This is a 
multi-line comment 
that spans multiple lines */
```

## Regular Expressions (Regex)

Regular expressions are patterns used to match character combinations in strings.

```javascript
"\n" // Line break
```

## Additional Readings

**JavaScript**

* <https://gitbook.gitbook.io/learn-javascript/>
* <https://learnjavascript.online/app.html?id=1437>

**Regex**

* <https://regexone.com>


# Expression Troubleshooting

## Introduction

This guide covers common After Effects expression errors and quick fixes. Follow these steps to troubleshoot, and find out how to ask for help if needed.

## Most Common Issue

{% hint style="danger" %}
The wrong Expression Engine (ExtendScript) is being used.\
\
**Fix:** \
**1. G**o to File > Project Settings > Expressions\
2\. Change the Expression Engine to **JavaScript** ([available on AE 2019 and later.](https://help.pixflow.net/portal/en/kb/articles/after-effect-change-expression-engin))&#x20;
{% endhint %}

<figure><img src="/files/EpYvv5hD6QkyKJN1O57c" alt=""><figcaption></figcaption></figure>

## Other Common Issues

* **Typos or Case Sensitivity Errors:** Double-check that variable or function names are spelled correctly and have the right case (JavaScript is case-sensitive).
* **Single Value Instead of an Array:** If you assign a single value to properties that expect an array (e.g., Scale), you will get an error.

```javascript
myScale = 5; // Incorrect
myScale = [5, 5]; // Correct
myScale = 5; s = [myScale, myScale]; // Another correct option
```

* [ ] **Missing Semicolons:** Make sure to end each line with a semicolon `;`
* [ ] **String vs. Variable Confusion:** Listing a variable as a string when it shouldn’t be. **Example:**\
  `"`myText" is a string, whereas `myText` is a variable.

## **When to ask for help?**

If you tried everything above, and nothing still works. There are two things you can do:

1. You can **download the tutorial project files** that I usually provide for free on my [Gumroad](https://nosleepcreative.gumroad.com/?recommended_by=more_like_this), and copy and paste my code into your projects to get it to work. From there, you can also compare what I have written and your code to see where is the mistake.
2. **If you have to ask me for help,** what I appreciate is having **more context and description** of your problem. For example:

* Which lines does the error occurred?
* What does the error(s) say?
* What have you tried?&#x20;
* Have you consulted this guide and tried the solutions I mentioned?
* What AE version are you running, and what OS.

**Sample format for requesting troubleshooting**

*Hello, I having `problem` with `line number`. The error says `errorMessage` . I have tried `solution` but I still cannot fix the issue.*&#x20;

### **What doesn't help**

1. Saying that "I wrote the code exactly" or I followed your tutorial. If it didn’t work, something else is likely wrong—usually a small typo.
2. Provide as much detail as possible so I can help you quickly.

## More readings

* [How to troubleshoot expressions errors](https://www.youtube.com/watch?v=VdaGqq4I0qM\&t=1426s), Intro to Expression Rigs in After Effects, Zack Lovatt


# Utilities

## Accessing sub-objects

### Get layer's pixel size&#x20;

```javascript
function getSize(layer){
	var src = layer.sourceRectAtTime();
	var s = layer.transform.scale
	var size = [src.width*s[0],src.height*s[1]]/100;
	return size;
}
```

### Get layer's top left coordinates&#x20;

```javascript
function getSrcRectTopLeft(layer){
	s = layer.sourceRectAtTime();
	localPos = [s.left,s.top];
	worldPos = layer.toWorld(localPos);
	return worldPos;
}
```

### Get effect index number

```javascript
// effect index 
thisProperty.propertyGroup(1).propertyIndex;
```

### Get number of effects applied to a layer

```javascript
// referencing locally
thisLayer("ADBE Effect Parade").numProperties
thisLayer("Effects").numProperties

// referencing other layer
thisComp.layer("layer")("ADBE Effect Parade").numProperties
thisComp.layer("layer")("Effects").numProperties 

// other method
thisProperty.propertyGroup(2).numProperties
```

* <https://www.youtube.com/watch?v=xgUNncvKXY8>

## Working with Array

* <https://dmitripavlutin.com/operations-on-arrays-javascript/>

### [Shuffling elements](https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array)

```javascript
function shuffle(a) {
    var j, x, i;
    for (i = a.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = a[i];
        a[i] = a[j];
        a[j] = x;
    }
    return a;
}
```

### Check how many array is empty

```javascript
const arr = [[], [1,4,5], [], [4,6,7];

// method 1: conditional -> sum
numbers.map(x=> x.length>0: 1:0).reduce((a, b) => a + b, 0) 

// method 2 
arr.filter(x => x.length>0).length // get array of true results -> length

```

### Finding minimum or maximum element

In ES6, you can use the `...` operator to spread an array and take the minimum or maximum element.

```javascript
var myArray = [1, 2, 3, 4, 99, 20];

var maxValue = Math.max(...myArray); // 99
var minValue = Math.min(...myArray); // 1
```

### Get length of each element

```javascript
// get length of each array element
elemLength = str.map(s=>s.length)
```

### [Sum of previous elements ](https://stackoverflow.com/questions/47095238/sum-of-previous-elements-from-an-array-in-javascript)

```javascript
// method 1: using mapget character index 
let array = [1,5,6,8,10],sum;
array = array.map(elem => sum = (sum || 0) + elem);

// method 2: using reduce and map
let array = [280,430,408,430,408];
array = array.map((elem, index) => array.slice(0,index + 1).reduce((a, b) => a + b));

//  best method: using double arrow functions
var array =[280, 430, 408, 430, 408]
result = array.map((s => a => s += a)(0));
result;
```

### Comparing a value to elements, filtering conditions

```javascript
let array = [1, 3, 5, 7, 10];
v = 6;

// method 1: conditional -> sum of array 
row = (array.map(c => v >= c ? 1 : 0)).reduce((a, b) => a + b, 0)

// method 2: get index of true results, then get max value
row = Math.max(...array.map(c => v>=c? array.indexOf(c):0))

// best method: filter 
row = array.filter(c => v >= c).length
```

## Increment by Index

* Usage: tiling, valueAtTime offset

```javascript
function indexInc(mainlayer, offset, randRange) {
    var startIndex = mainlayer.layer(index - 1).index
    var myIndex = index - startIndex;
    try {
        var inc = offset * random(randRange[0], randRange[0])* myIndex;
    } catch (e) {
        inc = offset * myIndex;
    }
    return inc;
}

// usage for tile y
mainLayer.transform.position + [0+indexInc(mainLayer,50]
```

## Checking selected layer

### **Shape Layer**

This snippet returns if the layer is a shape layer by checking if there is "Contents" property group.

```javascript
isShapeLayer = thisLayer.content == "Contents" ? 1 : 0;
```

## Loops

### Through every frame

```javascript
for(t = 0; t <  thisComp.duration; t = t + thisComp.frameDuration){ 
    // statements to execute
    }
```

## Unsorted

### [Convert cartesian coordinates to polar](https://creativecow.net/forums/thread/convert-cartesian-coordinates-to-polar/)

```javascript
//If you want it relative to the comp’s [0,0] (upper left corner)

[length(xyArray),radiansToDegrees(Math.atan2(xyArray[1],xyArray[0]))]
```

#### Explanation

&#x20;Using simple trigonometry:

Imagine you have the point \[960, 540];

Those 2 values, 960 and 540, represent two adjacent sides of a triangle.

Now, if you recall back to 9th Grade, you may remember that there is a simple equation to get the third side of that triangle. A² + B² = C². So, we can find the third side (the magnitude) by using an equation like:

var mag = Math.sqrt(Math.exp(position\[0], 2) + Math.exp(position\[1], 2));\
Essentially saying take the square root of X² + Y².

Fortunately, AE gives us the handy little ‘length’ operator, which simply does all of these computations for us.

—

Another similar equation can be used to find the angle of a triangle when you know two other sides, you may remember SOH CAH TOA.

Imagine the angle at the top left of your comp, now notice that you have the opposite side (the Y coord) and the adjacent side (the X coord). Since TOA uses both opposite and adjacent sides, we can get that angle using an equation like this:

```javascript
tan(theta) = opposite/adjacent
tan(theta) = 540/960
theta = tan−1(5625)

//or, in code
var angle = Math.atan(position[1] / position[0]);
var angle_deg = radiansToDegrees(angle);
```

## Null / Camera Rigs

### Add sliders with specific affix names to property&#x20;

{% tabs %}
{% tab title="expression" %}

```javascript
var n =  thisLayer("Effects").numProperties
var fxstr = "z_add"
for(i=1;i<=n;i++){
	if(effect(i).name.includes(str)){
		value+= effect(i)(1);
	}
}
```

{% endtab %}

{% tab title="function" %}

```javascript
function sliderAdd(fxName){
	n =  thisLayer("Effects").numProperties;
	for(i=1;i<=n;i++){
		if(effect(i).name.indexOf(fxName)==0){
			value+= effect(i)(1);
		}
	}
	return value;
};

sliderAdd("Slider");
```

{% endtab %}
{% endtabs %}

## Autonomous agents&#x20;

### Auto-capture ball by Aaron Cobb

```javascript
var ball = thisLayer;
var cup = thisComp.layer("Cup");

var captureDuration = .25; //time for ball to reach center of cup once capture beings
var captureRadius = 100; //radius around anchor point of cup at which ball will be captured.

var captureTime = thisComp.duration; //time at which capture begins, default to end of comp
var currentDistance;

for(t = 0; t < captureTime; t = t + thisComp.frameDuration){ //loop through frames
    currentDistance = length(ball.toComp(ball.anchorPoint.valueAtTime(t), t), cup.toComp(cup.anchorPoint.valueAtTime(t), t));
    if(currentDistance < captureRadius) captureTime = t; //if inside capture radius exit the loop
    }
    
// execute
ease(time, captureTime, captureTime + captureDuration, value, cup.toComp(cup.anchorPoint.value));
```

### Compounding ease() interpolation ([source](https://forums.creativecow.net/docs/forums/post.php?forumid=227\&postid=36351\&univpostid=36351\&pview=t))

You can't control the influence directly, but you can compound the ease such as below.&#x20;

```javascript
if (numKeys > 1){
  t1 = key(1).time;
  t2 = key(2).time;
  v1 = [0,540];  
  v2 = [1080,540];
  t = easeOut(time,t1,t2,0,1); // using a normalized value to drive the 2nd ease
  easeOut(t,0,1,v1,v2);
}else
  value
```

* **Interactive app for easing:** [**http://gizma.com/easing/**](http://gizma.com/easing/)
* [**http://robertpenner.com/easing**/](http://robertpenner.com/easing/)
* [**Ease function generator**](http://www.timotheegroleau.com/Flash/experiments/easing_function_generator.htm)
* [Tweening Guide](http://robertpenner.com/easing/penner_chapter7_tweening.pdf)
* [Interpolation tricks by Sol](http://sol.gfxile.net/interpolation/#c1)
  * Highly useful for learning about speed graph & math


# Shape & Mask

## General tips

### Maintain stroke width

```javascript
// from campkeyframe
sf = transform.scale[0]/100; ov = value;nv = ov / sf

// for parented shapes 
value / length(toComp([0,0]), toComp([0.7071,0.7071])) || 0.001;


// https://battleaxe.tumblr.com/post/101945073972/maintain-stroke-weight-expression
```

### Looping paths (loopOut() doesn't work for paths)

{% tabs %}
{% tab title="Pingpong" %}

```javascript
if (numKeys >1 && time > key(numKeys).time){
 t1 = key(1).time;
 t2 = key(numKeys).time;
 span = t2 - t1;
 delta = time - t2;
 seg = Math.floor(delta/span);
 t = delta%span;
 valueAtTime((seg%2) ? (t1 + t) : (t2 - t));
}else
 value
```

{% endtab %}

{% tab title="cycle" %}

```javascript
if (numKeys >1 && time > key(numKeys).time){
 t1 = key(1).time;
 t2 = key(numKeys).time;
 span = t2 - t1;
 delta = time - t2;
 t = delta%span;
 valueAtTime(t1 + t)
}else
 value
```

{% endtab %}
{% endtabs %}

## Accessing Shape parameters

Reference: <https://ae-expressions.docsforadobe.dev/group.html?highlight=shape%20property#group>

### Syntax & Usage

```javascript
thisProperty.propertyGroup(1).numProperties
thisProperty.propertyGroup(1).propertyIndex
```

### Shape Property Index

Let's say if you have multiple Ellipses or other shapes within a Shape Layer Contents, and you want to retrieve the index of each Shape:

```javascript
content("Ellipse 1").propertyIndex
```

```javascript
thisProperty.propertyGroup(3).propertyIndex
```

If you want to use parse the index via the property name:

```javascript
// using name as index eg. line_1
parseInt(thisProperty.propertyGroup(3).name.split("_")[1]); // method 1

parseInt(content(1).name.split("_")[1]) // method 2
```

### Shape Property Group and Index

```javascript
// shape group index
thisProperty.propertyGroup(2).propertyIndex // change num accordingly


```

### Examples

* [Property Group Index Expression + Free Preset](https://youtu.be/xgUNncvKXY8)

{% embed url="<https://youtu.be/xgUNncvKXY8>" %}


# Type & Text

## Introduction

A library of After Effects expressions to be used for sourceText property of a Text Layer.

## Repetition

### Repeat input string

<figure><img src="/files/jUaA7umwhDmgrCJEQrt9" alt=""><figcaption></figcaption></figure>

{% tabs %}
{% tab title="repeat()" %}

```javascript
n = 10; // number to times to repeat
value.repeat(n)
```

{% endtab %}

{% tab title="for-loop" %}

```javascript
var n = 8; // number of times to repeat
s = myText = value;
for(i=1; i<n; i++) s += myText; 
s;
```

{% endtab %}

{% tab title="vertical" %}

```javascript
n = 8; // connect to a slider 
s = myText = value;
for(i=1; i<n; i++) s += "\r" + myText; 
s;
```

{% endtab %}
{% endtabs %}

### Text Grid - Uniform Repetition

<figure><img src="/files/HDq94hOVUF7w6wz3H1CS" alt=""><figcaption></figcaption></figure>

{% tabs %}
{% tab title="repeat()" %}
**Explicit**

```javascript
var s = value;  // Source text
var numColumns = 5;  // Number of columns
var numRows = 10;  // Number of rows

var row = s.repeat(numColumns) + "\r";  
row.repeat(numRows);
```

**Concise**

```javascript
(value.repeat(5) + "\r").repeat(10);
```

{% endtab %}

{% tab title="For-loop " %}

```javascript
// User Input:
var numRows = 10; // Number of rows in the output
var numColumns = 22; // Number of columns in the output
var s = value; // Enter the value to be repeated in each cell

// Seed
var result = "";
var j = 0;
while (j < numRows) {
  var k = 0;
  while (k < numColumns) {
    result += s; // Placeholder for the actual random alphanumeric generation code
    k += 1;
  }
  result += "\r";
  j += 1;
}

result
```

{% endtab %}
{% endtabs %}

### Text Grid - Multiple Line Repetition

This code splits a comma-separated string into an array, then formats it into a text block with rows and columns by repeating each item with added prefixes and suffixes.

{% tabs %}
{% tab title="For Loop" %}

```javascript
const str = value;
const strArr = str.split(",");
const prefix = ""; 
const suffix = " ";
const numColumns = 5;
const numRows = 10;

let result = "";

for (let i = 0; i < numRows; i++) {
    const eleIndex = i % strArr.length;
    result += (prefix+strArr[eleIndex]+suffix).repeat(numColumns) + "\r"; 
}

result;
```

{% endtab %}

{% tab title="repeat()" %}

```javascript
s = value;
strArr = s.split(",");
prefix =" ";
suffix =" ";

numColumns = 5; 
numRows = 10; 

row1 = (prefix + strArr[0] + suffix).repeat(numColumns) + "\r";  
row2 = (prefix + strArr[1] + suffix).repeat(numColumns) + "\r";  
row3 = (prefix + strArr[2] + suffix).repeat(numColumns) + "\r";  

rows = row1 + row2 + row3;
rows.repeat(numRows);
```

{% endtab %}
{% endtabs %}

### Text Grid - Number Sequence

This code creates a string of sequential numbers between a start and end range. The numbers are arranged in rows and columns, and each number can have leading zeros and spaces after it.&#x20;

```javascript
//user variables
var startNum = 0;
var maxNum = 200;
var numCol = 10;
var numZero = 2;
var numSpace = 1;

var s = "";


for (var i = 1; i <= maxNum; i++) {
    // add startNum 
    var n = startNum + i - 1;

    // add zeroes
    for (var j = 1; j <= numZero; j++) {
        if (n < Math.pow(10, j)) s += 0
    }
    // add number to string
    s += n;

    // add spaces 
    for (var j = 0; j < numSpace; j++) s += ' '

    // add line break 
    i % numCol == 0 ? s += '\n' : s

}
```

### Text Grid - Random Letter

This function generates a grid of random letters, and the user specify the total number of letters and letters per row.

```javascript
function genLetter() {
    r = random(65, 90); //from a to z
    return String.fromCharCode(r);
}

function randAlphabet(maxNum, col, seed) {
    seedRandom(seed, true);
    var s = "";
    for (i = 1; i <= maxNum; i++) {
        s += genLetter() + ' ';
        if (i % col == 0) s += '\n'; // add line break
    }
    return s
}
randAlphabet(500, 25, 1)
```

### Text Grid - Random Binary&#x20;

![](/files/-M49QD9ejRgRdm7TmZ6Q)

{% tabs %}
{% tab title="1" %}

```javascript
function binary(maxNum, col, seed) {
    seedRandom(seed, true);
    var s = "";
    for (var i = 1; i <= maxNum; i++) { 
        s += Math.round(random()) + ' ';
        if (i % col == 0) s += '\n'; 
    }
    return s;
}

// Usage
binary(500, 25, 1);
```

{% endtab %}

{% tab title="2" %}

```javascript
n = 300; // connect to slider
seedRandom(seed,true);
let m = b = '';
for(i=0;i<n;i++){
	seedRandom(i+seed,true);
	b = Math.round(random(1)).toString()
	m +=b;
}
```

{% endtab %}
{% endtabs %}

***

## Randomization

### Random Letter

<figure><img src="/files/onNStNMZIXKA8K4DrhTe" alt=""><figcaption></figcaption></figure>

{% tabs %}
{% tab title="Solution 1" %}
{% code lineNumbers="true" fullWidth="true" %}

```javascript
// User Input
var numOfLetters = 10; // Modify the number of letters to generate
var useSpaces = true; // Modify to include spaces between letters (true) or not (false)
var changeEveryFrame = false; // Modify if the generated letters should change every frame

// Don’t modify below this line
seedRandom(index, !changeEveryFrame);

function genLetter() {
  var r = random(65, 90); // Generate a random number representing a letter (ASCII code for A to Z)
  return String.fromCharCode(r); // Convert the number to the corresponding letter character
}

var result = "";
for (var i = 0; i < numOfLetters; i++) {
  result += genLetter();
  if (useSpaces) {
    result += " "; // Add a space between letters if useSpaces is true
  }
}
result; 

//source: https://creativecow.net/forums/thread/random-letters-4/

```

{% endcode %}
{% endtab %}

{% tab title="Solution 2" %}

```javascript
// Number of rows in the output
var numRows = 1;

// Number of characters in each row of the output
var numChars = 5;

// Number of frames to hold the same random seed
var holdFrames = 5;

// Calculate the seed for randomization based on time and holdFrames
var seed = Math.floor(time / (holdFrames * thisComp.frameDuration));
seedRandom(seed, true);

var result = "";
var j = 0;

while (j < numRows) {
  var k = 0;
  
  while (k < numChars) {
    var randomCharCode = Math.floor(random(65, 91)); // Generate random number representing uppercase letter in ASCII
    result += String.fromCharCode(randomCharCode); // Convert random number to corresponding letter character
    k += 1;
  }
  
  result += "\r"; // Add a carriage return at the end of each row
  j += 1;
}

result; // Output the generated string

```

{% endtab %}
{% endtabs %}

### Random Digit

```javascript
seedRandom(10,true);
Math.round(random(9));
```

***

## String Manipulation

### Search and replacing string instances

```javascript
var searchString = /\r/g; // \r: lien break; \g: global flag
var replaceString = "newString";
value.replace(searchString, replaceString);
```

### Parsing Text

#### [Sourcetext from Comp Name](https://zacklovatt.com/split-sourcetext-from-comp-name)

```javascript
// if comp name is "comp_05", to get number use this
thisComp.name.split("_")[1] // replace delimiter based on your needs
```

#### Separating source text line feeds into an array

```javascript
// Method 1 
txt = thisComp.layer("insert Text").text.sourceText;
txt.split("\r")[3]; // Regex

// Method 2:using name as index
txt = thisComp.layer("insert Text").text.sourceText;
myIndex = thisLayer.name;
txt.split("\r")[myIndex];
```

#### [Number from comp name](https://www.w3schools.com/jsref/jsref_parseint.asp)

```javascript
myNum = parseInt(thisComp.name.split(" ")[1],10);
```

## Numbers

### Rounding numbers

{% tabs %}
{% tab title="to integer" %}

```
// Use any of the following
Math.floor(value);
Math.ceil(value);
```

{% endtab %}

{% tab title="pow" %}

```javascript
x = time;
pow = Math.pow(10,5) // 5 is the number of decimals 
x = Math.round(x*pow)/pow;
```

{% endtab %}

{% tab title="toFixed" %}

```
// apply to sourcetext
x = 2 // number of decimal points
value.toFixed(x);
```

{% endtab %}
{% endtabs %}

### Round up if above threshold

```javascript
function roundSpecific(num,thres){
    dec = num - Math.floor(num)
    if(dec>=thres) {num = Math.ceil(num);
}
return num
}
// usage 
roundSpecific(385.96,.9)
```

### Counter

```javascript
startTime = 0
endTime = 2;
startNum = 0;
endNun = 10000
linear(time,startTime,endTime,startNum,endNum);
```

## Dates

### Current date

```javascript
D = new Date(Date(0));
“” + D.getDate() + “/” + (D.getMonth()+1) + “/” + D.getFullYear()

// get year
D = new Date(Date(0));D.getFullYear()

// get month 
D = new Date(Date(0));D.getMonth()+1

// get day
D = new Date(Date(0)); D.getDate()
```

## Expressions selector

**Recommended readings**

* [ WorkBench 34: Expression Selector Intro](https://www.youtube.com/watch?v=FcSX2Heirko)

### Default

```javascript
selectorValue * textIndex/textTotal
```

### Alternating Effector

```javascript
if(textIndex%2) -100; else 100
```

### [Random ](https://forums.creativecow.net/docs/forums/post.php?forumid=227\&postid=8595\&univpostid=8595\&pview=t)position from textIndex

```javascript
seedRandom(textIndex,true);
random([100,100]);
```

### Select text indexes explicitly; e.g. 1, 3, 7, 14, 22, etc.?

```javascript
If you don't have a lot of numbers, then this works:

if(textIndex === 1 || textIndex ===3) {
 100;
} else {
 0;
}

If you do have a ton of numbers, then this works:

i = [1,3,5,7,10,11];
inArray(i);

function inArray(obj) {
 b = 0;
 for(i = 0; i < obj.length; i++) {
  if(obj[i] === textIndex) {
   b = 100;
   break;
  }
 }
 return b;
}
```

### Sin wave effector \[[source](https://forums.creativecow.net/thread/227/17667)]

```javascript
freq = .5;
selectorValue*Math.sin(time*freq*Math.PI*2 + Math.PI*2* textIndex/textTotal)
```

## Basics

```javascript
// getting the character count
l = thisComp.layer("your text layer").text.sourceText.length;

// getting word count 
l = thisComp.layer("your text layer").text.sourceText;
wordsCount = l.split(/ ,| | \./).length;


// Matching text with regex
thisComp.layer("text").text.sourceText.toLowerCase().match(/\w+\./))

// includes() — determines whether a string contains the characters of a specified strin
var str = "Hello world, welcome to the universe.";
var n = str.includes("world");
```

## Utility Functions

### Find Number of Layers that includes string

```javascript
function findLayerbyName(str) {
    var n = thisComp.numLayers;
    var numMattes = 0;
    for (i = 1; i <= n; i++) {
        thisComp.layer(i).name.includes(str) == 1 ? numMattes += 1 : 0;
    }
    return numMattes
}

findLayerbyName("matte")
```

##

##

## Expression Selector (Regex)

```javascript
https://forums.creativecow.net/thread/227/41461
Oleg Pirogov
https://dribbble.com/zeplin
```

```javascript

var t = text.sourceText;
var regex = /\d[a-z]+(?=,)/g;

function indexMatched(index){
var matched = false;
var match;
var i=[];

while ((match = regex.exec(t)) !== null){
matched |= match.index<index & index<match.index+match[0].length;
i.push([match, match.index, match.index+match[0].length]);
}
return matched;
}

indexMatched(textIndex-1) ? 100 : 0;
```

### [Words inside parentheses ](https://forums.creativecow.net/thread/227/42339)

```javascript
var t = text.sourceText;
var regex = /\(([^)]+)(?=\))/g;

function indexMatched(index){
var matched = false;
var match;

while ((match = regex.exec(t)) !== null){
matched |= match.index<index & index<match.index+match[0].length;
}
return matched;
}

indexMatched(textIndex-1) ? 100 : 0;

```

### Hexcode

```javascript
var t = text.sourceText;
var regex = /[A-Fa-f0-9]{6}/g;

function indexMatched(index){
var matched = false;
var match;

while ((match = regex.exec(t)) !== null){
matched |= match.index<index & index<=match.index+match[0].length;
}
return matched;
}

indexMatched(textIndex) ? 100 : 0;
```


# Cookbook

{% hint style="danger" %}
Encoutering expression errors? Check out this [Troubleshooting Guide!](https://app.gitbook.com/o/NW5KuSR8Tekqe0Wvv3JX/s/-Lgx0HTP5iKvQQwXUStq/~/changes/1080/after-effects/expressions/expression-troubleshooting)
{% endhint %}

## Introduction

Below are code used in my [YouTube tutorials](https://www.youtube.com/@NoSleepCreative/videos) for your reference and usage. This page&#x20;

## Phyllotaxis

{% embed url="<https://www.youtube.com/watch?v=K1P9NgVJqLQ>" %}

```javascript
//theta
var myIndex = index - thisComp.layer("controls").index;
var a = 137.508
var theta = degreesToRadians(myIndex * a);

theta

//position
var myIndex = index - thisComp.layer("controls").index;
var s = thisComp.layer("controls").effect("Spacing")("Slider");
var theta = effect("theta")("Slider");

x = s * Math.sqrt(myIndex) * Math.cos(theta);
y = s * Math.sqrt(myIndex) * Math.sin(theta);

[x, y] + [thisComp.width, thisComp.height] / 2

// Circle Size
var theta = effect("theta")("Slider");
var minSize = thisComp.layer("controls").effect("Min Size")("Slider");
var maxSize = thisComp.layer("controls").effect("Max Size")("Slider");
var maxRange = thisComp.layer("controls").effect("Distance Range")("Slider");

var sizeFactor = linear(theta, 0, maxRange, minSize, maxSize) / 100;
var s = thisComp.layer("controls").effect("Size")("Slider");
[s, s] * sizeFactor;

// Fill Color
var theta = effect("theta")("Slider");
var interval = thisComp.layer("controls").effect("Color Interval")("Slider");
var numColor = thisComp.layer("colors")("Effects").numProperties;

var colorIndex = Math.ceil(theta / interval) % numColor + 1;
thisComp.layer("colors").effect(colorIndex)("Color")


```

## Best Motion Trails in After Effects

{% embed url="<https://www.youtube.com/watch?v=9MCHTe8iBpk>" %}

### Wavey sine wave motion&#x20;

```javascript
// apply to X position after separating dimensions
var vel = effect("waveSpeed")("Slider")*Math.PI*2;
var amp = effect("waveHeight")("Slider");
var offset =Math.PI*2*degreesToRadians(effect("phase")("Angle"));

// main 
var v = amp* Math.sin(time*vel+offset);
v + value;
```

### createPath Motion Trails

```javascript
//setup 
var l = effect("Layer Control")("Layer");
var dur = effect("trailLength")("Slider");
var pts = [];

// calculate the trail length in frame numbers 
var currentFrame = timeToFrames(time);
var trailLength = currentFrame - dur;

// main: generate the points from the current time 

for (i = currentFrame; i > trailLength; i--) {
    t = framesToTime(i)
    ap = l.toWorld(l.transform.anchorPoint, t);
    ap -= [thisComp.width, thisComp.height] / 2;
    pts.push(ap);
}

// create the path using the points
createPath(pts, [], [], 0)
```

## Scaling Radial Grid

{% embed url="<https://www.youtube.com/watch?v=8BeI1qXzysU>" %}

### Parent/Child Link without scale inheritance

```javascript
ps = parent.transform.scale.value;
s = value[0]*100/ps[0];
[s,s]
```

### Aim Constraint

```javascript
target = thisComp.layer("controls"); // set this to the layer to aim at
p = thisLayer.toWorld(anchorPoint) - target.position;
radiansToDegrees(Math.atan2(p[1], p[0])) - 90
```

## Cyberpunk tech lines

{% embed url="<https://www.youtube.com/watch?v=Gfr0sUY5eo0&t>" %}

{% tabs %}
{% tab title="main" %}

```javascript
// user variables 
var pts = 50;
var pos = [0, 100];
var seed = 50;

// declaration 
var x, y; // coordinates
var c, mul; // direction changer
var vertices = [[0, 0]]; // create first point 

// vertices array 
for (i = 1; i <= pts; i++) {
  seedRandom(i + seed, true);
  c = random(); // create random num between 0 to 1 
  c > 0.5 ? mul = 1 : mul = -1; // change direction 
  oldEle = vertices[i - 1]; // get previous vertice

  y = random(pos[0], pos[1]);
  x = y * mul;

  // conditional: if even, go diagonal. If odd, go straight
  if (i % 2 == 0) {
    vertices[i] = oldEle + [x, y];
  } else {
    vertices[i] = oldEle + [0, y];
  }
}

createPath(vertices, [], [], 0);
```

{% endtab %}

{% tab title="branch" %}

```javascript
// user variables 
var pts = effect("pts")("Slider");
var pos = [effect("min_y")("Slider"), effect("max_y")("Slider")];
var seed = effect("seed")("Slider");

// get random point on first path
seedRandom(seed,true);
var myPath = content("main").path;
var myPathpts = myPath.points().length;
var myRandPt = Math.floor(random(myPathpts));
var mySelectedPt = myPath.points()[myRandPt];

// declaration 
var x, y // coordinates
var c, mul // direction changer
var vertices = [mySelectedPt] // create first point 

// vertices array 
for (i = 1; i <= pts; i++) {
  seedRandom(i + seed, true);
  c = random(); // create random num between 0 to 1 
  c > 0.5 ? mul = 1 : mul = -1; // change direction 
  oldEle = vertices[i - 1] // get previous vertice

  y = random(pos[0], pos[1]);
  x = y * mul;

  // conditional: if even, go diagonal. If odd, go straight
  if (i % 2 == 0) {
    vertices[i] = oldEle + [x, y];
  } else {
    vertices[i] = oldEle + [0, y];
  }
}

createPath(vertices, [], [], 0);
```

{% endtab %}
{% endtabs %}

## Radial Delay Rig

{% embed url="<https://youtu.be/N2E29KvQXgI>" %}

```javascript
tgt = thisComp.layer("control");
// d = length(L.transform.position, transform.position);
d = length(thisLayer.toWorld(transform.anchorPoint), tgt.toWorld(tgt.transform.anchorPoint));

delay = thisComp.layer("control").effect("maxDelay")("Slider");
offset = linear(d,0,2000,0,delay);
time-offset;
```

## Buck Apeel Circle Ripple

{% embed url="<https://www.youtube.com/watch?v=TwbDN8SX058&feature=youtu.be>" %}

**Ensure you have the following**

1. ring shape layer `Slider Controls` : size,copies, radius (anchorpoint-Y), myIndex
2. null layer named "controls" with `Slider Controls` : circle\_size, circle\_spacing, ring\_base\_size, ring\_spacing, dur
3. null layer named "colors" with `Color Controls` x 3

### **Auto-copies**

```javascript
cir = 2*Math.PI *effect("radius")("Slider"); // circumference of circle
n = thisComp.layer("controls").effect("circle_spacing")("Slider"); // max size of a circle
Math.floor(cir/n) // round down the results
```

### **Get myIndex**

```javascript
myIndex = index-thisComp.layer("controls").index-1;
```

### **Auto-scaling radius**

```javascript
myIndex = effect("myIndex")("Slider"); 
c = thisComp.layer("controls");
int = c.effect("ring_spacing")("Slider");
base = c.effect("ring_base_size")("Slider");

s = myIndex*int;s+ base;
```

### Auto-alternate color

```javascript
myIndex = effect("myIndex")("Slider"); 
num = myIndex %3+1;
thisComp.layer("color").effect(num)("Color")
```

### Stagger-animation - balls

```javascript
myIndex = effect("myIndex")("Slider"); 
s = thisComp.layer("controls").effect("circle_size")("Slider");
dur = framesToTime(thisComp.layer("controls").effect("dur")("Slider"));
offset = myIndex*dur;
s.valueAtTime(time-offset)
```

## Matrix Binary Rain Code

{% embed url="<https://youtu.be/p2r_abV9HL8>" %}

```javascript
seed = 10; // connect to slider
n = 50; // connect to slider

m = b = ''

for(i=0;i<n;i++){
	seedRandom(seed+i,true);
	b = Math.round(random());
	m += b;
}
```

## Vucko — *From Nothing to Something*

{% embed url="<https://youtu.be/1wrFAGKLGDk>" %}

### Random flickering&#x20;

```javascript
// apply this to your Time Remap property of your Sprite render 
seed = 20; // option:connect to a slider 
segMin = .5; //minimum segment duration
segMax = .8; //maximum segment duration
flickerDurMin = 1;
flickerDurMax = 5;

end = 0;
j = 0;

while ( time >= end){
  j += 1;
  seedRandom(j,true);
  start = end;
  end += random(segMin,segMax);
}
flickerDur = random(flickerDurMin,flickerDurMax);
if (time > end - flickerDur){
  seedRandom(j+69+seed,true);
  random(outPoint);
}else{
   seedRandom(j+seed,true);
  random(outPoint);
}

// original expression from Dan EbbertyVelocity = 200; //pixels per second
```

## Change Log

* 2021: Initial publish
* 2024.09.27: Added introduction, moved troubleshooting guide to a separate page


# Algorithmic

Last update: 8 June 2021

## Square&#x20;

### createPath

```javascript
vertices = [[0,0], [100,0], [100,100], [0,100]];
inTangents=[]
outTangents=[]
closed = true;
createPath(vertices,inTangents, outTangents, closed);
```

## 8-Sided Rectangle (Beveled Rectangle)

<figure><img src="/files/phFGFU1SJyaswI5aGnA0" alt=""><figcaption></figcaption></figure>

{% tabs %}
{% tab title="Expression" %}

```javascript
// Coordinates
var v = [[1.5, 1.5], [2.0, 1.0], [2.0, -1.0], [1.5, -1.5], [-1.5, -1.5], [-2.0, -1.0], [-2.0, 1.0], [-1.5, 1.5]];

// Create a path with zero tangents (straight lines)
createPath(v, [], [], true);

```

{% endtab %}

{% tab title="Mask" %}

```javascript
// Get the dimensions of the shape layer
var w = thisLayer.width / 2;
var h = thisLayer.height / 2;
var cut = Math.min(w, h) * 0.2; // Adjust the corner cut size relative to layer size

// Coordinates of the centered 8-sided rectangle based on layer dimensions
var v = [
    [w - cut, h], [w, h - cut], [w, -h + cut], [w - cut, -h],
    [-w + cut, -h], [-w, -h + cut], [-w, h - cut], [-w + cut, h]
];

// Offset to center the path
var offset = [thisLayer.width / 2, thisLayer.height / 2];
v = v.map(function(point) { return [point[0] + offset[0], point[1] + offset[1]]; });

// Create a path with zero tangents (straight lines)
createPath(v, [], [], true);

```

{% endtab %}
{% endtabs %}

## Triangle

### createPath

```javascript
l = 100;
w = 50;
vertices = [[0,0], [-w,l], [w,l]]
inTangents=[]
outTangents=[]
closed = true;
createPath(vertices,inTangents, outTangents, closed);
```

## Circle

$$
x = radius*sin(theta)\ y = radius*cos(theta)
$$

### createPath

* Source: [Dan Ebbert](https://forums.creativecow.net/docs/forums/post.php?forumid=227\&postid=39882\&univpostid=39882\&pview=t) — circle

{% tabs %}
{% tab title="no tangent" %}

```javascript
var pts = 50;
var a = 500; //radius
var completion = 100 / 100;

var t, x, y;
var vertices = [];

for (i = 0; i < pts; i++) {
  t = i / pts * Math.PI * 2 * completion; // element num/ num of elements ;
  x = a * Math.cos(t);
  y = a * Math.sin(t);
  vertices[i] = [x, y]
}
createPath(vertices, [], [], 1)
```

{% endtab %}

{% tab title="w/ tangent" %}

```javascript
w = 500; // width
r = w/2;
ratio = .5523;
t = r*ratio;
vertices = [[r,0],[0,r],[r,2*r],[2*r,r]];
inTangents = [[t,0],[0,-t],[-t,0],[0,t]];
outTangents = [[-t,0],[0,t],[t,0],[0,-t]];
createPath(vertices,inTangents,outTangents,1);
```

{% endtab %}
{% endtabs %}

## Lemniscate

A Lemniscate is a mathematical curve shaped like the number 8 or the infinity symbol (∞). The term "lemniscate" comes from the Latin word "lemniscus," which means "ribbon."

<figure><img src="/files/aV4xHTyEWgz6zWEvxAWk" alt=""><figcaption></figcaption></figure>

```javascript
function createLemniscatePath(center, radius, stretch, numPoints) {
    var vertices = [];
    
    for (var i = 0; i <= numPoints; i++) {
        var t = i / numPoints;
        var angle = 2 * Math.PI * t;
        var x = radius * Math.sin(angle) / (1 + Math.cos(angle) * Math.cos(angle));
        var y = radius * Math.sin(angle) * Math.cos(angle) / (1 + Math.cos(angle) * Math.cos(angle));
        vertices.push(center + [stretch * x, y]);
    }
    
    return createPath(vertices, [], [], true);
}

// Parameters
var center = [thisComp.width, thisComp.height] / 2;
var radius = 300;
var stretch = 1;
var numPoints = 50;

// Generate the Lemniscate path
createLemniscatePath(center, radius, stretch, numPoints);

```

## [Eight curve](https://mathworld.wolfram.com/EightCurve.html)

$$
x= a \*sin(t)\y=asin(t)cos(t)
$$

### Position

```javascript
// source: Dan Ebbert

center = [thisComp.width,thisComp.height]/2;
radius = 200;
period = 3;
angle = 2*Math.PI*time/period;
x = 2*radius*Math.cos(angle)*Math.sqrt(Math.cos(angle)*Math.cos(angle));
y = 2*radius*Math.cos(angle)*Math.sin(angle);
center + [x,y]
```

## Torus

$$
x=(a+bcosu)cosv
\\
y=(a+bcosu)sinv\\
z=bsinu
$$

### Position

```javascript
u = 1
v = 2
a = 540;

x = a*Math.cos(v*time)*Math.sin(u*time);
y = a*Math.cos(v*time)*Math.cos(u*time);
[x,y]+[thisComp.width/2,thisComp.height/2]
```

### createPath

```javascript
var pts = 50;
var u = 1
var v = 10;
var a = 75 // inner radius
var c = 450 // outer radius
var completion = 100 / 100;

var t, x, y;
var vertices = [];

for (i = 0; i < pts; i++) {
  t = i / pts * Math.PI * 2 * completion; // element num/ num of elements ;
  x = (c + a * Math.cos(v * t)) * Math.cos(u * t);
  y = (c + a * Math.cos(v * t)) * Math.sin(u * t);
  vertices[i] = [x, y]
}
createPath(vertices, [], [], 1)
```

## Wavy Circle

### Position

```javascript
u = 1
v = 10;
a = 75 // inner radius
c = 450 // outer radius
phase = 10; // animate this


x = (c+a*Math.cos(v*phase))*Math.cos(u*phase);
y = (c+a*Math.cos(v*phase))*Math.sin(u*phase);
[x,y]+[thisComp.width/2,thisComp.height/2]
```

## Conical spiral (equidistant)

### Position

```javascript
freq = 60;
mul = 500;
radius = 90;

x = radius*Math.sin(time*freq)
y = radius*Math.cos(time*freq)
z = time*mul
value  + [x,y,z]
```

## Archimedes Spiral

* [**Polar Coordinates in Houdini | VEX Quickies**](https://www.youtube.com/watch?v=hgEcnfyBvf8)**, David Kahl**

### createPath

{% tabs %}
{% tab title="path property" %}

```javascript
// connect to sliders
let w = 1000;
let points = 200;
let steps = 20;
let angle = 0;

let r = w / 2;
let step = (Math.PI * 2) / steps;
let radius = 0;
let vertices = [];

//main
for (i = 0; i < points; i++) {
    angle += step;
    radius = i / points * r;
    x = Math.cos(angle) * radius;
    y = Math.sin(angle) * radius;
    vertices[i] = [x, y];
}

createPath(vertices, [], [], 0)
```

{% endtab %}
{% endtabs %}

## Phyllotaxis&#x20;

### Position

```javascript
var a = 137.508;
var r = 25; 

var theta = degreesToRadians(myIndex * a);
var myIndex = index - thisComp.layer("controls").index;

x = r * Math.sqrt(myIndex) * Math.cos(theta);
y = r * Math.sqrt(myIndex) * Math.sin(theta);

[x, y] + [thisComp.width, thisComp.height] / 2;
```

## Harmonic Motion

### createPath

{% tabs %}
{% tab title="sine" %}

```javascript
// var ctrl = thisLayer;
var inc = 1500;
var amp = 300;
var n = 30;
var freq = .5
var seed = 185;

var vertices = [];
var x, y, pt, phase;
seedRandom(seed, true)
var offset = random() * Math.PI * 2

for (i = 0; i < n; i++) {
  pt = i / (n - 1);
  x = inc * pt

  phase = time * freq * Math.PI * 2 + pt * Math.PI
  //phase += offset;

  y = amp * Math.sin(phase);
  //y *= Math.sin(phase / 2);
  //y *= Math.sin(phase / 3);
  //y += noise(time + pt) * 100;

  // create point
  vertices[i] = [x, y]
}

createPath(vertices, [], [], 0)
```

{% endtab %}

{% tab title="squiggly" %}

```javascript
// var ctrl = thisLayer;
var inc = 1500;
var amp = 300;
var n = 50;
var freq = .5
var seed = 185;
var r = 0.25;


var vertices = [];
var x, y, pt, phase;
seedRandom(seed, true)
var offset = random() * Math.PI * 2

for (i = 0; i < n; i++) {
  pt = i / (n - 1);
  x = inc * pt 

  phase = time * freq * Math.PI * 2 + (pt * Math.PI /r)
  // phase += offset;

  w1 = Math.sin(phase);
	y = amp * w1;

  // create point
  vertices[i] = [x, y] 
}

createPath(vertices, [], [], 0)
```

{% endtab %}
{% endtabs %}

## Knots

<figure><img src="/files/D3hRWdOn29euusMpISPx" alt=""><figcaption></figcaption></figure>

<https://en.wikipedia.org/wiki/Knot_%28mathematics%29>


# Random properties

WIP - last updated 21 April 2021

## Abstract

{% embed url="<https://youtu.be/nqf5n_y7mE8>" %}

One of the most useful things you can do with Expressions is **randomizing layer properties.** Some properties include transform properties (position, rotation, scale, or opacity), color, or even Time Remap. **Learning to randomize properties is a good beginner exercise to raise one's comprehension of Javascript Expression. In this page, we will cover different ways to randomize properties.**

### **Understanding Random functions**

* random()
* random(minValue, maxValue)
* seedRandom(seed, timeless=false)

Core skills: randomize values, arrays, color

{% hint style="info" %}
**What is a seed?**\
\
A random seed (or seed state, or just seed) is a number (or vector) used to initialize a pseudorandom number generator. **To put simply, different seed number yield difference sequence of random number.**
{% endhint %}

## Position

### Wiggle

```javascript
wiggle(20,50);

// wiggle x axis 
x = wiggle(20,50)[0];
y = value[1];
pos = [x,y]

// wiggle y axis 
x = value[0[;
y = wiggle(20,50);
pos = [x,y]

// getting wiggle increment values only 
inc = wiggle(20,50)-50;
```

{% embed url="<https://youtu.be/a5JIRHATV4I>" %}

### positioning&#x20;

```javascript
// randomize between a range 
seedRandom(1,true);
x = random(300,1920);
y = random(500,1080);
[x,y];
```

```javascript
// using arrays and variable 
seed = 20;
min = [25,25,-1900]; 
max = [thisComp.width,thisComp.height,50]

seedRandom(seed,true);
random(min,max);

/* This is same as this
x= random(min[0],max[0]);
y= random(min[1],max[1]);
z= random(min[2],max[2]);
[x,y,z];
*/
```

## Opacity

### Flickering / Strobe

![](/files/-Lvzv6zr3sH_kO9D4HI-)

```javascript
// VARIABLES
    minSeg = 1.5; //minimum interval (must be > 0) 
    maxSeg = 2.5; //maximum interval (must be > minSeg) 
    
    // flickering duration
    minFlicker = .5; //must be less than minSeg 
    maxFlicker = 1; // must be less than minSeg 
    flickerDur = random(minFlicker,maxFlicker);
    
    //initial conditions
    segEndTime = 0; 
    i = 1; 

// Continuous loop: create a fixed random segment value and add to segEndTime
while (time >= segEndTime){ 
    i += 1; 
    seedRandom(i,true); 
    segEndTime = segEndTime + random(minSeg,maxSeg); 
} 

// Switch back to use the current time as input to the random seed.
seedRandom(1,false); 

// As time > threshold, flicker
if (time > segEndTime - flickerDur){random(0,100) }else{ 100 }

// Source: http://www.motionscript.com/expressions-lab-ae65/swinging-light.html
// Also see: http://www.motionscript.com/mastering-expressions/random-3.html
```

### Wiggle&#x20;

![](/files/-LxgTeeafXFWIXSvUAVz)

```javascript
// control = thisComp.layer("control"); // connect to null layer with sliders
freq = 1;
amp = 100;
octave = 1;
amp_mult = 3;

wiggle(freq, amp, octave, amp_mult, time)
```

### Wiggle with flicker&#x20;

![](/files/-LxgTee_fD3Lkg-RBd8A)

```javascript
// control = thisComp.layer("control"); // connect to null layer with sliders
freq = 1;
amp = 100;
octave = 1;
amp_mult = 3;

opacity = wiggle(freq, amp, octave, amp_mult, time)


// VARIABLES
minSeg = control.effect("minSeg")("Slider"); //minimum interval (must be > 0) 
maxSeg = control.effect("maxSeg")("Slider");; //maximum interval (must be > minSeg) 

// flickering duration
minFlicker = control.effect("minFlicker")("Slider");; //must be less than minSeg 
maxFlicker = control.effect("maxFlicker")("Slider");; // must be less than minSeg 
flickerDur = random(minFlicker, maxFlicker);

//initial conditions 
segStartTime = 0;
segEndTime = 0;
i = 1;

// Continuous loop: create a fixed random segment value and add to segEndTime
while (time >= segEndTime) {
    i += 1;
    seedRandom(i, true);
    segStartTime = segEndTime;
    segEndTime = segEndTime + random(minSeg, maxSeg);
}

// Switch back to use the current time as input to the random seed.
seedRandom(1, false);

// As time moves threshold, flicker
if (time > segEndTime - flickerDur) {
    random(0, 100)
} else {
    opacity
}
```

### Using sine function

![](/files/-LvzqIqZjkIfnahiz4Xp)

```javascript
// Mass flickering
vel = 50;
seedRandom(0,true);
Math.sin(time*vel+random(index))*100;
```

![](/files/-LvzqOfKOBy4vOe8vqGz)

```javascript
// 'Wave flickering'
vel = 50;
seedRandom(0,true);
Math.sin(time*vel+index)*100;

// Combining 
bool = 1;
vel = 50;
seedRandom(0,true);
wave=Math.sin(time*vel+index)*100;
rand =Math.sin(time*vel+random(index))*100;
bool==0 ? wave : rand;
```

### Random pop on

![](/files/-LvuSGW8ej9Hcu5gPtMv)

```javascript
seed = 29;
threshold = linear(time,0,thisComp.duration,0,100); // or Connect to slider to animate switch on & off

seedRandom(seed,true);
randValue = random(0,90);

if(randValue < threshold){
    100;} else 0
```

Tutorial: [Randomly Reveal Layers & Emojis with Expressions](https://www.youtube.com/watch?v=8MAo1T2rNK4), NSC&#x20;

### Random fade on&#x20;

![](/files/-LvuSL9ktGztg6U8qnuQ)

{% tabs %}
{% tab title="v2" %}

```javascript
var seed = 1;
var seedRandom(seed,true);

var startTime = 0; // specify when fade starts
var delay = random(0,1); // random delay
var fadeDur = framesToTime(20); // duration of fade

linear(time, startTime + delay, startTime + delay + fadeDur, 0, 100)
```

{% endtab %}

{% tab title="v1" %}

```javascript
seed = 1;
seedRandom(seed,true);
startTime = random(0,1); // random start time
dur = framesToTime(20); // duration of fade

linear(time, startTime, startTime + dur, 0, 100)
```

{% endtab %}
{% endtabs %}

## Random Color

### RGB color

```javascript
// Apply on a color property eg. Fill, Shape Fill
seedRandom(1,true);
random([0,0,0,1],[1,1,1,1])
```

### **From a color palette**&#x20;

{% embed url="<https://youtu.be/1wrFAGKLGDk>" %}

### Sequential cycling color from a palette

```javascript
// user variables
var vel = 2 ;
var numCol = 5;

//main
var inc = Math.floor(time * vel) + index; // counter
var n = inc % numCol + 1; // keep the num between 1 & numCol value

// reference a null with colors controls only 
thisComp.layer("controls").effect(n)("Color"); 
```

1. retrieve the absolute index of a layer,
2. add a slider that increment by a value at a set interval
3. do the mod calculation

### Random cycling color from a palette

```javascript
// user variables
var mySpeed = posterizeTime(3);
var colorNull = thisComp.layer("controls"); 

// calculate num of color controls
var numFx = colorNull("ADBE Effect Parade").numProperties;
var numCol = 0;
for (i = 1; i <= numFx; i++) {
    if (colorNull.effect(i).name.includes("Color")) {
        numCol += 1;
    }
}

// main
var n = Math.ceil(random(numCol));
thisComp.layer("controls").effect(n)("Color");
```

#### Get num of color controls

{% tabs %}
{% tab title="includes" %}

```javascript
var colorNull = thisLayer("ADBE Effect Parade");
var numFx = colorNull.numProperties;
var numCol = 0;
for (i = 1; i <= numFx; i++) {
    if (thisLayer.effect(i).includes("Color")) {
        numCol += 1;
    }
}
numCol;
```

{% endtab %}

{% tab title="search" %}

```javascript
var numFx = thisLayer("ADBE Effect Parade").numProperties;
var numCol = 0;
for (i = 1; i <= numFx; i++) {
    if (thisLayer.effect(i).name.search("Color") >= 0) {
        numCol += 1;
    }
}
numCol;
```

{% endtab %}
{% endtabs %}

## Time Remapping / Playback

![](/files/-LvkAgiEDExUK4lfIkT6)

### Random frame playback

```javascript
// Source Dan Ebbert

fr = 12; // frame rate;

numFrames = 8;

seedRandom(index,true);

seg = Math.floor(time*fr);

f = Math.floor(random(numFrames));

for (i = 0; i < seg; i++)

  f = (f + Math.floor(random(1,numFrames)))%numFrames;

framesToTime(f);
```

### Random delayed/advanced layer playback

```javascript
var seed = 1;
var seedRandom(seed,true);
var myDelay = random(1,10);
var time - myDelay;
```

### Play one frame at a time (without 'float time')

```javascript
var fps = 1;
x = framesToTime(Math.round(time*fps))
//There probably is a better way but I cannot figured it out right now.
```

### Random still frame (Good for spriting)

```javascript
//Apply this to a composition with a image sequence inside
seedRandom(0,true);
t= random(0,72);
framesToTime(t);
```

* for spriting images,
* refer to CoMotion 2021 title sequence background&#x20;

## Source text & strings

### [Generating non-repeating random numbers](https://www.codegrepper.com/code-examples/javascript/generating+non+repeating+random+nubmers+in+js)

```javascript
var nums = [1,2,3,4,5,6,7,8,9,10],//all numbers to be randomized
    ranNums = [],
    i = nums.length,
    j = 0;

while (i--) {
    j = Math.floor(Math.random() * (i+1));
    ranNums.push(nums[j]);
    nums.splice(j,1);
}
ranNums
```

### Using text animators

### Binary

{% embed url="<https://youtu.be/p2r_abV9HL8>" %}

### From a specific set of characters or words

eg. Matrix katakana

## Building a Randomizing rig or preset

Core skills: randomize time, Spriting, building controls, conditional randomizing with modulo operator (alternate colors)

{% hint style="info" %}
Keep in **After Effects scripting,** the random function only returns a random number between 0 to 1. What this means is that you cannot do  use **`random(20,30)`** to generate a random value between 20 and 30. You have to write a function for that, which you can reference [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random).
{% endhint %}

## Randomizing with AE scripts

1. Download Jeff Almasol's script from aescript or redefinery
2. Install script via After Effects or putting directly into the Applications folder
3. Modify values
4. Select layers, and run script file&#x20;


# Harmonic Motion

Written on Mar 10, 2021. Last updated on ... — WIP

## Abstract

Harmonic oscillations or sine waves are commonly observed in the trends of Motion Design (as of 2021). It seems Mathematics or Trigonometry plays a significant role in art and design. This page will served to inform Motion Designers how the Math behind sine wave works and how you can use it in animation, or use to generate waves paths or shapes

#### Why does it matter?

For those who are allergic or have distaste for Mathematics or Trigonometry, I like you to refresh your understandings of how we can use these concepts to:&#x20;

1. **Make complex animations** that may be impossible or tedious to do manually
2. **See animation in terms of data and numbers.** When I see animations like this, I do not see keyframes, but rather a sine wave being modulated to create a wavy motion \[insert animation ref].

#### **Readings**

* <https://www.motionscript.com/mastering-expressions/simulation-basics-1.html>
* [Math.sin](https://www.youtube.com/watch?v=Oiiq4wmbuPo\&t=160s), Evan Abrams
* [JS Math](https://www.w3schools.com/js/js_math.asp), w3schools
* [Periodic functions](https://www.mathsisfun.com/algebra/amplitude-period-frequency-phase-shift.html), mathsisfun
* [Harmonic](http://www.jjgifford.com/expressions/geometry/harmonic.html), jjgifford

#### Text

1. Ordinary Folk
2. iLLo,
3. Flatwhite Motion
4. Gunner

## Oscillations

### Terminology

* **Crest** — maximum value of upward displacement within a cycle
* **Trough** — minimum or lowest point in a cycle.
* **Cycle** — An oscillation, or cycle, is defined as a single change from up to down to up, or as a change from positive, to negative to positive.<br>
* **Wave Length:** the distance between two successive crests (period)or troughs of a wave.
* **Wave Height:** the vertical distance between the trough of a wave and the following crest<br>
* **Amplitude —** the height from the center line to the peak (or to the trough). Or we can measure the height from highest to lowest points and divide that by 2.&#x20;
* **Frequency —** the number of occurrences of a repeating event per unit of times<br>
* **Phase** —the location or timing of a point within a wave cycle of a repetitive waveform.
* **Phase shift** —  how far the function is shifted horizontally from the usual position.
* **Radian** — a unit of measure for angles that is based on the radius of a circle. A circle has 360° or 2pi radians.&#x20;

### Sine wave

$$
A\*Math.sin(\theta + C)
$$

* **amplitude** is A
* **phase** is theta
* **phase** **shift** is C

{% hint style="info" %}
**Why do we do append "Math." before sin?**&#x20;

This is because when we are writing expressions, we are using the **Javascript language of a Math object** to perform mathematical tasks on numbers. Some examples you may have seen include Math.cos, Math.round, or Math.ceil . You can learn more about it at [w3schools](https://www.w3schools.com/js/js_math.asp).
{% endhint %}

### Cosine wave

## Practical applications

### Creating sine wave loops with varying frequency

* If you are creating a looping animation with a series of sine wave with varying frequencies, you have to determine the duration of the composition, or vice versa.
* If your waves include frequencies of 1, .5, .2. Your composition duration should be 5s or multiple of 5s, because the slowest frequency is .2. For that wave to finish one cycle, it takes 1 second / 0.2 = 5 seconds.
* Hence, it's a game of multiplication and time tables. For more complex variations such as frequency values of 0.3, 0.4, 0.5, you will have to find a common denominator (.333,2.5,2) = 10s .

## Why generate paths with expressions

* My main concerns is aliasing issues, by using shape layers, we avoid jagged edges that are present when you use wave warp effect with a high wave height.&#x20;

## Amplitude modulation

### Frequency increasing

## Fractions & for-loop in createPath

In order to generate a smooth wavy line, we have to generate many points sticking close together to maintain curvature. This is because we do not want to be concerned with writing a function to calculate the in and out tangents.

## Damped Sine Wave

![](/files/-MY_20mHZeJAk3YUMSoh)

Source: [*An Ordinary Christmas* work files](https://www.ordinaryfolk.co/play), Ordinary Folk

```javascript
S = effect("Speed")("Slider");
A = effect("Amp")("Slider"); 
F = effect("Freq")("Slider") / 3.6;
R = effect("Resolution")("Slider");
W = effect("Width")("Slider");
E = effect("Exp")("Slider") * 100;

P = [];

for (i = 0; i < R; i++) {
    x = W / R * i * Math.exp(i / E)
    y = i * Math.exp(i / E) * Math.sin((time - inPoint) * S + i / (R / F)) * A;
    P.push([x, y]);
}

createPath(P, [], [], false)
```


# Staggering

delayed sequential offset - WIP

## Abstract

Staggering animation is one of the most common technique used in Motion Design. It's good to know this technique because you need not manually copy and paste keyframes from one layer to another and offset the timing. Instead you can animate one element, and make all the other layers reference that animation with an offset timing.

### Cited sources:

[Creating Trails](http://www.motionscript.com/mastering-expressions/follow-the-leader.html), MotionScript, Dan Ebberts

## Referencing layer index & valueAtTime

Generally, when we want to stagger or offset animations in time for a series of layers, we can make use of the layers' `index` number and the `valueAtTime` property.

#### Basic setup

![](/files/-Lvuf4jS4Nc5XQANBNQg)

```javascript
// Copying animation of a layer, and start it at inPoint of layer
thisComp.layer(index+1).transform.position.valueAtTime(time-inPoint)

// Using delay
offset = 1;
thisComp.layer(index+1).transform.position.valueAtTime(time-offset)    
```

#### Referencing index animated layer

{% tabs %}
{% tab title="1" %}

```javascript
tgt = thisComp.layer("main").transform.position // target layer & prop
delay = 5; //number of frames to delay
delay*= thisComp.frameDuration*(index - 1); // convert to time

tgt.valueAtTime(time - delay)
```

{% endtab %}

{% tab title="2" %}

```javascript
// alternatively you can do it this instead

delay = framesToTime(5); //convert to time method 2
thisComp.layer(1).position.valueAtTime(time - delay)

```

{% endtab %}
{% endtabs %}

#### Cascading index referencing

```javascript
delay = 5; //number of frames to delay

d = delay*thisComp.frameDuration;
thisComp.layer(index - 1).position.valueAtTime(time - d)
```

#### Absolute index referencing&#x20;

It is always best practice to use absolute index referencing, because you do not run the risk of your animation being affected if I were to add a new layer to the composition causing all the layers' index number. The simple way to absolute reference is to:

1. Create a **Null** layer or use your **main** **animated layer**, usually named "start"
2. Make sure the layers you want to offset is **underneath this "start" layer**
3. Get the **absolute index numbe**r by subtracting the Start layer index from the layer index number
4. Now you can use that value to **calculate the delay offset**

```javascript
var startLayer = thisComp.layer("startLayer");
var myIndex = index- startLayer.index;

delay = 5; //number of frames to delay

d = delay*thisComp.frameDuration*(myIndex - 1);
thisComp.layer(1).position.valueAtTime(time - d)
```

#### Scripts

### Adding auto-orientation

```javascript
strt = 0; //start time of template motion
end = 4.0; //end time of template motion

t = thisComp.layer("template");
offset = (t.effect("offset")("Slider")/100)*(index -1);
travel = linear(t.effect("travel")("Slider")/100,strt,end);
if (travel <= offset){
  vect = t.position.velocityAtTime(0);
}else{
  vect = t.position.velocityAtTime(travel - offset);
}
lookAt(position, position + vect)
```

### Following the Null's Orientation

```javascript
strt = 0; //start time of template motion
end = 4.0; //end time of template motion

t = thisComp.layer("template");
offset = (t.effect("offset")("Slider")/100)*(index -1);
travel = linear(t.effect("travel")("Slider")/100,strt,end);

u = t.toWorldVec([1,0,0],travel - offset);
v = t.toWorldVec([0,1,0],travel - offset);
w = t.toWorldVec([0,0,1],travel - offset);

sinb = clamp(w[0],-1,1);
b = Math.asin(sinb/thisComp.pixelAspect);
cosb = Math.cos(b);
if (Math.abs(cosb) > .0005){
  c = -Math.atan2(v[0],u[0]);
  a = -Math.atan2(w[1],w[2]);
}else{
  a = Math.atan2(u[1],v[1]);
  c = 0;
}
[radiansToDegrees(a),radiansToDegrees(b),radiansToDegrees(c)]
```

#### Case studies

{% embed url="<https://youtu.be/cLr1YDdqVxg>" %}

{% embed url="<https://youtu.be/TwbDN8SX058>" %}

## Distance-based

### Omni-directional

{% embed url="<https://youtu.be/N2E29KvQXgI>" %}

```javascript
tgt = thisComp.layer("control");
// d = length(L.transform.position, transform.position);
d = length(thisLayer.toWorld(transform.anchorPoint), tgt.toWorld(tgt.transform.anchorPoint));

delay = thisComp.layer("control").effect("maxDelay")("Slider");
offset = linear(d,0,2000,0,delay);
time-offset;
```

### Radial scale up staggering

![](/files/-Lvud2TcyFlQGLkBX6FC)

{% tabs %}
{% tab title="nsc" %}

```javascript
// VARIABLES + SETUP
target = thisComp.layer("master").transform.scale; 
maxDist = 1000;
maxDelay = 1;

dst = length(transform.position,[thisComp.width/2,thisComp.height/2]);
delay = linear(dst,0,maxDist,0,maxDelay);

// EXECUTION
target.valueAtTime(time-delay)
```

{% endtab %}

{% tab title="OF" %}

```javascript
//apply to scale
target = thisComp.layer("fade");
fade = target.effect("scale")(1);
delay = target.effect("delay")(1)*thisComp.frameDuration;
dist = length(thisLayer.toWorld(thisLayer.anchorPoint), target.toWorld(target.anchorPoint));
seed = seedRandom(15, true)
randomRange = target.effect("random")("Slider");
rand = (random(-randomRange, randomRange))*thisComp.frameDuration;
offset = delay/dist;
s = fade.valueAtTime(time - offset - rand);
[s,s]
```

{% endtab %}
{% endtabs %}

### Effector opacity fade on

![](/files/-LwnI2-VTH1AOJCZ-3JC)

{% tabs %}
{% tab title="nsc" %}

```javascript
//Create a null named "EFFECTOR" 
//Add 2 Slider Control Effects renamed to "maxDist" and "delay"


// EXECUTE
target = thisComp.layer("EFFECTOR").transform
maxDist = thisComp.layer("EFFECTOR").effect("maxDist")("Slider");
maxDelay = thisComp.layer("EFFECTOR").effect("delay")("Slider");

dst = length(transform.position, target.position);
delay = linear(dst, 0, maxDist, 0, maxDelay);

// EXECUTION
target.opacity.valueAtTime(time - delay)
```

{% endtab %}
{% endtabs %}

### Double directional

This allow you to row by row staggering by separating the dimensions for measuring distances.

```javascript
//user variables 
tgt = thisComp.layer("control");
delayX = 1;
delayY = 2;
distanceX = 1920;
distanceY = 400;

// logic
d1 = length(tgt.toWorld(tgt.transform.anchorPoint)[0],transform.position[0])
d2 = length(tgt.toWorld(tgt.transform.anchorPoint)[1],transform.position[1])
offsetx = linear(d1,0,distanceX,0,delayX);
offsety = linear(d2,0,distanceY,0,delayY);

//main
time-offsetx-offsety
```


# Tessellation & Tiling

Last update: 8 April 2021

## Tessellation

### Rectangular

```javascript
//Create a null layer at the top named "Start Tiles" with a Slider effect "Columns", 
//and one at the bottom named "End Tiles"

// For Position:
var controlLayer = thisComp.layer("Start Tiles");
var numColumns = Math.floor(thisComp.layer("Start Tiles").effect("Columns")("Slider").value);
var tileIndex = index - controlLayer.index-1;
var columnIndex = tileIndex%numColumns;
var rowIndex = Math.floor(tileIndex/numColumns);
var columnWidth = thisComp.width/numColumns;
var firstTile = thisComp.layer(controlLayer.index+1);
var rowHeight = firstTile.height/firstTile.width*columnWidth;
var xPos = columnWidth*(columnIndex+.5);
var yPos = rowHeight*(rowIndex+.5);[xPos, yPos];

// For Scale:
var controlLayer = thisComp.layer("Start Tiles");
var numColumns = Math.floor(thisComp.layer("Start Tiles").effect("Columns")("Slider").value);
var columnWidth = thisComp.width/numColumns;
var firstTile = thisComp.layer(controlLayer.index+1);
var rowHeight = firstTile.width/firstTile.height*columnWidth;
var xyScale = columnWidth/width*100;[xyScale, xyScale]
```

### Hexagonal

$$
height-to-width\ ratio\ of \ regular \  hexagon= 1:1.1547005
$$

```javascript
// POSITION Setup     
var controlLayer = thisComp.layer("Start Tile");    
var numColumns = Math.floor(thisComp.layer("Start Tile").effect("Columns")("Slider").value);    var Mmargins = Math.floor(thisComp.layer("Start Tile").effect("Margins")("Slider").value);    var myWidthRatio = thisComp.layer("Start Tile").effect("Height Adjustment")("Slider");    var myZPos = thisComp.layer("Start Tile").effect("Z-Pos Adjustment")("Slider");    var mySeed = thisComp.layer("Start Tile").effect("Seed")("Slider");    // Indexing     var tileIndex = index - controlLayer.index-1;    var columnIndex = tileIndex%numColumns;    var rowIndex = Math.floor(tileIndex/numColumns);    if (rowIndex % 2 == 0) {var oddEven = 1;}else{oddEven=0;}    // Z-Positioning     seedRandom(index+mySeed, true);    var zPos = random(-myZPos,myZPos);    

// Positioning     
var columnWidth = thisComp.width/numColumns ;    
var firstTile = thisComp.layer(controlLayer.index+1);    
var rowHeight = firstTile.height/firstTile.width*columnWidth;    
var xPos = columnWidth*(columnIndex+.5);    
var yPos = rowHeight*(rowIndex+.5);    
[xPos +oddEven*columnWidth/2, yPos*myWidthRatio,zPos];


// 
// SCALE Setup
var controlLayer = thisComp.layer("Start Tile");    
var numColumns = Math.floor(thisComp.layer("Start Tile").effect("Columns")("Slider").value);    
var myScaleRatio = thisComp.layer("Start Tile").effect("Scale Adjustment")("Slider");        

// Indexing     
var columnWidth = thisComp.width/numColumns ;    
var firstTile = thisComp.layer(controlLayer.index+1);    
var rowHeight = firstTile.width/firstTile.height*columnWidth;        


//Scaling     
var xyScale = columnWidth/width*100;    
[xyScale, xyScale]*myScaleRatio;
```

## Layer slider with responsive positioning

![](/files/-LwFgULsXXuEu4IUOpX0)

**Parameters:**

1. **Layer can be aligned in x-axis with adjustable even space in-between**&#x20;
   1. For that to happen, the anchor points of the layers must be centered
   2. This **prevents inconsistent opacity** for the layers on both sides
2. If a layer scale changes, the spacing should change accordingly
3. Create a control that just change the active "tile";

#### Tiling formula

$$
(target.width/2-space)-(active.width/2)
$$

{% tabs %}
{% tab title="One direction" %}
{% code title="" %}

```javascript
//POSITION

// VARIABLES	
space = 0;
dir = 1; // 1 for tile right, -1 to tile left
axisX = 1; // 1 to turn on, 0 to turn off
axisY = 0; //1 to turn on, 0 to turn off

// SETUP
target = thisComp.layer(index + dir)
tpos = target.transform.position;
tscale = target.transform.scale[0] / 100;
tSrc = thisComp.layer(index + dir).sourceRectAtTime().width / 2 * tscale
tSrcY = thisComp.layer(index + dir).sourceRectAtTime().height / 2 * tscale

s = sourceRectAtTime();
activeWidth = s.width / 2 * transform.scale[0] / 100
activeHeight = s.height / 2 * transform.scale[0] / 100


// EXECUTION: Center position to left of target layer, offset the width, + spacing
tpos += [(activeWidth + tSrc + space) * axisX, (activeHeight + tSrcY + space) * axisY] * dir; 


// OPACITY

minOpacity = 0;
maxDist = thisComp.width/2;

v = transform.position[0] // Get x position
d = Math.abs(length(v, thisComp.width / 2)); // Get distance between layers

ease(d, 0, maxDist, 100, minOpacity)
```

{% endcode %}
{% endtab %}

{% tab title="Two Directions" %}

```javascript
// VARIABLE
space = thisComp.layer("CONTROL").effect("step")("Slider");
center = thisComp.layer("Center");

// SETUP
dir = -1; // Direction for Right 
if (index < center.index) {
    dir = 1;
} // Direction Left if below Center Layer

target = thisComp.layer(index + dir)
tpos = target.transform.position;
tscale = target.transform.scale[0] / 100;
tSrc = thisComp.layer(index + dir).sourceRectAtTime().width / 2 * tscale

s = sourceRectAtTime();
activeWidth = s.width / 2 * transform.scale[0] / 100

// EXECUTE
tpos += [tSrc * dir, 0]; // // Center position to left of target layer 
tpos += [activeWidth * dir, 0] //// Offset the width 
tpos += [space * dir, 0] //add spacing
```

{% endtab %}
{% endtabs %}


# Type animators

{% embed url="<https://youtu.be/AHF_KSMTuIY>" %}


# Speed lines

WIP

## CC Particle World

### Lines

### Sprites

## Trapcode Particular&#x20;

### Flat lines

## &#x20;Custom expression rig&#x20;

##

###


# Radial Array

Tunnel, zoom, iris - WIP

## Explosion

### Using a normalized range

When using random function for a range, we generally use random(75,400). This works but if we want to upscale the setup, we would need to change both numbers. An alternative is to use a normalize range to multiply a base size eg. random(0.5,1) \* 400 will yield a value between 200, to 400. We can still maintain that ratio even if we change&#x20;

### Base setup&#x20;

$$
random(Radius)\*Math.sin(random(theta)+random(force)
$$

```javascript
var seed = thisComp.layer("controls").effect("seed")("Slider");
seedRandom(seed, true);

var mass = random(thisComp.layer("controls").effect("mass")("Slider"));
var a = thisComp.layer("controls").effect("angle")("Slider");
var r = thisComp.layer("controls").effect("radius")("Slider");

r *= random(0.5, 1); // randomize radius
r += (random(.5, 1) * mass); // add random force
var myAngle = random(360);

var theta = degreesToRadians(myAngle);
var x = r * Math.cos(theta);
var y = r * Math.sin(theta);

[x, y] + [thisComp.width, thisComp.height] / 2
```


# Orb & Trails

WIP

* Welcome to the Age of No-code, 2019 08 13
*


# Shading & Texturing

WIP

## Hand-drawin

### Boil effect

#### Posterize Time

#### Turbulent Displace

#### 3rd-party effects

* Shade it, EyeDesyn — $15
* Flexible noise gradient, Gareso — free

## Gradient&#x20;

### Pearlescent

#### Examples

* Age of no code
* TED-ED, Artificial intelligence,Champ
* COVID-19, The Furrow

### Grain

* [**Planets Orbiting Motion Graphic Tutorial in After Effects,**](https://www.youtube.com/watch?v=5uFcdU8-NTo) **AeMachine**

## Metal

### Gold

### Irisdescent

## **Faux 3D**

* **layer styles**
* Using 3D objects but 2D gradients
* **Glass**
  * glassmorphism
* **Crystal**
* Handdrawn
  * Grainy shading&#x20;
* **Abstract**&#x20;
  * painterly

## Hybrid

{% embed url="<https://www.instagram.com/p/CNYZ7h8H571/?igshid=dphzdilaomep>" %}


# Responsive

### Carousel / Rotating layers&#x20;

![](/files/-LvfBiUXsAJ1IE2haa_y)

```javascript
/*  There needs to be two layers named 'startCard' & 'endCard'
    This allows rotation value to dynamically change when layers are inserted or removed.
    All duplicates need to be placed within these two layers
*/

//anchor point
radius = 500
value+[0,0,radius]

// Y rotation

startIndex=thisComp.layer("startCard").index; 
endIndex = thisComp.layer("endCard").index;
numpt = startIndex-endIndex+1; // total number of layers
myIndex = index-startIndex;
angle = 360/numpt

myIndex*angle
```

#### Linking layers' rotation with opacity

![](/files/-LvfB_ueezf9KXCBgUob)

{% tabs %}
{% tab title="Using distance & vector position" %}

```javascript
// Make sure there is a camera 

//Opacity
startVal = 0;
endVal = 100;
fadeAngle = 180;

v = toCompVec([0,0,1]); // layer position to comp position in Z
d = length(toWorld(anchorPoint),thisComp.layer("Camera 1").toWorld([0,0,0]));
c = v[2]/d;
ease(c,Math.cos(degreesToRadians(fadeAngle)),1.0,startVal,endVal)

```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="using rotation" %}

```javascript
angle = transform.yRotation%360;
minAngle = 0;
maxAngle = 360;
mid = (maxAngle+minAngle)/2;
if (angle < mid)
  linear(angle,minAngle,mid,100,0)
else
  linear(angle,mid,maxAngle,0,100)
```

{% endtab %}
{% endtabs %}

## Challenge: creating user-friendly controls

* Writing expressions can be easy for you but it's a complete foreign language to other people. If you pass an expression setup to your team mates, there are chances they do not know how to operate it, modify or troubleshoot or their own.
* The best practice is to create everything they need in the Effects panel without them having to change any expressions.
* Subsequently, more functionalities can be added as the user realize the limitations of your setup.

## Importance of converting to world space

* sourceRectAtTime only reads the source size and any scale change is not applied. Hence to get the correct pixel size of a layer, this is the general formula&#x20;

$$
sourceRectAtTime().width\*transform.scale\[0]/100
$$

## Responsive sizing text box

* Uses: Lower thirds, quotation boxes

### Method

1. Get `sourceRectAtTime` of source text layer
2. Create `Slider Controls` for X & Y padding&#x20;

### Attaching layers to corners of a quote box

![Quotation marks attached to the corners of the text box](/files/-Mf2yJLsQ8_GRAi1DxJ4)

#### Method 1: Arithmetic&#x20;

1. Get the size of the text layer using sourceRectAtTime
2. Link the position of the layer to the text position
3. Subtract or add half the size of the quotation box to get the top or bottom corner

```javascript
s = thisComp.layer("text").sourceRectAtTime();
mySize = [s.width,s.height]/2 
thisComp.layer("text").transform.position + mySize // bottom corner
```

**Method 2: Converting sourceRectAtTime to World Space**

```javascript
s = thisComp.layer("text").sourceRectAtTime();
topLeft = [s.left,s.top]; // top left corner
botRight = topLeft+ [s.width,s.height]; // bottom right corner
thisComp.layer("text").toWorld(botRight) // change variable name to switch corners
```

#### Implementation

![Retrieving all sourceRectAtTime values using animation preset](/files/-Mf3--VVIiOnwNr2GhCR)

Personally, I like to **retrieve all property values and coordinates and do any necessary calculations into slider controls in a single shape layer or null control.** This way, I can just link other parameters to that one layer. The example above, I have saved all slider controls into an animation preset so I can reuse my setup without having to rewrite the expressions

### 2-liner with conditional sizing (left-aligned text)

```javascript
// null layer "controls"
    // 1. Create 2 layer controls and select text layers;
    // 2. Create 3 point controls: "heightWidth","heightWidthWithPad", "padding"


// "heightWidth" point control expression
t = effect("Layer Control")("Layer").sourceRectAtTime();
t2 = effect("Layer Control 2")("Layer").sourceRectAtTime(time - 1);
y = 50; // height of textbox 

t.width < t2.width ? [t2.width, y] : [t.width, y]

// "heightWidthWithPad" point control expression
effect("heightWidth")("Point") + effect("padding")("Point")


// Rectangle shape layer "textbox"
    // SIZE 
    thisComp.layer("controls").effect("heightWidthWithPad")("Point")

    // LAYER ANCHOR POINT
    s = sourceRectAtTime();
    [s.left,s.top] // left align
    [s.width/2,0]; // right align,right align your text layers in the paragraph panel & reposition everything as needed.


// Line 1 text justification
//Put a "Tracking" parameter text animator onto your text layer with this expression
padding = thisComp.layer("controls").effect("padding")("Point")[0];
numChar = text.sourceText.length;
padding/numChar;

// This will justify your line 1 to the textbox, provided that line 2 is shorter

```

## Shape follows typewriter

* Attach a shape layer to the end of  a type writer Text Animator on Text layer
* Or basically,  the shape always follows at the end if the written text for it to look like that shape is typing the text on screen?

The challenge is that: **sourceRectAtTime do not recognize the size change with Text Animator** that is effecting the typewriting.&#x20;

The solution is to&#x20;

* get the position of the text in world space
* the sourceRectAtTime width
* adding a padding&#x20;

$$
linear(completion,0,100, startPos,startPos+sourceRectAtTime.width
$$


# Automation

## Spreadsheet to text layers&#x20;

* Refer to CoMotion 2021 title sequence

## Spreadsheet to compositions

{% embed url="<https://youtu.be/ZQlgxDSBZwk>" %}

## Normalize width of layers

$$
nominalValue/width\*100
$$

```javascript
nominal = 100
offset = 900; // connect to slider control
threshold = 0;
//
swidth = thisLayer.sourceRectAtTime().width;
svalue = nominal/swidth;*

// conditional 
if(swidth>threshold){
    [svalue,svalue,svalue]*offset
}

```

```javascript
logo=thisLayer.source.layer(thisLayer.source.numLayers);
sHeight=height/logo.height;
sWidth=width/logo.width;
s=Math.min(sHeight,sWidth);
value*s
```

### [**Normalizing image/logo sizes** ](https://forums.creativecow.net/docs/forums/post.php?forumid=227\&postid=22667\&univpostid=22667\&pview=t)**based on sampling alpha**

$$
normalizedScale = value\*(nominalValue/width)
$$

{% tabs %}
{% tab title="width" %}

```javascript
nominalWidth = 200;
leftEdge = 0;

for (i = 0; i <= width; i++){
  temp = sampleImage([i,height/2],[0.5,height/2],true,time);
  if (temp[3] > 0){
    leftEdge = i;
    break;
  }
}

rightEdge = width-1;

for (i = width-1; i >= 0; i--){
  temp = sampleImage([i,height/2],[0.5,height/2],true,time);
  if (temp[3] > 0){
    rightEdge = i;
    break;
  }
}
value*nominalWidth/(rightEdge-leftEdge+1)
// cacheCompareSamplesPerSecond 0
```

{% endtab %}

{% tab title="height" %}

```javascript
nominalHeight = 200;
topEdge = 0;
for (i = 0; i <= height; i++){
  temp = sampleImage([width/2,i],[width/2,0.5],true,time);
  if (temp[3] > 0){
    topEdge = i;
    break;
  }
}
bottomEdge = height-1;
for (i = height-1; i >= 0; i--){
  temp = sampleImage([width/2,i],[width/2,0.5],true,time);
  if (temp[3] > 0){
    bottomEdge = i;
    break;
  }
}

alphaheight = (bottomEdge-topEdge+1); // in pixels 
value*nominalHeight/alphaheight*100/value[1]
```

{% endtab %}

{% tab title="ratio" %}

```javascript
// for logos that are symmetrical
//nominal values;
n1 = 200;
n2 = 400;
n3 = 800;

topEdge = 0;
for (i = 0; i <= height; i++){
  temp = sampleImage([width/2,i],[width/2,0.5],true,time);
  if (temp[3] > 0){
    topEdge = i;
    break;
  }
}

leftEdge = 0;

for (i = 0; i <= width; i++){
  temp = sampleImage([i,height/2],[0.5,height/2],true,time);
  if (temp[3] > 0){
    leftEdge = i;
    break;
  }
}
=
aRatio = leftEdge/topHeight;
if(aRatio<1.1){value*n1/leftEfge
```

{% endtab %}
{% endtabs %}

[**Expressions comment to prevent calculations on every frame**](https://forums.creativecow.net/docs/forums/post.php?forumid=227\&postid=35023\&univpostid=35023\&pview=t)

[**https://aescripts.com/auto-crop/**](https://aescripts.com/auto-crop/)


# Setup & Rigs

## 🛠 Toolkit or rigs setup Best Practices

![](/files/-M_a3T4LpoWVBMuvTpw2)

**Objective:** Make the toolkit as **fool-proof** as possible by using proper naming conventions, labeling compositions & layers, write my a readme instructions, making a video tutorial, and master properties arrangement. Fool-proof = intuitive , simplicity, coherent.

Give enough user controls that effectively does the job and not confuse or overwhelm users. AKA "less is more"

#### **Naming conventions**

* use **camelCase** and **underscore** (no spaces) for comp or layer names
* File structure: `_demo`, `builds`, `elements`
* for rig compositions, rename to `build_num` eg. build\_4
* in the comments, you can write a brief description of what the rig do

### L**abeling of layers and compositions**

* `green label` - for compositions / layers that users should modify or use
* `blue label` - secondary stuff for your own development purposes or for users to troubleshoot or their own
* `gray label` for anything that the user should not touch

!["readme" sample from plant rigs](/files/-M_a3ZSlQCGporZAx1zm)

### **Writing a user guide or readme**

* in a composition, write a description of what your rig does and instructions on how to use it
* this should be the f**irst composition user see when they open the AEP**

### **Cleaning the project file before delivery 🧹**

* be sure to remove any unused assets that may otherwise confuse the users by using `Reduce Project` or `Collect Project Files`
* close all compositions that will not be use, open all compositions that will be used

### **Other good practice**

* render animated elements used (eg. textures)
* create `demos` or samples of what your toolkit can do to let users know the extent of your setup
* avoid 3rd-party plugins that would be difficult for user to acquire

### **Essential Graphics**

* Create two groups: `design` and `motion`
* the design controls should change the stylization or look; there should not be any keyframes
* as for `motion`, anything that effects a movement for the rig will go here eg. wiggle sliders, duration,

### For users

* communicate bugs or error report

### For Leads checking toolkits

* test if all controls work and `Master Properties` are nested in the composition
* making it simpler to use and lighter to render; keep in mind that users may not be as proficient in AE or expressions. It is
* naming convention

## Spriting / multi-image texturing

### Using string matching&#x20;

{% tabs %}
{% tab title="2020" %}

```javascript
// timeRemapping
var src = thisLayer.source;
var txt = thisComp.layer("file").text.sourceText.toLowerCase();

// loop match
for (i = 1; i < src.numLayers; i++) {
    if (src.layer(i).name.toLowerCase().match(txt)) {
        myLayer = src.layer(i);
        break;
    } else {
        9999 // catch error
    }
}

inP = myLayer.inPoint;
outP = myLayer.outPoint-framesToTime(0);
dur = outP - inP;
linear(time,inPoint,dur,inP,outP)
```

{% endtab %}

{% tab title="2019" %}

```javascript
//timeRemap
framesToTime(effect("frameSelect")("Slider"));


// Slidercontrol
myComp = thisLayer.source;
ext = ""//.png
txt = thisComp.layer("lastName").text.sourceText.toLowerCase();

// loop match
for (i = 1; i < myComp.numLayers; i++) {
    if (myComp.layer(i).name.toLowerCase().match(txt)) {
        i-1 // -1 as time starts from 0 ;
        break;
    } else {
        100 // catch error 
    }
}
```

{% endtab %}
{% endtabs %}

### Text layer as a check

```javascript
t = timeToFrames(time);
t = clamp(t,1,index-1);
thisComp.layer(t+1).name;
```


# Getting started with Scripting

WIP

## Recommended readings

### Learning Javascript

* JavaScript: The Definitive Guide by David Flanagan (Just read the parts about coding; not web dev)

### References

* [**AE Scripting Guide**](http://docs.aenhancers.com/)
* <https://estk.aenhancers.com/index.html> (Contains ScriptUI documentation)
* **ScriptUI**
  * [Interactive Dialog Builder](https://scriptui.joonas.me/)
  * [Peter Kahrel's ScriptUI documentation](http://www.kahrel.plus.com/indesign/scriptui.html) (recommended)
  * [Adobe Javascript Tools Guide](https://forums.adobe.com/external-link.jspa?url=https%3A%2F%2Fwww.google.co.uk%2Furl%3Fsa%3Dt%26rct%3Dj%26q%3D%26esrc%3Ds%26source%3Dweb%26cd%3D1%26cad%3Drja%26ved%3D0CC8QFjAA%26url%3Dhttp%253A%252F%252Fwwwimages.adobe.com%252Fwww.adobe.com%252Fcontent%252Fdam%252FAdobe%252Fen%252Fproducts%252Findesign%252Fpdfs%252FJavaScriptToolsGuide_CS5.pdf%26ei%3D84vEUdipCdPv0gX064DYCQ%26usg%3DAFQjCNHopvf5agDw1OgtcvbB61RRF_ucOA%26sig2%3Dz0r1T-MYoBSpXgdejliHSQ%26bvm%3Dbv.48293060%2Cd.d2k) (not as good, but official)
  * **Two ways to browse the object structure to see what exists:**
    * Use the generated web pages at <http://jongware.mit.edu>/, eg.
      * ScriptUI - <http://jongware.mit.edu/scriptuihtml/Sui/index_1.html>
      * Illustrator (CS6) - <http://jongware.mit.edu/iljscs6html/iljscs6/>
      * InDesign (CS6) - <http://jongware.mit.edu/idcs6js>
      * Photoshop (CS5) -[ http://jongware.mit.edu/pscs5js\_html/psjscs5/](< http://jongware.mit.edu/pscs5js_html/psjscs5/>)
    * **Open up the Adobe Extendscript Toolkit** (ESTK, on a Mac it's in Applications > Utilities > Adobe Utilities...), then open Help > Object Model Viewer, choosing "ScriptUI classes" from the top left drop down menu.Or look at the Javascript Tools Guide, + the Intro to Scripting guide in the help menu
  * **Notes**

    For a script to be dockable, you must install the scripts into the ScriptUI folder, and you must invoke it from the Window menu. Then it will open as a panel, and you can drag and drop it into the UI as you would any other panel.

### Training&#x20;

* [FXPHD AFX210 Introduction to After Effects Scripting ](https://www.fxphd.com/details/196/)— highly recommended for beginners
* [FXPHD AFX226: Scripting in After Effects](https://www.fxphd.com/details/516/), MATHIAS MÖHL
* [FXPHD AFX303 Advanced Scripting for After Effects, Part 1](https://www.fxphd.com/details/539/), Feb 2017
* [FXPHD AFX304 Advanced Scripting for After Effects, Part 2](https://www.fxphd.com/details/541/) , Feb 2017
* [ExtendScript Script Writing Training, David Torno](https://www.provideocoalition.com/after-effects-extendscript-training-complete-series/)

### Others

* [After Effects Menu Command IDs](https://www.provideocoalition.com/after-effects-menu-command-ids/)
* <http://www.redefinery.com/index.php>
* [The Coding Train ](https://www.youtube.com/user/shiffman)by Daniel Shiffman

### More resource list

* [ NoSleepCreative motion design coding resources](https://papaly.com/duitbetter/9kjal/motion-code)
* <https://zacklovatt.com/ae-scripting-resources>

## FAQs

### What are some recommended scripts to use?

| Type | Scripts                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Free | <p></p><ul><li><a href="https://www.videocopilot.net/blog/2018/05/fx-console-updated-to-v1-0-3/">FX Console</a></li><li><a href="https://aescripts.com/ease-and-wizz/">Ease & Whizz</a></li><li><a href="https://aescripts.com/label-maker/">Laber Maker</a></li><li><a href="https://aescripts.com/project-cleaner/">Project Cleaner</a></li><li><a href="https://www.battleaxe.co/downloads">Buttcapper</a></li><li><a href="https://aescripts.com/repositionanchorpoint/">RepositionAnchorPoint</a></li><li>EaseCopy</li><li>Saber</li></ul> |
| Paid | <p></p><ul><li>Flow</li><li>Ray Dynamic Color</li><li>Ray Dynamic Texture</li><li>Overlord</li><li>Gifgun</li><li>Kbar or Quick Menu</li></ul>                                                                                                                                                                                                                                                                                                                                                                                                  |

### Why should I learn scripting?

### I know how to use expressions but how to get to the next level?

I usually recommend people to watch FXPhd training on Introduction to After Effects Scripting. From there on, you should be confident enough to pave your own path; yes it is that magical.

### How do I learn automation?

Automation is a concept; there is no standard technique. You need to have the foundations of coding and scripting to create your automation workflow.


# Scripting

Here you will find javascript snippets  that  performs one certain small task for learning and application

## Recommended Readings

**Repositories**

* [**Kbar Scriplet Github**](https://gist.github.com/search?p=5\&q=%23KBar+%23AfterEffects\&ref=searchresults\&utf8=%E2%9C%93)
* [**Redefinery Scripting Fundamentals**](http://www.redefinery.com/ae/fundamentals/)
* [**http://www.motionscript.com/ae-scripting/pre-comp-to-layer-dur.html**](http://www.motionscript.com/ae-scripting/pre-comp-to-layer-dur.html)

### **Functions**

```javascript
//String
indexOf() // gets index of character
split("delimiter") // Split a string into an array of substrings:
length //Return the number of characters in a string
match // Search a string for "ain":
slice() // remove characters from front

// Arrays 
splice() // add elementsto array
toString() // convert to string 

//REGEX
\t // tab
\n // line
\r // carriage return
\s // whitespace


Ref: https://www.w3schools.com/jsref/jsref_replace.asp
```

## Useful Extendscript references&#x20;

| Item                            | Code                                                              |
| ------------------------------- | ----------------------------------------------------------------- |
| **Alert**                       | alert("This is an alert")                                         |
| **Select**                      | openDialog("Please select files")                                 |
| **Open file**                   | var spreadsheet = File("/Users/ddu/Desktop/spreadsheet.csv");     |
| **Open (Prompt)**               | var spreadsheet = File.openDialog("Please select .csv file");     |
| **Read**                        | var readOK = spreadsheet.open("r");                               |
| **Prompt (with default value)** | var value = prompt("What is the value", 10," This is the title"); |
|                                 |                                                                   |

## Basics

```javascript
// Selection
var proj = app.project;
var myComp = app.project.activeItem; // or use "comp"
var myLayers = myComp.selectedLayers;


// Setting values 
~.property("Position").setValue([120,120]);

// making guide layers
.guideLayer = true;

// adding expressions
var exp = "string of expression";
~.transform.position.expression =exp;
```

## How to use Menu Commands

```javascript
// Using ID number
var inMenuID = 2000;
app.executeCommand(inMenuID);


// Using name
app.executeCommand(app.findMenuCommandId("New Project"));
```

## [Adding](https://ae-scripting.docsforadobe.dev/layers/layercollection/?highlight=addnull)

```javascript
//solid
app.project.item(index).layers.addSolid(color, name, width, height, pixelAspect[, duration])

//null
myNull = app.project.activeItem.layers.addNull(); 


```

### Solid Layer

{% tabs %}
{% tab title="black" %}

```javascript
// Black Solid at Comp size

myComp = app.project.activeItem;
mySolid = myComp.layers.addSolid([0,0,0], "Solid", myComp.width, myComp.height,1);
```

{% endtab %}

{% tab title="comp color" %}

```javascript
// Create solid named background with composition background color

comp_bg = app.project.activeItem.bgColor;
myComp = app.project.activeItem;
mySolid = myComp.layers.addSolid(comp_bg, "BG", myComp.width, myComp.height,1);

```

{% endtab %}

{% tab title="ramp" %}

```javascript
//Create solid named background with a ramp effect

myComp = app.project.activeItem;
app.beginUndoGroup("Add Ramp")
mySolid = myComp.layers.addSolid([0,.8,.4], "BG", myComp.width, myComp.height,1);
mySolid.startTime = 0
myEffect = mySolid.property("Effects").addProperty("Ramp");app.endUndoGroup();
```

{% endtab %}

{% tab title="check error" %}

```javascript
{
	var activeItem = app.project.activeItem;

	if (activeItem == null || !(activeItem instanceof CompItem)) {
		alert("Select a comp before running this script");
	} else {
		// create a red, comp-sized solid layer.
		theSolid = activeItem.layers.addSolid([1,0,0],"Solid Layer", activeItem.width, activeItem.height, 1);

		// find the solid's color array values.
		c = theSolid.source.mainSource.color;

		alert("Created a new solid with color values [" + c[0] + "," + c[1] + "," + c[2] + "]");
	}
}
```

{% endtab %}
{% endtabs %}

### Adjustment Layer

```javascript
// Add Adjustment Layer with Effect.jsx
try{
    var adjLayer = app.project.activeItem.layers.addSolid([0,0,0], "Adjustment Layer", app.project.activeItem.width, app.project.activeItem.height, app.project.activeItem.pixelAspect, app.project.activeItem.duration);
    adjLayer.adjustmentLayer = true;
    adjLayer.effect.addProperty("Curves"); 
    }
catch (e) {
    alert (e);
    }
```

### Text layer

```javascript
app.project.activeItem.layers.addText('sourceText')
myText.property("Source Text").expression = " thisComp.name + \" (\" + (1 + (time/thisComp.frameDuration)) + \")\"  "; //add expression
myText.property("Position").setValue([172, 644]); //set position to lower right corner

//using an array
var content = ['text','text','text'] // read content
for(var i=0; i < content.length; i++){
    app.project.activeItem.layers.addText(content[i]);
}

```

More details:<http://docs.aenhancers.com/layers/textlayer/#textlayer>

### Shape layer&#x20;

```javascript
myComp = app.project.activeItem;
myColor = [0,128,255]; // How to set hex code though? Attached to a global fill?

// Create shape layer
var myShapeLayer = myComp.layers.addShape();
myShapeLayer.name = ("minRect");

// Create shape layer & shape (Ellipse, Rect,)
var shapeGroup = myShapeLayer.property("Contents").addProperty("ADBE Vector Group");
var myRect = shapeGroup.property("Contents").addProperty("ADBE Vector Shape - Rect"); //
myRect.property("Size").setValue([300,100]);

// Create stroke properties
var myStroke = shapeGroup.property("Contents").addProperty("ADBE Vector Graphic - Stroke");
myStroke.property("Color").setValue(myColor);
myStroke.property("Opacity").setValue([100]);
myStroke.property("Stroke Width").setValue([2]);


// Create fill
var myFill = shapeGroup.property("Contents").addProperty("ADBE Vector Graphic - Fill");
myFill.property("Color").setValue(myColor);
myFill.property("Opacity").setValue([100]);
var myRepeater = shapeGroup.property("Contents").addProperty("ADBE Vector Filter - Repeater");

// Source: https://forums.creativecow.net/docs/forums/post.php?forumid=227&postid=28156&univpostid=28156&pview=t
```

### Creating a hyperlink&#x20;

```javascript
// Source: https://stackoverflow.com/questions/17665920/open-web-page-in-after-effects-with-extendscript

// checking that the script can access the network:

if (app.preferences.getPrefAsLong("Main Pref Section", "Pref_SCRIPTING_FILE_NETWORK_SECURITY") != 1) {
    alert("Please tick the \"Allow Scripts to Write Files and Access Network\" checkbox if Preferences > General");

    // Then open Preferences > General to let people tick the checkbox
    app.executeCommand(2359);

    // Here you should check again if they ticked it, and choose to continue or stop ...
}
// checking of the OS:

var os = system.osName;
if (!os.length) {
    // I never remember which one is available, but I think $.os always is, you'll have to check
    os = $.os;
}
app_os = (os.indexOf("Win") != -1) ? "Win" : "Mac"

//os-dependent system calls:

var url = "http://aescripts.com";

if (app_os == "Win") {
    system.callSystem("explorer " + url);
} else {
    system.callSystem("open " + url);
}
```

## Folder creation

{% tabs %}
{% tab title="basics" %}

```javascript
//create a single folder
 app.project.items.addFolder("foldername);
 
 // create a folder set
var topFolder = app.project.items.addFolder("Top Level");
topFolder.parentFolder = app.project.rootFolder;
var subFolder = app.project.items.addFolder("Sub Level");
subFolder.parentFolder = topFolder;


// number of items in project panel
app.project.items.length
```

{% endtab %}

{% tab title="parentFolders" %}

```javascript
// Put comma between folder names & NO space between
var str = "output,main_comps,precomps,assets,reference";
var arr = str.split(",");

//Create parent folders
for (i = 0; i < arr.length; i++) {
    app.project.items.addFolder("0" + i + "_" + arr[i].toString().toUpperCase());
}
```

{% endtab %}

{% tab title="createChildFolder" %}

```javascript
// Put comma between folder names & NO space between
var str = "output,main_comps,precomps,assets,reference";
var arr = str.split(",");

//Create parent folders
for (i = 0; i < arr.length; i++) {
    app.project.items.addFolder("0" + i + "_" + arr[i].toString().toUpperCase());
}
app.project.items.addFolder("Ω MESSY");

// Create subfolders using loop
var subfoldersStr = "a_LOGO,b_PHOTOGRAPHY,c_FOOTAGE,d_MOVS,e_TEXTURES,f_AUDIO"
var subfoldersArr = subfoldersStr.split(",");
for (i = 0; i < subfoldersArr.length; i++) {
    var assetSub = app.project.items.addFolder(subfoldersArr[i].toString());
    assetSub.parentFolder = app.project.item(4);
}

```

{% endtab %}
{% endtabs %}

## Instance of

```javascript
for (var i=0; i<proj.selection.length; i++)
{
    if (proj.selection[i] instanceof CompItem)
        comps[comps.length] = proj.selection[i];
}
```

## Check if

### [Check if Layer Has Specific Effect Applied To It](https://community.adobe.com/t5/after-effects/check-if-layer-has-specific-effect-applied-to-it/td-p/10116580?page=1)

```javascript
var myLayer = app.project.activeItem.layer(1);
var hasEffect = false;

for (var i = 1; i <= myLayer.property("Effects").numProperties; i++) {
    if (myLayer.property("Effects").property(i).matchName == "ADBE Tile") {
        alert("It does!");
        hasEffect = true;
        break;
    }
}

if (!hasEffect) {
    myLayer.property("Effects").addProperty("ADBE Tile");
}
```

## Limitations

### indexOf()

```javascript
IndexOf is a string function and doesn't work with arrays anywhere.


//Source: https://forums.creativecow.net/docs/forums/post.php?forumid=227&postid=37977&univpostid=37977&pview=t
```

## Removing

### Effects property group \[[1](https://aenhancers.com/viewtopic.php?t=1897)]

{% tabs %}
{% tab title="comp" %}

```javascript
// removes ALL effects from ALL the layers in active composition

var myComp = app.project.activeItem;
var myEffects;

function removeCompFx(){
  for (var i = 1; i <= myComp.numLayers; i++){
    try{
      myEffects = myComp.layer(i).Effects;
      for (j = myEffects.numProperties; j > 0; j--){
        myEffects.property(j).remove();
      }
    }catch(err){
    }
  }
}

app.beginUndoGroup("removeFx");
removeCompFx();
```

{% endtab %}

{% tab title="selected layers" %}

```javascript
// removes ALL effects from SELECTED layers in active composition

var myComp = app.project.activeItem;
var mySelectedLayers = myComp.selectedLayers;
var myEffects;

function removeSelectedLayersFx(){
  for (var i = 0; i < mySelectedLayers.length; i++){
    try{
      myEffects = mySelectedLayers[i].Effects;
      for (j = myEffects.numProperties; j > 0; j--){
        myEffects.property(j).remove();
      }
    }catch(err){
    }
  }
}

app.beginUndoGroup("removeFx");
removeSelectedLayersFx();
```

{% endtab %}
{% endtabs %}

### Expressions

```javascript
```

## Randomize \[[1](https://www.aenhancers.com/viewtopic.php?t=1082#top)]

### Position

```javascript

//Distributes layers in 2D space within comp size
var thisComp = app.project.activeItem;
var myLayers = thisComp.selectedLayers;
var x = thisComp.width;
var y = thisComp.height;
var randX,randY;

function getRndNum(min, max) {
  return Math.random() * (max - min) + min;
}
for(i=0; i<myLayers.length; i++){
  randX = getRndNum(0,x);
  randY = getRndNum(0,y);
  myLayers[i].property("Position").setValue([randX,randY,0]);
  // myLayers[i].property("Position").setValue([x,y])

}

```

## Misc

### [**Change the background color for the active comp**](https://gist.github.com/aescripts/74ba7303530af9fb9766fa6f50cd3cba)

```javascript
/* Changes the background color for the active comp to white. 
Can be customized to any color you'd like by simply changing the [1,1,1] value to reflect the appropriate RGB values...

Example colors:
[0,0,0] = Black
[0.5,0.5,0.5] = Grey
*/

app.project.activeItem.bgColor=[1,1,1];
```

### Duplicate selected n times

{% tabs %}
{% tab title="prompt" %}

```javascript
app.beginUndoGroup("Duplicate Selected Layers");
var comp = app.project.activeItem;
if(comp){
var numCopies = prompt("How many copies?",5);
    if (numCopies){
	for (var i=0; i < comp.selectedLayers.length; i++) {
	for (var j=1; j <= numCopies; j++) {
	comp.selectedLayers[i].duplicate();
			}
		}
	}
}
app.endUndoGroup;
```

{% endtab %}

{% tab title="15" %}

```javascript
app.beginUndoGroup("Duplicate Selected Layers");
var comp = app.project.activeItem;
if(comp){
var numCopies = 15
    if (numCopies){
	for (var i=0; i < comp.selectedLayers.length; i++) {
	for (var j=1; j <= numCopies; j++) {
	comp.selectedLayers[i].duplicate();
			}
		}
	}
}
app.endUndoGroup;
```

{% endtab %}
{% endtabs %}

## Kbar Scriptlets

### Changes selected Solid source's color to white&#x20;

```javascript
{
	var activeItem = app.project.activeItem;

	if (activeItem == null || !(activeItem instanceof CompItem)) {
		alert("Select a comp before running this script");
	} else {
		if (activeItem.selectedLayers.length < 1) {
			alert("Select a solid layer before running this script");
		} else {
			solidLayer = activeItem.selectedLayers[0];
			solidLayer.source.mainSource.color = [1,1,1];
			alert("Changed solid's color to white.");
		}
	}
}
```

Source: Paul Tuersley, <https://aenhancers.com/viewtopic.php?t=65>&#x20;

### Change comp bg color to black > white > grey

```javascript
myComp = app.project.activeItem
var bg = myComp.bgColor;
var n =0 ;

var baseColor = [0,0,0];
var col_1 = [1,1,1];
var col_2 = [.5,.5,.5];


if(bg[0]==0&&bg[1]==0&&bg[2]==0) {n=1} // black to white
if(bg[0]==1&&bg[1]==1&&bg[2]==1) {n=2} // white to grey
if(bg[0]==.5&&bg[1]==.5&&bg[2]==.5) {n=3} // grey to black


switch(n){
  case 0:
    app.project.activeItem.bgColor = baseColor;
  break;

  case 1:
    app.project.activeItem.bgColor = col_1;
    break;

	case 2:
    app.project.activeItem.bgColor = col_2;
    break;

	case 3:
    app.project.activeItem.bgColor = baseColor;
    break;
}

```

## Arrays

### Shuffle&#x20;

```javascript
function shuffleArray(array) {
    var currentIndex = array.length, temporaryValue, randomIndex;

    // While there remain elements to shuffle...
    while (0 !== currentIndex) {

        // Pick a remaining element...
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;

        // And swap it with the current element.
        temporaryValue = array[currentIndex];
        array[currentIndex] = array[randomIndex];
        array[randomIndex] = temporaryValue;
    }

    return array;
}
```


# Utilities

## Template

```javascript
// template
var myComp = app.project.activeItem;
var myLayers = myComp.selectedLayers;
var ctrl //= myComp.selectedLayers[0];
////////////////////////////////////////////////////////////////////
```

## Generating random numbers

### Max

```javascript
function getRandNum(max) {
    var x = Math.floor(Math.random() * max);
    return x;
};
```

### range

```javascript
function getRandRange(min, max) {
    return Math.random() * (max - min) + min;
}
```

### Random element from array

```javascript
var item = items[Math.floor(Math.random() * items.length)];
```

### Generating combinations with non-repeating elements

* Will break if caught in infinite loop⚠️

```javascript
var nums = [1, 2, 3, 4, 1, 2, 3, 2, 3, 1]; //all numbers to be randomized
var ranNums = [];
var numLayers = nums.length;
var j = 0;

for (i = numLayers; i > 0; i--) {
    j = Math.floor(Math.random() * i); // rand choice
    
    // non-repeating random choice 
    if (ranNums.length > 0) {
        while (nums[j] == ranNums[ranNums.length - 1]) {
            j = Math.floor(Math.random() * i);
        }
    }
    ranNums.push(nums[j]);
    nums.splice(j, 1);
}

//usage
alert(ranNums)

```

### Trim string

```javascript
function trim(str) {
    return str.replace(/^\s+/, '').replace(/\s+$/, '');
}
```

### Measuring distance between 2 points

```javascript
function distanceVector(v1, v2) {
    var dx = v1[0] - v2[0];
    var dy = v1[1] - v2[1];
    return Math.sqrt(dx * dx + dy * dy);
```

## Removing duplicates in array

### [Compress Array by Peter Kahrel](https://community.adobe.com/t5/indesign/js-how-to-remove-duplicate-items-from-an-array/m-p/3044978)

The **arrayCompress** function is very original, but I am skeptical about its performance on large arrays.

*Also, there is two important issues to mention:*

*1) the original array is not preserved, because **array.sort()** reorders its own elements -- we can fix this using **array.concat().sort()**.*

*2) the function does not work if any of the supplied strings already contains **"\r"**.*—  Marc Autret

```javascript
function arrayCompress(array){
    var str = array.sort().join('\r')+'\r';
    str = str.replace(/([^\r]+\r)(\1)+/g,'$1');

    str = str.replace(/\r$/,'');
    return str.split('\r');

}
```

### Hash-sieving&#x20;

## Creating

### Null

```javascript

function addNull(myName) {

    try {
        var myNull = myComp.layer(myName)
        myNull.name = myName;

    } catch (e) {
        var myNull = myComp.layers.addNull();
        myNull.name = myName;
        myNull.label = 9; // green

    }
    ctrl = myNull;
    return myNull
}
```

### Slider

```javascript
function addSlider(layer, fxName) {
    try {
        layer.effect(fxName)("Slider")
    } catch (e) {
        efx = layer.property("Effects").addProperty("Slider Control");
        efx.name = fxName.toString()
    }
    return efx
}
```

### effect

```javascript
function addFx(layer, fxName, yourFxName) {
    // eg. addFx(ctrl, "Slider Control", '')
    efx = layer.property("Effects").addProperty(fxName);
    if (yourFxName != '') {
        efx.name = yourFxName.toString()
    }
    return efx
}

```

## Check

### If layer exist

```javascript
function doesLayerExist(comp, myname) {
    for (i = 1; i <= comp.numLayers; i++) {
        if (comp.layer(i).name == myname) {
            alert('it does');
            return true;
            break
        }
    }
    // alert('nope')
    return error;
}
```

### If effect exist in layer

```javascript

var myLayer = app.project.activeItem.layer(1);
var hasEffect = false;
for (var i = 1; i <= myLayer.property("Effects").numProperties; i++) {
    if (myLayer.property("Effects").property(i).matchName == "ADBE Tile") {
        alert("It does!");
        hasEffect = true;
        break;
    }
}
if (!hasEffect) {
    myLayer.property("Effects").addProperty("ADBE Tile");
}


```


# Master Properties

### Add Property as Essential Property&#x20;

```javascript
function addToMotionGraphicsTemplate(comp, property) {
    if (property.propertyGroup(1).name === "Effects") {
        var fx = property.property(1);
        fx.addToMotionGraphicsTemplateAs(comp, property.name);
    } else {
        property.addToMotionGraphicsTemplateAs(comp, property.name);
    }
}
```


# ScriptUI

## Creating anything

```javascript
//creating a dialog/palette window
var box = new Window('dialog', "title here"); 

// creating a button
box.add('button',undefined, "Close", {name:'title here'});


// creating static text 

// creating a group

// Creating a panel

// Creating
```

### Making dialog box resizable

### Formatting size, alignment

```javascript
"group { \
            orientation:'column', alignment:['fill','top'], \
            header: Group { \
                alignment:['fill','top'], \
                title: StaticText { text:'" + rd_KindaSortaData.scriptName + "', alignment:['fill','center'] }, \
                help: Button { text:'" + rd_KindaSorta_localize(rd_KindaSortaData.strHelp) +"', maximumSize:[30,20], alignment:['right','center'] }, \
            }, \
```


# Tooling

WIP 24.09.27

## **Introduction**

**What is Tooling in Motion Design**?&#x20;

In Motion Design, *tooling* refers to the **building** of various different kinds of components to streamline and optimize the design and animation process, enabling designers to work efficiently, automate repetitive tasks, and produce high quality animations. This could as simple as After Effects Animation Presets (FFX), rigs, scripts, or plugins.&#x20;

**Why tooling, why create tools?**

As we grow as designers, our focus shifts to advancing and **scaling** production to tackle bigger, more complex projects, often involving multiple team members. Creating tools helps increase our leverage—not just by streamlining our own work but by empowering others to perform at a higher level. This reduces the need for constant intervention, ensures design consistency, and optimizes existing processes.&#x20;

**Tools, Tooling, Toolkitting, what's the difference?**

* **Tools** refers to the thing that creates or help you do the work; eg. After Effects and Adobe Suite is a creative tool to make designs, Trapcode Particular is a plugin that allows you to create particles,
* **Tooling** refers to the building of the tools/parts
* **Toolkitting** refers to the process of grouping tools into a unified set. For example, one can make brand animation AEP toolkit for a company to produce social media content. All designs/animations/assets are prepped in the toolkit, and the user just need to make minimal modification to the elements such as the copy or images being used.

**Seriously, why is this important?**

We shouldn't see all these as separate skills, but an integral part of a **business** operations/technical direction...

## References

<https://github.com/nosleepcreative/after-effects-styleguide>


# Toolkitting


# Knowledge Base


# Naming Convention


# DAM

Digital Asset Management


# Formulas

## Introduction

Here is a page with Cinema 4D Formulas that you can use for Formula Effectors or Fields. Formulas are primarily based on C++ syntax.

## Formula Appendix, [*Maxon Help Guide*](https://help.maxon.net/c4d/2024/en-us/Default.htm#html/6194.html)

Basic

```cpp
px,py,pz - Position
rx,ry,rz - Rotation
sx,sy,sz - Scale

u,v,w - UVW
id - Object Index
count - Object Count

falloff - Falloff weight
t - Project Time[-∞..+∞]
f - Frequency[-∞..+∞]

Conditional
?(a;b)
(3>4)?(10;20)
?(a;b)

Arguments such as mod(a;b) must be separated by a semi-colon or by squared brackets [] (then without curved brackets)

rnd(100) is the same as rnd[100] and rnd(100;234) is the same as rnd([100][234]).
```

**Mathematical Operators**

```plaintext
+	Addition	144 + 14 = 158
-	Subtraction	144 - 14 = 130
*	Multiplication	144 * 2 = 288
/	Division	144 / 12 = 12
(	Left parenthesis	3 + 4 * 2 = 11
```

**Units**

```cpp
km	Kilometer	1km = 1000m
m	Meter	144 - 14 = 130
cm	Centimeter	1cm = 0.01m
mm	Millimeter	1mm = 0.001m
um	Micrometer	1um = 0.000001m
nm	Nanometer	1nm = 0.000000001m
mi	Mile	1mi = 1609.344 m
yd	Yard	1yd = 0.914m
ft	Foot	1ft = 0.305m
in	Inch	1in = 0.025m
B	Frame Number
```

Logical Operators

```cpp
 =	Equal compare	1km = 1000m
==	Equal compare	144 - 14 = 130
>	Greater than	1cm = 0.01m
<	Less than	1mm = 0.001m
>=	Greater than or equal compare	1um = 0.000001m
<=	Less than or equal compare	1nm = 0.000000001m
!=	Not equal compare	1mi = 1609.344 m
!	Not	1yd = 0.914m
|| or. or	Or	1ft = 0.305m
&& or. and	And	1in = 0.025m
&	Bitwise and	 
|	Bitwise or	 
^	Bitwise xor	 
~	Bitwise not	 
?(a; b)	Condition, if statement: a, then b	(3 > 4) ? (10; 20) = 20; kann ebenfalls
so formuliert werden: if(3 > 4; 10; 20)	
```

**Constants**

```cpp
e	The constant e (Euler Number) = 2.71828	 
pi	The constant Pi (circular number) = 3.14159	 
pi05	Half Pi	 
pi2	Double Pi	 
piinv	Inverse Pi	 
pi05inv	Half inverse Pi	 
pi2inv	Double inverse Pi	 

// Functions
sin(a)	Sinus	
cos(a)	Cosinus	 
acos(a)	Arcus cosinus	 
asin(a)	Arcus Sinus	 
tan(a)	Tangent	 
atan(a)	Arcus tangent	 
cosh(a)	Cosinus hyerbolicus	 
sinh(a)	Sinus hyerbolicus	 
tanh(a)	Tangent hyerbolicus	 
floor(a)	Round down	floor(11.8) = 11
ceil(a)	Round up	ceil(11.2) = 12
round(a)	Rund	round(11.8) = 12
abs(a)	Absolute / Value	abs(-11) = 11
sqr(a)	Square exponentiation	sqr(5) = 25
sqrt(a)	Square root	sqrt(49) = 7
exp(a)	Exponential function	exp(5) = 148.41
log10(a)	Logarithm to the base of10	log10(100) = 2
log(a)	Logarithm to the base of e	log(e) = 1
trunc(a)	Truncates a number	trunc(-11.8987) = -11
rnd(a{; b})	Random or 0 and a, opt. b as seed	 
pow(a; b)	Exponentiation	pow(2; 3) = 8
mod(a; b)	Modulo	mod(10; 4) = 2
clamp(a; b; c)	Clamps val. of c or a & b	clamp(2; 6; 10) = 6
min(a; b)	Minimum value a or b	min(4; 7) = 4
max(a; b)	Maximum value a or b	max(4; 7) = 7
(a) << (b)	Bitwise shift to left	1 << 4 = 16
(a) shl
```

## Getting Started

{% embed url="<https://youtu.be/pfW2HdjWLqg>" %}

## Concepts

White to dark vertical

```cpp
id/count
```

Dark to white center, vertical

```cpp
1 - abs(mod(id/count; 1) - 0.5)*2
```

Dark to white center, horizontal

```cpp
1 - abs(mod(u; 1) - 0.5)*2
```

**Radial - White to Dark Center**

```cpp
sqrt(px*px + py*py + pz*pz)/1000
```

## Formula Library

**Default/Wave**

```cpp
/0.5 + sin( ( subfields + ( id / count ) + d ) * f * 360 ) * 0.5
```

**Alternating Lines**

<figure><img src="/files/PCSjIOZLnATLPnugL84E" alt=""><figcaption></figcaption></figure>

```cpp
mod((id/80);2)?(t*f;-t*f)
```


# Python Cheat Sheet

| Syntax/Concept                                                               | Example                                                                                                    | Explanation                                                                |
| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| Print statement                                                              | print("Hello, world!")                                                                                     | Outputs the given text to the console                                      |
| Comments                                                                     | # This is a comment                                                                                        | Comments are ignored by Python and are used to document code               |
| Multiline comment                                                            | """                                                                                                        |                                                                            |
| This is a multiline comment.                                                 |                                                                                                            |                                                                            |
| It can span multiple lines without the need for multiple comment symbols.    |                                                                                                            |                                                                            |
| You can use it to document your code or temporarily disable a block of code. |                                                                                                            |                                                                            |
| ""”                                                                          |                                                                                                            |                                                                            |
| Variables                                                                    | x = 5                                                                                                      | Variables are used to store data and can be assigned and reassigned values |
| Data types                                                                   | int, float, string, bool, list, tuple, dict, set                                                           | Different types of data that can be stored in variables                    |
| Numeric operations                                                           | +, -, \*, /, %, \*\*                                                                                       | Operators used for arithmetic operations                                   |
| Comparison operators                                                         | ==, !=, >, <, >=, <=                                                                                       | Operators used to compare values                                           |
| Logical operators                                                            | and, or, not                                                                                               | Operators used to combine and manipulate boolean values                    |
| Conditional statements                                                       | if, elif, else                                                                                             | Statements used to conditionally execute code                              |
| Loops                                                                        | for, while                                                                                                 | Statements used to iterate over a sequence of data                         |
| Functions                                                                    | def my\_func():, return                                                                                    | Blocks of code that can be called and returned                             |
| Lambda functions                                                             | lambda x: x + 1                                                                                            | Anonymous functions used for simple operations                             |
| Classes                                                                      | class MyClass:, def **init**(self):, self                                                                  | Used to define custom data types and associated functions                  |
| List methods                                                                 | append(), extend(), insert(), remove(), pop(), index(), count(), sort(), reverse()                         | Methods used to manipulate lists                                           |
| Tuple methods                                                                | count(), index()                                                                                           | Methods used to manipulate tuples                                          |
| Dictionary methods                                                           | keys(), values(), items(), get(), update(), pop(), popitem(), clear()                                      | Methods used to manipulate dictionaries                                    |
| Set methods                                                                  | add(), remove(), discard(), pop(), clear(), union(), intersection(), difference(), symmetric\_difference() | Methods used to manipulate sets                                            |

##

## Getting Started

* Corey Schafer,  [Object-Oriented Programming ](https://www.youtube.com/watch?v=ZDa-Z5JzLYM\&list=PL-osiE80TeTsqhIuOqKhwlXsIBIdSeYtc) 6 parts&#x20;
* Setting up a Python Development Environment
  * Requirements: syntax highlighting, beautification, linter,  IntelliSense: list members, parameter info, quick info, autocompletion,&#x20;
  * [Corey Schafer](https://www.youtube.com/watch?v=06I63_p-2A4\&list=PL-osiE80TeTt66h8cVpmbayBKlMTuS55y\&index=8)

## Class

* Why? Logically group our data and functions that we can easily reuse or build upon
* **Terminology**
  * Attributes and methods - functions that is associated with class
  * A class is a blueprint for creating instances

```python
class Employee:
    pass 

# instances of a Employee classes
emp_1 = Employee()
emp_2 = Employee()
s
# unique data 
#manually variable setting - prone to human error
emp_1.first = 'Corey'
emp_1.last = 'Scafer'
emp_1.email = 'cScafer@company.com'
emp_1.pay = '50000'

emp_2.first = 'Test'
emp_2.last = 'User'
emp_2.email = 'testUser@company.com'
emp_21.pay = '60000'
######

class Employee:
    def __init__(self,first,last,pay):
        #set instance variable 
        self.first = first
        self.last = last
        self.pay =pay
        self.email = first +'.' + last + '@company.com'
        
    # each method within a class automatically takes the insance as the first argument
    # and we always call that self
    def fullname(self)
        return '{}{}'.format(self.first,self.last)
    
# better solution: runs init automatically 
emp_1 = Employee('Corey','Scafer',50000)
emp_2 = Employee('Test','User',60000)

print(emp_1.email)
print(emp_2.email)

# running actions
    #manually 
    print('{}{}'.format)emp_1.first,emp_1,last))
    
    # better 
    print(emp_1.fullname()) # notice the parenthesis as it is a method

#notes
#classes are kinda like function
# remember to put self in methods in class
    emp_1.fullname() is same as Employee.fullname(emp_1))
```


# For Artists

## Potential uses

### **Ultimate Motion Design researcher**

#### Videos

* Input a list of parameters to scrape: studios Vimeo channel, IG artists, Vimeo staff picked or liked videos, Motionographer
* Frequency every 2 weeks
* Download into a folder, or create title cards for videos, and stitch them together&#x20;
* Input all data in a Google Sheets or TSV

**Auto-post to social media**&#x20;

**Publications & Writing**

* Motionographer: diversity and gender check
* Companies mission statements
* Writing analysis: most commonly used words?

## Research & Scraping

| Type                 | Tool                                                                                                                                                                                                                          |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Videos               | Youtube-dl                                                                                                                                                                                                                    |
| Website              | Httrack                                                                                                                                                                                                                       |
| Instagram content    | <p></p><p><https://instaloader.github.io/index.html></p>                                                                                                                                                                      |
| Youtube channel data | <ul><li><a href="https://www.thepythoncode.com/article/using-youtube-api-in-python">Via API</a></li><li><a href="https://www.thepythoncode.com/article/get-youtube-data-python">Via webscraping</a>, the pythoncode</li></ul> |

## Creative

| Type             | Tool                                                       |
| ---------------- | ---------------------------------------------------------- |
| Video Storyboard | <https://pypi.org/project/storyboard/>                     |
| Scene detection  | <https://pyscenedetect.readthedocs.io/en/latest/download/> |
| Color            | <https://github.com/rodartha/ColorPalette/>                |
| Data-moshing     |                                                            |

## Automation

| Type | Tool |
| ---- | ---- |
|      |      |
|      |      |
|      |      |

## Other uses

### Monitor <a href="#id-5--monitor-a-website-to-get-informed-about-an-upcoming-concert-of-artist" id="id-5--monitor-a-website-to-get-informed-about-an-upcoming-concert-of-artist"></a>

### Bots

### Recognize <a href="#id-7--recognize-individuals-in-crowd" id="id-7--recognize-individuals-in-crowd"></a>

* Machine Learning Prediction
* Web Scraping
* Share Market / Cryptocurrency Tracker
* Chatbot
* File Management
* Data Mining
* Send Reminder Emails and Texts
* Update Excel Sheets Automatically
* Fill Online Forms
* Internet of Things


# Maya Environment

```
Cam
    opt + LMB - rotate
    opt + RMB - scale
    opt + MMB - move
    
Viewport
    frame geometry - H
    frame selected object - o
    Show Attribute Editor - Ctrl + A
Settings
    preferences - 
    Project - 
    Render -
    
Essential 
    Commander - 
```

## Setting up Visual Studio Code for Maya

{% embed url="<https://www.youtube.com/watch?v=sYi1CtKdkow>" %}

1. Install Python, Visual Studio Code
2. In VSC, install MEL - Maya Embedded Language, Maya-code, Maya-Py, Maya Code
3. Download latest [devkit](https://www.autodesk.com/developer-network/platform-technologies/maya) > copy devkit into dev kit folder in your Maya application folder&#x20;
4. Modify your JSON&#x20;
5. In Maya > Script Editor > Open ports by entering these code

```javascript
import maya.cmds as cmds
# Open new ports
cmds.commandPort(name=":7001", sourceType="mel", echoOutput=True)
cmds.commandPort(name=":7002", sourceType="python", echoOutput=True)
```

To enable ports at startup create a file named userSetup.mel in the following folder:

```bash
Windows: <drive>:\Documents and Settings\<username>\My Documents\maya\<Version>\scripts
Mac OS X: ~/Library/Preferences/Autodesk/maya/<version>/scripts.
Linux: ~/maya/<version>/scripts.
(where ~ is your home folder)
```

In the userSetup.mel file add the following

```
commandPort -name "localhost:7001" -sourceType "mel" -echoOutput; 
commandPort -name "localhost:7002" -sourceType "python" -echoOutput;
```

```javascript
{
    "python.pythonPath": "python",
    "python.autoComplete.extraPaths": [  "C:/Program Files/Autodesk/Maya2019/devkit/other/pymel/extras/completion/py" ],

}
```

/Applications/Autodesk/maya2020/devkit

## [Autodesk tuts](https://www.youtube.com/watch?v=eXFGeZZbMzQ)

### Part 1: Creating and Manipulating Objects

* open Script Editor to see echo MEL command&#x20;
* go to Help > Python reference&#x20;
* flags: ch,o,w,g,d,name
* DAG - direct acyclic graphic: transform node>shape node > data structures
* Window > Setting / Preferences >  Preferences > Selection > Track Selection Order

Hotkeys

* Cmd T - new python&#x20;

{% tabs %}
{% tab title="keyRotation" %}

```python
import maya.cmds as cmds

def keyFullRotation(pObjectName,pStartTime, pEndTime, pTargetAttribute):

    #print '%s type: %s' % (objectname, objectTypeResult)
    cmds.cutKey(pObjectName, time=(pStartTime,pEndTime), attribute=pTargetAttribute)
    cmds.setKeyframe(pObjectName, time= pStartTime, attribute = pTargetAttribute, value=0)
    cmds.setKeyframe(pObjectName, time= pEndTime, attribute = pTargetAttribute, value=360)
    
    #linear tangent
    cmds.selectKey(pObjectName, time-(pStartTime,pEndTime), attribute = pTargetAttribute
    cmds.keyTangent(inTangentType = 'linear', outTangetType='linear')
    
    
selectionList = cmds.ls(selection=True, type = 'transform))

if len(selectionList)>=1:
    #print 'Selected items: %s' % (selectionList)
    
    for objectName in selectionList:
    
    startTime = cmds.playBackOptions(query=True,minTime=True)
    endTime = cmds.playBackOptions(query=True,maxTime=True)

    #objectTypeResult = cmds.objectType(objectName)
    
    keyFullRotation(objectName, startTime,endTime,'rotateY')
else: 
    print ' Please select at least one object'
```

{% endtab %}

{% tab title="aimAtFirst" %}

```python
#aimAtFirst.py

import maya.cmds. as cmds
selectionList = cmds.ls (orderedSelection = True)

if len(selectionList) >=2:
    print 'Selected itesms: %s' %(selectionList)
    targetName = SelecitonList[0]
    selectionList.remove(targetName)
    
    for objectName in SelectionList:
        print 'Constraining %s towards %s' % (objectName, tartgetName)
        cmds.aimConstraint(targetName, objetName, aimVector = [ 0,1,0])

else:
    print 'Please select two or more objects.'
```

{% endtab %}

{% tab title="randomInstances" %}

```python
#randomInstances.py

import maya.cmds as cmds 
import random

random.seed(1234)

# selectionOrder 
result = cmd.ls(orderedSelection = True)
print 'result: %s' % (result) # replace string technique

transformName = result[0]
# create a group 
instanceGroupName = cmds.group(empty=True,name = transformName + '_instance_grp')

#instancing with for loop
for i in range(0,50):

    instanceResult = cmds.instance(transformName, name = transformName + ' _instance#'
    
    cmds.parent(instanceRsult,instanceGroupName)
    x = random.uniform(10,10)
    y = random.uniform(0,20)
    z = random.uniform(-10,10)

    cmds.move(x,y,z, instanceResult)
    
    #randomize rotation
    xRot= random.uniform (0,360)
    yRot= random.uniform (0,360)
    zRot= random.uniform (0,360)
    cmds.rotation(xRot,yRot,zRot, instanceResult)
    
    # randomize factor
    scalingFactor = random.uniform(0.3, 1.5)
    cmds.scale(scalingFactor, scalingFactor,scalingFactor, instanceResult)

# hide original cube & center pivit
cmds.hide(transformName)
cmds.xform(instanceGroupName, centerPiviots=True)

```

{% endtab %}

{% tab title="randomCubes.py" %}

```python
#randomCubes.py

import maya.cmds as cmds 
import random

random.seed(1234)

#commenting out multiple lines
'''
#fetch all objects who name starts with myCube + wildcard
cubeList = cmds.ls('myCube*') 

#delete all cube items in cubeList
if (len(cubeList)) > 0:
    cmds.delete(cubeList)
'''
    
result = cmds.polyCube(w=9,h=9,d=9, name = 'myCube#')
transformName = result[0]
# create a group 
instanceGroupName = cmds.group(empty=True,name = transformName + '_instance_grp')

#instancing with for loop
for i in range(0,50):

    instanceResult = cmds.instance(transformName, name = transformName + ' _instance#'
    
    cmds.parent(instanceRsult,instanceGroupName)
    x = random.uniform(10,10)
    y = random.uniform(0,20)
    z = random.uniform(-10,10)

    cmds.move(x,y,z, instanceResult)
    
    #randomize rotation
    xRot= random.uniform (0,360)
    yRot= random.uniform (0,360)
    zRot= random.uniform (0,360)
    cmds.rotation(xRot,yRot,zRot, instanceResult)
    
    # randomize factor
    scalingFactor = random.uniform(0.3, 1.5)
    cmds.scale(scalingFactor, scalingFactor,scalingFactor, instanceResult)

# hide original cube & center pivit
cmds.hide(transformName)
cmds.xform(instanceGroupName, centerPiviots=True)

```

{% endtab %}
{% endtabs %}

###

## [Justin Israel: Python for Maya Artists](https://www.youtube.com/watch?v=PDKxDbt6EGQ)

### Why

* widespread
* cross platform&#x20;
* cross-software&#x20;

## Troubleshooting&#x20;

### Modifying userSetup.mel

Mac:  \~/Library/Preferences/Autodesk/maya/2020/scripts

##


# Maya snippets

## Selection

### Action if selection has item or not

```javascript
import maya.cmds as cmds
target = cmds.ls(sl=True)
if target:
    print('yes')
else:
    print('no')
```

## Adding objects

### To a curve

```javascript
import maya.cmds as cmds
from random import uniform
delta = 1.0/10
for n in range(40):
    if uniform(0,1) > 0.5:
        x,y,z = cmds.pointOnCurve( 'curve44', pr=(delta * n), p=True )
        cmds.sphere(r=uniform(0.01, 0.04))
        cmds.move(x,y,z)
```

```javascript
import maya.cmds as cmds
from random import uniform
delta = 1.0/10
for n in range(40):
    if uniform(0,1) > 0.5:
        x,y,z = cmds.pointOnCurve( 'curve44', pr=(delta * n), p=True )
        cmds.sphere(r=uniform(0.01, 0.04))
        cmds.move(x,y,z)
  
#----------------------------------------
import maya.cmds as cmds
from mesh_utils import *
from random import uniform
  
positions = get_faces_midpoint('pPlane1', False)
for x,y,z in positions:
    inst = cmds.instance('pCone1')[0]
    y_angle = uniform(0, 360)
  
    cmds.rotate(0, y_angle, 0, inst, relative=True)
    cmds.move(x,y,z, inst)
#----------------------------------------
    
```


# VSFX 705

## Setting up&#x20;

### Cutter for Mac

#### Modifying the run file&#x20;

```
export PYTHONPATH=$PYTHONPATH:$RMANTREE/bin
export PATH=$RMANTREE/bin:$PATH

export MAYA_USER_DIR=$HOME/Documents/maya
export RMS_SCRIPT_PATHS=$MAYA_USER_DIR/rfm_scripts/image_tool
RMANFB=it

# change directory below to where your cutter is
cd /Users/ddu/Desktop/ddu/projects/vsfx_705/cutter

# To uncomment the next line - remove the '#' character

java -Xms512m -Xmx512m -classpath .:cutter.jar Cutter
```

#### Making the text file executable

```
chmod 777 run
```

### Setting up Maya Env for Mac

<http://fundza.com/rfm/customizing/index.html>

1. Copy `rfm_scripts` folder to /Users/ddu/Documents/maya
2. copy `scripts` folder to /Users/ddu/Documents/maya
3. Copy `Arnold Shaders` to /Users/ddu/Documents/maya/projects
4. copy `maya.env` file to /Users/ddu/Library/Preferences/Autodesk/maya/2020

* Maya  > Window > Plugin manager > Ensure Renderman for Maya is loaded and auto-loaded
* check script editor for environment and preferences&#x20;

### Student web spaces

1. Go myScad > [my info](https://my.scad.edu/uPortal/f/my-info/normal/render.uP) > [Web Space Activation](https://sso.scad.edu/ssomanager/c/SSB?pkg=hwskwebs.P_WebsRegistration)
2. Go to: <https://studentpages.scad.edu/instructions.html> > Myfile&#x20;
3. Upload your html and asset files to **<https://sav-myfile.scad.edu/myfile/ws-idrive/Savannah/Webspaces/Studentpages/web\\_pages>**

### [Atom](https://www.youtube.com/watch?v=DjEuROpsvp4)

* **Core:** font size: 20, source code pro, 4 spaces tab, Scroll past end&#x20;
* **Packages:** Turn off auto-complete-plus & snippets

```python
apm install script autocomplete-python minimap file-icons python-autopep8 linter-flake8 
maya language-mel
pip install autopep8
pip install flake8 
```

{% hint style="info" %}
if linter does not show up, delete your Atom config files located: `/Users/userName/.atom/config.cson`
{% endhint %}

### **Notes**

```
keep in mind Renderman Attribute Editor, Shelf, Menu bar
```

## Using cutter

* `cmd+click` on a function (eg.print) to read the [**Built-in Functions** ](https://docs.python.org/3.8/library/functions.html)documentation

## Resources

#### Documentation

* [Python built-in functions](https://docs.python.org/3.8/library/functions.html)

#### Learning Python for Maya

* [**Autodesk Introduction to Python Scripting in Maya** ](https://www.youtube.com/watch?v=eXFGeZZbMzQ\&list=PL-4p6ppgFOkWtUtcp46Z_AufwVP0CougD)
* [Python Scripting for Maya Artists](http://www.chadvernon.com/blog/resources/python-scripting-for-maya-artists/) (on-line), Chad Vernon

#### **Learning Python**

1. [Guru99: Python Tutorial for Beginners](https://www.guru99.com/python-tutorials.html)
2. [Learning Python](http://shop.oreilly.com/product/9780596158071.do), Mark Lutz, O'Reilly Media
3. [Think Python](http://www.greenteapress.com/thinkpython/html/index.html)(on-line), Allen Downey  &#x20;

## Getting started with Python

**Key terms:** list, tuple, dictionary&#x20;

```python
# script is called test.py but it 
# implements a module called "test"
# a modules contrains attributes
# an attribute can be, eg. name of a variable 

# the built-in datatypes are, nubmers, text(string),
# (and collections) list, tuple, dictionary. file.


age = 26
name = "tom"
family = 'jones'
nationatlity = 'welsh'

# an attribute can also be the name of function 
#create function
def person() 
    print(age)
    print(name)
    print(family)

#creating list 
countries = []
countries.append('usa')
countries.append('china')
countries.append('new zealand')
countries.append('england')
#countries.sort() 
#countries.reverse

# using a tuple (fixed value list) - for vertices data structures transfer
locked = (2,4,3,6,8,9)
# i can test my code by printing some value 
# this call the values 
# but comment it out if used asa module
person() 


if __ name__ == '__main__':
    #person() #(debugging purposes) 
    
    #for place in countries:
        # print(place)
    
    #print(countries[3])
    
    print(locked[0])

#print(__name__) # return name of module from where it was run

```

{% tabs %}
{% tab title="fileWriting" %}

```python
# file_test.py
# an example of how to store text in a document 

out_file= open('file directory', 'w')
for n in range(10):
    out_file.write('sphere -r 1;\n)
    out_file.write('move %f %f 0;\n' % (n,(n-2))) # placeholder %
     
out_file.close()

# to run the mel document in Maya use this mel...
#source "filedirectory"
```

{% endtab %}

{% tab title="Python" %}

```python
#vsfx705/cutter/using_test.py
# only possible if the python files exist in the same directory
import test 
from importlib import reload

print(test.nationality)
test.person

```

{% endtab %}

{% tab title="importRandom" %}

```python
# importing random
import random
val = random.uniform(0,1)
print(val)

for n in range(10):
    val = random.uniform(0,1)
    if val>0.5:
        print(val)
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="rib\_test" %}

```python
# rib_test.py
"""
Points "P" [0 0 0   3 5 6    5 6 7   9 9 9] "constantwidth" [1.0]
"""
  
import random
  
rib_file = open('/Users/ddu/Desktop/ddu/projects/vsfx_705/cutter/data2.rib', 'w')
  
rib_file.write('##bbox: -5 -5 -5 5 5 5\n')
rib_file.write('Points "P" [\n')
for n in range(100000):
	x = random.uniform(-5, 5)
	y = random.uniform(-5, 5)
	z = random.uniform(-5, 5)
	rib_file.write('%f %f %f\n' % (x,y,z) )
rib_file.write('] "constantwidth" [0.05]')
rib_file.close()

#Maya > Renderman menu > Archive > import rib archive 
```

{% endtab %}

{% tab title="gen\_points" %}

```python
# maya/scripts/gen_points.py
  
import random
  
def cubic(num, side):
    data = []
    n = 0
    while n < num:
        x = random.uniform(-side/2, side/2)
        y = random.uniform(-side/2, side/2)
        z = random.uniform(-side/2, side/2)
        data.append( (x,y,z) )
        n = n + 1
    return data
  
def box(num, width, height, depth):
    data = []
    n = 0
    while n < num:
        x = random.uniform(-width/2, width/2)
        y = random.uniform(-height/2, height/2)
        z = random.uniform(-depth/2, depth/2)
        data.append( (x,y,z) )
        n = n + 1
    return data
    
# how to create a spherical point cloud 
def spherical(num,radius):
    pass # define function but not implemented
```

{% endtab %}

{% tab title="rib\_particles" %}

```python
# maya/scripts/rib_particles.py
import random
import gen_points
  
rib_file = open('/Users/ddu/Desktop/ddu/projects/vsfx_705/cutter/data2.rib', 'w')
data = gen_points.cubic(10000,10,0.05)
  
rib_file.write('##bbox: -5 -5 -5 5 5 5\n')
rib_file.write('Points "P" [\n')

for coord in data:
	rib_file.write('%f %f %f\n' % (coord[0],coord[1],coord[2]) )
	
rib_file.write('] "constantwidth" [0.05]')
rib_file.close()

#Maya > Renderman menu > Archive > import rib archive 
```

{% endtab %}
{% endtabs %}

```python
questions
    why is my cutter so slow?
    does not have vsfx705
    cannot open hyperlink
```

## Lesson 3

{% tabs %}
{% tab title="recap" %}

```python
list [] 
tuple () fixed values 
## bbox: -5 5 -5 5 5 5 # read by rib

def writeCubic(path

cmd E to render in Renderman

```

{% endtab %}
{% endtabs %}


# Cookbook

## Unsorted

```python
# Get Active Object
obj = doc.GetActiveObject
```

## Matrix Array Transformation

#### Theory

### Position

**Selecting a single element**

```python
n = 20

# Position: Vector to Real
x = marr[n].off.x 
y = 20
z = marr[n].off.z

marr[n].off = c4d.Vector(x,y,z)
```

**Selecting a single element**

```python
for i in range(cnt):
  x = marr[i].off.x 
  y = 20+i*5
  z = marr[i].off.z
  
marr[i].off = c4d.Vector(x,y,z)
```

### Rotation

#### Single Axis

```python

rot_x = c4d.utils.MatrixRotX(c4d.utils.Rad(45))
rot_y = c4d.utils.MatrixRotY(c4d.utils.Rad(30))
rot_z = c4d.utils.MatrixRotZ(c4d.utils.Rad(45))

marr[6] *= rot_x
   
```

#### Multiple Axes with HPB to Matrix

```python
r_x = c4d.utils.Rad(11)
r_y = 0
r_z = c4d.utils.Rad(18)

vect = c4d.Vector(r_x, r_y, r_z)
rotation = c4d.utils.HPBToMatrix(vect,5)

marr[6] *= rotation
```

### Scale

```python
for i in range(cnt):
    x = random.uniform(0.2,1) 
    y = random.uniform(0.2,1)
    z = random.uniform(0.2,1)
    vect = c4d.Vector(x,y,z)
  #  marr[i].Scale(float(i/10))
    marr[i].Scale(vect)
```

## Color

<pre class="language-python"><code class="lang-python">carr = moData.GetArray(c4d.MODATA_COLOR) # Color Array
<strong>
</strong><strong># Gray Scale
</strong># carr[0] = c4d.Vector(0.5) 

for i in range(cnt):
    r = random.random()
    g = random.random() 
    b = random.random()
    carr[i] = c4d.Vector(r,g,b)
    
# Update Color Array
moData.SetArray(c4d.MODATA_COLOR, carr, hasField)

</code></pre>

## References

* C4D SDK Documentation
*
* [Cinema 4D Python Bytes](https://www.youtube.com/playlist?list=PLpss88MSwvy5-a_RU1kHJtDcflY57VW7F)
* [Cinema4D Python SDK](https://developers.maxon.net/docs/Cinema4DPythonSDK/html/manuals/introduction/python_script_manager.html)

[C4D Python SDK Extended Github, Plugin Cafe](https://github.com/PluginCafe/cinema4d_py_sdk_extended)<https://github.com/aturtur/cinema4d-scripts>

##

## Formula

Documentation

**Alternate intensity based on row number (Animate over time)**

```jsx
mod((id/5);2)?(t;-t)
```

**Animate over time based on the row number sequence**

```jsx
(id/5)/(count/5)*1.5*t
```


# archive


# Webscraping

#### Documentation / Tutorials

* [XPath Syntax](https://www.w3schools.com/xml/xpath_syntax.asp)

#### Python

* <https://instaloader.github.io/index.html>

#### Google sheets

* [Import XML Guide](https://zapier.com/blog/google-sheets-importxml-guide/)&#x20;
* [Monitor YouTube and Instagram data](https://martechwithme.com/monitoring-youtube-channels-subscribers-with-google-sheets/)

## **Why scrape?**

### Application

* General: Competitive and price analysis, Lead generation, Keyword research
* **Research:** Science Product reattach, Finding / filling a job, Government oversight
* **Financial:** Stock analysis, Insurance and risk management, News gathering and analysis

Scraping for a car scrape the car buying websites to find all the teslas Evaluate the price to find great deals Scrape airfares and adjust the deals for airfare expenses Send an email digest of the top deal each day

**Python libraries** • beautiful soup • Scrape • Selenium

**Process** • set a start\_url variable • download html • parse html • extract useful information • transform or aggregate • save the data • Go the the next url

**HTTP overview Request** > response via https Web address / verb / user agent GET - retrieves data POST - sends data to the server User agent identifies the browser or web scraper

```python
# URL hacking query string
# Python URL strings 
host =‘www.iseecars.com’ 
path = ‘/used-cars/used-tesla-for-sale’ 
location = ’66592’ 
query_string = f#LOcation={location}&Radius =all&Make = Tesla&Model=Model+3’ start_url = f’
http://{host}{path}{query_string}’

# Python requests 
import requests 
start_url = ‘’ downloaded_page requests.get(start_url)
print(downloaded_page.text)
```

HTML & CSS Selectors css=> ‘title’ h1 li - list item Ul - unordered list ol - ordered list

### CSS Selectors&#x20;

```css
li
title
h1 
'#vin3827' // HTML ID
',auto-listing'

ul li // 
//class selectors
'ul.listings li#vin3827'

```

```python
exmaple = open("example.html","r")
html = example.read()
#hyml = requests.get(url).text
example.close

from bs4 import BeautifulSoup
soup = BeautifulSoup(html)
print(soup.prettify())

soup.title
soup.li
spup.find_all('li')
```

### XPath

```python
//ul[@class='listings"]/li[@id="vin3827']
```

## Legal Risks

getting sued for copyright infringement  / private websites&#x20;

1. Safe
   1. public government website
   2. scraping for personal use
   3. aggregated data project and research
   4. terms & conditions that allows&#x20;
2. More risky&#x20;
   1. scraping for personal use even though prohibited by the terms and conditions
   2. scraping data you don't own while logged in
   3. large scale scraping to publish widely promoted "news" reports
3. Relatively risky
   1. large scale scraping for profit
   2. create a commercial product
   3. scraping large company websites for profit
   4. creating and selling derivatives works
   5. scraping personally identifiable data (PII)

case-study: hiQ vs LinkedIn

## Python

### Scraping environment with JupyterLab

{% tabs %}
{% tab title="DL page" %}

```
#Import packages
import requests
from bs4 import Beautiful Soup
import pandas as pd

# Download and parse the HTML
start_url = 'https://...'

# Download the HTML from start_url
downloaded_html - requests.get(start_url)

# Parse the HTML with BeautifulSoup and create a soup object 
soup = BeautifulSoup(downlaoded_html.text)

#save a local copy
with open('downloaded.html', 'w) as file:
    file.write(soup.prettify())
```

{% endtab %}

{% tab title="JupterlabEnv" %}

```python
# Setup & Install Packages
#pyenv install 3.74
#pyenv local 3.74

#pipenv --python 3.7.4
#pipenv install requests
#pipenv install beautifulsoup4
#pipenv install pandas

#pipenv intall jupyterlab

# Check Installation
# !pyenv local
# !python - V
# !pip list
```

{% endtab %}

{% tab title="pandas" %}

```
# SEelct table.wiki table

table_head = full_table.select('tr th')

print('----------')

```

{% endtab %}
{% endtabs %}

##


# Google Sheets Formulas

## Recommended Readings

| **Item**                      | Links                                                                                                                                                                                                                                                                                               |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Documentation / Tutorials** | <ul><li><a href="https://www.ablebits.com/office-addins-blog/2019/04/30/google-sheets-compare-two-sheets-columns/">Comparing two columns </a></li><li><a href="https://infoinspired.com/google-docs/spreadsheet/use-trim-function-split-google-sheets/">Trim & Split functions</a></li></ul><p></p> |

## Counting

```java
// where $A:$A is your desiredrange

// if cell contains specific word
= countif($A:$A,"*_ALT*") // cannot be done with an arrayformula

// errors
=countif($A:$A,ISERROR())

// loading https://www.reddit.com/r/googlesheets/comments/aplwa6/importxml_loading/
=COUNTIF(ARRAYFORMULA(ISERR(A1:A1000)),true)
=TEXT(COUNTIF(ARRAYFORMULA(ISERR(A1:A1000)),false)/1000,"0%")

// whitespace
=COUNTA(SPLIT(A1, " "))

// count containing based on cell
=countif(A:A,"*"&A2&"*")
```

## Misc

```java
// if blank, no formula
= ARRAYFORMULA(IF(ISBLANK(A2:A),"",V2) 

// join header row & other row by each cell with delimiter (2rows)
= ARRAYFORMULA($B$1:$K$1&" — "&B2:K2))

// split by line break, transpose vertically, sort, flatten by 
= arrayformula(textjoin(char(10),1,sort(transpose(split(O2,char(10))))))
```

## REGEX

```java
// exclude first word
REGEXEXTRACT(trim(A2:A)," .+")

//first name
REGEXEXTRACT(A2,"^([\w\-]+)")
REGEXEXTRACT(A2, "\S+") 

// match text and filter range
https://stackoverflow.com/questions/42846220/regexmatch-with-regex-reference-to-cell
```

## Conditional formatting

### Searching for errors

```java
// custom formula
=iserror(B1)=true

// weekends where A1 is the first date in the column.
=or(WEEKDAY(A3)=1,WEEKDAY(A3)=7)
```

## Comparing two columns

```java
// list all matches from sheet 2 based on cell value
FILTER(sheet2!A:A, REGEXMATCH(sheets!A:A,A3)) 

// compare 2 columns for MATCHES / DIFFERENCE
=ArrayFormula(IF(A2:A=C2:C,"MATCH","DIFFER"))
```


# SQL

## Recommended Readings

| **Item**                                                              | Links                                                                                                                                                                                                                                                                          |
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Documentation / Tutorials**                                         | <ul><li><a href="https://www.youtube.com/watch?v=YufocuHbYZo">SQL for Beginners</a></li><li><a href="https://online.maryville.edu/online-bachelors-degrees/management-information-systems/careers/">Management Information Systems Careers</a></li></ul>                       |
| <p><strong>Industry /</strong> <br><strong>Case-studies</strong> </p> | <ul><li></li></ul>                                                                                                                                                                                                                                                             |
| **Books**                                                             | <ul><li></li></ul>                                                                                                                                                                                                                                                             |
| **Cheatsheet**                                                        | <p></p><ul><li><a href="https://www.sqltutorial.org/sql-cheat-sheet/"><https://www.sqltutorial.org/sql-cheat-sheet/></a></li><li><strong>Luke Harrison:</strong> <a href="https://websitesetup.org/sql-cheat-sheet/"><https://websitesetup.org/sql-cheat-sheet/></a></li></ul> |

```
select
from
where
order by [desc]
```

## Google Sheets

### [Multiple contains ](https://infoinspired.com/google-docs/spreadsheet/multiple-contains-in-where-clause-in-query/)

```
=QUERY(A1:A,"Select * Where not A Matches '.*AB.*|.*DJ.*' ",1)
=query(C323:C335,"Select C where not C contains 'soccer'")
=QUERY(C:C,"Select C Where not C Matches '.*ezoic.*|.*soccer.*' ",1)

```

### Referencing cells in query&#x20;

```
query(sheet2!A:G,"select A where G contains '"&L3&"'")

=query(SX_Sessions!$B$2:$E$120, 
"select B,D 
where E ='" &B3&"' 
AND C = '"&$B$1&"'")
```

### Hyperlinks

```
=IMPORTXML(B3, "//a/@href")
```


# Terminal

## Homebrew

* <https://brew.sh/>

## FFMPEG

### Making gifs

* <https://askubuntu.com/questions/648603/how-to-create-an-animated-gif-from-mp4-video-via-command-line>
* <https://medium.com/@colten_jackson/doing-the-gif-thing-on-debian-82b9760a8483>
* <https://superuser.com/questions/556029/how-do-i-convert-a-video-to-gif-using-ffmpeg-with-reasonable-quality>

```bash
ffmpeg \
  -i yourFile.mov \
  -r 15 \
  -vf scale=512:-1 \
  -ss 00:00:03 -to 00:00:06 \
  yourFile.gif
  
  #hq
  ffmpeg -i demo.mov -vf "fps=15,scale=800:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif

```

## ImageMagick

### Documentation

* <https://imagemagick.org/script/download.php#macosx>
* <https://imagemagick.org/script/convert.php>
* <https://imagemagick.org/script/mogrify.php>

### Compression

* <https://stackoverflow.com/questions/7261855/recommendation-for-compressing-jpg-files-with-imagemagick>
* [Convert & save with same name](https://stackoverflow.com/questions/9992174/imagemagick-command-to-convert-and-save-with-same-name)#

```bash
#basic
magick image.jpg -strip -interlace Plane -gaussian-blur 0.05 -quality 85% -resize 75%  result.jpg

# compress all jpg in folder 
magick *.jpg -strip -interlace Plane -gaussian-blur 0.05 -quality 85% result.jpg
    
#parent folder
convert *.jpg -strip -interlace Plane -gaussian-blur 0.05 -quality 85%  -set filename:f '%t_web' ../'%[filename:f].jpg'

# into target folder in same directory
mogrify *.jpg -strip -interlace Plane -gaussian-blur 0.05 -quality 85% -path ../web *.jpg

# into target folder in parent directory
mogrify *.jpg -strip -interlace Plane -gaussian-blur 0.05 -quality 85% -path web *.jpg
```

### Change file format

* Your EPS file is in CMYK colorspace. You need to convert it to sRGB before processing it

#### PNG to JPG

{% tabs %}
{% tab title="white bg" %}

```bash
//batch 
mogrify -background white -flatten -format jpg  *.png

// single
convert Chun.png -background red -flatten  png_small.jpg

// and compress
convert moom_ref.png -format jpg -quality 85% test.jpg
convert moom_ref.png -format jpg -strip -interlace Plane -gaussian-blur 0.05 -quality 85% test.jpg



```

{% endtab %}

{% tab title="black bg" %}

```bash
//single
convert *.png -alpha off image.jpg

// batch
magick mogrify -format jpg *.png
```

{% endtab %}
{% endtabs %}

#### EPS to PNG

```
mogrify -format png -density 100 -colorspace sRGB -background transparent -units PixelsPerInch -resize 2475x3525 *.eps
```

#### Extract alpha from PNG

```
mogrify -set colorspace RGB -alpha extract -format jpg *.png
```

#### Extract alpha from white

```bash
convert test.jpg -fuzz 50%  -transparent white result.png

//batch
mogrify -fuzz 50%  -transparent white -set colorspace RGB -alpha extract -format jpg *.png


// batch add alpha from white in pngs, save to new folder
mogrify -fuzz 50%  -transparent white -set colorspace RGB -alpha extract -format jpg -path ../mask *.png
```

#### Extract color from image

```
// select red, fill rest with black
convert test.png -fill white -fuzz 10% -opaque red output.jpg

// has black outline    
convert test.png -fill black -fuzz 20% -opaque red -transparent black output.png 
convert test.png -fill black -fuzz 5% -opaque red -transparent black output.png 

mogrify -fill black -fuzz 5% -opaque red -transparent black output.jpg *png

// select red only

convert test.png -fill black -fuzz 20% -opaque #B93C3C -transparent black output.png 


```

#### Converting images to black or a fill color

```
//batch overwrite
mogrify -format jpg -fill black -background black -colorize 100%  *.jpg

```

## HtTrack

```
http://duitbetter.com/2021/04/05/shader-dev-study-01-c-arnold/,http://duitbetter.com/2021/04/12/shader-dev-study-02-sidemask-pattern/,http://duitbetter.com/2021/04/20/shader-dev-study-03-height-to-color-pattern/,http://duitbetter.com/2021/05/09/shader-dev-study-04-moom-osl-shader/

+*.gif +*.jpg +*.png +*.mp4 
```

## Ultimate Mac environment setup

### Homebrew

{% tabs %}
{% tab title="packages" %}

```bash
#homebrew
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

#packages
brew install youtube-dl
brew install python
brew install imagemagick
brew install ghostscript
brew install npm
brew install storyboarder

$ sudo easy_install pip
$ sudo pip install --upgrade pip

#cask
brew install caskroom/cask/brew-cask

#update xcode
sudo rm -rf /Library/Developer/CommandLineTools
xcode-select --install
```

{% endtab %}

{% tab title="graphical" %}

```bash
#utility
    brew cask install google-chrome
    brew cask install obs
    brew cask install streamlabs-obs
    brew cask install clipgrab
    brew cask install spotify
    brew cask install handbrake
    brew cask install vlc
    brew cask install easyfind
    brew cask install station
    brew cask install sync
    brew cask google-backup-and-sync
    brew cask install the-unarchiver
    brew cask install zoomus
    brew cask install alfred

#code
    brew cask install atom
    brew cask install processing

# design
    brew cask install figma
    brew cask install blender
    brew cask install adobe-creative-cloud
    brew cask install zxpinstaller
```

{% endtab %}
{% endtabs %}

* xcode: <https://stackoverflow.com/questions/34617452/how-to-update-xcode-from-command-line>
* [Installing packages from terminal](https://www.howtogeek.com/211541/homebrew-for-os-x-easily-installs-desktop-apps-and-terminal-utilities/)

### Atom setup &#x20;

```bash
#Go to Menu > Install Shell Commands
#run below
apm install adobe-script-runner atom-beautify prettier-atom atom-spotify2 
atom-transpose case-keep-replace change-case copy-path duplicate-line-or-selection
editorconfig file-icons git-plus highlight-selected local-history project-manager 
related set-syntax sort-lines sublime-style-column-selection tab-foldername-index 
toggle-quotes atom-wrap-in-tag atom-ternjs autoclose-html 
autocomplete-modules color-picker docblockr emmet emmet-jsx-css-modules 
es6-javascript js-hyperclick hyperclick pigmentstree-view-copy-relative-path
lodash-snippets language-babel atom-jest-snippets one-dark-ui dracula-theme

##react-es7-snippets sync-settings  linter-eslint 

```

### Get all DMG

```bash
#utility
    open https://www.pureref.com/freedownload.php?build=OSX64.dmg&version=1.11.1&downloadKey=kwshPqIAWUNsGVwJYCjKag%3D%3D
    #utorrent
    #Microsoft Office
    open https://login.microsoftonline.com/?whr=scad.edu
    open https://depts.scad.edu/coronavirus/academic-software

# optimize
    open https://apps.apple.com/us/app/magnet/id441258766?mt=12
    
#creative 
     open https://www.blackmagicdesign.com/products/davinciresolve/
```

### Change screenshot directory

```
cd ~/desktop
mkdir screenshots

defaults write com.apple.screencapture location ~/desktop/screenshots
defaults write com.apple.screencapture type -string "png"
```

### [Disable Drop-shadow screenshots](https://www.dessol.com/blog/disable-drop-shadow-mac-osx-window-screenshots/)

```
defaults write com.apple.screencapture disable-shadow -bool true
killall SystemUIServer
```


# C++

## Pointers

```cpp
// delclaring pointers
int* ptr; // default value 0 when printed 

int var; // live in an address 0xA, think of it as empty container 

int var = 7; // assignment of 7 into the var container

```

* **What is a `Identity Matrix`**
* * A square matrix in which all the elements of the principal diagonal are ones and all other elements are zeros. The effect of multiplying a given matrix by an identity matrix is to leave the given matrix unchanged.
* **What is a `Pointer`:**
  * A variable that stores the memory address as its value. A pointer variable points to a data type (like int or string) of the same type, and is created with the \* operator. The address of the variable you're working with is assigned to the pointer: — [w3schools](https://www.w3schools.com/cpp/cpp_pointers.asp)


# Unreal Engine

##

| **Item**                      | Links                                        |
| ----------------------------- | -------------------------------------------- |
| **Documentation / Tutorials** | <ul><li>​</li></ul><p>​</p>                  |
| **Industry / Case-studies**   | <ul><li>​</li></ul>                          |
| **Books**                     | <ul><li>​</li></ul>                          |
| **Papers**                    | <p>​</p><ul><li><strong>​</strong></li></ul> |

## ​Notes

1. **Optimization**
   * figure out what to model and what to simulate (geo vs texture)
2. **Texturing**&#x20;

   * Real-world scaling

   * **Bitmaps**
     * Original&#x20;
     * Base Color&#x20;
     * Normal&#x20;
     * Roughness
     * Metallic&#x20;
     * AO

   * Quixel / Photoshop /&#x20;

   * **Bitmap2Material**
     * Use your photos to make bitmaps

   * **Substance Designer**
     * Seamless tiling&#x20;
     * Node-based

   * **Substance plugin (download via MarketPlace)**
     * sbsar files&#x20;
     * <https://source.substance3d.com/>
     * **in SBS file > Sepcific Parameters >  Expose Parameters**

   * **Create a new material  (node base)**
     * Add bitmaps from content browser: drag & drop into `Material Editor`
     * `TextureCoodinate` — UV tiling into Bitmaps
     * `blend`
     * `staticSwitch`
     * `3pointsLevels`
     * Description functionality
     * Convert to parameter
     * **Hotkey**&#x20;
       * **C —** create a frame to organize nodes
       * **3** — create RGB
       * **hold 1** — Create a constant value
     *

   * Child material&#x20;

## Cinematics&#x20;

* Navigation
  * wasd keys
* Sequencer
  * Linear editor
  * Change static mesh and state
* Camera Rig Rail
  * Easily create motion path for cameras
* Cine Camera Actor
  * Digital Film&#x20;
* Crane&#x20;
* **Master Sequence**
  * Possess-able cameras- Exist in level (camera-centric projects)
  * Spawn-able cameras - only exist in sequence
  * New track
    * Add camera > Animate via parameter panel

New Motion Design syllabus (real-time)

* Real-time,&#x20;
* Otimized workflow (all stages can be worked on at the same time)
  * Model
  * Texturing
  * Animation
  * Editing & compositing
* Team: a texturer, animator, compositor, director, project manager

## Questions:

1. **Cinematic**
   1. How to view through camera ?
2. **Texturing**
   1. How to texture HDA in unreal
   2. Subsurface scattering
   3. Emissive and glow materials
3. **Integration**
   1. How to get Houdini Engine in Unreal&#x20;
   2. Getting dynamics and simulations into Unreal


# Concert Visualization

Best practices

* rendered elements should be loopable or prepped to looped in compositing before further effects are done


# Dome-projection

## How to make a

### WHAT IS IT

A dome-projection is…. usually half spherical but may extend further (latitude)

Here are the existing full dome artists and projects that you get look up

* Diana Reichenbach
* The Illuminauts
* [http://www.synthestruct.com](http://www.synthestruct.com/)
* [http://www.mysquare.ch](http://www.mysquare.ch/)

### THEORY (WHY & SO WHAT)

Lorep ipsum

Visual grammar of the dome&#x20;

1. Cross-section view of a dome
2. Latlong composition
3. Dome master
4. Responsive 3d model embedded

#### FILE TYPES

* Size: 4K x 4K (4096 x 4096 pixels), no less than 2K x 2K (2048 x 2048 pixels)
* Format: png sequence, jpg sequence
* Frame Rate: 30fps
* Sound: Stereo or 5.1 mix
* Rendering tests
  * Size: 2k x 2k (enlarged to 4k in using plugins or other software such as Red Giant’s Instant4k, Nuke’s 4k upscale node, Gigapixel, ON1)
  * Format: H264 Mp4
  * h264 at 30fps

### How to view your dome animation

* Dome players – amateras

### How to make it

AE: VR Comp editor\
C4D: Spherical camera & Output settings\
Render full but lose quality\
Render 0 latitude & fit frame?\
Recommended settings\
– follow dome projectionist requirement\
Fulldome standards

### **B‌est practices & Things to consider**

#### Designing the animation for the viewer

The north of the Dome player is at the bottom part of the composition, so when you are building the visuals keep in mind that everything should be reversed, otherwise people won’t see anything… unless you are working for a 360 dome player, where the audience has access to all angles.

#### Speed

‌We will experience a different speed of our visuals at the Dome compared to playing back from the computer screen. For most cases, what you have animated will be faster on the dome. This matters as the scale of the dome is immense larger; making small details more apparent. ‌

#### Contras, luminescence, blacks

‌For Dome-projections, it is best to **work with a black background with high contrast on the colors of your visuals.** The light of the projectors will bounce around, therefore, making it hard to see the visuals if there isn’t enough contrast or the highlighters are too bright.

As the screen is spherical, a lot of the projected light bounces off the white surface and lights up the entire room. Then all black becomes grey.

In order to keep a decent contrast, the average level of bright pixels has to stay low, and large bright areas must be avoided (ie: bright skies).

#### Safety

Be aware of not causing your audience epilepsy or motion sickness. We are creating an extrasensory experience for everyone to enjoy, without making them physically sick.

#### Delivery to your team editor

Organization is paramount in a large-scale collaboration. The Illuminauts film was a 15 people project. To ensure the safe delivery of you r completed aniamtions or visuals to your editor, please follow the following guidelines.

1. Render out and upload a 4K x 4K .mp4 video file of your sequence. This will ensure that the entire sequence is uploaded and that we aren’t missing any parts of your sequence.
2. Please ask your project manager on the best way to upload the files eg. Google Drive, email, wetransfer,etc.
3. Naming convention
   1. PLEASE LABEL YOUR MP4 USING THE FOLLOWING CONVENTION\
      ACT#\_LASTNAME\_FRAME-NUMBERS\
      For example: Act1\_Reichenbach\_0001-5000.mp4\
      This tells me that this sequence belongs in act 1, that Reichenbach created it, and that if I was cross checking the file against a png sequence, I would need frames 1-5000 (5000 frames total).\
      \*If your Act has a specific order for the various parts, please indicate that in your file name, or send Paola and Desmond your desired order.\
      If you are having trouble rendering at 4K at this time, please export and upload a 2K x 2K .mp4 for Paola/Desmond to work with in their edit, that they can later replace with a 4K x 4K .mp4 when it is finished rendering on your end.

#### Delivering the film to the projectionist

‌Based on *The* *Illuminauts*‘ film at the Macon Dome Film Festival 2019 held at the Museum of Arts and Sciences, the ideal delivery format for the museum was **png sequences.**

When working remotely with your peers and team, and you need to pass each other renders to the main editor, please ensure that&#x20;

* the entire image sequence are zipped or compressed into a folder to avoid missing frames due to upload issues on an individual basis. and ensuring faster online upload
* &#x20;Always render an mp4 (even if lowre res) as a reference and backup, for the image sequences
* Also, be prepared to submit the files at least 2 days earlier than the deadline to avoid being late.

### TUTORIALS

### PREMIERE PRO

[360 video to fulldome workflow in Premiere Pro](https://youtu.be/xM_PDDpaD_Y)

#### AFTER EFFECTS

* Stabilizing Footage and Tracking 3D elements in a 360 scene
  * <https://www.premiumbeat.com/blog/vr-comp-editor-360-video/>
* using VR Comp Editor
* Creating a 3D environment to use 3D effects
  * <https://www.youtube.com/watch?v=lRjY8o2Ypg0>
* How to use Camsphere (good for blending effects such as trapcode)
  * <https://vimeo.com/125726168>
  * This is an after effects project set up for export to fulldome and VR. Please reference the tutorial for instructions on how to use the project file. The scripts associated with the project do a great job of blending Trapcode and other AE 3D effects (sometimes you can see the seams in the Adobe immersive plugins)
  * NOTE: To use the project you will need to install the plugins in the folder: FTUVPass, DuplicatewithConnections,

#### PHOTOSHOP

* **Creating a 360 spherical painting**
  * <https://magazine.artstation.com/2017/04/360-pano-painting-tutorial-jama-jurabaev/>
  * <https://studiobehind90.com/2018/11/01/how-to-360-virtual-reality-vr-illustration-photoshop-cc17-cc18/>
  * \*\*Using multiple layers when painting in 3D: <https://forums.adobe.com/thread/2401296>

#### **DOME PLAYER**

* Amateras Dome Player – Drag and drop player
* <https://www.orihalcon.co.jp/amateras/domeplayer/en/>
* **PARASITIC LIGHT CALCULATION TOOL – TO COMPENSATE FOR LIGHT BOUNCE**
* <http://nestimmersion.ca/parasit.html>

#### **PLUG-INS:**

* UNITY – Dome Tools: <https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/dome-tools-62664?fbclid=IwAR3lAbMQRkytVRTZQ8TBpDbO\\_iJ0HipQfaENWbxsxNYU6t9FDNscAElMZQ0>
* **C4D**
  * <http://blendy360cam.com>
  * <https://www.cineversity.com/vidplaylist/cv-vrcam/cvvrcam\\_install>

### Resources

* Latlong grid PNG

&#x20;Written by Desmond Du, Paola Baiz, and Diana Reichenbach Drag widget here[PrevPREVIOUSHow to pass Adobe Certified Expert Exam](http://nosleepcreative.com/2019/07/20/adobe-certified-expert-what-about-them/)

* [admin](http://nosleepcreative.com/author/admin/)
* [December 30, 2019](http://nosleepcreative.com/2019/12/30/)
* [No Comments](http://nosleepcreative.com/?p=25236#respond)

Copyright © 2019 NoSleepCreative

*
* &#x20;
*
* &#x20;
*
* &#x20;
*


# UI UX

<https://developer.apple.com/design/human-interface-guidelines/>


# Professional Etiquettes

Here is a short guide of things you should be doing in a successful collaboration or professional job

## E-mail Etiquette by Professor Dominique Elliott

### **General:**

* **#1: e-mail NEVER goes away:** Once you hit the Send key, your e-mail is there for all humanity to see… until the end of times.
* **#2: It can be very hard to judge the tone of an e-mail.**&#x59;ou need to be much more careful than in oral communication, not less.
* \#3: chances are it may be forwarded to someone it was not intended for.

### **Email formatting**

* Write a clear subject line
* Write a salutation, even on replies
* Keep it brief
* Don’t text message
* Bullet your main points or action items when appropriate

### **Courtesy**

* Always respond
* Respond quickly
* Take time to proofread (punctuation, grammar, spelling)
* Consolidate your e-mails. Don’t e-mail someone 4 times an hour.

Think about the questions you need answers to.

### **Professionalism**

* Use emoticons only if you feel it clarifies tone, in a professional manner. Not advisable to a superior.
* Avoid discussing private matters/issues.
* Remain positive in your tone.
* Do not blame others.

### **Tone**

#### **Always double-check your tone. The difference between:**

> “ If you ever get this project done….”

and

> “ When you get the project done…”

#### Bottom line: Before you hit send, ask yourself if you would speak the same way in person.

If you are on the receiving line of an aggressive e-mail, breathe, stay polite and diffuse the situation. Try to move the conversation to another forum.

> “I’m sorry you feel this way. Perhaps we could discuss it in person (or over the phone).”


# Woes

## **Making best of our the cards we are dealt**&#x20;

* Recontextualizing how we look at our cards, and coming out with new combinations to win the game, play different a game
* Reframe&#x20;

### Fighting the losing battle

Keywords: Murphy law’s&#x20;

### Confirmation bias

Pressure, peer pressure, expectations, confirmation bias - looking for the best parts from people and worst of you > Imposter syndrome > we are actively looking for how we are vulnerable and unworthy > neglect your self and identity&#x20;

### Questioning self-worth and imposter syndrome's

* Recruiters pivot, H1B first timers
* Unfair, question our self-worth,&#x20;
* leaving the country, death sense for your career, denial of opportunities or even try, taken away at the lat minute
* Unlucky ones , unfavorable conditions or circumstances&#x20;

### Embrace and Pivot&#x20;

* accept your defeat, and wait and prepare for the moment of glory
* more time to grow, patience, embracing uncertainty&#x20;
* Reassessment, and investigate how to&#x20;


# How to get better

Posted 10 Apr 2021, Updated on 13 Apr 2021

## **Abstract**

**What's the best way to improve as a motion designer?**

> *The best way to improve as a Motion Designer is your way.*&#x20;

There is no shortage of online advice from successful Motion Designers telling you the same things over and over: Do personal projects, put yourself out there, create and post something daily, or collaborate with people. Apparently, something is not working. The problem is that we have a septic focus on "becoming better" when we do not really know what better even means, or how does one measure that type of success. The real question to ask is **what kind of Motion Designer do you want to become**? How do you position yourself to differentiate yourself from others? One that specializes in After Effects expression/scripting? Or someone who makes beautiful Cinema 4D Octane renders? Or are you known for a certain type of aesthetic or style? I wrote a brief guide on how I positioned myself for success in my [Medium](https://desmonddu.medium.com/journey-to-an-art-school-full-ride-again-e67b3ff134b4) article, do check it out for my in-depth thoughts.

\
Everything begins with your intentions. The strategy is to niche down to your strengths and interests, and manifest those two things into your career or work. Take a look at Ordinary Folk, Vucko, Peter Clark, GMUNK, or any other successful artists. Think about what makes them outstanding, and how you can incorporate that into your career. One introspective framework to use the Japanese concept of "Ikigai" which translates to "a reason for being." To break it down simply, it is a compass of your soul that will bring you to where you need and want to be. A strong Ikigai lasts a lifetime, and you will never be lost because you know where you are walking. Once you identify what sort of designer or animator you want to become, start creating works that echo that identity. Personally, I positioned myself as an educator; someone who loves to teach and wants to develop a teaching career in the future. I demonstrate that through my YouTube tutorials and doing software workshops for students in school, it is as simple as that.&#x20;

\
As for a surefire way to get better at **motion design skills** (eg. design, animating, expressions), I realized that teaching is the best and fastest way. As the Physicist Richard Feynman said: "If you want to master something, teach it." Teaching is a way to translate the external knowledge you gained into something of your own. It crystallizes competency and expertise, allowing you to challenge what you think you know. Many of you reading this now will think to yourself: "But I'm not good enough" or "I'm not a master so I cannot teach". Personally, I believe that mastery is an act or behavior, not a role or label. You do not need to be a famed motion designer like Ben Mariott or JR Canest to teach. You demonstrate mastery by teaching even if you are just teaching a beginner how to use the pen tool in After Effects. Whether you do that via Instagram carousel posts, YouTube tutorials, or blogging, it is up to you. Find out what works best for you.&#x20;

## Understanding Intentions&#x20;

```javascript
// opening / self-portrait
tell me about yourself
What do you need help with 
what's on your mind 

// intentions 
What is your goal?
Why do you want to get better?
What does better means to you?
How do you think you get better?
When do you want to get better?

What's holding you back
    what are you afraid of?

// identity
what kind of motion designer do you want to become? eg. attitude / vibe / voice

what are you working on now?
    why do I need to do this?
    what is stopping you from doing it?
    when will start working on it?

Intentions
	what do you intend to do with your life?
	what are your goals?

Expectations
  What are you expecting/ trying to gain from this project?
  Are your expectations realistic?
	why do you have such high expectations?
	do you know your limits?

	why do you feel low when you don't do enough
	what is enough? do you want more ?
	how much more 
	lack of internal goals
```

## Learning to learn 🧠

### Level 1: Absorbing information faster - discovery

Application: Learn subject faster / master a software quicker

**Skimming.** Double the playback speed or the highest you can comprehend when watching YouTube tutorials, or download them if possible and do the same with VLC player. This is similar to speed-reading technique where you get a quick overview of what you are going to read, and the second time reading at a regular speed will help your brain . **Just copy whatever is being taught even if you do not understand.** Your brain will make sense of everything as you progresses, and what was unknown to you seems pretty apparent.

1. Sourcing videos with ClipGrab or youtube-dl
2. Youtube-dl can help you download videos automatically from a youtube playlist or a vimeo profile. This way you can speed watch or analyze a particular artist or a subject matter efficiently.
3. Speed-watching with YouTube Speed Controller Chrome Extension
4. Taking notes with your repository or wiki

An artificial intelligence can be trained by giving a good dataset. This is no different from a human being, we go through training, classes and lessons, and put whatever we learnt into practice. Over time, this becomes experience and intuition or unconscious competency. The only difference is the speed and effort. A machine can be run perpetually and remembers all its data perfectly compared to our short working memory. That said, we still can leave from machine learning in its training model. We need to put our mind with the right type of data, a consistent set preferably. Hence, when you training your creativity, you hone in on a focus and watch tutorials maybe on Blender software only, and go deeper from there. The key is that deep consistency.

### Level 2: Selective learning, focus, analysis

1. Download the video you want to analyze
2. Select a scene to focus on: I will bring my clip into AE and trim the composition to a segment
3. Play it frame by frame: Slowing down the playback will help you catch details you would most often miss
4. Make it grayscale: Sometimes there are just too many visual elements going on so remove distractions where you can
5. Focus on one element
6. Find patterns:There is usually a pattern behind the animations; nothing is truly random.
7. Be patient: It took me 2 weeks to figure out the solution for animating the icons. I had to experiment alot and make mistakes
8. Have fun: Don't lose of the fact that we design and animate because it brings us joy and value to our life so don't be so hard on yourself if you cannot figure something out.

## Master Study 🦋

### Abstract

Our biggest thing to focus on is not on software skills or expressions but our eyes as designer as animator. Why do master studies? When I was working at WarnerMedia, most of my work was broadcast and I wanted to try something but it's hard to get out of our comfort zone and do something different. We have a finite amount of time to learn or get better at something, so the question is how do we effectively become better motion designer.

Would you do dailies which is a practice that you involves making a creation every single day and posting on social media like Beeple? But not many people have that much time and energy to dedicate one hour or two hours each day, even so the payout of doing dailies is somewhat of a lifelong process. You might have to stick it out for a year before you see great results. In addition, it's not that easy to just start doing dailies and committing to it, it requires discipline. It's like exercise, it's good to exercise every single day but would you do it?

Hence effectiveness and efficiency are both factors to consider: How do we get the best / most results from doing little. How do we optimize our learning

**Keywords:** How to learn better,

### What is a Master Study

* An investigation of what makes a successful piece of work, be it techniques, aesthetics, or concept.&#x20;
* Reverse-engineering how it was produced, but rather having a building your own framework to reach a high production quality work. — Expanding your comfort zone, upgrading your skillsets, making sense of things in your own sense
* An exploration and discovery of ...
* * **You breakdown and recreate** your favorite motion graphics/animation/video frame by frame and analyse how a shot was crafted.That means reviewing frame-by -frame how a sequence work

### Why should you do Masters Studies

* Emulating our role models, when we look at a succesful motion designer or motion design work, we do not just marvel at how wonderful they are, but rather we see a piece of ourselves in them; a better version.
* Lack of time, and not knowing what will work and will not. It's about failing faster. The more wrong we are, the more "correct" our next creation is..

### How does the process of Masters Studies informs learning: Guided Imitation

Often we want to learn a new subject faster with comprehension and mastery. To learn software, your go-to method would probably be watching tutorials and following along. That may seem like a bore to some but there is a deep concept behind that process and that is call:

> Guided Imitation

**This is a concept** used in language learning. Language learning is not an easy feat but its methods can be applied to just about anything when it comes to learning.

*WIP: A strange thing to ask would be what is define what makes a learning/comprehension successful one - retention, ease of recall, application, remixing.*

*When materials has been developed to present Spanish as a spoken language, and the skills of understanding and speaking are accordingly emphasized. In order to understand the materials, one must first understand the method upon which they are built. This method is known as **GUIDED IMITATION.** Its goals is to teach one to speak easily, fluently with very little accent, and to do this without conscious effort, just as one speaks his own language without conscious effort. There are two very important aspects of this method.*

*First learning a relatively small body of material so well that it requires very little effort to produce it. This is **OVERLEARNING**. If a student over-learns every dialog and drill as he goes through this book, he will almost certainly experience rapid progress in learning the language.*

*The second aspect is learning to authentically manipulate the sounds, sequences, and patterns of the language. The important implication here is the reality of both the model and the imitation. The model (teacher, recording, etc) must provide Spanish as people really speak it in actual conversations, and the student must be helped to an accurate imitation. Above all, the normal tempo of pronunciation must be the classroom standard; slowing down is, is this context distortion. —*&#x45;xcerpt from Foreign Service Institute. - Spanish Basic Course Volume 1 Student's Textbook

In short, MS is a form of self-guided imitation exercise. By not being guided by a person or a tutorial, you are left to formulate to your own thoughts and ideas which is one of the most difficult things to do in life. But just like any other skills, as you practice how to think for yourself, the process gets easier and more enjoyable.

### How to do Master Studies

#### Level 1: Replication / Emulation

* context&#x20;
* focus on replication, no need to be concerned about idea, design motion test
* reverse engineering your success
* empowering your identity

#### Level 1.5: Innovation / experiments

#### Level 2: Translation / Re-contextualizing

* changing flavor or the subject matter

#### Level 3: Shared transformed vision

* Explain clearly to your team
* Creative confidence and flexibility to lead towards ②
* explain 1️⃣ clearly to your team
* creative confidence and flexibility towards 2️⃣
* more rationalization, build expertise and mastery

#### How to select a master study project

Pick a studio or artist

* Pick a work
* Pick a shot
* Pick a discipline
  * **Design**
    * niche: modeling, texturing,&#x20;
  * **Animate**
    * niche
* Select a deadline
* Document your learning and present&#x20;

### Conclusion

The truth is that there is no shortcut to getting better at anything; time and effort will be always be a constant and the results that we developed might always seem invisible to us. What we can control is our lifestyle and behavior that brings us closer to our goals or success .

#### Bibliography

* [Sasuke Chunin first exam](https://youtu.be/3jnuxvb4Yik?t=333), 1st Tomoe — Replication
* [Sasuke vs Orochimaru](https://youtu.be/MwJUK2JtSgw), 2nd Tomoe — Clarity, higher reading ability
* [Kakashi vs Zabuza](https://youtu.be/uKtLZzEtoNw?t=110),  3rd Tomoe — foresight
* [Sharingan training with Sasuke](https://www.youtube.com/watch?v=Mjpw4EpPBu4)
* [Rasengan training with Jiraiya](https://gogoanime.so/naruto-episode-87) - 15 mins

## Mentoring 🪞

### Why get mentoring or coaching?

I believe everyone has the answers and talents they are looking for in them already. They are just laying dormant and unrecognized. A mentor's roles are to:

* **Hold a mirror to your whole being,** and bring to your attention what matters. This is crucial because a mentee has not been equipped with tools to think for themselves or deeper, or asking the right questions.
* Organize your thoughts and feelings by guiding you from topic to topic, summarize and paraphrasing what you said&#x20;
* Asking the right questions and debunking myths
* Hold you accountable for things you say are doing to do

### What mentoring is not

* Someone who gives you instructions to follow — because ultimately you should have more ownership of your growth and life, and learn to think for yourself and your future.

### What you should aim to get out of mentoring

* **Discovering your Element**
  * **Everyone have different modes of learning; what works for a person might not work for you.** You have to identify is your optimal way of learning. Is it through sheer practice and experimentation, or do you prefer analytical approach through deconstruction of an animation.
* **Unlearning**&#x20;
  * **Alternatively learning something else might help with the subject better.** eg learning Javascripting helped my comprehension of the procedural workflow of Houdini in terms of how data and attributes are translated and modulated to become a visuals.

## Developing your creative practice ⭐️

![](/files/-MYQ7-QhXstZ-kLTEGO2)

### What is a creative practice

{% hint style="info" %}
It's about how you think for yourself and formulate your own thoughts based on informed decisions
{% endhint %}

* an animation > reel > portfolio >career> creative practice>identity
* methodologies and disciplines eg. pencil and paper, painting, writing, coding, live-action
* subject matter
* services: consultation

### Compound effect

*

### Documenting your experience&#x20;

```
what is your goal
why do you want to do it?
what is holding you back?
what you are ignorant about
```

### Documenting your procedures and methodologies&#x20;

Why: rationalizing how we do the things we do, mapping what we know and what we are ignorant about that we&#x20;

* Frequency: once a week&#x20;
* Broad strokes: filter

```
MD 
    C4D
    After Effects
        tips trick · cookbook - technique, procedures, the how-tos
        best practice - that that people should do 
```

## Teaching to learn ❤️

> If you want to master something, teach it. *— Richard Feynman*

Everyone is obsessed with being a master at their own domain and they believe that it's a title or role reserved for the elite few. The question to ask here are:

```
How do you know someone is a master?
What qualities makes a master
What actions or behaviours

// turning point
Do you think it's a question of role (master) or actions/behaviours (mastery)
```


# Portfolio / Showreel

What am I looking for when reviewing a reel or a website.

## **Abstract**

In late 2019, I saw a senior motion designer position at my company; and thought to myself what it takes to be one. I don't think it was a matter of technical skills because everyone on my team seems to able to perform at similar levels. That's when I thought to myself that it was a matter of "experience and the 'eye'; it means being able to spot mistakes and have confidence to approve a design . That is why I decided to write my own guide of what I deemed is good as a way of training my understanding of what it takes to be a senior level designer.

## Project / work review

![4 zones of Awesomeness by onepixelbrush](/files/-Lxby3_FX6YY-E4Xn7xo)

Above is good way to set parameters for what makes a work good.

## **FAQs**

1. ***I did a project collaboration in which I was responsible for secondary elements (eg. background) but the production values lies in the the 3D rendering and animation that was not done by me. Can I still put that shot in my reel?***
   * You have to ask yourself what are the implications of putting that shot in the reel:
     * Clients or employers will definitely ask if you did the 3D stuff or if you can recreate it
     * You are promoting your peer's work rather than yours so he/she will get the job instead
     * You are highlighting your weakness rather your strength; you are wasting screen time to showcase your skills and talents!&#x20;
2. ***My peers want to put a shot from a collaborative project you did together in his/her reel even though you were the one responsible for more than 80%  for that shot. Should I give them permission?***
   * The situation is reversed now in this case and so is the answer. If they want to put it in their reel sure; **they are promoting your work.**
   * However, do have your peer credit you for that shot wherever he or she post the work eg.website process page or showreel video description.


# Design with cooking

Making sense with the art of making food

## THESIS

If you searched the definition of cooking, you would find “the practice or skill of preparing food by combining, mixing, and heating ingredients.”  If we were to switch the word “food” with “design” or art”, doesn’t that definition still seemed applicable? To me, I find the art of cooking not so different from art and design. Both realms worked in a similar fashion of creating something pleasant be it through how it looks or how it tastes. Hence, we can view the process of cooking as an analogy to the process of how we create art and design. With the framework of seeing the final result of a visual design as a “dish” and the act of cooking as the “process”, we can have a better mental model of creating fantastic visuals. To do so, we need to define the main components of cooking and how it relates to design. <br>

Keywords:  cooking, terminology<br>

## BODY

Ingredients&#x20;

* They are your inspirations, sources, they could be a fine art painting, the aesthetics of your favorite designers, music, or it could even the life experience of traveling. There is no fixed definition of what your visual ingredient is; it is simply the fuel that helps you create a creative project.  The more ingredients you have, the more options or combinations you have to create a variety of dishes.&#x20;
* Having understood that, we also need to know about common or popular ingredients that we all have access to such as Pinterest or the Google Search Engine. While they are wonderful tools to gather visual inspirations, you need to know that many would use them as inspiration or reference due to its convenience of providing you with images. These “common” ingredients, however, means that the chances of you cooking a dish similar to your peer is rather high. So how can your cooking stand out then?
* What you want to do is to find “exotic” ingredients, things that only you or limited people have access to. It could be looking at arabesque patterns in a library book, or watching non-digital media work just as industrial design, or watching a documentary. The key is to be conscious that you have to “hunt” down your ingredients by yourself; instead of letting the internet do everything for you. You are the one who controls what you put in your cooking.&#x20;

Cooking — Tools and skills&#x20;

* There are a plethora of tools in the kitchen from a knife, to a frying pan, to a crockpot; there is always something out there that can help you cook better and more efficiently. In a way, they are kinda like digital softwares like Adobe Creative Cloud, 3D software like Cinema 4D, or traditional skills like drawing or painting. It is good to learn a variety of tools to add into your toolbox so that you can best wield the best tool for the right occasion. Learning to wield and apply these tools involves knowledge which you can get from tutorials, books, learning from your peers or teachers. The more practice with your tools the better you get.

Recipes&#x20;

1. These are online tutorials, books, guidance and instructions from peers, teachers or mentors. Whether you want to follow a recipe step-by-step or adapt to your own cooking is entirely up to you. However do know that, one day you need to be creating your own recipes; you have got to translate the amalgamation of your skills, knowledge, and experiences into a formula that can be deemed yours.&#x20;
2. To quote Johannes Itten, a swiss painter associated with Bauhaus, “Learning from books and teachers is like traveling by carriage, so we are told in the Veda. But, the carriage will serve only while one is on the highroad. He who reaches the end of the highroad will leave the carriage and walk afoot.” One day, you will reach a stage where you have enough skills and knowledge to complete the task that is given to you, but beyond that you have to forge your path and convey something that you think is relevant to the world, to reach a higher level of existence in this creative practice.

Taste

1. Finally, we have Taste. Taste can be equated to the aesthetics of a visual; how beautiful an image looks to the beholder. However, it is important to know that people have different taste and definitions of what is beautiful or good to them. An example I often give is that if I like to cook Japanese food to someone to someone who prefers Indian food, they may not necessarily enjoy it . Translate that to designer-client relationship, my preferred visual solutions, no matter how awesome it is rendered or animated, may not be what the clients want to use to communicate their products. Hence, the two of us might not get along but it’s not personal; it is simply not their cup of tea.&#x20;
2. Great food is a fine balance of the ingredients you procured, the tools and means on how you cook them, and presentation which ultimately bring forth the great taste. How you grow as a designer is not to make an exciting intense flavourful dish, but it is the sensitivities to taste the subtleties in food, analyze them so you can apply it to your cooking, and control the sensitivities of taste that brings forth the best taste.

## SO WHAT / CALL TO ACTION

* Using the cooking framework, hopefully you can better understand what sort of taste you want to create with your food and how you grow as a designer by finding “ingredients” and developing “skills and tools” to cook them.
* When I first began my journey into art and design (visual effects actually), I was completely new to everything be it the software used, the ideation process or the professional pipeline to produce a film. Due to my inexperience, I simply did not understand the “design” world. However if we were to compare the process to a relatable activity that most of participate in such as cooking, perhaps we can better understand things.
* There are many ways to understand how design makes sense to you, this is just my way of making sense of art and design, so you should develop your own too. In the book, A Technique for Producing Ideas by James Webb Young, he describes the process producing ideas creative process like a kaleidoscope. The more pieces of glass you have, the more beautiful the result is.&#x20;
* “The kaleidoscope, as you know, is an instrument which designers sometimes use in searching for new patterns. It has little pieces of colored glass in it, and when these are viewed through a prism they reveal all sorts of geometrical designs. Every turn of its crank shifts these bits of glass into a new relationship and reveals a new pattern. The mathematical possibilities of such new combinations in the kaleidoscope are enormous, and the greater the number of pieces of glass in it the greater become the possibilities for new and striking combinations.” [Link](http://www.advancedhiring.com/portals/0/docs/a%20technique%20for%20getting%20ideas%20-%20james%20wood%20young.pdf)

Resources&#x20;

Here are some supplemental media about cooking that I personally feel is associated with  art and design. Have a watch!

* [Jiro Dreams of Sushi](https://www.youtube.com/watch?v=M-aGPniFvS0)
* [Ants on a Shrimp](https://www.youtube.com/watch?v=Q7SYpav7a_k)
* Netflix’s Chef's Table: Pastry Episode 4 Will Goldfarb


# Media theories

## Medium is the message

It is not so much about the output of the medium but rather how it shapes culture and society

Take for instance:

**Smartphones vs landlines**

* Back before smartphones or Internet, we only had landlines to communicate over a distance. If someone did not pick up the phone; that was it.
* With the Internet and our phones, we are constantly connected regardless of time and space, and we even have read receipts,&#x20;
  * This generates expectations of: immediate response, constant connectivity, fast-paced communication
  * The way we live our lives might be accelerated due to these factors&#x20;

**Television vs Netflix**

* Television: top-down distribution, and plays an episode only once; if you miss it you will never get to watch it again
* Netflix: you decide what you want to watch, when you want to watch, how much you want to watch
  * generates infinite distractions

**Radio vs Spotify**

* Radio: you listen to what was playing and you cannot control it
* Spotify doesn't give you music; it gives you access to music

**Search Engine vs Recommended feeds**

* I used to actively search for what I want to watch on the Internet but these days YouTube has algorithm to decide what I think I would like
* Subconsciously, I let the Internet decide to think for me

**Writing vs auto-correct**

A question i posed to my professor was what would happened to society if  advanced machines did the thinking for us, and to which he said: "well, it has already happened. Take a look at auto-correct and word suggestions". Isn't that in some way controlling the way we think?

## Post-Cinematic Affect


# Post Cinematic Affect

## **Post-Cinematic Affect**

Post-Cinematic Affect is about what it feels like to live in the affluent West in the early 21st century. Specifically, it explores the structure of feeling that is emerging today in tandem with new digital technologies, together with economic globalization and the financialization of more and more human activities. The 20th century was the age of film and television; these dominant media shaped and reflected our cultural sensibilities. In the 21st century, new digital media help to **shape and reflect new forms of sensibility.** Movies (moving image and sound works) continue to be made, but they have adopted new formal strategies, they are viewed under massively changed conditions, and they address their spectators in different ways than was the case in the 20th century. The book traces these changes, focusing on four recent moving-image works: Nick Hooker's music video for Grace Jones' song Corporate Cannibal; Olivier Assayas' movie Boarding Gate, starring Asia Argento; Richard Kelly's movie Southland Tales, featuring Justin Timberlake, Dwayne Johnson, and other pop culture celebrities; and Mark Neveldine and Brian Taylor's Gamer

Affect - influence something or make a different too

Simply put, the theory is about **what it feels like to live in affluent west in the 21st century**. It talks about an emergence of a different media regime where media reflects reality, and that it addresses the audience differently than in 20th century; shaping new ways of response. The world that we live is a world of hypermediacy, and ubiquitous digital technologies. It is abstraction of social processes but they do not represent them entirely

Examples of hypermediacy: Mosaic of Kali Yuga, Requiem of a dream, Deadpool, Kill the Ego

## What I will be doing:

A short film using live-action footage to create a nightmarish montage about our contemporary world system. The imagery will irrational things we do these days; buying what you want but what you don’t need, defensive mechanisms, overthinking and inaction, overwork and unexamined, etc. All of which will be used to remind viewers of the medium that they are watching. Eg.

experience of the medum is itself an experience of the real and authentic

Keywords:

Metamorphosis

**Course Project**

Because this course is not only concerned with your knowledge and understanding of critical theory, but your ability to apply it to your own work, this course requires the production of a project. Typically this project is an adaptation of what you study for your term paper, but does not necessarily have to be based on your term paper research.

The project is the adaptation and application of some theory we examine in this course, either in a lecture, or through the term paper, and then used in the production of a finished work. This project is broken into several stages based on the work flow typical to media production, but these data points in the process can be adapted as needed to suit projects different from animations, motion graphics or visual effects-type work. Such variances are encouraged, but should be discussed before you start working on them.

You are encouraged to produce an innovative, interesting project in this course, and experimental projects that fall outside the parameters of standard media work are encouraged.

This project must be documented in a process book, showing the development of the ideas and the application of the theory chosen for the production of the project. Students are expected to be pro-active on their own behalf, working and developing their paper/project on their own. If you have a concern or problem, it is your reponsibility to come see the professor.

When preparing documentation of projects that are non-traditional, please bear in mind that your project should be no longer than you would be willing to sit through if it was someone else's work. Please try to confine your length to 5 minutes or less.

Benchmark 1: Pitch (Project Proposal Presentation)

Length: 5 minutes Due: Class 6

Instructions: You will have five (5) minutes to present. Have an explanation for what you want to do for your project, so get to the point! Any materials that will help explain what you want to do should be part of your presentation, such as tentative storyboards, mood boards, concept sketches or other visual aids to make your proposal understandable are highly encouraged (and required). Use an appropriate presentation software such as Microsoft PowerPoint to prepare your presentation; Adobe Acrobat is not appropriate for presentations.

Benchmark 2: Storyboard & Mood Boards / Proof of Concept Due: Class 9 in Dropbox

Please schedule time to meet outside class if needed.

Benchmark 3: Animatic/Alpha Version

Due: Class 12 in Dropbox

Please schedule time to meet outside class if needed.

Benchmark 4: Description of Theory Use

Length: 1-2 pp, print out to hand-in DUE: Class 15

This is a short paper discussing specifically what the theory you are using in your project is, how it has been used, and making the connection between that theory and your project explicit.

This statement is brief: it must get to the point with a minimum of verbiage and be explicit about what and how the connection between theory and practice has been made in your project; it is an essential part of your course project.

Benchmark 5: Roughcut / Beta Version Presentation Due: Class 15 in dropbox; will screen in class

This is a presentation of the rough cut in class. Please dress appropriately. You do not need to prepare a powerpoint explaining your project, but you should have a presentation to show your progress. Expect this class to be a group crit of what you have actually done for the project.

Benchmark 6: Finished Project Presentation and Process Book

Length: up to 5 minutes

Due: Class 20 on your flashdrive/DVD to hand-in

As your course project is primarily about the process of taking your theory and developing a project based on your understanding, you will need to document the design and development process in a process book.

A Process Book includes all your notes, sketches, ideas, annotations on your research and design concepts for the project. At a minimum, this should cover a description of the theory, your brainstorming and concept development, as well as notes related to the implementation of the project.

While a fully realized project may be impossible (as with some animation and interactive design work), students are expected to attempt to produce their project as fully as possible within the constraints of the class. This process book documents this work, and so is an essential part of your finished project.

All final completed work for this class will be handed in as both a print-out (for written material) and on a flashdrive or Data- DVD for all written, visual materials, presentations and other material. Flashdrives/DVDs will not be returned.

Checklist of Materials to Hand-in:

(1) a print out of the final paper and the draft paper

(2) an electronic copy (.pdf or .doc) of the final paper (on the flashdrive or DVD)

(3) your final project (on the flashdrive or DVD)

(4) a digital copy of your process book (on the flashdrive or DVD)

(5) electronic copies of all your handed-in summaries (on the flashdrive or DVD)

(6) a flashdrive or DVD with all files burned to it

(7) all media has the Project Slate Template, included in the Dropbox to identify any project video you hand-in at

\_\_\_\_\_

\_\_\_\_\_

\_\_\_\_\_

\_\_\_\_\_

\_\_\_\_\_

\_\_\_\_\_

\_\_\_\_\_

the start of the file


# Marxism, Reproduction and Aura

Marx, "Capital" excerpt;&#x20;

●	Utility = value ≠  the amount of labour required  ≠ & = commodity presents use value and exchange value

●	Labour twofold nature - use value cannot confront each other...

●	Bodies of commodities = matter + labour

●	Value in commodity A exist in relation to commodity B

●	Labour creating value for a product is a value itself

Benjamin, "The Work of Art in the age of Mechanical Reproduction";&#x20;

●	No identical reproduction in a work of art due its missing presence in time and space

●	Aura of art is reduced when it is mechanically reproduced

●	Uniqueness = inseparable from its being imbedded in the fabric of tradition

●	Films makes you unable to think; your thoughts are replaced by moving images compared to an arrest by a painting

●	Public is an examiner, but an absent-minded one

Critique of Digital Capitalism Chapter 3

●	Illusion of infinite resources of the digital production without any real expenditure

●	Aura of info: separation of the meaning present in a work from the physical representation of that work

●	Capitalist paradox of escalating value - constant demand to create more commodity value in order to extract more wealth from society ….

●	Digital copies are all identical originals

●	Rejection of real expenditures required…

●	Limit of a digital work not based on time but rather on its availability within contemporary tech. Obsolete > emulation

●	Digital - accumulation and management problems

●	Illusion that digital is immaterial

●	Reproduction is the source and vehicle for a work’s aura

●	Aura of digital suggests magical production without consumption =  digital capitalism and elision of capitalism

●	Abbing: Art became less obscure, more accessible and thus less magical because of technical reproduction

●	Aura is extended through copies rather than diminishing. Authenticity becomes a meaningful value once there are reproductions of an art work, similar but identical in appearance to their source

●	Art with dual nature: history testimony  and the relationship of that object to the tradition that produced it = physical and spectator’s knowledge

●	Uniqueness of IP: right to read than own a copy

Conclusions

●	Theories are lenses that help to see, analyse, and dissect our world. There is no “correct” theories but ones that help us see things with clarity better.


# Heuristics & Authorship

### Intentional Fallacy / Wimsatt & Beardsley

The reading discusses about linking the author’s intention to the artwork and its implications. Even though a work is birthed from the author’s design or plan in his mind, it does not mean we should seek out the roots of the artist and his prestige into reading his book.&#x20;

### Death of an Author / Barthes

The text talks about how we are always seeking closure in work; to find explanation or meaning from creator. However, Barthes argues that that the author has no power over his words that belong to the reader who interprets them.That is to say the social and cultural indicators of the author is not correlated to how one interpret the text. The text is itself a thing of its own, and its value should judge on the words alone; what the word themselves actually say.  The decoding of the symbols is for the reader alone, and the author and process of of writing is not of importance. Barthes’s notable examples include the Van Gogh’s madness and Tchaikovsky's vices. These two artists are renowned for their tragedy, hardship or extreme circumstances that pushes the value of the author into the work itself. As seductive as it is to bring the richness or sufferings the artists experienced to empower the work they produced, it is the art, in this case “language”, that speaks for itself. Simply, we are removing the ego from the artwork or text, and examining and understanding for what it is. Yet, it is tough to do so, the reader will associate the identity of author to valorize the text; trying to figure out the author’s intentions and the message or meaning he is trying to make

Instead of finding closure with the author or the artist, one should see a text as what it is, and from there make their own interpretations.

The work is what it is, period.

### What is an Author / Foucault

In summary, the reading suggests the detachment of the author from the writing and text he produced. It is similar to an acousmatic experience when listening to music, so instead of being concerned about hearing a sound without an originating cause to be seen, we are concerned with simply what the language is trying to communicate and it does not matter who was the one who wrote it.&#x20;

On closer research, this text is a response and critique on Barthes’ thesis. While both agrees that the role of author has somehow empower the text they produced, however, in different ways. Foucault complicates the notion of what it means to be an author, he does by asking about the function of the author.&#x20;

Reversal of required authorship in scientific and literary text

There is a need to seek out the identity of author and his background to make out the meaning of his text = author plays a role in our view of literary works

Historical analysis of discourse

Author makes a discourse of a subject possible, allowing for more divergence

I suppose the author’s intentions, conditioning, beliefs are part of his branding. We use the Gestalt theory between the relationship of the author and his production. The author can be akin to the whole, and the sum of the parts are his text.

### The originality of Avant Garde / Krass

Blurred distinction the valorization of production of artwork copies - in what sense is the new cast an original? (Rodin’s gates of hell) Is this not a violate of the period  style&#x20;

Citation as reproduction — everything we do is a reference to something that has been done, be it nature, paintings of old masters, technique. Hence, isn’t everything we do a copy?

Discourse of originality — In avant-garde, originality is something that everybody aspired as it possesses a new kind of origin. With the belief that one is the original creator, his or her prodution will share the same uniqueness.

The grid as a citation —  A refusal of speech and a form of silence, hence a ground zero for artist to work on.&#x20;

Representation > Picturesque ?

What if we do not repress the concept of copy — Since everything is a referent to something of the past. A depiction is a reference from one code to another.&#x20;

Everything is a remix&#x20;

Does it matter if  we copy? Plagiarism as a negative form of author.

Is an experience and social activity a referent?&#x20;

Does a copy or remix introduce a new form of discourse

A tree as an analogy; everything came from the roots, above the ground as a strong big trunk, then branches off in an endless replication

Michael Tovey’s Design Trends: We always look back into the past, maybe that’s all there really was

Eg. The Critique of  book is an example of the discourse of reproduction and citation

In this course, we  are creating our own branch / twig from the theories that have already been established\*

### Critique of Digital Capitalism / Betancourt

As my comprehension of authorship progressed, I came to understand the third kind of authorship, “digital authorship”, as our digital footprints; what we upload, like, commented on the Internet. By using these authorship, companies like Google and Facebook cash in on our modes of interest and activity to synthesize a commodity or at least lead us to one through advertisements. Hence, the more time time we spend on the Internet, the more we are “writing” information for companies to valorize on. Hence, as stated in the book, “the digital transforms social activity into commodity forms”.

Status & behaviour inito commodity —Translation of agency apparent in history, biography, psychology > immaterial commodity&#x20;

Other arguments / thesis mentioned in the book:

Digital technology reflects the capitalism in contemporary society while having an invisible framework > A voluntary authorship in which we give out personal information for the sake of convenience and accessibility&#x20;

without considering the repercussions. It is has become a new normal for us to connect every app to our digital profile. We are under constant surveillance yet we do not take actions about it. Our privacy has been compromised and violated willingly, yet unknowingly.

The only way out is not to participate in the tools created by Google or Facebook or social media.

Unlimited potential without human intervention > Facebook content delivery algorithm

The veil of free cost,accessibility,unlimited production


# 02 Semiotics

**Thesis**

* Imagination is an act of knowledge; baroque representation turns on language and its formulas
* The total has another effect than the adding up of the parts; there is the remainder.
* **Grand rhetoric:** To defer perception is to engender a new meaning. Like a riddle, there is no fun if you solve instantly but if you took great effort and time to arrive at the solution, you will find great joy and satisfaction with the meaning. “The forced” participation empowers the viewer to find meaning.
* A myth is a t**ype of speech** not confined orally, but also to modes of writing or representation
* The special trick of myth is to present an ethos or beliefs as it was a natural condition of the world, though however, it is simply a man-made perspective. A myth expresses the intentions of the source, be it a storyteller, designer, or writer.
* The evolved definition of myth: any cultural activity that implies an ethos or ideology as the focus of belief.
* A myth is not just speech but also a a form of communication in a culture, that promote the myth-makers own position.

**So what? & Notes**

* In a way, when we use abstracted graphics or visuals in our projects, are we not using the same rhetoric as Arcimboldo did? In motion graphics, we are encouraged to seldom use a direct representation of a concept or a product but rather use related images to create a meaning that arrives back at the concept.
* Composite heads: heads hesitates between coding and decoding. We see the whole (portrait) first, then the sum of its parts (vegetables and fruits). Duality of visual communication of both direct and ambiguity.
* Metaphor dependence on coup de force ( A sudden, violent act.)
* PES would be a modern-day Arcimboldo; orchestrating animation with auditioned everyday items
* The uncanniness of Arcimboldo's paintings play on two levels; objective and suggestive. Hence is what you see what it really is? A graphical friction. A duplicity of graphisms.
* Metaphors, metonymy(conceptual), allegory, allusion, antanaclasis, agnomination
* Builts off the previous class on authorship and intentionality, intentions reaches a depth of fun and playfulness
* **We are visual magicians that draw from many centers of culture to concoct an illusion or a mystery that draws the participants close**
* A myth is like a magic trick, the wonders of the magic is only appreciated if one believes in it. Or rather it is like a conjured illusion. For example, Malaysian politicians would start construction projects for the public to create the myth of being generous and compassionate, and that people are willing to vote for them. In this example, another metaphor would possibly be that it is similar street-cred. The stories associated with modern products or figures creates a mythic appeal that people succumb to.
* My understanding of Barthes’s myth is that it is a discourse, any medium can contribute to the discourse, giving it the power to become a natural condition of the world. A dominant discourse of ideology becomes a center where all unique expressions are positioned.

\*Paraphrased notes from online sources used in this reading summary


# 3 Process?

## Abstract

Does it matter how your art is made? Or how you arrive at the solution. Perhaps it does or it might not. The value of your project can shift based on where you want to focus on.

Betancourt, Intellectual Process, Visceral Result

### Thesis&#xD;

Automation of art-making raises the question of **where does the genius lies; in the art made by the machine, the design of the machine by the creator, or the machine itself.**

### So what? & Notes&#xD;

We fetishize objects and monumentalizing them on another realm but that should not be the way. Art should shift consciousness and not be just an item for idolatry. The mental or abstract concept that one generate from interacting with the art is more important.

The reader as the author plays a huge role in generating variations to infinity experiences.

Perhaps the question of how should we situate the artwork should be supplemented with another question; are we trying make money here, or are we trying to change / shift culture, or are we just making art for interpersonal experience&#x20;

As for human agency in art making, there is no need for one to actually make art physically by himself; you can pay someone else to do it for you and it is still just acceptable. An example would be Damien Hirst's For the love of God, an artwork that he did not make by spending hours in the dark concepting a masterpiece,

## &#x20;LeWitt, Sentences on Conceptual Art&#x20;

&#x20;Art is not just following conventions, it is whatever you want to be; creating new meaning and experience.&#x20;

\#03 Illogical judgements lead to new experience.  I relate to this sentence as most of works are informed by automatism. It is not just when I am in a “flow” when making my design. It is also contributed by other factors such as inane conversations and critique with my peers, delayed procrastination, reading books and so on. My whole life is a design methodology in which I identify essential pieces of my project, which I call “omens”, and synthesized and translate them into my project

\#18 One usually understands the art of the past by applying the conventions of the present thus misunderstanding the art of the past. The value of art changes over time, we need to look at art within the time period it was created

\#32 Banal ideas cannot be rescued by beautiful execution. What there are many “eye candies” out there on web or social media, that does not mean they are special. It simply means that you satisfied a brief. A good design is one that sparks discussion and inspire innovation.

|   |
| - |


# 05

**Paper**

**Eisenstein,** "The Cinematographic Principle and the Ideogram";

**Burch, "Chapter 1," Theory of Film Practice***, "*

**Thesis**

* Combination of two hieroglyphics does not = sum but product
* Translate that into cinema, you have a montage that juxtapose with one another to create meaning
* The shot is no an element of montage but a montage cell. The collision of two pieces arises a concept
* Decoupage refers to the final form of a script; with all the essential information to execute it. It is a breakdown of a narrative into shots and sequences before filming.
* Decoupage third French meaning refer to what results when the spatial fragments / succession of spatial fragments excerpted in the shooting process, converge with the temporal fragments whose duration may be roughly determined during shooting
* Stitched continuity - temporal relationship (temporal ellipsis/ time abridgement) = closure; fragmented perception and meaning-making from fragments. Kinda like a black hole that distort space and time and warps you from point A to B

**So what? & Notes**

* Cinema can be compared to a comic book, where reading all the frames gives you the context of the narrative or into a single gestalt
* Disproportionate depiction of an event
* Montage is derived from our past experiences and ability to make sense of things by identifying patterns; with one single image, meaning is broadly debatable but as you introduce more elements into a montage; you kind-of insert more “clues” for a reader to derive a meaning.
* Montage concept is rooted in Japanese cinema
  * They adapt the spongy shapelessness of our own “inner” naturalism = psyche
* Flashback as a form of time reversal
* Match-cuts = certain rules had to be abided so as for viewer not to lose orientation
  * Eye-line match: when one exit left, must enter new space or contiguous from the right to maintain direction of movement

**Conclusion**


# 06 Technology & Mediation

**Paper**

## **McLuhan**, The Medium is the Massage

**Thesis**

* Societies more shaped by the nature of the media than by the content of the communication. **All media are extensions of some human faculty.**
* The global village; we all connected and able to participate **without the limitations of time and space.** Electric circuitry message is Total Change, ending psychic, social, economic and political parochialism. A place for everything and everything in its place.
  * We used to go to the factory to work and resume our personal lives after we step out but now work is ubiquitous and permeates into every moment of our lives. It is life and work has been blended into a single concoction, and you are unable to separate them back.
  * It is an instantaneous world of electric informational media involves all of us, all at once.

**So what? & Notes**

* Applying this to social media Instagram = dominated by edited curation of a person life = simulation of reality = creates a hyperreality = causes depression
* Printing as the first uniform repeatable commodity
* Print tech created the public. Electric tech created the mass. Public =sepeate individuals walking around with separated fixed pov.
* Our official culture is striving to force the new media to do the world of the old
* Teach-in = package to discovery in educational processes = new way
* Electric circuitry confers a mythic dimension our ordinary individual and group action, Forces us to live myth but we continue to fragmentarily, and on single, separate planes.
* Television demands participation and involvement = engagement
* Information war happening constantly and involving everybody everywhere

## **Manovich**, "Understanding Meta-Media"

* Metamedia is the remapping of old media objects into new structures
* Data or parameters from old media is channeled into a new domain for manipulation. Eg. using visual to sound then glitched then back to visual
* This does not apply to just media but only our bodies too, we can use sensors and interactive gadgets that mapped human interaction or processes. Eg. The works of Afik Rendol using machine-learning algorithm to sort 1.7 million documents to generate an immersive installation
* Metamedia object contains language and meta-language - the original media structure and the extension/simulation/amplification

### So What?

* It echoes the McLuhan's Medium is the message; where everything is simply an extension of something else: Thoughts > speech > writing > prints > internet??

## **Conclusion**

* Everything has become unified and ubiquitous - there is no linear form of production or consumption. Everything is being churned out and consume at the same time in a radical new way. Internet and media has birthed a collective consciousness of the world


# Formalism

Art has a power of its own to define or reposition itself in a radical way as a cultural dominant. We are free to create art as a means to an end, or we can use it to challenge conventions, we can even use it as a basis for a new form of art or technology. Some questions that can be raised would be: what sort of art makes the most money, what makes an art good or bad )(but how do we define these arbitrary terms in the first place), or what sort of art scares people?

Rosinger, "What Shall We Look for in Art?";&#x20;

### Thesis&#xD;

Art is neither a vehicle for communication nor that communication is the purpose of artistic creations; yet most of us firmly believe that it is. This is because we tend to search for hidden messages in art rather than appreciate the aesthetic qualities.

Art is exhibition of form that satisfies the creator

Art can be used to please the creator or others; also as a way to show superiority or to show off

Art can make someone immortal even after their death.

Art is about the joy of creation

### So what? & Notes&#xD;

Personally, when i look at art, I’m looking for a novel experience or change in my perception. Such of these arts can be distorted and metamorphic imagery that makes your brain work harder to decipher what is the content. I think it is this engagement that makes me enjoy art and something that I look for.

That is a some sort of satisfaction gained when you create something or art with your own abilities. You feel compelled to share it with others or hear praise about your efforts and creation. I supposed it is like having a baby, you think that it is the most wonderful thing you created after being f\*cked so hard in life.

Greenberg, "Modernist Painting";&#x20;

Naturalistic art use art to conceal art by erasing the flatness of the canvas (integrity of the picture plane); modernism used art to call attention to art by acknowledging the flatness as a positive factor (eg. Manet, Cezanne)

Modernism has abandoned the representation of the kind of space that recognizable objects can inhabit

Autonomy is achieved when painting divest itself = abstract.&#x20;

### So What:

Modernism = color and application, about medium not illusionistic. It doesn't have to mean something, it could be anything. It ask questions that is hard to answer or impossible to.

Any mark on a canvas removes its flatness

Deliberateness; the limiting conditions of art are altogether human conditions. = we define our limits

Ziv, "Parallels Between Suprematism and Flash"&#x20;

Suprematism as the domination of form and intellect by using pure geometric forms

New technology will destroy the status quo and birth a new form of art

Suprematism and Flash are very much alike - such as form, color, motion and context

Abstract vector-based graphics can be seen as a reusage of the language of modernist abstraction and design.

### &#xD;So what

It is interesting to see Suprematism as an invented visual language or language of icons with its own meaning not pertaining to conventions, nature or reality. Shouldn’t we as art students aspire to craft our own “visual voice” in similar fashion? We should design our own signs imbued with personal meanings.

Perhaps one should look into Suprematism to improve their motion graphics skill


# Simulation

**Text**

Simulations

**Tier 1**

* The simulacrum is never that which conceals the truth - it is the truth which conceals that there is none
* We confuse the *map* as being the real
* **Simulacrum**: is reflection of a basic reality, masks and perverts a basic reality, masks the absence of a basic reality, it bears no relation to any reality whatever: it is its own pure simulacrum
* Orders of simulacra: Counterfeit / Production / Simulation
* Public opinion = hyperreal - lives only off of montage and test-manipulation
* Polls as a simulacrum of public opinions; do we really know its verity, influence, accuracy in representation?
* The unreal is no longer that of dream of fantasy of a beyond a within, it is that of a *hallucinatory resemblance of the real within itself.*

**Tier 2**

* Disneyland - suspension of the real and into the imaginary world. Make us believe that the rest is real, when actually everything else are no longer real, but of **the order of the hyperreal and of simulation**
* **Watergate -** a simulation of a scandal to regenerative ends
* A fake hold-up / robbery - lead to people perceiving as the real due to how the established order is (Southland tales?)
* Hyperreality and simulation are deterrents of every principle and of every objective
* Production as a restoration of the real which escapes it.Contemporary production is itself hyperreal.
* Television watches you: implosion of meaning = simulation begins
* War is peace
* All media and the official news service only exist to maintain the illusion of actuality
* Reality itself, entirely impregnated by an aesthetic which is inseparable from its own structure, has been confused with its own image > reality is not reality because we live our lives with simulations

**Conclusion**

* Hyperreal cannot be broken for there is no basis in reality; but it is ubiquitous everywhere. We already live in an esthetic hallucination of reality. Truman show might be a good example of this fabricated-domed reality; everything seems real on the surface but is not when you look behind, it was just an illusion.


# The Gaze & Media Critique

**Text**

Simulations

**Tier 1**

* Use psychoanalysis to discover where and how the fascination of film is reinforced by pre-existing patterns of fascination already at work within the individual subject and the social formations that have moulderd him > understanding fetish to learn about fetish in film
* Woman is symbolic because she cannot produce phallus
* Function of woman in forming the patriarchal unconscious is 2x = symbolises the castration threat by her real absence of apnis, and second thereby raises her child into the symbolic
* Woman’s desire is subjected to her image as bearer of the bleeding wound, she can exist only in relation to castration and cannot transcend it
* Spectator identifies with main male protagonist = screen surrogate = erotic look twofold = satisfaction
* Male movie star glamourous features = ideal image in the mirror
* When screen surrogate “gets the girl”, spectator feel the same feelings of possession > movies are like softcore pornography minus the fornication bit
* Lack of penis = threat of castration and unpleasure. First avenue of escape: Voyeurism associated with sadism; asserting control and subjecting guilty person through punishment or forgiveness. Second: fetishistic scopophilia

**Tier 2**

* Scopophilia, anice word for voyeurism, is a form of pleasure at the cinema
  * Contrast of the darkness in the auditorium and motion picture generate the illusion of voyeuristic separation > as if looking through a pinhole camera (Sexual pleasure)
* The cinema satisfies a primordial wish for pleasurable looking AND goes beyond **narcissistic aspect. Identification with the image seen. (ego libido)**
* Women setup according to-be-looked at-ness; sexual object, pin-ups, striptease
  * She is a spectacle but her visual presence works against the development of a storyline, to freeze the flow of action in moments of erotic contemplation (eg. Megan Fox in Transformer)
  * Serves as erotic object for characters within the movie, and for the spectator in the cinema
* Ultimate fetish by Sternberg = powerful look of the male protagonist is broke in favour of the image in direct erotic rapport with the spectator. Female as a the perfect product.
* True perversion is barely concealed under a shallow mask of ideological correctness - man is right, woman is wrong
* Rear window - Jeffries is the audience, apartment block as the screen. Lisa on spectator side not interesting but an erotic dimension increase when she is on the other side. Jefferies puts him squarely in the phantasy position of the cinema audience.

**Conclusion**

* 3 different looks associated with cinema: that of the **camera** as it records the pro-filmic event, that of an **audience** as it watches the final product, and that of the **characters** at each other within the screen illusion. Yet the first two are denied and subordinate to the third. Camera has become the medium to produce an illusion of Renaissance space. Camera’s look is disavowed to create a convincing world in which spectator’s surrogate can perform with verisimilitude.


# Import

## 10 -12&#x20;

## **Psychoanalysis, Cognition, and Media**<br>

| **Text**       | **Freud, "The Mystic Writing Pad" and "The Uncanny";**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | **Garrison, "The Poetics of Ambivalence";**                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | **Liebman, "Un Chien Andalou: The Talking Cure"**                                                                                                                                                                                                                                                                                                                                                                                                          |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Tier 1**     | <ul><li><strong>Mystic writing pad = functioning of the perpetual apparatus of our mind</strong> </li><li><strong>It solves the problem of combining the two functions by dividing them between two separate but interrelated component parts of systems</strong></li><li><strong>Perception > Short term memory > Permanent</strong></li><li><strong>It’s like using RAM memory vs computer storage memory</strong></li></ul>                                                                                                                                                                                      | <ul><li><strong>Three forms of ambivalence: Affective, will, intellectual</strong></li><li><strong>Freud: ambi as key to analysis</strong></li><li><strong>Ambivalence transforms conflict and even ambiguity into opposition</strong></li><li><strong>Opposition generates ambivalence</strong></li><li><strong>Ambivalence compounds the values by setting each in opposition to the other = > 20 opposite pairings</strong></li><li><strong>Ambivalence confuses, devours and tortures</strong></li></ul> | <p><strong>Dream-work: Transformation of a latent verbal thought into manifest visual image</strong></p><p><strong>Dream work must reformulate scandalous or morally repugnant thoughts in order to allow them to be represented in the dream</strong> </p><p><strong>You must listen and see</strong> </p><p><strong>It achieve the marvelous through complex transfer of language to image; semiotic transfer of language into visual forms</strong></p> |
| **Tier 2**     | <ul><li><strong>Uncanny = class of the terrifying which leads back to something long known to use, once very familiar</strong></li><li><strong>Unheimlich vs heimlich</strong></li><li><strong>Involuntary return to the same situation but differs radically in other respects</strong></li><li><strong>Uncanny fulfils the condition of stirring those vestiges of animistic mental activity within us and bring us to expression</strong></li></ul>                                                                                                                                                              | <ul><li></li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           | <ul><li><strong>Anemic cinema - spiral of language and image into illusory depth. 3D dimensional image, illusion of meaning generated by grammatical structure</strong></li><li><strong>Most of images are overdetermined, tied together in countless obvious or elusive ways by a series of phrases and concepts</strong></li><li><strong>Freud: Each image is rebus</strong></li><li></li></ul>                                                          |
| **Conclusion** | <ul><li><strong>Duality / simultaneity / double generates the uncanny; the idea of familiarity yet it feels radically different. We live in world of bifurcation or polarities which makes the duality so difficult and alienating. But what does the uncanny do? What can we do with it?</strong></li><li><strong>Why is deja-vu such an incredibly strange feeling for us?</strong></li><li><strong>What is the relationship between psychoanalysis and cinema? Why is cinema especially important from a psychoanalytic perspective?</strong></li><li><strong>Horror in cinema - monsters to</strong> </li></ul> |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                            |

## **Propaganda / Documentary / Realism**<br>

| **Text**       | **Propaganda Appeals**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | <p><strong>Lotman, The Illusion of Reality</strong>  </p><p><strong>Critique of Digital Capitalism Chapter 8</strong></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                    |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| **Tier 1**     | <ul><li><strong>Manual for making propaganda: on the same team, convenience (Spotify), problem-solver (Mr Muscle), Taichi master shifting the blame, hating on something together, anxiety-inducing > urgency and security needed, admiration and envy, people’s need to do right / social justice warrior, amplifying people’s ideas</strong></li><li><strong>A need to disassemble propaganda; which appeal, its audience, emotional or rational, its verity, reliability</strong> </li><li><strong>Devices:  playing the victim, playing the hero, fallacies, slogans (puts an end to thinking and uses emotional appeal), referral/prestige/quotation/testimonials (dentists, celebrity endorsement), my way or the highway, taichi people’s belief into the propagandist's, identification (one of us), mainstreaming, jedi mind trick with distortion and false evidence</strong></li></ul> | <ul><li><strong>Cinema as reality; audience as witness and participant</strong></li><li><strong>The better we a person, the less resemblance we find in photograph of him</strong></li><li><strong>Non-artistic photography enforces a single, automatic dependency</strong></li><li><strong>60: the aim of art is not simply to render some object or other, but to make it a carrier of meaning</strong></li><li><strong>Juxtaposition of real life and cinema life; underscored the artistic conventionality of the world he depicts and made us us forget about the conventionality</strong></li><li><strong>Feeling of actuality, the sense of resemblance to life without = no art of the cinema, is not something elementary, provided by direct sense perception. / facilitated by associations with artistic and cultural experience of society</strong></li></ul> |                    |
| **Tier 2**     | <p><strong>Lackey, Reflections on Cavells Ontology of Film</strong>  <br></p><ul><li><strong>Panofsky: processes of all earlier representational art start from an idealistic conception of the world</strong></li><li><strong>Switch the camera on , and the process becomes automatic</strong></li><li><strong>Bazin: objectivity of film results from the disassociation of the film image from the usual humanizing associations the filmed objected would have if seen with the naked eye</strong></li></ul>                                                                                                                                                                                                                                                                                                                                                                                 | <ul><li></li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | <ul><li></li></ul> |
| **Conclusion** | <ul><li><strong>Types of propaganda + illusion of cinema as reality = propaganda manifesting in reality</strong></li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |                    |

## **Censorship & Production Codes**<br>

| **Text**       | <p><strong>Maltby, “A Brief Romantic Interlude”;</strong> <br></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | <p><strong>Pally, Sex and Sensibility, Chapters 1, 2, 3</strong><br><br></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Tier 1**     | <ul><li><strong>Just because there is a censorship rule doesn’t not mean the story cannot be good; you can use this to your advantage</strong></li><li><strong>By creating sequences that audiences can make paradoxical or ambiguous meaning, you let them write the story in between.</strong></li><li><strong>It is very much like Scott McCloud idea of closure in which the reader is able to think of what happens in between gutter.</strong></li><li><strong>This requires a sophisticated audience that can draw on relevant contextual knowledge to assist in meaning making</strong></li></ul><p><strong>\_\_\_\_\_\_</strong></p><ul><li><strong>references: the role of the reader by Umberto eco and understanding comics</strong> </li></ul> | <ul><li><strong>Who decides what needs to be censored</strong></li><li><strong>Censorship = danger = deludes from thinking about / questioning the status quo, from finding faults with what is widely accepted = ignorance = society/individual having tunnel vision and cannot think for themselves</strong></li><li><strong>As I was reading this, I thought to myself how terrible the past was when it was all censored but then I realized that the world today is very much censored. In America, there are some taboo words or subject you cannot bring up for risk of hostile feedback. For example, calling people by the Color of their skin, saying the right pronoun for transgender. There is an increased sensitivity to these matters.</strong></li></ul><p><img src="https://lh5.googleusercontent.com/IXhph73DfxsGGCE9hdLUVTFKJbm9zePzGICmGFNMNc3iQzEToREZTMojiLN4rSrwurb9OaaxOfgWcltqkwsnn-401kR36aMz5LBiXqaL6yl02Q9Q3N9fYJpejJHmSGkKQn9QiVA5" alt=""></p> | <ul><li><strong>In Singapore, the news is never interesting because I like to think it is safe and problem free but what if the media is just withholding the reality. If you do not see it, you do not recognize it. Ban the image and one is rid of the act. Eg. Korean movie Taxi Driver;Gwangju uprising 1980;  large-scale civil uprising which was brutally suppressed by large-scale civil uprising which was brutally suppressed. “. The junta blamed “vicious rioters” and “communist agitators” for the casualties, saying the military had been there only to protect people.</strong></li><li><strong>But Mr. Hinzpeter’s footage exposed those assertions as lies — not just to the world, but to South Koreans.”</strong></li><li><strong>Chapter 3: Japanese less rape rate despite violent and abundance of pornographic materials than Singapore which banned these. People get off at these outlets instead of manifesting their depravity in reality</strong></li></ul> |
| **Conclusion** | <ul><li></li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |

## **Appropriation, Tactical Media & Semiotic Disobedience**<br>

| **Text**       | <p><strong>Katayal, “Semiotic Disobedience”;</strong> </p><p><strong>Keywords: vandalism, guerilla semiotics, myth, Barthes</strong></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                                                 | <p><strong>CAE, Electronic Civil Disobedience, chapter 1</strong><br></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Tier 1**     | <ul><li><strong>Memes & parody as semiotic disobedience</strong> </li><li><strong>Spirit of semiotic disobedience reflects some of the same class goals and interests of traditional civil disobedience</strong></li><li><strong>Offered the audience the chance to recode a national symbol</strong></li><li><strong>502: the dominant industry today is information, not products. For civil disobedience to have any meaningful effect, the resisters must appropriate something of value to the state. Once they have an object of value, the resisters have a platform from which they may bargain for change.</strong></li><li><strong>511: SD aims to create a dialogue where one is absent and tries to reclaim the inducement of passivity among modern consumers. … seek to reverse the privileged position of the speaker or author and make the audience an active participant instead of a generally passive spectator</strong></li><li><strong>Culture jamming: introduce noise into the signal as it passes from the transmitter to receiver = unintended interpretations</strong></li><li><strong>The goal is to interrupt, disrupt, and replace the speech of the corporate entity with  of the disenfranchised consumer</strong></li><li><strong>Debord: we do not want to work towards the spectacle of the end of the world but towards the end of the world of the spectacle</strong></li></ul> | <ul><li><strong>543: Part 1 verbal and visual signs within language are entirely arbitrary meanings can be unpacked, reframed, and pierced in new and inventive ways</strong> </li></ul><p></p> | <ul><li><strong>For CD to have any meaningful effect, the resisters must appropriate something of value to the state. Once they have an object of value, the resisters have a platform from which they may bargain for change.</strong></li><li><strong>But streets or city now of no value> change to information valorization instead?</strong></li><li><strong>Money has no point of origin but is part of a circular or spiraling flow, the best we can expect to find is the flow itself.</strong></li><li><strong>ECD - trespass and blockage</strong></li><li><strong>Selective blockage must be considered</strong></li><li><strong>Power has retreated to cyberspace</strong></li></ul> |
| **Tier 2**     | <ul><li><strong>Case studies; Nike, Native American, Bhopal gas crisis and  Yes Men</strong> </li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | <ul><li></li></ul>                                                                                                                                                                              | <ul><li></li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| **Conclusion** | <ul><li><strong>Semiotic disobedience is about having conversation using a universally or widely understood/familiar visual language/ platform</strong> </li><li><strong>The only way forward is through; fight fire with fire</strong></li><li><strong>We need more Yes Men; maybe they should do one with SCAD on SCAD Day</strong></li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |                                                                                                                                                                                                 |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |

## **The Contemporary**<br>

| **Text**       | **Johnson, Modernity Without A Project, chapters 1, 2 and 5;**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | **Keedy, "Zombie Modernism";**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | **Geers, "Neo-Modern";**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Tier 1**     | <p><strong>Entering the 21st century, the postmodern succession has given way to a doom-laden, apolitical orthodoxy. This book offers suggestive readings of “the contemporary” in light of high modernity, postwar modernity, and postmodernity, as framed by the influential institutions of modern art and the spectacles of millennial architecture. Modernity without a Project critiques and connects historical avant-garde currents as they are institutionally expressed or captured, and scrutinizes the remake of New York’s Museum of Modern Art, Minoru Yamasaki’s vanished Utopias, the “anarchitecture” of Lebbeus Woods, recent work of Rem Koolhaas, delirious developments in Dubai, and the unexpected contribution to architectural debate by the late Hugo Chavez.</strong></p><ul><li><strong>What is contemporary</strong></li><li></li></ul> | <ul><li><strong>Zombie modernist - the living dead who design among us</strong></li><li><strong>The message is the same: “I am the voice of clarity and reason, authority and progress, in charge of this family’s values.” > Bauhaus idealized and mythologized by designers… its ideal of universality was a myth and mirage, shattered by the war, politics and the demands of a consumer society</strong></li><li><strong>Modernism is no longer as style, it’s an ideology: of conservatism</strong></li><li><strong>Meaning is unstable and has to made by the reader. To impose a single text on the readers is authoritarian and oppressive</strong></li><li><strong>We must allow ourselves to look at design in new and challenging ways, we must look for ourselves.</strong></li></ul> | <p><strong>Renewed interest in abstraction, materiality, and process in ways that on the surface, recall the formal strategies of modernist art and its Minimalist offshoots</strong></p><p><strong>Slow gravitational pull, in both production and reception towards a less reflexive and more nostalgic attitude,</strong></p><p><strong>Today's artists, critics, and salespeople fall back on the old mantra of process because in the absence of the lofty discourse that fueled much modernism, there is so little to discuss except process.</strong></p><p><strong>(book) Critique of Digital Capitalism Chapter 10</strong></p><ul><li><strong>Digital capitalism deny physicality - 3d printer, crypto$$$, debitcard, no physical store, self-ordering system, work remotely</strong></li><li><strong>Generate asset bubbles, followed by crashes precisely because the denial of physicality that is the aura of the digital — an illusion that denies the constraints imposed by physical materiality)</strong></li></ul> |
| **Tier 2**     | <ul><li></li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | <ul><li></li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | <ul><li><strong>Qns: there are services without a physical location: banks, telco, Amazon. The thing you need to day is just a room and food and wifi. The only place that cannot be replaced is a restaurant, is food the only thing we cannot deny its physicality</strong></li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| **Conclusion** | <ul><li><strong>What now? What is beyond this class in terms of theories; what have we not covered? How does this inform our practice? What does making a work based on a theory As we delve deeper into this knowledge, I find myself departing from just being a worker and rather tell people what to do instead.</strong></li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |


# 10-12

**Text**

Johnson, Modernity Without A Project, chapters 1, 2 and 5;

Keedy, "Zombie Modernism";

**Geers, "Neo-Modern";**

**Tier 1**

Entering the 21st century, t**he postmodern succession has given way to a doom-laden, apolitical orthodoxy**. This book offers suggestive readings of “the contemporary” in light of high modernity, postwar modernity, and postmodernity, as framed by the influential institutions of modern art and the spectacles of millennial architecture. Modernity without a Project critiques and connects historical avant-garde currents as they are institutionally expressed or captured, and scrutinizes the remake of New York’s Museum of Modern Art, Minoru Yamasaki’s vanished Utopias, the “anarchitecture” of Lebbeus Woods, recent work of Rem Koolhaas, delirious developments in Dubai, and the unexpected contribution to architectural debate by the late Hugo Chavez.

* What is contemporary
* Zombie modernist - the living dead who design among us
* The message is the same: “I am the voice of clarity and reason, authority and progress, in charge of this family’s values.” > Bauhaus idealized and mythologized by designers… its ideal of universality was a myth and mirage, shattered by the war, politics and the demands of a consumer society
* Modernism is no longer as style, it’s an ideology: of conservatism
* Meaning is unstable and has to made by the reader. To impose a single text on the readers is authoritarian and oppressive
* We must allow ourselves to look at design in new and challenging ways, we must look for ourselves.
* Renewed interest in abstraction, materiality, and process in ways that on the surface, recall the formal strategies of modernist art and its Minimalist offshoots
* Slow gravitational pull, in both production and reception towards a less reflexive and more nostalgic attitude,
* Today's artists, critics, and salespeople fall back on the old mantra of process because in the absence of the lofty discourse that fueled much modernism, there is so little to discuss except process.

**(book) Critique of Digital Capitalism Chapter 10**

* Digital capitalism deny physicality - 3d printer, crypto$$$, debitcard, no physical store, self-ordering system, work remotely
* Generate asset bubbles, followed by crashes precisely because the denial of physicality that is the aura of the digital — an illusion that denies the constraints imposed by physical materiality)


# Recommended books

## Self-discovery&#x20;

### Journey, developing your meaning-making compass

1. [Strangest Secret](https://www.youtube.com/watch?v=NbBHR_CD56M\&t=3s), Earl Nightingale
2. The Alchemist, Paulo Coelho
3. Start with Why, Simon Sinek
4. Ikigai

### **Framework**

1. *12 Rules for Life,* Jordan Peterson

#### Spiritual

1. *The New Earth*, Eckhart Tolle
2. *The Power of Now*, Eckhart Tolle

### Ubermansch / Transcendence

* Thus Spoke Zarathustra&#x20;
* Brave New World, Huxley
* 1984, Orwell
* Donnie Darko
* Ecology of the Mind, Bateson
* Stealing Fire

## Development

### Making the best out of your life

* Defining Decade, Meg Jay
* **On making Meaningful Choices**
  * [Philosophy of Mr Nobody — How to make meaningful choices](https://www.youtube.com/watch?v=ANUunK6kiqU)
  * [Ruth Chang — How to make Hard Choices](https://www.youtube.com/watch?v=8GQZuzIdeQQ)
  * Tatami Galaxy - how different decisions do not affect your reality
* *Metaskills: Five Talents for the Robotic Age*, Marty Neumeier

### **Mindset**

1. James Clear
2. Give and Take, Adam Grant
3. *Thus spoke Zarathustra*, Nietzche

### Unlearning

1. Midnight Gospel, Episode 5, Annihilation of Joy
2. Think Again, Adam Grant

### Element

* Ken Robinson

#### **Media references**

* [Kakashi Explains Chakra Natures, Naruto Starts Rasenshuriken Training, Naruto Shippuden ](https://www.youtube.com/watch?v=ROoCV-aQ_sw)
* Avatar unusual bending styles&#x20;
* [Water Divination Test in Hunter x Hunter](https://www.youtube.com/watch?v=WUUuLUjBlqg)
* [Sorting Hat in Harry Potter](https://www.youtube.com/watch?v=xQZFWA2KDbw)

## Creative

### Getting better

* Context
  * Expression
    * [Three Steps to Becoming a Better Artist Immediately](https://youtu.be/amlwcI8dh_g), ArenaNet's Horia Dociu

### Rose-colored + Mindset

* *On Making Money vs Quality Work*, Saul Bass
* *On the creative process*, Ira Glass
* *Art & Fear*, David Bayles

### Rethinking

* [Why working harder is not getting you to closer to your goal](https://www.youtube.com/watch?v=UtDiO5lH-kE\&list=PL1TQbviAEvf0E3SJD1MF1ybptvOcadXaG\&index=7), Chris Do

### **Design thinking and seeing**&#x20;

* *Framed Ink: Drawing and Composition for Visual Storytellers*, Marcos Mateu-Mestre
* *Framed Ink 2: Frame Format, Energy, and Composition for Visual Storytellers*, Marcos Mateu-Mestre
* Ge Wang, Artful Design
* Start with Why

### Science

* *Reductionism in Art and Brain Science: Bridging the Two Cultures*, Eric Kandel
* *Understanding Comics*, Scott McCloud
* [Intellectual montage](https://youtu.be/NtnTs90knro), Eisenstein

## Career

### Learning

* [Learning Houdini: You're Doing It Wrong and How to do it Right | Matt Estela | SIGGRAPH 2019](https://www.youtube.com/watch?v=Y22rYfJE64o\&t=2060s)
* *Framed Ink Vol.1 ,* Mateu Marcos

### **Positioning**

* [On Pitching yourself](https://www.linkedin.com/learning/jodi-glickman-on-pitching-yourself), Jodi Glickman
* [Should You Specialize or Be a Generalist?](https://www.youtube.com/watch?v=wCPbPMRNnvk), Tim Ferriss

### Teamwork and culture

* Culture Code, Daniel Coyle

## Business

### Freelancing

* Freelance Manifesto, Joey Korenman&#x20;
* Company of One, Paul Jarvis&#x20;
* Win Without Pitching, Blair Enns&#x20;
* Ask, Ryan Levesque&#x20;

### Pricing

* *Implementing Value Pricing,* Ron Baker
* *Burn Your Portfolio*, Michael Janda&#x20;

### Marketing & Advertising

* *Storybranding*, Donald A. Miller
* [*Instagram Strategy for Business Growth*](https://www.domestika.org/en/courses/1102-instagram-strategy-for-business-growth), Dot Lung


# Things I learned

Inspired by the book Creativity Inc by Ed Catmull; here are some adage and anecdotes I find compelling or neologized in my life.

> The trick is to think of each statement as a starting point, as a prompt toward deeper inquiry, not as a conclusion — Ed Catmull, Creativity Inc, pg 315

## Personal quotes

*My creativity is one that is based on organizational, data, writing code, teaching.*

*It is not about "interesting", it is about "communication" and engaging your audience.*

*Excellence is not just a habit; it is a lifestyle. You have to embody it.*&#x20;

*When you are young, you should aim for a breadth of experience before settling on a focus what you need to learn and develop is **how to focus**.*

*Doing good work is good but having people who recognize your talents and push you is even better. Being able to do that for yourself and others is the best.*

You can't make people do something but you can **raise their expectations and lead them to commit to it.** You do so by asking 2 questions "what's stopping you from doing X" and "By when do you think you can do it?".

## My father&#x20;

$$
知彼知己，百战百胜
$$

zhī bǐ zhī jǐ , bǎi zhàn bù dài

know your enemy and yourself and you can win a hundred battles (every battle) — idiom, from Sunzi's Art of War

## On uncertainty

* "We can never be right, we can only prove we're wrong." — Richard Feynman

## On failure

*Failure is not an end, it's a new opportunity. If we never fail , we will never know which path is not meant for us. Every time you fall short , your true journey becomes more transparent.*

## The only thing you can control

> *The only constant in life is change. How you live your life depends on how you interpret and respond to those changes*&#x20;

*Stop comparing yourself to her. She's been there longer than you and she's had different opportunities than you. The only thing you can control is what you can do for yourself and putting yourself in positions to succeed. Focus on that and you'll never feel like you're living under someones shadow.*

## Things we should get comfortable saying

* Thanks for correcting me. I did not realize that
* I had not thought of it like that. I understand now
* I was wrong about that, and I have changed my mind
* I should do some more research before I argue this point

## Bateson

&#x20;*Ever present* / *Never twice the same* / Ever changing / Never less than whole.&#x20;

*You do not think your thoughts, you think your culture thoughts.*

## Craig Smith

&#x20;   "If I don't get it when I see it, it's not good"

&#x20;   "It's doesn't matter what I think or like — a reply to student asking which designs he likes"

&#x20;   "Use colors where there is function - eg. Braun calculator"

&#x20;   "Biggest technological motivation is pornography"

## John Colette

> "Your personal branding? I'm sorry, you are a nobody "

### Free your process

Most of the work that you have done to date is “short cycle” - idea > sketch > execution > review. Which is great because it mimics the production cycle in a commercial context.

For longer works, the process can be….sticky. I want to outline a few general strategies to help you become “unstuck” as you progress.

Ideally - you will have a set of assets created at the end of this class that will take two forms - \*\*a database\*\* \[project rushes to be edited] and in the other case a \*\*shot list\*\*.

Let me go through each.

A \*\*shot list\*\* is straightforward - it’s a detailed set of shots that are planned and describe a linear process. Let’s call it a “film” and the shot list is based on \*\*storyboards\*\*.

&#x20;   From the outset, this process will take the form of:

* idea / theme
* moods and visual feel
* &#x20;treatment \[intention for realizing the theme]
* &#x20;script
* storyboards
* style frames
* shot list

So this is a little different to the process that we would use in most MOME classes – where the starting point is an exploration of the idea and then the creation of mood boards to gather strong visual direction to the project before commencing.

**You will notice here that the storyboards come after the script** – that’s intentional – because understanding what you want to do should really inform how the storyboards work, style frames come even later because these are very much about realizing the script and what you want to say in the script, so the visual motifs will \*support\* the project not \*lead\* it. \[But that's not a rule - you can start int he usual manner - it just doesn't work for a lot of the longer styles fo project]

{% hint style="info" %}
If you have done your work properly the script should really indicate some fundamental choices about the shots, sequence, rhythm, camera choice and staging of each part of the piece - leading you into a more considered process with storyboards and style frames.
{% endhint %}

&#x20; Once you have style frames in place - you will have a fairly good idea what is required to produce your particular visual style for the project, as workflow, and therefore, you can develop both a \*\*vertical\*\* list in a spreadsheet which outlines the shots required, and \*\*horizontal\*\* list of the various processes that are involved for your particular project. Each shot can be tracked through the processes for its completion.

&#x20; Everyone’s approach will require a separate set of processes because some people work in illustration, some people work in 3D, some people work in composited scenes and more likely the work may be a composite of these processes.

So understanding the parameters of your work takes us to the last stage of the design process, which I break down into:

* &#x20;\*\*scope\*\* (theme/feel/treatment)
* &#x20;  \*\*specification\*\* (script / storyboards / shotlist)…. and
* \*\*design\*\* (styleframes).

After this point you should be ready to commence the \*\*build\*\* of your work which is fairly straightforward, and just means groaning away through the spreadsheet and making sure everything works after you’ve assembled it. This last phase of testing and revision is pretty familiar from anything you have already worked on – it’s an opportunity to refine and develop your piece.

With this said, please consider \*\*sound\*\* and whether this will drive the process as the primary motivation within the piece or whether it will support what is primarily a visual narrative. Many pieces that work with voice-over to drive the imagery we could consider audio dominant - and in this sense the audio should be recorded as early as possible, based on a script, to set specific terms for the production that follows. In the first instance this will give you an idea of the duration of the work, and also can assist with the development of an aromatic based on your storyboards.

&#x20;   So that’s the linear approach, and what should be try to aim for by the end of the class.

&#x20;**In the second example of process – the \*\*database\*\* – we’re looking at a more extensive editing process.**

In this approach, you will work outwards from particular themes and assemble a range of material that you then consider refining through the editing process. In this sense there are strong similarities with documentary filmmaking where you need coverage, and then work out how to assemble a story from the material you have.

I will indicate where this is important with your individual projects but it’s a different approach and requires you to sit back in the thematic stage of the process and consider strategies for over creating media and then refining it in the edit.

One aspect of this approach should be an engagement with your theme at different levels. By this I mean not sitting with the idea all the time – as this can lead to confusion – but working between thinking, capturing, assembling and review as the idea develops.

One strategy I have suggested for this approach is the use of index cards, which can contain individual ideas, themes, images, whole quotes, single words or story points. You should be able to arrange these in different ways to consider how your ideas might come together.

Similarly, I would encourage you to use some visual ideation through assemblage – what I mean here is something like scrapbooking, or a journal that has both text, images, colors – even evocative things that seem tangential to the project but you feel somehow connect or influence the work. Taking your thinking out into a secondary form of assemblage – this kind of extended collage process is a way of remixing all of the discrete thinking tools that we use – mood boards, free writing and various visual planning tools. Think think of this as a sort of artist’s notebook but think of yourself as a filmmaker as you make it.

It may seem like a lot of trouble to go to but working in this way will help you put your thoughts outside of yourself and will give you a discrete process that can help reveal things about your project and your approach that just thinking or sketching or planning alone will not. So think of it as a kind of alternate edit in progress.

The main point of this approach is to **incorporate some non-linear thinking in a recursive way into your approach to the material**. We will all settle back into linear processes and inspiration is very often non-linear. So if you choose to do this you can think of this as a separate artwork that will in many ways complement the main work you’re doing :-)

### BEYOND A JOB

* Having diverse skillset allows you to be self-sustainable to take on projects; rather being good at say C4D and thrive only in NYC. If that is the case, you find that there is a lack of jobs or assignments when you leave NYC
* Find a way to move from service to **product** - eg. Cindy Suen
* Newsletter - a tool to make money for Graphic Designer - promote a product
* As as student: Be a lion and eat everything in the hunting ground; don't be picky
* Follow the money and see where it goes. See what an entity values by looking at their checkbook
* sit down and think about what you want in the next five years and work towards it
* Surveying the office
  * How much does rent cost for a squarefoot
  * How much is housing
* **What matters as I have one foot out of school**
  * Finding your visual language or your gift is usually our primary goal
  * Rite of passage - you will ascend to seniority and skills
  * But think long-term self-sustainable career - can you turn your service into a product

<br>

## **Everybody speaks design, just differently -  Matt Hryhorsky**

Working with clients can be frustrating because they may not use the same jargons and terminology to communicate to us what they want. The truth is everyone used a different language when describing designs. We all have different standards and interpretations of the same word. To me, the word “beautiful” means nature, skies and books. To you and everyone else, it could mean something else entirely.

As a designer, it is our job to find out our client’s interpretation. We should not dismiss clients who don’t “get” it but rather ask ourselves, what are they looking at? Design is not an elite club, don’t assume clients know the terminology we used in design.&#x20;

### **To close this gap in communication**

Favor conversations over presentations. Your design should not be a a surprise to your clients. They should be with all the way in the beginning from concept to execution. Bring your client to the table. Be a service provider rather than a product-maker.

Client know what they want but they just use different words. Design is good conversation and understanding people.

### **Stop presenting multiple concepts**

Though it may seem like a good idea to give your clients choices, you actually sounds like “I don’t know what is the best solution for your design, so you can choose it” instead.

## **It’s just a jpeg -** [**Beeple** ](http://beeple-crap.com/)

Mike Winkelmann AKA Beeple is famed for his everydays projects and incredible Cinema 4D designs that has spanned over ten years.  Yet, he still calls them “crap” and do not have a strong attachment to much of his work. For Beeple, he sees his everydays as a way to grow as an artist and learn. He described about his works on his Instagram are just jpegs, nothing more.

## **Don’t take your art too seriously - Mateo Mounier**

Mounier shared about his “enlightenment” in art school when a teacher asked the class to bring their best drawing or painting, and proceeded to destroy them in the most horrible way possible. The point was not to take your art too seriously no matter how much time and effort you put in, and that you can always make more. We are not our art but we are artist. Just keep moving forward and make good art.

## **If you love your design, then we love it too - Joshua Davis**

In the first installment of No God No Heroes panel at FITC Toronto 2018, Davis shared about his experience of almost getting fired from a project with a band during his early days. He talked about how he sent his videos to the band for feedback. To which, the guitarist said “I play guitar. I’m in band. How am I supposed to know what is the best. If you love your design, then we love it too.”&#x20;

## **PES: "I just wanted to make a film about chair having sex"**

## **Find, make, steal time - Grant Skinner**

In Skinner’s talk, he shared about the importance and the tangible benefits of “play” in our art and career. During his schooling days, his penchant websites, programs and application in his own time helped him get a job/

## **Kyle Cooper "Paul Rand impression"**

> "So you're still making that trash art" — Kyle Cooper's impression of his mentor Paul Rand after making the title sequence for 'S7ven'.

> If you came here for a pat in the back, you came to the wrong place.


# Mac Superuser

The essential guide to essential knowledge for essential stuff

## Troubleshooting

### [Apps will not connect to internet](https://apple.stackexchange.com/questions/6147/some-applications-on-macbook-pro-think-internet-is-not-connected-when-it-is)

```
dscacheutil -flushcache
```

### [External HDD won't mount](https://apple.stackexchange.com/questions/268998/external-hard-drive-wont-mount)

#### Diagnostics

```
ps aux | grep fsck
```

```
sudo kill -9 2587
```

###

* [Remove monitor audio output](https://discussions.apple.com/thread/6044880#:~:text=You%20need%20to%20go%20to,as%20the%20main%20audio%20source.)
  * I think I found a solution! It's not about the audio output - it's about what display is your 'main display'. You need to go to System preferences > Display > Arrangement. Here, drag that little white title bar on the main display screen, which currently will be on the HDMi display, to your mac display. Apple will always keep the audio output corresponding to the main display as the main audio source. Once you change the main display to your inbuilt display, the HDMi audio output is never used by default! This solved it for me.
  * A simple fast way to select connected Audio Output devices, is to hold the Alt (option) key and click the Sound icon on your Menu Bar.

### Bypass Gatekeep to use apps from anywhere

1. Use[ terminal to disable settings](https://macpaw.com/how-to/allow-apps-anywhere)
2. Control + RMB open an app

## Apps

* **Utilities**
  * Magnet: <https://apps.apple.com/us/app/magnet/id441258766?mt=12>

## Essentials Shortcuts

| Shortcut             | Function        |
| -------------------- | --------------- |
| Cmd shift A          | Applications    |
| Command + Spacebar   | Finder bar      |
| Cmd + Shift + G      | Go to path      |
| Option + RMB on file | Get file name   |
| Shift-Cmd-Q          | Log out         |
| F3                   | Mission Control |
| Cmd-F3               | Show Desktop    |

### Get path directory of file (hold option + RMB)

![](/files/-Lx6r2d4Sd4auk6gFmvM)

## Notes

* Make use of Finder top bar
* Preview in 'collage"


# Applescript

|                               |                                                          |
| ----------------------------- | -------------------------------------------------------- |
| <p>tell / end tell</p><p></p> | - begin statement end - end statement                    |
| keystroke                     | keystroke using {command down, option down} key code 123 |

\-- name all processes tell application "System Events" to name of processes

\--Setting SettingBounds tell application "Finder" to set the bounds of the window 1 to {x,y,width,height} -- SettingBounds using System events tell application "System Events" to tell process "After Effects" set position of window 1 to {0, 50} set size of window 1 to {600, 650} end tell


# InDesign

## Core skills

* paragraph and character style&#x20;
* margins and columns&#x20;
* placing images
* creating text & image boxes

## Shortcuts

```
hide guide - w 
preview mode - shift + w
exit preview - esc 
show ruler - cmd + r
hide guides - cmd + " ?

text panel - command + t
```

## Design principles

$$
alignment  \times consistency  \times legibility  \times contrast
$$


# Illustrator

## How to flatten missing fonts when you import a PDF&#x20;

```
First create a new document in Illustrator
Go to File -> Place and choose your PDF
Make sure the link box is checked and click Place. 
When the Place dialogue box pops up, click OK.
Go to Object -> Flatten Transparency... 
    Make sure Convert All Text to Outlines is checked and click OK.
Release the clipping mask and move objects around
```

## Copying appearance to another layer

* <https://www.gameartguppy.com/illustrator-quick-tip-how-to-copy-appearances-between-objects/#:~:text=To%20copy%20the%20Appearance%20of%20the%20third%20path%20to%20the,be%20the%20same%20(3).>
* **Stacking appearances**: make a graphic style that is just the drop shadow that you want.

  select \[object b] and `option` click that graphic style to apply it without interfering with any other appearance attributes.

## Core skills

* Duplicate last action&#x20;
* Touch type tool
* shape builder tool
* Appearance&#x20;
* **Drawing**&#x20;
  * Blob brush tool
  * Curvature tool
  * Recolor artwork palette
  * Draw inside mode&#x20;
  * Pencil tool & simplify&#x20;


# Blender

## Recommended Readings

| **Item**                                                              | Links                                                                                                                                                                                                                                                                               |
| --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Why Blender                                                           | [Why it is free?](https://www.youtube.com/watch?v=yfg8ydtOUDg)                                                                                                                                                                                                                      |
| **Documentation**                                                     | <ul><li><a href="https://www.dummies.com/web-design-development/blender/blender-for-dummies-cheat-sheet/">Hotkeys for dummies</a></li><li><a href="https://docs.blender.org/manual/en/latest/index.html">Blender manual</a></li></ul><p></p>                                        |
| **Tutorials**                                                         | <https://www.blenderguru.com/>                                                                                                                                                                                                                                                      |
| <p><strong>Industry /</strong> <br><strong>Case-studies</strong> </p> | <ul><li></li></ul>                                                                                                                                                                                                                                                                  |
| **Resources**                                                         | <ul><li><a href="https://blenderartists.org/t/new-blog-list-of-free-texture-sites/418648"><https://blenderartists.org/t/new-blog-list-of-free-texture-sites/418648></a></li><li><a href="http://freetexturesite.blogspot.com/"><http://freetexturesite.blogspot.com/></a></li></ul> |
| **Papers**                                                            | <p></p><ul><li><a href="https://blenderartists.org/"><strong><https://blenderartists.org/></strong></a></li></ul>                                                                                                                                                                   |

## Hotkeys

```c
// from c4d to blender
tab
shift tab
shift a - add 
a - select all
anchor point : mesh
tilde - 
z: render views

Zoom into an object - / 
fit frame to selected - numpad 0
Scale by normals - alt + s

//Common Keyboard Hotkeys
A	Select all
Alt+A	Deselect all
Shift+A	Show Add menu
Shift+D	Duplicate > hit enter
Alt+D	Linked duplicate

E (edit mode)	Extrude
F (edit mode)	Create face/edge

G	Grab/move
Alt+G	Clear location
H	Hide selected
Alt+H	Reveal all
I	Insert keyframe

Ctrl+J	Join selected objects
L (edit mode)	Select linked vertices
Shift+L (edit mode)	Deselect linked vertices
M	Move selection to collection
Ctrl+M	Mirror selection
N	Toggle Sidebar visibility
Ctrl+N	New Blender session
Ctrl+N (edit mode)	Calculate normals outside
O (edit mode)	Enable proportional editing
P (edit mode)	Separate to new object
Ctrl+P	Make parent
Alt+P	Clear parent
R	Rotate
Alt+R	Clear rotation
S	Scale
Alt+S	Clear scale
U (edit mode)	Unwrap mesh
Ctrl+S	Save file
X	Delete selection
Ctrl+Z	Undo
Ctrl+Shift+Z	Redo
Spacebar	Play animation
Shift+Spacebar	Show Tool menu
Ctrl+Spacebar	Maximize editor area
Tab	Toggle Edit mode
Ctrl+Tab	Show mode pie menu
Tilde (~)	Show view pie menu
F2	Rename selected object
F3	Show search menu
F9	Show floating Last Operator panel


Action	Result
Left-click	Select
Shift+left-click	Add to selection
Ctrl+left-click (edit mode)	Remove from selection
Left-click+drag	Box selection
Alt+left-click (edit mode)	Edge/Face loop select
Middle-click+drag	Rotate view
Shift+middle-click+drag	Pan view
Ctrl+middle-click+drag	Zoom view
Right-click	Context menu
```

|   |   |
| - | - |
|   |   |

## Notes

* learn principled shader


# Premiere Pro

* lengthen a clip in the middle of video without cutting or trimming time of other clips: If you hold down the CTRL key while dragging the IN or OUT point of a clip, it will move everything else accordingly. When putting mouse cursor over end of clip, it should turn to a red bracket when in position to extend clip end – press CTRL and it turns yellow and then it will ripple. If you make a mistake, CTRL-Z undo, so no worries.


# Mathematics

## Recommended readings

* Introduction to Linear Algrebra
* [3Blue1Brown](https://www.youtube.com/channel/UCYO_jab_esuFRV4b17AJtAw)

## Syntax Guides

* &#x20;<https://github.com/cben/mathdown/wiki/math-in-markdown>
* <https://faculty.math.illinois.edu/~hildebr/tex/course/intro2.html>

$$
a^2 + b^2 = c^2
$$

$$
\alpha + \beta +\delta+\theta +\phi \rho
$$

$$$
Consider (eq:a):

$$ \alpha = \beta $$        (a)
$$$

```
Consider (eq:a):

$$ \alpha = \beta $$        (a)
```

$$
@equation(id)
x = \sum\_{i=1}{N} i
@/
$$

```
@equation(id)
x = \sum_{i=1}{N} i
@/
```

$$
$ y=\sum\_{i=1}^n g(x\_i) $
$$

```
 $ y=\sum_{i=1}^n g(x_i) $
```

$$
\begin{align}
(a+b)^3 &= (a+b)^2(a+b)\\
&=(a^2+2ab+b^2)(a+b)\\
&=(a^3+2a^2b+ab^2) + (a^2b+2ab^2+b^3)\\
&=a^3+3a^2b+3ab^2+b^3
\end{align}
$$

```
\begin{align} 
(a+b)^3 &= (a+b)^2(a+b)\\
&=(a^2+2ab+b^2)(a+b)\\
&=(a^3+2a^2b+ab^2) + (a^2b+2ab^2+b^3)\\
&=a^3+3a^2b+3ab^2+b^3
\end{align}

```

$$
\[
\left|\sum\_{i=1}^n a\_ib\_i\right|
\le
\left(\sum\_{i=1}^n a\_i^2\right)^{1/2}
\left(\sum\_{i=1}^n b\_i^2\right)^{1/2}
]
$$

```
\[
\left|\sum_{i=1}^n a_ib_i\right|
\le
\left(\sum_{i=1}^n a_i^2\right)^{1/2}
\left(\sum_{i=1}^n b_i^2\right)^{1/2}
\]
```


# Probability

Mod

## Models & Axioms

* Sample space&#x20;
  * List `set` of possible possible outcomes (OHM)
  * Mutually exclusive - there will be a definite outcome&#x20;
  * collectively exhaustive&#x20;
  * at the right granularity&#x20;
  * Model definition&#x20;
* probability laws&#x20;
* **Examples**&#x20;
  * Discrete  / finite&#x20;
    * two rolls of a tetrahedral die&#x20;
  * continuous
  *


# Linear Algebra

## Why linear algebra

* Translation and manipulation of space and data
* We usually understand 3D objects such as a primitive cube as a single mass but the reality is that they are made of points. A cube has at least 4 points. Each point has it whole XYZ coordinates. How can we perform transformations across all these points. The answer is using matrices/linear transformation. A matrix, in a way, is like a rule, that can be apply to each point.

| Item                                   | Cheat                                                                                                                                                                   |                                      |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| **Linear Transformation**              | <p><strong>Conditions:</strong><br>1. Origin remains fixed</p><p>2. All lines remain straight </p>                                                                      |                                      |
| Linear Combination                     | <ul><li>Sum of two vectors </li><li>Tip-to-tail method</li></ul>                                                                                                        |                                      |
| Span                                   | <ul><li>Span of 2 vectors is set of all their linear combination</li></ul>                                                                                              |                                      |
| Linearly dependent                     | Remove one point and there is no change                                                                                                                                 |                                      |
| Scalars                                | numbers                                                                                                                                                                 |                                      |
| Composition                            | Product of two matrices in a single action                                                                                                                              |                                      |
| Determinant                            | <p>Scaling factor </p><ul><li>if negative, orientation is flipped</li><li>det(m₁m₂) = det(m₁)det(m₂)</li></ul>                                                          |                                      |
| **Dot product**                        | if dot product of 2 vector = 0, then vectors are perpendicular                                                                                                          |                                      |
| **Cross product**                      |                                                                                                                                                                         |                                      |
| Basic vectors                          | <p>i-hat - unit vector of x<br>j-hat - unit vector of y</p><ul><li>The basis of vector spaces is set of linearly independent vectors that span the full span.</li></ul> |                                      |
| Eigenvalue                             |                                                                                                                                                                         |                                      |
| Eigenvector                            |                                                                                                                                                                         |                                      |
| Rank                                   | <p>Rank 1: Single line</p><p>Rank : 2D Plane</p><p>Rank 3: 3D plane</p>                                                                                                 |                                      |
| Duality                                | Natural but surprising correspondence                                                                                                                                   |                                      |
| Cramer's rule                          |                                                                                                                                                                         |                                      |
| Gaussian Elimination                   |                                                                                                                                                                         |                                      |
| Translating between coordinate systems | <ol><li>Translate to your own basic vectors</li><li>Perform linear transformation</li><li>Inverse translate basis vectors back to original</li></ol><p>A⁻¹MA</p>        |                                      |
| Identity matrix                        | Multiplying any matrix by the *identity matrix* results in the same matrix.                                                                                             | <p>1 0 0</p><p>0 1 0</p><p>0 0 1</p> |
| Kernel                                 |                                                                                                                                                                         |                                      |
|                                        |                                                                                                                                                                         |                                      |

#### Unit Vector — a vector whose length =1

$$
u = v/||v||
$$

**Tips**

* Do one transformation at a time from right to left
*


# Shader Dev

For Arnold Render with C++

#### Tutorials

* [**Compiling Custom Arnold Procedurals (Stand-ins) to Make Mandelbulbs with Maya MtoA, CGStirk**](https://youtu.be/BrZYnjoZLj)
* <https://docs.arnoldrenderer.com/display/A5AFMUG/Technical?preview=%2F40111108%2F40404366%2FArnoldShadersTutorial.pdf>
* <https://docs.arnoldrenderer.com/display/A5AFMUG/Creating+a+Shader>

  <https://docs.arnoldrenderer.com/display/A5ARP/Creating+a+Simple+Plugin>

#### Books

* <https://thebookofshaders.com/>

## Setting up

1. Download VSC
2. Download Arnold SDK

## Setting up Visual Studio Code

{% embed url="<https://youtu.be/DIw02CaEusY?t=583>" %}

## **Creating the Maya interface for your shader**

### Referencing your template files

1. Use the template from [Arnold docs](https://docs.arnoldrenderer.com/display/A5AFMUG/Creating+a+Shader)
2. Open your Maya env file located in `~/Library/Preferences/Autodesk/maya/2020/`
3. Insert this line at the end and save the file

```
MTOA_TEMPLATES_PATH = $HOME/Documents/maya/projects/arnold
```

{% hint style="info" %}

#### In Professor Kesson's Cutter script editor v8.34 and above, it will automate the process of parsing your cpp file for the node parameters, and write into a python template file.

{% endhint %}

## Utilities

### Mix

```cpp
AtRGB mix(AtRGB a, AtRGB b, float alpha){
	return a*(1-alpha) +b *alpha;
	}

```


# Getting Started with After Effects

WIP

**Welcome to your first taste of Motion Design**

In this free training video series, you will learn everything you need to know to start using After Effects today. This is not an overview of the software, this is a real training series that covers advanced techniques

**What Version of After Effects do I need?**

Most version would suffice; I'm currently running version 17.13

**Why is it free?**

I believe that teaching is a quality of kindness and love, and I want to share my love with you. We do not need a reason to perform acts of kindness. I am dedicated to help you reach your success the best I can. You can always consider supporting me by making a monthly donation via my Patreon.

**Why should I learn After Effects?**

After Effects gives you the ability to create stunning motion graphics, visual effects, and animation. It is industry standard tool that is used by almost every company and studio. Learning this tool is the first step you can take to enter the world of Motion Design.

## Content

### **Introduction to After Effects:**

* Workspace management
* Importing and organize footage & assets in the project window
* footage properties
* Create new composition
* Playback controls

### **Animation**

* animating keyframes
* changing the
* animation properties - ease
* speed graph

### Animation - Type

* text animators
* animation presets

### Working with other Apps: Illustrator, Photoshop

* importing PSD as a composition and footage
* importing AI files and file preparation

### Effects

### Time remapping

### 3D integrations

* importing Cinema4D style & C4D lite

### Expression

Unlock the full power of After Effects with the magic of Javascript and coding

### Rendering

* Render multiple format
* After Effects Output Modules
* Adobe Media Encoder

## What's next?

Congratulations on finishing the course! You are a bonafide Motion Designer now, and your journey is about getting even more exciting. I am sure you are curious about how to approach your adventure so below are resources and tips on you can get better on your craft and be a Super Motion Designer.

* **Actionable steps**
  * Learn shortcuts
  * Motion Design workflows
  * Optimization with Scripts & Extensions
  * **Find something to focus on**
    * technical direction
    * character animation & rigging
    * shape animation
    * compositing
    * type animation
* **Further readings**

  * Design for Motion, Austin Shaw
  * [Motionscript.com](http://Motionscript.com)
  * Motionographer

  **Resources**

  ‌

  * Design
    * Futur Academy: <https://www.youtube.com/channel/UCqHuGF2axS8Yf89r1tUVS_A>
  * Motion:
    * Ben Marriott:<https://www.youtube.com/c/BenMarriott/featured>
    * EcAbrams :<https://www.youtube.com/user/ECAbrams>
    * Black mixture:<https://www.youtube.com/user/BLVCKMXTR>
    * Workbench: <https://www.youtube.com/channel/UCSZMFHE56UDeEKNBan0HOCA>
    * School of motion: <https://www.youtube.com/channel/UCAhdxqdrDN3gWJkaUFl9G-Q>
    * Motion design school: <https://www.youtube.com/channel/UC-L0yvYPpGQZD3PHDLKiUpg>
  * 3D:
    * Greyscale gorilla<https://www.youtube.com/user/GreyscaleGorilla>
    * Eyedesyn <https://www.youtube.com/user/eyedesyn>
    * Patrick Foley
    * Blender guru :<https://www.youtube.com/user/AndrewPPrice>
    * Ian Hubert:<https://www.youtube.com/user/mrdodobird>
    * Ducky 3d:<https://www.youtube.com/channel/UCuNhGhbemBkdflZ1FGJ0lUQ>

  ‌

  There are a lot of beginners who do not know how to get into motion design or the resources

  ‌

  **FAQs**

  pply for a motion designer job, what are the best aspects your portfolio needs to consist of?

## Concepts

* Nesting 3D compositions&#x20;


# Best Practices

{% hint style="success" %}
Professionalism and expertise does not lies in how good you are at a software or the quality in your portfolio, these soft skills such as organization and thoughtfulness factors into a good motion designer.
{% endhint %}

## File Organization & Management

> Good housekeeping rules make collaboration a seamless and enjoyable experience.

{% hint style="info" %}
**Why is important?**

1. **Team-level** people do not need spend time looking for the right comps or assets, unified system of how to make sense of project files and their elements, avoid confusion <br>
2. **Personal-level** curation - never fret where your files are , easy access for reel editing or upload, avoid duplicates and reduce storage space usage, cleanliness <br>
3. **Desmond-level:** I hate unorganized people
   {% endhint %}

Since my journey in digital media in 2010, the most efficient and optimal file folder structure I have used is the one from WarnerMedia Studios. Working there, we mostly just access just 2 folders: `projects` and `library`. `Projects` contains folders of different projects with a standardized naming convention, and `library` is a folder filled with assets such as textures, stock photos, 3D models, and so on. I used to separate project folders based on "personal" and "professional" but then I realized it was better to just combine them.

```
root
    projects
        project_1 // use "standard" file folder structure below
        project_2
        ...
    lib
    branding
    portfolio
```

### Folder Structures templates

If you are on a mac, you can copy any of the snippets below to create a folder structure on your desktop. Alternatively, you can download zip files&#x20;

#### HOME — Database

{% tabs %}
{% tab title="v2" %}

```bash
cd ~/desktop
mkdir home
cd home

mkdir -p data/{00_passport_photo,01_id,02_employment,03_studies,04_immigration,05_tax,06_housing,07_insurance,receipt}
mkdir -p portfolio/{_final_delivery,footage/{2020,2019,2018,2017},lib/{01_logos,02_photography,03_footage,04_movs,05_textures,06_3DModels,07_audio,08_fonts},working_file}
mkdir -p 'projects'/DATE_PROJECTNAME
mkdir -p branding/{_final_delivery,lib/{01_photo,02_featured,03_accolades,04_references},working_files}
mkdir -p 'Ω UNSORTED'
```

{% endtab %}

{% tab title="v1" %}

```bash
cd ~/desktop
mkdir HOME
cd HOME

mkdir -p OUT
mkdir -p DATA/{ID,PASSPORT,IMMIGRATION,PROFILE_PHOTOS,SIGNATURE,TAX,HOUSING,INSURANCE}
mkdir -p PORTFOLIO
mkdir -p 'PROJECT — PRO'
mkdir -p 'PROJECT — PERSONAL'/DATE_PROJECTNAME
mkdir -p 'Ω UNSORTED'
```

{% endtab %}
{% endtabs %}

#### For Projects

{% tabs %}
{% tab title="small" %}

```bash
cd ~/desktop
mkdir project_folder_smallForm
cd project_folder_smallForm

mkdir -p 01_Out
mkdir -p 02_Dailies
mkdir -p 03_Workfiles/AEPs
mkdir -p 04_Assets
mkdir -p Ω_SANDBOX
```

{% endtab %}

{% tab title="standard" %}

```bash
cd ~/desktop
mkdir project_DVFX
cd project_DVFX

mkdir -p '_final_delivery'
mkdir -p working_files
mkdir -p dailies
mkdir -p 'lib'/{_from_client,_seq,01_logos,02_photography,03_footage,04_movs,05_textures,06_3DModels,07_audio,08_fonts}
```

{% endtab %}

{% tab title="shaw" %}

```
cd ~/desktop
mkdir project_folder
cd project_folder

mkdir -p ELEMENTS/{3D,AUDIO,FONTS,FOOTAGE,RASTER,VECTOR}
mkdir -p DELIVERABLES
mkdir -p PRESENTATION/{00_PDF,01_INDESIGN,02_STYLEFRAMES,03_WIP,04_BTS}
mkdir -p PROJECTS/{AEP,C4D}
mkdir -p REFERENCE
mkdir -p RENDERS
```

{% endtab %}
{% endtabs %}

### File naming conventions

#### Naming Projects&#x20;

As someone who makes tutorials, I use project code to differentiate them.&#x20;

```javascript
//nosleepcreative
ms - masterstudies
exp - expression
gen - generative 
collab - collaboration
cs - carousel

// personal
fl - freelance
```

For one-off projects, I still abbreviate them into project code such as "comotion" to "cm"

### Quick access with [Alfred](https://www.alfredapp.com/)

The major benefit of having a consistent file structure and naming convention is how you can **access your files just by using the keyboard in a second** rather than clicking through a series of folder to get to it. I use a macOs and I make use of this free app called [**Alfred**](https://www.alfredapp.com/) which is basically a faster and customizable version of Spotlight (the search bar).

## How to deliver files&#x20;

When sending files over to your teammates or any other personnel, please make use of the `Reduce Project` feature in AE. This will remove any used assets or compositions

## Optimization & Efficiency

### Workspaces

### Animation Preset

**Why**: to avoid recreating the same things over and over again, it is a good practice to save and curate your commonly used effects and their settings into animation preset. This way you can avoid rewriting expressions, setting keyframes, or applying combination of effects.

As a motion designer, I highly recommend everyone to build their own library of animation presets that will serve as their bag of tricks. **Not sure animation presets but rigs or templates AEPs as well.**

#### How to save animation presets&#x20;

Select the properties / property groups that you want > `animation menu` > `Save as Animation Preset`

![](/files/-Ly_yHNKcfePqjUcWyr2)

### How to save Render Settings(ars) and Output Modules (aom)

If you want to save a render-settings template for use on another system

* Cick the **Save All button in the Render Settings Templates dialog box before you close it**&#x20;
* or, reopen the dialog box later by choosing Edit > Templates > Render Settings).&#x20;
* Save the file in an appropriate location on your hard disk, such as in the After Effects application folder.&#x20;
* All the currently loaded render settings are saved in a file with the .ars extension.&#x20;
* Then, copy this file to the disk of the other system. When you start After Effects on that system, choose Edit > Templates > Render Settings, click the Load button, and select the new .ars file to load the settings you saved.

[**Source**](https://forums.creativecow.net/docs/forums/post.php?forumid=2\&postid=1040525\&univpostid=1040525\&pview=t)

### Extensions

### ScriptUIs

### Project scale

Skills: using proxies, internal file marking, and render setting.&#x20;

Editing can become such a pain when things aren't optimized as files get bigger and longer. Some file sizes that are 2-3Gb only actually need to be under 100 Mb. If you set up your files properly so that someone else can use it, your team will love you for it.

**Readings**

* [**10 Tips for Increasing Your Productivity in After Effects**](https://blog.pond5.com/12772-10-tips-for-increasing-productivity-in-after-effects/?fbclid=IwAR3fskQ3c6PKZ2sKcw-bY_JP6B8EwdFiuC-F6fdn-CQfvUdvj8y9PtgEt8Q)

## Communication

When working with my peers, here are specifications I always provide for their final delivery.

```
specs
    resolution - 1920x1080
    fps
    duration
    codec - prores 422 hq or prores 4444+alpha

Animation
    shading done via rendering/AE post
    specific properities - rot x -90 to 90

project file delivery 
    reduce project
```

## Shortcuts that you should know&#x20;

### Basics

| Command              | Shortcut               |
| -------------------- | ---------------------- |
| Quit                 | Cmd + Q                |
| Close composition    | Cmd + W                |
| New project          | Cmd+Alt+N              |
| New Folder           | ⌥+⇧+⌘+N&#xD;&#x9;&#xD; |
| New Composition      | Cmd+N                  |
| New Adjustment Layer | Cmd + Alt + Y          |
| New solid            | Cmd+Y                  |
| New Null Layer       | Cmd + Alt +Shift + Y   |
|                      |                        |

### Timeline

|                           |                                       |
| ------------------------- | ------------------------------------- |
| Show animated properties  | U                                     |
| Show modified properties  | UU                                    |
| Show Expressions          | EE                                    |
| Replace Footage           | Cmd + Option + H                      |
| Adjust Kerning            | Option (Alt) + Left/ Right Arrow keys |
| Adjust Tracking           | Option (Alt) + Up/Down Arrow keys     |
| Trim comp to in & out     | Cmd+Shift +X                          |
| Trim layer inPoint to CTI | cmd+ \[                               |
| Trim layer inPoint to CTI | cmd+ ]                                |
| Render                    | Cmd + Shift + /                       |
| Render Queue              | Opt + Cmd + 0                         |
| New project               | Opt + Cmd + N                         |

```
Collapse layer properties - Shift + ~
```


# Pimping up AE

## Resources

#### AE Script Starter Pack

* [FX Console](https://www.videocopilot.net/blog/2018/05/fx-console-updated-to-v1-0-3/)
* [Ease & Whizz](https://aescripts.com/ease-and-wizz/)
* [Laber Maker](https://aescripts.com/label-maker/)
* [Project Cleaner](https://aescripts.com/project-cleaner/)
* [Buttcapper](https://www.battleaxe.co/downloads)
* [RepositionAnchorPoint](https://aescripts.com/repositionanchorpoint/)
* Easecopy

#### Others

* After Effects Output modules

#### NoSleepCreative Expression Starter Pack

* Basic Expression Workshop: <https://youtu.be/aZ5F1eCm428>
* Expression snippet library: <https://docs.nosleepcreative.com/code/javascript-for-ae/expressions>

#### Recommended Readings

**Expression** **Documentation**

* [**Aenhancers — Expressions**](http://expressions.aenhancers.com/)
* [W3 School Javascript](https://www.w3schools.com/js/js_object_definition.asp)
* [**Expression guide**](https://readthedocs.org/projects/after-effects-expressions-guide/downloads/pdf/latest/)
* [**JR Canesto AE Tricks Google Sheets**](https://docs.google.com/spreadsheets/d/1a3ArTUHAJwVi-ObZofvz6IfrKbSGSENlaTIRTs8pAJU/edit#gid=0)

**Tutorials**

* \*\*[Motionscript\*\* by Dan Ebbert](http://www.motionscript.com/)
* [Animoplex](https://www.youtube.com/channel/UCbfz_keteqaKbpiRiS95Dqg)
* [AE Incredible Expressions Challenge](https://www.youtube.com/playlist?list=PLZAr8tT8TcsRj62nIO7ILCMitj5RKjsMf)

## Installing scripts

* **How to install script & scriptsUI**
  * via AE menu
  * via placing in directory&#x20;
  * via [aescripts + aeplugins manager app](https://aescripts.com/learn/aescripts-aeplugins-manager-app/)
  * practice with:  RepositionAnchorPoint
* **Installing via DMG:**&#x20;
  * fx console - shortcut, saving screenshots, copying to clipboard
* **How to install ZXP extensions with ZXP installer**
  * Install Flow

## Setting up your workspaces

## AE Organization & management

{% hint style="info" %}
Essentially, you want to use the same principles as above: having a consistent folder structure, responsibly naming your files, and reducing project size.
{% endhint %}

### Folder Structures

{% file src="/files/-MNuu63zE077ZQ9LSqrW" %}
After Effects Folder Structures
{% endfile %}

### Setting up preferences to auto-load AEP template&#x20;

Under Preferences > New Project  > Choose Project Template > Select AEP to use for startup

![](/files/-MPe0tqQUYokY_l8OKoC)

## After Effects Output Modules (AOM)

```javascript
Rule of thumb: 
prores 422HQ for delivery, 
4444+alpha for video that needs alpha, 
LT if storage space is limited,

mp4: high quality 2 pass encoding 50mbps, max render quality
```

### How to save Render Settings(ars) and Output Modules (aom)

If you want to save a render-settings template for use on another system

* Click the **Save All button in the Render Settings Templates dialog box before you close it**&#x20;
* or, reopen the dialog box later by choosing Edit > Templates > Render Settings).&#x20;
* Save the file in an appropriate location on your hard disk, such as in the After Effects application folder.&#x20;
* All the currently loaded render settings are saved in a file with the .ars extension.&#x20;
* Then, copy this file to the disk of the other system. When you start After Effects on that system, choose Edit > Templates > Render Settings, click the Load button, and select the new .ars file to load the settings you saved.

[**Source**](https://forums.creativecow.net/docs/forums/post.php?forumid=2\&postid=1040525\&univpostid=1040525\&pview=t)

### How to load AOM files

Have a item in the render queue > `Output Module` > `Make Template` > `Load` > Select AOM file

![](/files/-MPe1SjjcTwZn3HADXN8)

{% file src="/files/-MNuuGq1cF7KPK3ZLwxl" %}
NSC After Effects Output Modules
{% endfile %}

##


# Environment

### Locations

```
/Library/Application Support/Adobe/CEP/extensions
/Applications/Adobe After Effects 2020/Plug-ins
/Applications/Adobe After Effects 2020/Scripts
/Applications/Adobe After Effects 2020/Scripts/ScriptUI Panels
```

## Adobe Environment setup

### Preferences location

```
/Users/userName/Library/Preferences/Adobe/After Effects/16.1/ModifiedWorkspaces
/Users/userName/Library/Preferences/Adobe/Premiere Pro/13.0
~/Library/Preferences/Adobe/Audition/10.0/
```


# Houdini

## Recommended Readings

#### Industry / Case Studies

* ​Rohan Dalvi&#x20;
* Entagma

#### Documentation / Tutorials&#x20;

* [**https://www.sidefx.com/docs/houdini/vex/index.html**](https://www.sidefx.com/docs/houdini/vex/index.html)
* [**VEX Language Reference**](https://www.sidefx.com/docs/houdini/vex/lang.html)
* [**VEX Functions**](https://www.sidefx.com/docs/houdini/vex/functions)
* <https://www.sidefx.com/learn/getting_started/>
* <https://www.hipflask.how/>
* <https://www.sidefx.com/docs/houdini/>
* <https://www.sidefx.com/forum/>
* [SideFX Digital Learning Material](https://docs.google.com/spreadsheets/d/11FbYBV_OV2INv3LCk38fmcgZbuVrgxYaZK-1KifCpyc/edit#gid=0)&#x20;
* Algorithmic
  * [Junchiro Horikawa](https://www.youtube.com/c/JunichiroHorikawa/videos)

**Repositories / Wiki**

* [Deborah Fowler](http://www.deborahrfowler.com/HoudiniResources/HOUDINI-RESOURCES.html)
* [**Tokeru**](http://www.tokeru.com/cgwiki/?title=Houdini)
  * [Joy of VEX](http://www.tokeru.com/cgwiki/index.php?title=JoyOfVex)
* [**Tosin Akinwoye**](https://tosinakinwoye.com/2017/01/23/houdini-vex-snippets/)
* [**Kiryha**](https://github.com/kiryha/Houdini)
* [**Jtomori**](https://github.com/jtomori/vex_tutorial/blob/master/README.md)
* [**John Kunz**](http://mrkunz.com/blog/08_22_2018_VEX_Wrangle_Cheat_Sheet.html)

**Mathematics**

* Khan Academy
* [Procedural noise](https://www.scratchapixel.com/lessons/procedural-generation-virtual-worlds/perlin-noise-part-2)
* [**3Blue1Brown​**](https://www.youtube.com/channel/UCYO_jab_esuFRV4b17AJtAw)
* [Cross Product and Dot Product: Visual explanation](https://www.youtube.com/watch?v=h0NJK4mEIJU)
* [The Applications of Matrices | What I wish my teachers told me way earlier](https://www.youtube.com/watch?v=rowWM-MijXU\&feature=youtu.be)[ers told me way earlier](https://www.youtube.com/watch?v=rowWM-MijXU\&feature=youtu.be)

## **Abstract**

* **Houdini** is a 3D software known for it's procedural generation tools. The word procedural might sound vague to you but in short what it means to to me is that:
  * Non-destructive setup&#x20;
  * Flexibility and adaptability
  * The software do most of the work; you just need to create the tools&#x20;
* This software has a steep learning curve, and it is especially difficult if you have not used a node-based software such Nuke previously. **It is natural not to comprehend what you are doing where you are starting out;** just keep watching tutorials daily and one day your brain will somehow makes sense of the things you never thought you understand. This pretty much applies to learning of any subject matter.
* To get started with Houdini, start by thinking in "points". If you can manipulate points in any way you want; you would have no problem with the software.

## Shortcuts

| Function                           | Windows                  | Mac                                       |
| ---------------------------------- | ------------------------ | ----------------------------------------- |
| <p></p><p>View properties </p>     |                          | MMB                                       |
| Reveal Properties Panel            |                          | P                                         |
| <p>Align nodes<br>Layout nodes</p> |                          | <p>Hold A + Drag (Down/Right)</p><p>L</p> |
| Move in-out of nodes               |                          | U & I                                     |
| Cut node connection                |                          | Y                                         |
| Radial Menu                        |                          | V                                         |
| Network box                        |                          | shift + O                                 |
| Camera views                       |                          | Cmd 1/2/3/4                               |
| Delete Channel                     |                          | Ctrl + Shift + LMB                        |
|                                    |                          | Shift W                                   |
| Save Quickview                     | Ctrl + numpad 6-9        | Cmd + numpad 6-9                          |
| Load Quickview                     | Space+ numpad 6-9        |                                           |
| Go to next / previous level        | Alt + Left / Right arrow |                                           |

## Terminology

| Item   | Description                                                                                                                                                                                                                                                                                                                                        |
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Object | **Object type nodes in an Object type folder.** These Object nodes allow you build transform constraint hierarchies. Geometry type Object nodes contain SOP nodes that construct and modify geometry that inherit any transforms at the object level.                                                                                              |
| SOPs   | **Surface Operators** or geometry nodes that are inside an object folder. These are used to construct and modify geometry. Any kind of geometry from polygons to volumes.                                                                                                                                                                          |
| DOPs   | **Dynamic Operators** or simulation/solver nodes that are used to construct simulations. Simulations read in geometry from SOPs and passes this data in to the DOP solvers.                                                                                                                                                                        |
| SHOP   | **Shading Operator**s are materials that represent a shader to apply to geometry. Some are hard coded with vex and others are folders that you can dive in to and modify the VOPs inside.                                                                                                                                                          |
| VOPs   | **Vector Operators** inside VOP network nodes are used for everything from building shaders to modifying geometry, volumes, pixels, and more.                                                                                                                                                                                                      |
| VEX    | **Vector Expression Language.** The code language used to write shaders. VOPs are wrappers around VEX code snippets.                                                                                                                                                                                                                               |
| CVEX   | **Context agnostic Vector Expression Language.** This has replaced all the VEX specific contexts throughout Houdini. It is a generalized language that uses the same environment and functions anywhere inside Houdini.                                                                                                                            |
| COPs   | **Composite Operators** in composite type folders. Used in image compositing operations.                                                                                                                                                                                                                                                           |
| ROPs   | **Render Operators** in side ROP Output directories which are used to create render output dependency graphs for automating output of any type of data and for triggering external processes like rendering. Commonly used to generate sequences of geometry, simulation data and trigger Render tasks that generates sequences of images to disk. |
| CHOPs  | **Channel Operators** used to create and modify any type of raw channel data from motion to audio and everything in between. Most users safely ignore the CHOP context, and so can you, for now. Put it on the “get to it later” list when learning Houdini. But definitely keep it on the list.                                                   |

## Best practices / Tips

* When using `copytopoint` for an object and a grid, you can attach an `add` node after the grid to delete all unused geometry; leaving only the points.
* With more than one node selected, hold alt/option and drag a new connection. It will automatically create a `merge`node.
* When using the TAB menu to create a node, you can type the initials of the node name to access it. Example:
  * Point wrangle: PW&#x20;
  * Attribute from Map: AFM or AM


# Cheatsheet

## hscript

#### References

* Sidefx, [Expression cookbook](https://www.sidefx.com/docs/houdini/ref/expression_cookbook.html)
* Sidefx, [Parameter Expressions](ttps://www.sidefx.com/docs/houdini/network/expressions.html)
* <https://www.sidefx.com/docs/houdini/expressions/index.html>

#### Repositories

```c
$CY // copy number    
```

## Data types declaration

```c
int x = 18; // integer
float y =  3.142 // float 
string name = "John";  // string
vector v = {1,1,1};
matrix3 m = ident(); // identity matrix creation
quaternion 

// array form: member_type var_name[]:
float my_array[];
vector_array[];
str_array[];

//global attribute
@myGlobalAttribute
v@myVector = set(-1,-1,-1);
i@var = 1;
```

## Statements

```c
// Loops
for(int i =1; i<10;i++)
    {
}

// if conditional 
if(x==1){
    ...
    }else{
    ...
}

// while 
while(condition){
    yourStatement;
}
```

## Attributes

{% code title="" %}

```c
normalize 
// Position
@P 
@P.x
@P.y
@P.z

// Normal
@N 

// color
@Cd.r
@Cd 
@Cd.g
@Cd.b
@Alpha // Alpha


//scale
@pscale = 1;

@scale.x = 1;
@scale.y = 1;
@scale.z = 5;

// Set scale, and manipulate one axis only
@scale =set(1,1,1); 
@scale.y = 2.

// commonly used
@ptnum
@
```

{% endcode %}

```c
 
// Position
@P 
@P.x
@P.y
@P.z

// Normal
@N 

// color
@Cd.r
@Cd 
@Cd.g
@Cd.b
@Alpha // Alpha


//scaling
@pscale = 1;

@scale.x = 1;
@scale.y = 1;
@scale.z = 5;
    
// Set scale, and manipulate one axis only
@scale =set(1,1,1); 
@scale.y = 2.
```

## Functions

```c
v@myVector = set(-1,-1,-1);

fit01(attribute,minVal,maxVal);
fit(attribute,ominVal,omaxVal,minVal,maxVal);
rand(value);
    
normalize
    
//noise types 
noise 
anoise
snoise 
pnoise 

    
//Copystamp
stamp("../copy1","variable",0)
```

## Expressions

```c
Time — $T / @Time
Frame — $F (int) / $FF (float)
Stamp — stamp("path","variable/channel",defaultValue)
    eg. stamp("../copy1","rotation",25)


//Centroid
$CEX, $CEY , $CEZ

$HIP — Project path
$HIPNAME — HIP project name

// Parsing file name 
name.$F4.jpg // $F4 padding: 0008.jpg
```

## Creating controls

```c
ch('threshold')
chf('threshold')
chi('threshold')
chv('vector_parm)'

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)
```


# Cookbook

## Generating points

Ensure that `pointwrangle` is set to run over Detail&#x20;

### Stacking boxes

{% tabs %}
{% tab title="pointwrangle" %}

```c
//user controls 
float size = chf("size");
int pt =  chi("numpt");

// OR reference box size with expressions
// float size  = `chs("/obj/Boxes/box4/sizey")`; // notice the backticks for expressions

for(int i =0 ;i<pt;i++){
    float x = 0;
    float y = i*size;
    float z = 0;
    v@loc = set(x,y,z);
    addpoint(0,v@loc);
}
```

{% endtab %}

{% tab title="copystamp" %}

```c
// change center to bottom for SOP
ch("sizey") * .5

//place expresssion into translate Y of a copy stamp node
ch("../box1/sizey") + $CY * ch("../box2/sizey")

// get bounding box og geometry
bbox("../merge1",D_YSIZE)
```

{% endtab %}
{% endtabs %}

### Stacking spheres

{% tabs %}
{% tab title="vex" %}

```c
//user controls 
int pt =  chi("numpt");
float size  = 2*`chs("/obj/SnowMan/sphere1/rady")`*`chs("/obj/SnowMan/sphere1/scale")`;

for(int i =0 ;i<pt;i++){
    float x = 0;
    float y = i*size;
    float z = 0;
    v@loc = set(x,y,z);
    addpoint(0,v@loc);
}
```

{% endtab %}

{% tab title="expressions" %}

```c
// align sphere center to bottom
ch("rady")*ch("scale")

// reference scale
ch("../sphereBase/scale") * .8

// transform / stacking 
ch("../sphereBase/rady") * 2 * ch("../sphereBase/scale")
+ ch("../sphereStomach/rady") * 2 * ch("../sphereStomach/scale")

// using bbox
bbox("../merge1",D_YSIZE)
```

{% endtab %}
{% endtabs %}

### Circle

{% tabs %}
{% tab title="vex" %}

```c
int pt = 18;
float angle = 360/pt;
float radius = 20;

for (int i = 0; i < pt; i++)
{
    float x = radius * cos(radians(angle * i));
    float y = radius * sin(radians(angle * i));
    float z = 0;
    v@loc = set(x, y, z); 
    addpoint(0,v@loc);
} 
```

{% endtab %}

{% tab title="expression" %}

```
// copystamp
10 * cos(10 * $CY)
10 * sin(10*$CY)
```

{% endtab %}
{% endtabs %}

### Spirals&#x20;

{% tabs %}
{% tab title="Constant" %}

```c
int points = chi("points");
float radius = chf("radius");
float freq = chf("freq");
float mul = chf("mul");
vector pos ={0,0,0};


pos.x = radius*sin(@Time*freq);
pos.y = radius*cos(@Time*freq);
pos.z = @Time*freq*mul;

addpoint(0,pos);
```

{% endtab %}

{% tab title="Regular" %}
{% code title="Source: David Kahl Polar Coordinates in Houdini" %}

```c
// 1st point wrangle

int points =chi("points");
float step = (PI*2)/ ch("steps");

vector pos;
float angle = chf("angle");
float radius = chf("radius");


for(int i=0; i<points;i++){
    angle+= step;
    radius = float(i)/ float(points);
    pos.x = cos(angle) * radius;
    pos.z = sin(angle) * radius;
    addpoint(0,pos);
}

// 2nd point wrangle
float norm = float(@ptnum)/float(npoints(0));
@P.y=norm*chi("mult");

// 3rd point wrangle
for(int i= 0;i<npoints(0);i++){
    int prim = addprim(0,"polyline");
    addvertex(0,prim,i);
    addvertex(0,prim,i+1);
    
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Phyllotaxis

* [Phyllotactic wrangle nodes examples](http://deborahrfowler.com/HoudiniResources/WrangleNodeExampleVexFunctions.html), Deborah Fowler
  * <http://deborahrfowler.com/MathForVSFX/Phyllotaxis.html>
  * <http://deborahrfowler.com/MathForVSFX/PhyllotacticZoetrope.html>
* [The Algorithmic Beauty of Plants](http://algorithmicbotany.org/papers/#abop) - chapter 4, Springer-Verlag

#### Vogel’s formula

$$
r = c\sqrt n \θ = n \* 137.508
$$

#### Parametric equations

$$
x =  c \sqrt n*cos ( n \* 137.508 )\y=  c \sqrt n*sin ( n \* 137.508 )
$$

{% tabs %}
{% tab title="vex\_fowler" %}

```c
// source: deborahrfowler.com

int total = chi("total");
float cval = ch("cval");
float zdepth = ch("zdepth");
float angle = 137.508;

void makephyllo(int total; float cval; float zdepth; float angle){
    float x,y,z;
    vector loc ={0,0,0};
    
    // set up the rotation azis variables to orient objects correctly onto the points
    // to do this, we will associate an orient attribute with each point;
    vector axis = {0,0,1};
    float radrotAngle;
    vector4 orient;

    for(int i =0;i<total;i++){
        x = cval *sqrt(i) * cos(radians(angle*i));
        y = cval *sqrt(i) * sin(radians(angle*i));
        z = i*zdepth;
        loc =set(x,y,z);
        
        // set up rotation - orient attribute
        radrotAngle = radians(angle*i);
        orient = quaternion(radrotAngle,axis);
        addpoint(geoself(),loc);
        
        // note that the addpointattrib creates the attribute, it is necesary to use setpointattrib to write the values
        addpointattrib(geoself(),"orient",orient);
        setpointattrib(geoself(),"orient", i, orient, "set");
        
        }
}
    
makephyllo(total,cval,zdepth,angle);

```

{% endtab %}

{% tab title="vex\_kiryha" %}

```c
// Source: https://github.com/kiryha/Houdini/wiki//vex-snippets

int count = chi('points');
float bound = 10.0;
float tau = 6.28318530; // 2*$PI
float phi = (1+ sqrt(5))/2; // Golden ratio = 1.618
float golden_angle = (2 - phi)*tau; // In radians(*tau)
vector pos = {0,0,0};
float radius = 1.0;
float theta = 0;
int pt;


vector polar_to_cartesian(float theta; float radius){
    return set(cos(theta)*radius, 0, sin(theta)*radius);
}

for (int n=0; n<count; n++){
    radius = bound * pow(float(n)/float(count), ch('power'));
    theta += golden_angle;
    
    pos = polar_to_cartesian(theta, radius);

    // Create UP, pscale and N attr
    pt = addpoint(0, pos);
    setpointattrib(0, "pscale", pt, pow(radius,0.5));
    setpointattrib(0, "N", pt, normalize(-pos));
    setpointattrib(0, "up", pt, set(0,1,0));
}
```

{% endtab %}

{% tab title="exp" %}

```c
//formula
c * sqrt( $CY ) * cos ( $CY * angle )

// with correct values
2 * sqrt( $CY ) * cos( $CY * 137.508 ) i
```

{% endtab %}
{% endtabs %}

$$
x = \rho cos\theta sin\phi\y = \rho sin\theta sin\phi\z=\rho cos\phi
$$

### [Torus](https://math.stackexchange.com/questions/324527/do-these-equations-create-a-helix-wrapped-into-a-torus) / Toroidal

```c
```

$$
x=(a+bcosu)cosv
\\
y=(a+bcosu)sinv\\
z=bsinu
$$

```c
// Attribute wrangle SOP (Detail mode) 

float vel = chf('vel');
int numpt = chi('Points');
float a = ch('a'); // completion
float b = ch('b'); // arc length
float u = ch('v'); // radius
vector pos; 

for(int i=1;i<numpt;i++){

    addpoint(0,pos);
    float offset = @ptnum*vel*i;
    addprim(0,"polyline",i);
    addvertex(0,1,i);
    pos.x = u*cos(a*offset)*sin(b*offset);
    pos.y = u*sin(a*offset)*sin(b*offset);
    pos.z = u*cos(offset*b); 
}
```

{% tabs %}
{% tab title="1" %}

```c
//  Have a geo & scatter sop before the wrangle node

float t = 1.0*@elemnum/@numelem ;

float completion = ch('completion') * 2 * $PI;
float coils = ch('coils');
float R = ch('outerRadius');
float r = ch('innerRadius');

float u = t * completion * coils ;
float v = t * completion ;

float x = cos(v)*(R+r*cos(u));
float y = sin(v)*(R+r*cos(u));
float z = r * sin(u);

@P = set(x,y,z);

//https://berniebernie.fr/wiki/Houdini_VEX
```

{% endtab %}

{% tab title="2" %}

```c

float t = 3.0*@elemnum/@numelem ;

float a = ch('a'); // radius
float b= ch('b'); // inner radius
float u = ch('u')*t; // coils
float v = ch('v')*t; // completion

float x = (a+b*cos(u))*cos(v);
float y = (a+b*cos(u))*sin(v);
float z = b*sin(u);

v@P = set(x,y,z);

//https://math.stackexchange.com/questions/324527/do-these-equations-create-a-helix-wrapped-into-a-torus
```

{% endtab %}
{% endtabs %}

### Mobius strip

$$
x = \[ R + s cos(½ t)] cos(t)\\
y= \[ R + s cos(½ t)] sin (t) \\
z = s sin(½ t)
$$

```c
//  Have a geo & scatter sop before the wrangle node

float completion = ch('completion');
float t = completion*@elemnum/@numelem ;
t += ch('vel');
float R = chf('radius'); 
float s = chf('s');
vector pos = @P;

float x = (R+s*cos(.5*t))*cos(t);
float y = (R+s*cos(.5*t))*sin(t);
float z = s*sin(0.5*t);

@P = set(x,y,z);
//https://berniebernie.fr/wiki/Houdini_VEX
```

Check out: <https://www3.math.tu-berlin.de/geometrie/Lehre/SS17/MathVis/exercise01.pdf>

### Cardioid

```c
```

Also check out: [Times Tables, Mandelbrot and the Heart of Mathematics](https://www.youtube.com/watch?v=qhbuKbxJsk8\&feature=youtu.be)

## Points transformation

### Random pscale

{% tabs %}
{% tab title="static" %}

```c
@pscale = rand(@ptnum)
@pscale = fit01(@pscale, ch('min'),ch('max')); // fit within range 
```

{% endtab %}

{% tab title="animated" %}

```c
```

{% endtab %}
{% endtabs %}

### Random delete points/prim/id

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

// shorthand
if rand(@pt)<ch('threshold') 
   removepoint(0,@ptnum);
```

### Random 'pushing' along Normal

```c
float factor = fit01(rand(@ptnum),chf('min'),chf('max'));

@N*=ch('scale')*factor;
@N = pow(@N,1.1);
@P= @N;

```

## Rotation

### Rotate to point to center

```c
//orientVector_Lavrenov

@N = normalize(-@P);
v@side= normalize(cross(@up,@N));
float rot_amount = length(@P)*-chf("rotation_mul");

matrix3 m = ident();
rotate(m,rot_amount, @side);
@N = normalize(@N*m);
@up = normalize(@up*m);

```

### Rotation with p\@orient

```c
float rotx = ch('rot_x');
float roty = ch('rot_y');
float rotz = ch('rot_z');
 
vector r = set(rotx,roty,rotz);
 
p@orient = eulertoquaternion(radians(r),XFORM_XYZ);
```

### Rotating points with matrix

```c
matrix3 m = ident(); // identity matrix creation
float angle = radians(chf("degrees")); // angles in radians
vector axis = {0,1,0}; // axis to turn

rotate(m,angle,2);
@P *= m;

```

## Scale

### Scale primitive locally with matrix & foreach

{% tabs %}
{% tab title="Local" %}

```c
float scale = chf('scale');
vector nml = prim_normal(0, @primnum, {0,0,0});
int pts[] = primpoints(0, @primnum);
foreach(int pt; pts){
    matrix m = instance(v@P, nml, scale, {0,0,0}, {0,0,0,1}, v@P);
    vector pos = point(0, 'P', pt) * m;
    setpointattrib(0, 'P', pt, pos, 'set');
} 
// Source:https://www.sidefx.com/forum/topic/50477/?page=1#post-227472
```

{% endtab %}

{% tab title="towards Prim Center" %}

```c
float scale = chf('scale');
int pts[] = primpoints(0, @primnum);
foreach(int pt; pts){
    vector pos_pt = point(0, 'P', pt);
    vector dir = normalize(pos_pt - v@P);
    vector pos = pos_pt + dir * scale;
    setpointattrib(0, 'P', pt, pos, 'set');
} 
```

{% endtab %}
{% endtabs %}

## Spreading points in one axis

![](/files/-LpYNk2ZFLi1gt2lNu59)

```c
@P.y = normalize(curlnoise(@P+@Time*.02)*0.5);
@pscale = rand(@ptnum);
@Cd = rand(@ptnum);
```

## Color

![](/files/-Ly-MIz90NgoH826uL8z)

### Band(s) of color moving across geo in one-axis

```c
@dir = @P.y;
float width = chf('width');
float offset = chf('offset');
float vel = chf('vel');
@Cd = sin(offset+width*@dir-@Time*vel);
@pscale = @Cd;
```

## Oscillations

### Sin wave

```c
abs(sin(@Time*rand(@ptnum)+chf('Z')));
```

## Using Cd for alpha

```c
float u  = clamp(@value,,0,1); 
@Alpha = chramp('ramp_value'),u)
```

## Connecting lines

### Plexus — Entagma

```c
float maxdist = chf('max_dist');
int npts[] = nearpoints(0,v@P,maxdist);

removeindex(npts,0);
i[]@npts = npts;

foreach(int npt; npts){
     addprim(0,"polyline",@ptnum,npt);
}
   
```

## Type

### Random character

```c
 \\`int(fit01(rand($F),1,94))` 
 
 // use 65-90 for lower case letters.
 
 // Time Shift SOP
 stamp('../copy1','step',2)
 
 // copystamp SOP
  fit01(rand(@ptnum+$F+22),0,100)
```


# Techniques

Proceduralism

## Readings

* <https://www.deborahrfowler.com/HoudiniResources/HoudiniOverview.html>

## Transferring attributes

* Using `attribtransfer` eg. P, Cd
* Using Pointwrangle Get attributes from second input in wrangle node \[[src](https://www.sidefx.com/forum/topic/54084/)]

&#x20;If you want to get an attribute (lets say color) from a specific point number (lets say 123456) from input 2, you can use

```
@Cd = point(1, 'Cd', 123456);
```

If you have the same number of points on both inputs and you want to get an attribute from the corresponding point on input 2 you can use this shortcut

```
@Cd = v@opinput1_Cd;
```

Where the number 1 describes the input port.

&#x20;Ah, you want the number of points on input 1?<br>

```
@number_of_points_on_input_1 = npoints(1)
```

## Copy stamping & Looping

* [Looping](https://www.deborahrfowler.com/HoudiniResources/Overview-Looping.html), Deborah Fowler

There are three ways of manipulating and copying points

1. `Copy Stamp` with Expressions - good for quick prototyping
2. `Copy to Points` with a SOP eg. `circle`
3. `Copy to Points` with `pointwrangle` and VEX

###

## Point generation&#x20;

1. Using VEX
2. Using `line` to create points > `point` to change the position eg. Creating circle of points

## Orient objects or profiles to a curve

### Using polyframe

## Instancing = packed geo & copypoints

#### Tutorials

* <https://vimeo.com/207724703>

### Lights&#x20;

* `Instance` - similar to copytopoints to grid
  * Select Instance object
  * Place points or geo inside network
  * Point Instancing: Fast-point for geometry, **full point instancing** for lights&#x20;

### **Random geometries**

* Pros: faster processing and work with render engines
* Reveal instance in viewport via Display Opetion > Geometry > Instancing

1. create mmultiple objects: demo1, demo2, demo3
2. attribcreate -&#x20;
   1. string , name: "instance", String: /obj/demo1
   2. /obj/demo\`round(fit01(rand(@ptnum),1,2))\`

![](/files/-MY-vJ1pLS80lPgzo8GQ)

### **Random geometry with copytoPoints**

* **Attach an attribute called "variant"  to each geometry**

1. geometry eg. object\_merge > pointWrangle - `i@variant =1;`

#### Generating a random integer value for each point&#x20;

* **grid>** attribrandomize - scale > point wrangle

```
int(rint@variant = fit01(rand(@ptnum),0,2));
```

* **Retrieve the random variable values  by listing "variant" in the Piece Attrbute from  copytopoints**&#x20;
* transform using target point orientation
* Setting the object to faceup: pointwrangle: @N = {1,0,0};

#### Unpacking

* Arnold renderer does not accept pack**ed** geo
* add `unpack`

## Texturing

### Random color ovveride

```c
// rand bw color
rand(@ptnum), rand(@ptnum), rand(@ptnum)
// rand RGB
rand(@ptnum) , rand(@ptnum+25), rand(@ptnum+10)
```

## Multi-image texturing

* [Texture Override](https://www.deborahrfowler.com/HoudiniResources/HoudiniTipsAndTricksRender.html), Deborah Fowler
* [Light Instancing](https://www.deborahrfowler.com/HoudiniResources/Lights-Instanced.html), Deborah Fowler

### Using copy stamp and expressions

Prerequisite: You must use an image sequence; eg. all files are named: image\_04.jpg

1. Assign  a `material` SOP and input a principle shader to target object
2. Activate `Overrides use Local overrides` and `merge Ove`r`rides`
   1. Parameter: **basecolor\_texture**
   2. Use any of these expressions: &#x20;

```c
// using frame number
$HIP/textures/image_$F2.png

// random image from concatenating strings
$HIP/textures/image_`padzero(2,ceil(fit01(rand(@ptnum),0,7)))`.png
$HIP/tex/`image_floor(fit01(rand(@primnum),0,90))`.png

// Use all of your sequence frames: 
$HIP/tex/`image_@primnum%90`.jpg

```

* 90 is an arbituary value ; you can use your total image sequence frames
* &#x20;the **backticks \`** allows use to add an expression into the string
* This technique is similar to copyStamp; we are referencing primnumber and adding an different image for  each.

### Texture override

**CopyPacked geo**

* grid with uvproject1
* expression in material node (point attrib)

**CopyUnpacked**

* stamp input
* material

### Method: based on frame number

1. copy stamp
2. material&#x20;
   1. parameter: basecolor\_texture
   2. type: string value
3. String value:

### Based on UV&#x20;

Pros: good for seamless tiling eg. brick tesselattion&#x20;

1. grid > uvproject > group > material

### Based on luminance value

* [https://forums.odforce.net/topic/29212-texture-on-copy-based-on-luminance-value/](https://forums.odforce.net/topic/29212-texture-on-copy-based-on-luminance-value/?do=findComment\&comment=165461)

## Texturing & UV

### Best practice for assigning materials

* Texturing prim faces with the same image using groups: <https://www.deborahrfowler.com/HoudiniResources/Overview-UVs.html>
* polygon sop >  `uvproject`
  * `uvquickshade`

## Recursive subdivision

Space partitioning algorithm

### Tutorials:

* [Loops & VEX: Artistic Quadtrees](https://youtu.be/uN8Kxxvpkzc), Entagma
* [Spiral Pattern Generation Tutorial - Houdini + Cinema4D](https://www.youtube.com/watch?v=ZHgzif3iIzY), Roman Pillai

## Unsorted VEX notes

### Torus wrangle node example

```c
// bbox equivalent 
@Cd.r = relbbox(0,@P).x;
@Cd.g = relbbox(0,@P).y;
@Cd.b = relbbox(0,@P).z;
```

* Using `facet` to make unique points;

### Simulating bubble popping with scatter

```c
if(@P.x>ch('threshold') + .5 * (noise(@P * 5)* 2 - 1)){
    removepoints(@ptnum)
}
```

* Sphere > Scatter > delete by threshold for pos.x
* particlefluid surace


# Dynamic


# Rendering & Lighting

## **Using flipbook**

Good for fast preview animation

* Exporting as avi  = large file > compressed via Handbrake
* MPlay, export > ffmpeg > as mp4

## IPR render

## Orange lighting exercise&#x20;

* Noise bumps- In Principled Shader > Displacement > Noise Displacement
* PBR renders
* environment light
  * unlink sunlight
  * change to Area, normalize, back to sun
  * change sun angle
* Shadow noise
  * increase min/max ray samples to 16/32
* Importance of EXR

## **Notes**

* Using separate mantra nodes for test and finder render
* force object & exclude object
* tiled renders, and restitching them&#x20;

## Using img network

* nodes: bright, over, color
* resizing flat background

Lights

point lights - good for bulb

disk light highlights

Mantra

mind your samples

reflect limit 10 - 15 (glass), turn down if not reflecting

DOF in Compositing, not in render

Motion Blur in renderer

Using commandline rendering script - rename version, mantranode, and hip file

**Optimizing render times**

Tiled render - Quick render by reducing tile to 2, and specify tile index

## 🔦 Lighting

| Lights                            |   |
| --------------------------------- | - |
| <p>sunlight & keylight</p><p></p> |   |
|                                   |   |

distant - cheaper, good for blocking

sun - blurred shadow

Spotlight - not so good

attenuation, active radius - good for instancing lights

Light bank

Data tree

Mantra > Objects > Headlight Creation

Simulating warm and cool lights to create dimensions

Lighting linking - for more controls

**Instancing lights**

instancing - pack geometry - does not inherit all details

`attribcreate`

you cannot see instances till you render it


# Animation

## Using CHOP & motionfx

{% hint style="info" %}
Channel operator and manipulation: controlling information
{% endhint %}

* Usage: sinewave node export to a property eg. object y-position, export and combine multiple values&#x20;
* Applicable with `forloop` detail and copy stamping
* Octopus tentacle blob example
  * Create a rigged tentacle
  * Use noise in CHOP to offset blob tentacles animation
  * instance the blob with copystamp to create variant

###


# Particles

## History of particles in CGP

points controlled by attributes eg. forces, velocity

* Uses: fire

#### Pop Source

* Source
  * points - uses some of the pointss
* Birth&#x20;
  * Impulsive Activation: immediate. burst on first frame: `$F==1`
  * Constant Activation - Emit over seconds
* Attributes
  * Velocity default - add to inherited velocity cuz of variance&#x20;

#### Pop collision detect

* Specify SOP object and response - die on contact

#### Using popwrangle

```
```

* Importing information from popnet
  * Under Object Merge, Object: popobject info instead of using a dopimport


# Others

Cheatsheet

##


# Modeling

## Nodes you should be familiar with&#x20;

* Carve
* Resample
* Polyframe
* Sweep
* Skin
* Polyfill
* Polybevel

![Using Skin node to skip connect n-primitives](/files/-Lv1BpgplZhs1WmJ0Vmz)

## HUD

* Grid
  * `box` > `pointsfromvolume`&#x20;
  * `VOP`&#x20;
  * `point` add alpha&#x20;
  * Symbol making
    * Circle > resample > delete > xform
* Outer rings
  * Circle (open arc) > copy&#x20;
  * Transform > resample > polyframe > copy&#x20;
  * Grid > polybevel > merge > cirle
  * Circle > sweep > carve&#x20;
* Part 3&#x20;
  * Pattern  0 N
* Part 4 connecting lines
  * tube&#x20;
  * popnet
  * popwrangle&#x20;
    * i\@origin = i\@id
  * popreplicate&#x20;
  * popattract
  * popvop > tnoise to vel
  * popcollsiondetect
  * pop

I would create "sprites" seperately and add object merge

* Rectangle > bevel&#x20;
*


# Fluids - Pyro & Smoke

## Recommended Readings

| Items                                                                                                                                                                  | Links                                                                                                                                                                                                                                                                                                    |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Documentation**                                                                                                                                                      | <p></p><ul><li><a href="https://www.sidefx.com/docs/houdini/nodes/dop/pyrosolver.html">Pyro</a><a href="https://www.sidefx.com/docs/houdini/nodes/dop/pyrosolver.html">solver</a></li><li><a href="https://www.sidefx.com/docs/houdini/nodes/dop/pyrosolver_sparse.html">Pyrosolver sparse</a></li></ul> |
| <p><strong>Industry /</strong> <br><strong>Case-studies</strong> </p>                                                                                                  | <ul><li><a href="http://www.tokeru.com/cgwiki/index.php?title=Smoke_and_Pyro">Tokeru </a> - Smoke & Pyro</li><li><a href="https://vimeo.com/225159293">Pyro Tips & Tricks // Jeff Wagner // Illume Webina</a>r</li></ul>                                                                                 |
| **Books**                                                                                                                                                              | <ul><li>Fluid Simulation for Computer Graphics, Second Edition</li></ul>                                                                                                                                                                                                                                 |
| **Papers**                                                                                                                                                             | <p></p><ul><li><p><a href="https://www.cs.ubc.ca/~rbridson/fluidsimulation/">Fluid Simulation for Computer Animation //Robert Bridson                                                                                                                                                                    |
| & Matthias Müller-Fischer</a></p><ul><li><a href="https://www.cs.ubc.ca/~rbridson/fluidsimulation/fluids_notes.pdf">SIGGRAPH 2007 Course notes</a></li></ul></li></ul> |                                                                                                                                                                                                                                                                                                          |

## Approach

1. Advect particles  or points (Garbage in garbage out; interesting source interesting output)
2. Convert to **VDB** (stores values where there is one hence faster and cost-effective)
3. Add `DOP` >  Add `smokeobject` + `pyrosolver`
4. Add disturbance or details with microsolvers (Gas `dissipate`, `disturbance`, `turbulence`)
5. Optimize simulation calculation with`gasresizefluiddynamic`
6. Caching simulation
7. Texturing & Rendering

## **Syllabus**

* &#x20;**Kinesthetic learning**
  * Do R\&D on different settings and render them out

##

## Shadow not showing in viewport (not solved)

* Viewport preferences > Under the Effects tab make sure HDR rendering is enabled.&#x20;
* Under the Geometry tab of the Display dialog there is also a Volume Quality drop down.
* Smoke density in smoke

## From Applied Houdini volumes II&#x20;

### Good practice

* **Division sizes:** 150 (sketch), 300 (detailed), 600 (HQ)&#x20;
  * Use Takes to easily toggle values
* Use size of container/division size to get the optimal value for voxel size
* Use **OpenCL** to speed up rendering if you have a good graphics&#x20;
* Override divisions  to about 50 for visualizing guides&#x20;

### Notes

* Temperature is creating velocity
  * Visualize velocity&#x20;
* Gas resize fluid dynamic - have a threshold to cut down on size of bounding box
  * Tracking object - use original&#x20;
* MICROSOLVER
  * gasdissipate&#x20;
  * gasdisturb&#x20;
    * &#x20;Take edges and perturb them
    * prevents mushroom smokes when you disturb the vel
    * control settings - vel
* Rest field
* PRESSURE

## &#x20;Applied Houdini Dynamics III

* **Alternate cloud volume**&#x20;
  * `cloud`
  * `cloudnoise` &#x20;


# Rendering

## Mantra

* **Camera**
* * Change resolution, camera properties
* Light
  * Color Editor: create complementary colors
* Render Settings
* **Data tree > Light Bank**
  * rename all lights and change their properties
* Out > **Mantra node**
  * Resolution Scale&#x20;
  * padding: $F4.jpg > 0001.jpg
  *
  * **Images tab**
    * Extra Image planes (AOV)
      * Image passes
  * **Rendering tab**&#x20;
    * Rendering engine: PBR
    * Pixel sample: increase to reduce noisy renders
    * Limits
  * **Objects tab**
    * **Candidate objects: \* (all)**
      * Using bundles - @bundleName

## Settings

* Pixel samples — antialiasing (higher values = less noise)
* Samplings — noise levels
  * Min Ray samples
  * Max Ray samples

## Jason iversen PBR

* Pixel Samples: 7x7 (up to 10x10 if the scene really needed it)
* Min/Max Ray Samples: 1/9 – sometimes 2/9
* Noise Level: 0.08 (this seemed good enough to us … less than film grain)
* Reflect/Diffuse Limits: 2, 2
* Color Space: Gamma 2.2
* Color Limit: 4 (your 1 is clamping way too hard)
* Photons: 2m photons for a huge room. Yours is 7m! I'm sure 1m is fine for this space. Ratio was 2.5.

Source: <https://www.sidefx.com/forum/topic/21548/>


# REGEX

## Recommended Readings

| **Item**                      | Links                                                                                                                                                                                                                                                                                                                     |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Documentation / Tutorials** | <ul><li><a href="https://regexone.com/"><strong><https://regexone.com/></strong></a></li><li><a href="https://www.rexegg.com/"><https://www.rexegg.com/></a></li><li><a href="https://www.regular-expressions.info/lookaround.html"><strong><https://www.regular-expressions.info/lookaround.h></strong>tml</a></li></ul> |
| Cheatsheet                    | <ul><li><a href="https://dev.to/catherinecodes/a-regex-cheatsheet-for-all-those-regex-haters-and-lovers--2cj1"><https://dev.to/catherinecodes/a-regex-cheatsheet-for-all-those-regex-haters-and-lovers--2cj1></a></li></ul>                                                                                               |
| **Books**                     | <ul><li></li></ul>                                                                                                                                                                                                                                                                                                        |
| **Tester**                    | <p></p><ul><li><a href="https://regex101.com/"><https://regex101.com/></a></li><li><a href="https://regexr.com/"><https://regexr.com/></a></li><li><a href="https://regex101.com/r/gcC3ZQ/3/">My Dataset</a></li></ul>                                                                                                    |

## What is regular expression?

{% hint style="info" %}
**A regular expression is a sequence of** [**characters**](https://en.wikipedia.org/wiki/Character_\(computing\)) **that define a search** [**pattern**](https://en.wikipedia.org/wiki/Pattern_matching)**.** Usually such patterns are used by [string searching algorithms](https://en.wikipedia.org/wiki/String_searching_algorithm) for "find" or "find and replace" operations on [strings](https://en.wikipedia.org/wiki/String_\(computer_science\)), or for input validation. It is a technique developed in [theoretical computer science](https://en.wikipedia.org/wiki/Theoretical_computer_science) and [formal language](https://en.wikipedia.org/wiki/Formal_language) theory. — Wikipedia \
\
It works similar to when we are searching something on Google but in a more advanced and specific way.&#x20;
{% endhint %}

### Why it matters?

* **Remove human errors** when it come to countless of data sorting or wrangling
* **Save you time and effort**  - once you written it once, it's reuable&#x20;

## The basics&#x20;

### Character class&#x20;

\[]

## Cookbook

```java
//1st word including hyphen eg.Bethune-Cookman
^\w+\b[-]{0,1}(\w+)?


1st 2 words with/without "'s" 
^\w+\s\w+[\']?s?

//2 words only
^\w+\s\w+$ 

// searching ???
.+\(.+\)

// Last word in parenthesis
\(([^)]*)\)[^(]*$
```

### HEX codes

```java
[A-Fa-f0-9]{6} // single 


// HEX codes from "Primary: 0050A3 Secondary: FFFFFF" 
 \s[a-zA-Z0-9]{6,} 
```

### NCAA

```java
// team names 
(\w*Alt\w*){0,1}((-\s)?\w*ALT\w*){0,1}","")

// breaking 
^\w+[-]?\w // catch hyphenated compound
^\w+\b[-]{0,1}[\w+]? // break two words 
^\w+[']?\w?\s\w+[\']?s?" // break words with apostrophe 

\w+\s\w+$ // capture last 2 words 
\w+$ // capture last word 

// optimized 
^[\w's&-.]+[ &]?[\w's&.]+


// workflow 
// 1. break school with State 
^[\w's&-.]+[ &]?[\w's&.]+ [State]+
^[\w's&-.]+[ &]?[\w's&.]+ [StateUniversity]+
```


# Sandbox

* [rouping Layers in AE](https://www.reddit.com/r/AfterEffects/comments/1bdar3o/i_dont_wanna_precompose_i_wanna_group/?utm_source=share\&utm_medium=web2x\&context=3)

## AE Naming Convention Style Guide

**Naming Details**

* When not using scene-shot naming convention, give sufficient details to your name such as indicating direction of motion, colors, etc.

> Why? Naming sequentially via number or letters is not helpful in helping users identify what the composition is, especially if you aren’t working with a sequential narrative; different deliverables requires different specifications and naming convention.

*

Dashes vs Underscore

* Dashes for chaining details
* Underscore separate details

### Terms

#### Directions

<table><thead><tr><th width="184">Name</th><th>Abbreviation</th><th>One-Letter Acronym</th></tr></thead><tbody><tr><td>Horizontal</td><td>Hori</td><td>H</td></tr><tr><td>Vertical</td><td>Vert</td><td>V</td></tr><tr><td>Diagonal</td><td>Diag</td><td>D</td></tr><tr><td>Left</td><td>Left</td><td>L</td></tr><tr><td>Right</td><td>Right</td><td>R</td></tr><tr><td>Top</td><td>Top</td><td>T</td></tr><tr><td>Bottom</td><td>Bot</td><td>B</td></tr><tr><td>Left to Right</td><td>LeftRight</td><td>LtoR</td></tr><tr><td>Top to Bottom</td><td>TopBot</td><td>TtoB</td></tr></tbody></table>

Colors

| Name of Color | Abbreviation | One-Letter Acronym |
| ------------- | ------------ | ------------------ |
| Red           | Rd           | R                  |
| Blue          | Bl           | B                  |
| Green         | Gr           | G                  |
| Yellow        | Yl           | Y                  |
| Purple        | Pp           | P                  |
| Orange        | Or           | O                  |
| Pink          | Pk           | P                  |
| Brown         | Br           | B                  |
| Black         | Blk          | B                  |
| White         | Wht          | W                  |

>

## AE Tools Style Guide

### Base Naming Convention

Dash-separated

```
 Brand* - Name - Details 
 
 * Optional
```

> Why? In orde to accomodate for incoming AE artist with varying skill experience, it's beneficial to name your composition in a readable way. There's need to be a balance between having structure and making sense for the users

```
Attribute Name (Control Type (Min: min_value, Max: max_value, Unit: unit_of_measurement)
```

### Transition Properties

```
1. Transition Type (Dropdown)

2. Transition Completion (Slider, Min: 0%, Max: 100%)
    Transition Completion - In
    Transition Completion - Out

2. Direction (Dropdown/Angle Control)
3. Duration (Slider, Min: 0 sec, Max: ∞ sec)

5. Scale (Point, Min: 0%, Max: ∞)
6. Scale (Point, Min: 0%, Max: ∞)

7. Opacity (Slider, Min: 0%, Max: 100%)
8. Feathering (Slider, Min: 0, Max: ∞)

```

## References

* Airbnb Javascript Style Guide
* UE5 Style Guide, Ullah

## Techniques

### Glass Refraction Effect

```
1. Create a luma matte tiled
2. Use `Displacement map` effect
3. Duplicate the 
```

* Mograph Mill. "Create a Refracted Glass Effect in After Effects Tutorial." YouTube video, September 11, 2021. <https://www.youtube.com/watch?v=zvdOIpajDMQ&t=287s>.

## Version Control for Design

* How do you manage version control for developing designs and explorations?

**What is Version Control in software development?**

Version control is a method that record modifications as they occur, facilitating collaborative effort among multiple developers on a single project. It preserves a chronological log of changes, ensuring that specific version can be accesses and restored whenever necessary.

&#x20;**Why is relevant to visual design?**

* Collaborative
* Manage huge volume of designs or animations or iterations

Readings

* <https://www.artworkflowhq.com/resources/efficient-version-control-for-creative-teams>


# Nexrender

This page is incomplete

<figure><img src="/files/QDdBTbDmriUKPC4XrrKQ" alt=""><figcaption><p>Built with love using nodejs • Brought to you by <a href="https://github.com/inlife">@inlife</a> and other <a href="https://github.com/inlife/nexrender/graphs/contributors">contributors</a></p></figcaption></figure>

## Abstract

This guide outlines the steps required to set up a nexrender rendering cluster, utilizing one EC2 instance as the nexrender server, your local machine as the worker node, and Google Sheets and Google Apps Script to send a curl request for a render job to the server.&#x20;

By following this configuration, users can easily establish a distributed rendering system for their projects, which can significantly reduce the time required for rendering complex tasks. The setup process is explained in detail, providing users with a clear understanding of the necessary components and how to connect them to create a functional rendering cluster.

{% hint style="info" %}
Overall, the client initiates requests to the server, the server manages the rendering process by assigning tasks to workers, and the API provides a programmatic interface for interacting with the server.
{% endhint %}

## Resources

* <https://www.npmjs.com/package/@nexrender/api>
* [GitHub - inlife/nexrender: 📹 Data-driven render automation for After Effects](https://github.com/inlife/nexrender)
* [How to create an After Effects rendering bot](https://plainlyvideos.com/blog/after-effects-render-bot/)

## Checklist for rending cluster

1. Launch the cloud instances for the worker and server nodes
2. Ensure that the necessary files are accessible in Google Drive
3. Launch the worker node to initiate the rendering process
4. Set up the server node to receive and process rendering requests
5. Use a curl request to send a rendering job from the Google Sheets interface to the server node
6. Monitor the progress of the rendering job and retrieve the output files once completed

## Practice

Prior to setup your rendering cluster, you should familiarize yourself with sending a render job using your workstation to replace text and media (image, video, sound)

* [ ] Download the nexrender binaries from [Github](https://github.com/inlife/nexrender#using-binaries)
* [ ] Launch the CLI applications from the terminal
* [ ] Prepare an After Effects template. This should contain text or media to replace
* [ ] Prepare a JSON to send render bo

## How to set up a nexrender cluster

<figure><img src="/files/lrkbu9ZVWt81KlqHS7wC" alt=""><figcaption></figcaption></figure>

### Web Server & Environment Setup

To set up a server and install Nexrender on it, you can follow these general steps:

* [ ] **Choose a server -** You can use a cloud-based service like Amazon Web Services (AWS) or Microsoft Azure to set up a virtual server in the cloud, or you can use a physical server that you own or rent.
* [ ] **Choose an operating system** - Once you have your server, you'll need to choose an operating system to install on it. Nexrender supports Windows, macOS, and Linux, so you can choose the operating system that best suits your needs and preferences.
* [ ] **Download the nexrender binaries:** You can download the latest version of nexrender server and worker node from the official nexrender GitHub repository.

[Web Server Concepts and Examples](https://www.youtube.com/watch?v=9J1nJOivdyw)

[How to Create an EC2 Instance in AWS in 2023](https://youtu.be/0Gz-PUnEUF0)

### Modify Security Group

By default, most EC2 instances have their security group rules configured to block ICMP traffic. If this is the case, you will not be able to ping the IP address. You can try modifying the inbound rules of your instance's security group to allow ICMP traffic.&#x20;

Security Group: Edit Inbound rules - Custom TCP, Port Range: XXXX

#### Binary vs Programmatic Installation

if you just want to use Nexrender as a standalone tool to render After Effects projects, you can use the pre-built binary version. If you want to use Nexrender as a library in your own code or run the Nexrender Server on your own server, you should install the programmatic module via npm.

### Installation of Node.JS on EC2

The nexrender API can be installed and run on your EC2 instance as a Node.js application. The API can then be configured to listen for requests from your Google Form and trigger the rendering process on the nexrender server.

```javascript
sudo yum install -y gcc-c++ make
curl -sL https://rpm.nodesource.com/setup_16.x | sudo -E bash -
sudo yum install -y nodejss
```

### Installing nexrender server

[npm: @nexrender/server](https://www.npmjs.com/package/@nexrender/server)

#### Binary Installation

```jsx
wget <https://github.com/inlife/nexrender/releases/download/v1.43.0/nexrender-server-linux>
chmod +x nexrender-server-linux
./nexrender-server-linux
```

#### Launch ✅

```json
nexrender-server --port 3000 --secret=myapisecret
```

#### Installation

```json
npm install @nexrender/server --save

sudo npm install -g @nexrender/server
```

#### **Usage (programmatic)**

```jsx
const server = require('@nexrender/server')
const port = 3000
const secret = 'myapisecret'
server.listen(port, secret)
```

This code sets up a Nexrender server that will listen for incoming requests on port **`3000`** and require clients to provide a secret password in order to connect. Once the server is running, clients can connect to it and submit rendering jobs to be processed.

Here's how it works:

1. The first line of code imports the **`@nexrender/server`** package and assigns it to the **`server`** variable. This package provides the functionality to start a Nexrender server.
2. The second line of code sets the **`port`** variable to the value **`3000`**. This specifies the port on which the Nexrender server will listen for incoming connections.
3. The third line of code sets the **`secret`** variable to the value **`'myapisecret'`**. This is the API secret that clients will use to authenticate with the Nexrender server.
4. The fourth line of code starts the Nexrender server on the specified **`port`** and with the given **`secret`**. The **`server.listen()`** method is called with two arguments: the **`port`** and the **`secret`**. This method listens for incoming connections on the specified port and requires clients to provide the specified API secret when making requests to the server.

### Installing nexrender API

By using the [nexrender API](https://www.notion.so/duitbetter/Research-nexrender-cluster-91392910c0c6453695bebcef35d8bf9b?pvs=4#8721ca77d76e4c559fc8458459b9ffa0), you can automate the process of submitting jobs to nexrender, which can save you time and reduce the risk of errors. You can also use the API to retrieve job status and output files, which can be helpful for tracking job progress and managing rendered output.

#### Installation

```json
npm install @nexrender/api --save
```

#### Usage

```jsx
const { createClient } = require('@nexrender/api')

const client = createClient({
    host: '<http://3.15.46.159:3000>',
    secret: 'myapisecret',
    polling: 3000, // fetch udpates every 3000ms
})

const main = async () => {
    const result = await client.addJob({
        template: {
            src: 'file:///Users/ddu/Desktop/nexrender/project/project.aep',
            composition: 'main',
        }
    })

    result.on('created', job => console.log('project has been created'))
    result.on('started', job => console.log('project rendering started'))
    result.on('progress', (job, percents) => console.log('project is at: ' + percents + '%'))
    result.on('finished', job => console.log('project rendering finished'))
    result.on('error', err => console.log('project rendering error', err))
}

main().catch(console.error);
```

This code creates a client connection to a Nexrender API server, using the **`createClient`** method provided by the **`@nexrender/api`** package.

It then sets the host and secret credentials required to access the server, and sets the polling interval to check for job updates every 3000 milliseconds.

The **`main`** function uses the client to add a new job to the server, specifying the template source and composition to use. The **`result`** object is returned by the **`addJob`** method and is used to track the job's progress.

The **`result`** object also sets up event listeners to handle job events such as creation, starting, progress updates, completion, and errors. When an event is triggered, the corresponding callback function is called to handle it.

If you are running the Nexrender server on the same EC2 instance as the client script, you can use the internal IP address of the instance, which can be obtained by running the **`curl <http://169.254.169.254/latest/meta-data/local-ipv4`**> command from within the instance.

If you want to access the Nexrender server from outside the instance (for example, from your local computer), you would use the public IP address or DNS name of the EC2 instance, which you can find in the EC2 console or by running the **`curl <http://169.254.169.254/latest/meta-data/public-ipv4`**> command from within the instance. However, you would need to make sure that the necessary security group rules are in place to allow inbound traffic to the instance on the Nexrender server port.

**How to copy a file over**

```jsx
scp -i <path to private key> <local file path> <ec2-user>@<public IP or hostname>:<remote directory>
```

[Online API Testing Tool | Test Your API Online](https://reqbin.com/)

## nexrender-API

```json
mkdir nexrender-server
cd nexrender-server

npm init -y
**This will create a package.json file in the nexrender-server directory.**

**Run the following command to install the nexrender server node package:**
npm install nexrender-server
ls

Once the installation is complete, 
you can start the nexrender server node by running the following command:
nexrender-server
```

### Installing worker

Requirements: Windows/Mac

Pre-requisite: After Effects

If you have the binary file for the Nexrender Worker, you can still use it on your Mac laptop. To run the Nexrender Worker binary, you will need to open a terminal window and navigate to the directory where the binary file is located. Then, you can run the binary using the following command:

```
./nexrender-worker-macos
```

This will start the Nexrender Worker on your Mac laptop. By default, the worker will look for a Nexrender server running at **`http://localhost:3000`** and will not use a worker secret key.

#### Launch

If you need to connect the worker to a different server or use a worker secret key, you can pass command-line options to the binary. For example, to connect the worker to a server running at **`http://example.com:8080`** and use a worker secret key of **`abc123`**, you can run the following command:

```
./nexrender-worker-macos --host <http://18.191.217.227:3000> --secret myapisecret
```

[npm: @nexrender/worker](https://www.npmjs.com/package/@nexrender/worker)

[Deploy NodeJS APP on AWS EC2 Instance | NodeJS on EC2 | Running NodeJS APP on AWS EC2 | AWS Projects](https://www.youtube.com/watch?v=S45jZCvd2M8)

## Curl vs JavaScript API

Curl and JavaScript API client are both used for interacting with APIs, but they have different use cases and advantages.

**Curl** is a command-line tool used to transfer data to and from servers using various protocols, including HTTP, HTTPS, and FTP. It is useful for testing APIs or automating tasks that require interacting with servers through the command line. Curl is particularly useful for quick one-off requests or for scripting repetitive tasks.

On the other hand, a JavaScript API client, such as the @nexrender/api library shown in your example, is a software module that can be integrated into a web application to interact with an API. It is useful for more complex API interactions or when you need to handle API responses in a specific way.

The JavaScript API client provides a more user-friendly interface for interacting with the API, making it easier to handle responses and errors, and can be integrated into more complex applications. It also provides additional functionality, such as event listeners that can notify you of job progress or errors.

In summary, if you need to quickly test an API or automate tasks, curl is a good choice. If you are building a web application that interacts with an API, a JavaScript API client may be a better choice.

**Sending curl to server**

```jsx
curl \\
    --request POST \\
    --header "nexrender-secret: myapisecret" \\
    --header "content-type: application/json" \\
    --data '{"template":{"src": "file:///Users/ddu/Desktop/nexrender/project/project.aep",
            "composition": "MAIN"}}' \\
    <http://18.222.190.254:3000/api/v1/jobs>
```

## Submitting Form Responses to a server

#### Formatting Google Forms to JSON for nexrender

* **Set up a Google Form to collect render job details:** You can create a Google Form to collect details about the After Effects project to be rendered, such as the composition name, output format, and render settings.
* Create a script: You can use a programming language such as JavaScript, Python, or Ruby to create a script that reads the data from your Google Form and sends a request to the nexrender API.


# Terminology

<table><thead><tr><th width="180">Role</th><th>Description</th></tr></thead><tbody><tr><td>Client</td><td>A program or application that initiates requests to a server. In the context of nexrender, a client can be an After Effects user who submits a render job request to the nexrender server.</td></tr><tr><td>Server</td><td>A computer or software program that responds to requests from clients. In the context of nexrender, the server receives render job requests from clients and manages the rendering process by distributing tasks to workers.</td></tr><tr><td>Worker</td><td>A computer or software program that performs tasks assigned by the server. In the context of nexrender, a worker is responsible for rendering a specific task in a job, such as rendering a particular composition or output file. Multiple workers can be assigned to a single job to complete the rendering process faster.</td></tr><tr><td>Node</td><td></td></tr><tr><td>API</td><td>An interface that allows software applications to communicate with each other. In the context of nexrender, the API is a set of programming interfaces that allow developers to interact with the nexrender server programmatically, for example, by submitting jobs or retrieving render job status.</td></tr><tr><td>AWS EC2</td><td>Amazon Elastic Compute Cloud (Amazon EC2) is a web service that provides resizable computing capacity in the cloud. It is designed to make web-scale cloud computing easier for developers. With Amazon EC2, you can obtain and configure capacity with minimal friction. You can use it to deploy and run virtual servers in the cloud, allowing you to quickly scale capacity up or down according to your computing needs. Amazon EC2 is one of the core services of Amazon Web Services (AWS) and it can be used to run a variety of workloads, including web applications, big data processing, and machine learning.</td></tr><tr><td>EC2 Instance</td><td>Virtual server in Amazon's Elastic Compute Cloud (EC2) that runs an operating system and applications. It is essentially a virtual machine that is hosted in the cloud, providing computing resources on demand. You can think of it as a remote computer that you can access and control over the internet. Each EC2 instance is essentially a separate computing environment, with its own set of allocated resources, such as CPU, memory, storage, and networking. When you launch an EC2 instance, you can choose the instance type that best fits your needs based on the required amount of resources and performance.</td></tr><tr><td>Virtual machine</td><td>A virtual machine is a software-based emulation of a physical machine that runs on top of a host operating system. It allows multiple virtual machines to be created on a single physical machine, each with its own operating system, applications, and virtualized hardware resources such as CPUs, RAM, and storage.<br><br>Virtual machines are typically used for server virtualization, where they allow multiple applications or services to be run on a single physical server, improving hardware utilization and reducing costs. They are also used for software development and testing, providing developers with a sandboxed environment to test their applications without affecting the production system. </td></tr><tr><td>Virtual Desktop </td><td> A virtual desktop, on the other hand, is a user interface that runs on top of a virtual machine or a physical desktop. It allows users to access a virtualized desktop environment over a network, enabling them to run applications and access resources as if they were using a physical desktop.</td></tr><tr><td>Environment</td><td>In general, an environment is a collection of hardware and software resources that work together to support a specific application or set of applications. This can include everything from the operating system and middleware to the hardware components like processors, memory, and storage. It can refer to either a virtual machine or a virtual desktop, as well as to a physical computer or server. </td></tr></tbody></table>


# Project Files Preparation

**AEP**

* \[ ] Abbreviate your project folder - remove extension suffix

**AE Layers**

* \[ ] Our naming convention would require us to link layer names to the spreadsheet column headers. You can identify and name layers that will change based on convention "textInput\_\[number]" and "imageInput\[number]"
* \[ ] Make layers that do not have input shy layers
* \[ ] For layers that needs
* \[ ] Add a marker indicating "REPLACE TEXT/IMAGE"


