AE: Compositing Lights

Long, long ago I saw an article or talk by Paul Haeberli, of SGI. Oh, he covered many interesting and clever graphics tricks. One of them was the idea of “synthetic lighting”, or, “doing lighting in post”.

He has a page about it, here.

The idea is pretty simple. If you have images (or animations) of individual lights, you can add them together to get multiple lights. It appears to be a relatively common render feature these days, but I’d never played with it before. So here goes.

+


=

You can color and mask them, too, to get some pretty nifty effects, all from the same source images.

The pictures above, showing my infantile modeling skills, were done in Luxology modo, using full radiosity render. This can take a while! 10 minutes per low res frame, about.

The youtube video below shows some further examples of getting liveliness out of just a few frames, using this idea of additive post-process lighting.



click for
content

AE: A Stupid Text-Control Trick

Here’s a little movie that demonstrates a text track being used to “trigger” the opacity of another track.

one-part.mov

click for
http://omino.com/pixelblog/wp-content/uploads/2009/03/one-part.mov

Controlling Pip Opacity From Text

I needed a blinking pip. (It’s actually for an interesting optical effect… but for now, we’ll just talk about the pip.) Rather than keyframing each blink, I used a Text track where A is a very dim blink, and Z is a very bright blink. The blinks all have the same luminous decay. Every keyframe on the Text track triggers a new blink.

The expression to do this is actually a little program. (Exactly what some artists hate…)

Here’s the expression for controlling the Pip’s opacity. It’s in 3 parts: 1) Find the most recent Text track keyframe, 2) See what letter it was, from A to Z, and 3) Set the opacity, taking into account the brightness and how long it’s been decaying.

// find most recent key
var s = thisComp.layer("controlTrack").text.sourceText; // score layer
var n = s.numKeys;
var kValue = "A"; // default value
var kTime = 0;
for(var i = 1; i <= n; i++)
{
	var k = s.key(i);
	if(k.time <= time)
	{
		// only care if there's a char in our position.
		var a = k.value.charAt(0).toUpperCase();
		if(a >= "A" && a <= "Z")
		{
			kValue = a;
			kTime = k.time;
		}
	}
}

// now, how long ago was that?
var age = time - kTime;

// map character a-z to 0.0-1.0
kValue = kValue.charCodeAt(0);
kValue -= 65;
kValue = kValue / 25.0;

// decay appropriately
var result = kValue * Math.pow(0.3, age) * transform.opacity;

// done.
result

Why do this tricky control business with a text track, instead of just keyframing the flashes more directly? This way, the behavior is very well specified... and even more so for the next movie.

Controlling Five Pips With a Text Track

five-parts.mov

click for
http://omino.com/pixelblog/wp-content/uploads/2009/03/five-parts.mov

You can easily see what's going on here. Five characters control five pip's blinks.

The clever bit was to avoid pasting that monster expression from above into five different tracks. Instead, a single slider control track is driven from the text, and shows the first pip's blinking at time=0, the second pip's at time=300, the third's at time=600, and so on. The whole animation is 20 seconds, so there's plenty of room on the timeline for this.

Each pip's opacity is driven from the appropriate section of this slider channel:

pip0 opacity: transform.opacity * thisComp.layer("controlTrack").effect("scoreReader")("Slider").valueAtTime(time + 0*300)

pip1 opacity: transform.opacity * thisComp.layer("controlTrack").effect("scoreReader")("Slider").valueAtTime(time + 1*300)

pip2 opacity: transform.opacity * thisComp.layer("controlTrack").effect("scoreReader")("Slider").valueAtTime(time + 2*300)

... and so on.

So, why pile this cleverness atop an already tricky expression? Because with an expression that tricky, anything is better than duplicating five times across different tracks!

Here's the expression, which extracts brightness from the text track, for each position, at times separated by 300 seconds.

// Allow different sections of this track to extract the brightness for each pip.
// we divide it up into 5 minute segments (300 seconds). To find out your brightness
// at a particular time, examine *this* track at time + 300 * pipNumber.
//
// This is an alternative to duplicating the rather ornate expression into each pip, at
// the expense, of course, of complexity.
//

var segmentDuration = 300;
var segmentIndex = Math.floor(time / segmentDuration);
var segmentTime = time - segmentIndex * segmentDuration + .01; // local time... plus 1/100 for roundoff

// find most recent key
var s = thisComp.layer("controlTrack").text.sourceText; // score layer
var n = s.numKeys;
var kValue = "A"; // default value
var kTime = 0;
for(var i = 1; i <= n; i++)
{
	var k = s.key(i);
	if(k.time <= segmentTime)
	{
		// only care if there's a char in our position.
		var a = k.value.charAt(segmentIndex).toUpperCase();
		if(a >= "A" && a <= "Z")
		{
			kValue = a;
			kTime = k.time;
		}
	}
}

// now, how long ago was that?
var age = segmentTime - kTime;

// map score character a-z to 0.0-1.0
kValue = kValue.charCodeAt(0);
kValue -= 65;
kValue = kValue / 25.0;

// decay appropriately
var result = kValue * Math.pow(0.3, age);

result

And lastly, here's the self-contained After Effects project.

AE CS4: Pixel Bender Quick Notes

Here are some super short notes about using Pixel Bender inside of After Effects CS4. This post is just another dicing of the available info culled from the After Effects help, and the Pixel Bender Developer Guide.

But it’s the stuff that I most needed to get started, as well as a handy copy-and-paste source for the parameter control types.

This is about Pixel Bender in After Effects specifically.

Installing

Let’s start at the end. To use a Pixel Bender kernel in After Effects, just drop it in the Plug-Ins folder.

  • By default, it shows up in the Pixel Bender effects category.
  • It won’t show up until the next time you start After Effects
  • If it has any syntax errors, AE will warn you as it starts up, and reject the kernel.
  • Any changes to the kernel won’t show up until you quit and re-run After Effects. (Purge-all doesn’t seem to reload it…)
  • (And you can put it in a subfolder of Plug-Ins, of course, to keep things organized.)

Authoring

Source Image To work with After Effects, near as I can tell, it must take at least one image4 source. Even if the kernel is a pure generator, it needs to take an image input.

Multiple Source Images If the kernel takes more than one source image, the additional sources can be chosen in AE by a layer control. (Grand!)

Control Types By default, all parameters show up as sliders. But you can request a different control in the parameter description.

Example

Here’s an example of a Pixel Bender kernel that just generates a solid color. It has several parameter controls on it of the different supported types, and accepts a second layer as input. These are all ignored! But we can see how the controls are displayed, which is handy.

Here’s a screen capture, with the About box. (Trivial bug, the display name isn’t used in the About box…)

pbSolidColor.png

And here’s the code for the kernel, showing the various descriptors.

<languageVersion : 1.0;>

kernel solid_color
<namespace : "omino";
 vendor : "Omino PixelBlog 2009";
 version : 2;
 description : "Generates a solid color.";
 displayname: "Solid Color";
 category: "omino"; >
{
 input image4 src;
 input image4 src2;
 output pixel4 dst;

 parameter float4 color
  <defaultValue: float4(1,0,0,1);
   aeDisplayName: "Color";
   aeUIControl: "aeColor";>;

 parameter float angle
  <defaultValue: 45.0;
   aeDisplayName: "Angle";
   aeUIControl: "aeAngle";>;

 parameter float2 point
  <aePointRelativeDefaultValue: float2(0.5,0.5);
   aeDisplayName: "Point";
   aeUIControl: "aePoint";>;

 parameter int popup
  <defaultValue: 3;
   aePopupString:"Zero|One|Two|Three|Four";
   aeDisplayName: "Popup";
   aeUIControl: "aePopup";>;

    void evaluatePixel()
    {
        dst = color;
    }
}

Onward

With this amount of flexibility, and the instant cross-platform nature of Pixel Bender kernels, the barriers to entry for effects development have been dropped to almost nothing. Great stuff!

After Effects CS4: Ultrabrief First Impressions

Joy!

I finally have returned from several months away, back into the usual routine. My fresh copy of After Effects CS4 was waiting! (Thanks so much, you know who you are!)

Verrrry brief first impressions.

Darker, Darker

I love how each successive version is a bit darker, more mysterious looking. It’s just like Luke Skywalker, remember how in the first movie he’s wearing something like a beige judo gi, and by Jedi he’s all in black and getting rather professional? AE is following the same sequence here.

But seriously, I like it.

(How long til UI-fashion flips back around to rose-petal-white and no visible edges? Maybe when e-paper starts to be the dominant output format. Bring on the new colors for 2020. Tufte said it would be like this.)

Pixel Bender

It’s so simple, just drop your .pbk files into the Plug-Ins folder and they show up in the Effects & Presets list, in the Pixel Bender category. Love it. More to come on this topic.

Still, first impressions: need a way to influence the parameter control rendering in the UI, to get grouping, and point and color controls.

UPDATE Jeff at Redefinery corrects me again. Pixel Bender filters can define the control type for each parameter, like this (excerpted from the latest pixel bender online help):

parameter float blend_with_original
<
  minValue: 0.0;
  maxValue: 100.0;
  defaultValue: 0.0;
  description: "Amount to blend with original input"; //comment only, ignored in AE
  aeDisplayName: "Blend Factor"; //AE-specific metadata
  aeUIControl: "aePercentSlider"; //AE-specific metadata
>;

Legal values for aeUIControl include aeAngle, aePercentSlider, aePoint, aeColor, and a couple others.

Online Help

Hate it. I do know After Effects pretty well… but also, I do flip to the manual not infrequently. I don’t miss the paper manual, not one bit. But I don’t much care for where CS4’s “After Effects Help…” takes you, some catch-all page of community goodies. The community pages are great, and I’m happy when Google lands me up there.

I just want the table of contents. And CS3’s help viewer seemed tighter and snappier.

UPDATE I see this has been fixed in 9.0.1! Help takes you to the contents page.

A Mysterious ASIO Driver

I never saw this before… but Cubase is offering After Effects 9.0 as an available ASIO driver. I have no idea what this means… More research is needed! Possibly a side effect of being able to preview AE out to an ASIO sound card.

Some Tiny Stuff

Todd K at Adobe posted a pretty comprehensive list of CS3->CS4 changes at http://blogs.adobe.com/toddkopriva/2008/09/an_unordered_approximately_com.html. Many of them are small… but cumulatively it’s good stuff.

Here’s one that really, well, really does make a difference. If your view is scaled to 25%, then the resolution is automatically dropped by the same amount.

(You can imagine the deep philosophical discussions on whether that’s the right thing to do… “But when you scale back up, your cache is gone!” But, praise Darwin, these things have to be tried, and by God, we all of us irrevocably ascend towards perfection.)

Overall

So, overall, After Effects 9.0 aka CS4 seems to be an evolutionary step.

As a relatively light recreational user, many of the subtler workflow changes are outside my domain. I don’t have a render farm, nor major pipeline and multi-tool integration issues.

But on the Eye Candy side… I dare say we can still anticipate some startling Pixel Bender innovations over time, enabled by AE9.

AE Feature Request (Dear Adobe)

Update: Dear Adobe — please acquire and incorporate ObviousFX’s Copy Image plugin as part of After Effects proper.

The plugin, available for Mac and Windows, adds an Edit menu item, Copy Image, which copies the current composition image to the clipboard.

Thanks, ObviousFX and thanks, Rich, for pointing it out for me. Great stuff.


Original post:

Hopefully, someone will point out that this is already in After Effects CS4. But I’m such a luddite that I haven’t upgraded or even played with AE CS4 yet.

Sometimes, I use After Effects as a really powerful drawing program, no animation. It works in a very… engineer-friendly way, for compositing. I like that I can concoct a tree of layers, and modifiers on those layers, and use expressions to “rig” them together.

Here’s my feature request:

Copy Frame, High Quality

It’s pretty simple. It would place the current frame of the current comp at either full resolution, or maybe current resolution, as a PNG with transparency(or whatever is appropriate, here in 2009), onto the clipboard, ready to be pasted into another drawing app (or an email or whatever).

I realize with modern graphics displays and screen grabs you can get pretty good pastes… but you’ll have to crop carefully, maybe rearrange the workspace to get it visible, &c. And there’s render-to-file, but what a bother.

So I’d like Copy Current Frame as a feature, please. Thanks!

AE: A Snowflake

colorfulSnowflake.jpg

download snowflakeSteps.aep

Featuring: Bevel Alpha, omino kaleidoscope, and animated paths.

Sounds like the USA has had a heck of a Christmas weather run! Folks taking their vacations on airport waiting benches, and so forth. In particular, Seattle, home to After Effects. Where I am, it’s 7:33 pm, and I’ve just returned, sweating, from a nice bowl of Mun Eefoo Mee. Total google hits for that dish: 0, but the chef told me it’s his specialty, and it was delicious. Cost, with a cup of iced sweetened barley, 5 Ringitts Malaysian. Current temperature: 80F. Current exchange rate: 3.8 Ringitts to the US Dollar.

It’s my kind of place. “Christmas” is a national holiday, but nobody celebrates beyond a few santas at the mall. On the 25th, the shoe stores and the hardware stores were all open. As were thankfully the restaurants; I’m expated here alone for a few months, no home cooking for this coder.

So, in a fit of boundless atheism, I spent the 25th cobbling together an After Effects project to grow snowflakes!

Step 0: Research

I found this great site, http://snowcrystals.com/ maintained by Kenneth G. Libbrecht, a Caltech physics professor. Fabulous stuff, including movies of lab-grown snow crystals!

After reading his site, and other sources, and general pondering, I jumped in with the scripting. It’s only a 2 day project, so it’s not really going to accurately mimic the physics of snow… but we’ll settle for “suggestive” and “cool-looking”.

(And, here is a short article about snowflake symmetry.)

Step 1: Growth

step1-spikypath.mov

click for
http://omino.com/pixelblog/wp-content/uploads/2008/12/step1-spikypath.mov

This movie shows one branch of a snowflake being “grown”. It’s a layer mask path, animated by ridiculous please-don’t-read-the-code script I wrote… but, truth to tell, you could animate almost anything in there, and, by the end, it’s going to look pretty snow-ish. You can download my script if you like. It’s kinda tweaky; the main trick is that the lengths parameter consists of letters, where a is a very short spike, and z is full length.

Step 2: Hexagonal Symmetry

We all know how to make a paper snowflake, with three or four folds and some scissors. We’ll do the same thing with my plugin, omino kaleidoscope, downloadable here.

(You can also use CC Kaleida, which is included with AE these days, to make an 8-fold snowflake. But use mine for authentic regulation 6-way symmetry.)

The omino kaleidoscope works by using an AE layer’s Mask Path to represent the shape of the mirrors. Any path will work (though curves are treated as straight segments). For snowflake symmetry, we need a wedge which is one twelfth of the pie. Again, I wrote a script, wedgePath to do this. But you could draw the mask manually, if you’re careful. (Be sure to set its mode to “none”, we don’t want it to clip the image.)

And set up omino kaleidoscope as shown in the screenshot above.

Step 3: Moreness

step3_moreness.mov

click for
http://omino.com/pixelblog/wp-content/uploads/2008/12/step3_moreness.mov

So far so good. Next, let’s add a few more layers of animated paths. We’ll superimpose them to get different gray-levels. Some of them are time-shifted, to evolve at different rates. Different transfer-modes can liven this up a little. Again: you can animate almost anything, and the kaleidoscope will make it snowflake-like.

Step 4: Imperfect

step4_imperfect_frame.jpg

To make it look just a shade less mechanical, we can have the snowflake grow a little bit irregularly. Now, it is supposed to be a crystal, so we’ll go gently with this. Real snowflakes often show subtle imperfections like this, presumably due to environmental variations during formation.

The above frame is from Step 3, with Time Displaclement applied. Here’s the layer used as the Time Displacement Map. It ranges from black to 50% grey, ensuring that only negative time displacements will be used.

slownoise.mov

click for
http://omino.com/pixelblog/wp-content/uploads/2008/12/slownoise.mov

Note. Time Displacement is a render-time hog, since AE needs to render many frames past and present for each final frame. It’s helpful to disable this effect while tinkering, turn it back on for the render.

Step 5: Crystallize

This is the last step, really. We’ll use a few applications of Channel Mapper to convert luma to alpha. And then, this is the exciting part, we use Bevel Alpha with several colored lights to get the colorful crystalline look.

The “light angle” for the bevel effect has been animated with an expression

effect("Bevel Alpha")("Light Angle") + time * 90

just to keep it lively.

Also, Channel Mapper has been used to pull a dark grey in for the snowflake’s color. The different brightnesses earlier were mapped to alpha, for the beveling; the final result looks better with colors darker than white.

And I’m not above adding a bit of Find Edges and Glow, no sir. The secret sauce is ketchup. Whatever it takes!

Here’s the final result:

finalMovie.mov

click for
http://omino.com/pixelblog/wp-content/uploads/2008/12/finalMovie.mov

As ever, here’s the After Effects project. It doesn’t require any assets (the finalMovie comp references the photo and music loops, but pay it no mind).
download snowflakeSteps.aep

And so far, it has not been a cold day in Penang, Malaysia.

AE: Mask Vertices from ExtendScript

We’ll take it as axiomatic that scripting After Effects is pretty keen. But sometimes you can get lost in the nest of properties, property groups, values, attributes, and the subtle differences in nomenclature for properties and attributes used by After Effects and the JavaScript.

It is definitely possible to access and manipulate each vertex on a layer mask. Below is a script which displays some mask points, and then modifies a vertex. It will show this alert:

verticesGot.png

And this is the script which displays the dialog, and then modifies the 4th vertex of the mask. It demonstrates the recipe to navigate the Masks, Mask, Mask Path, and so on.

One thing first. Many sites and blogs show only very, very short scripts. I take a slightly different approach. I think code should tell a story. I try to build things up as simply as possible. Despite its apparent length, I think you’ll find the script easy to follow. Just go 1 line at a time.


// Utility to find a comp by name.
function findComp(name)
{
	for(var i = 1; i <= app.project.numItems; i++)
	{
		var item = app.project.item(i);
		if(item != null && item.name == name)
			return item;
	}
	return null;
}

// Show the vertices of the first mask of comp1/layer1.
function main()
{
	var comp = findComp("comp1");
	var layer = comp.layer("layer1");
	var masks = layer.Masks;

	var firstMask = masks.property(1);

	if(firstMask == null)
		return;

	var maskPathProperty = firstMask.property("Mask Path");
	var maskPath = maskPathProperty.value; // or valueAtTime(t) if  you like

	var sm = "Vertices\n";
	var vertices = maskPath.vertices; // array of [x,y] pairs
	for(var i = 0; i < vertices.length; i++)
	{
		var p = vertices[i];
		var x = p[0];
		var y = p[1];
		sm += "v[" + i + "] = " + x + "," + y + "\n";
	}

	alert(sm); // Show the vertices.

    // Now, we change a point.
	var p = vertices[3];
	p[1] = 300;

	// Must be "put back" bit by bit.
	maskPath.vertices = vertices;
	maskPathProperty.setValue(maskPath);

}

main();

A few notes:

  • To change the vertex, we need to assign it back to the Mask Path and then into the Mask property; changing it "in place" won't alter the actual mask.
  • Chris-g notices that you must assign the vertices before assigning closed to true or false; assigning the vertices "automagically" sets closed to true. Thanks Chris!

Hope that's useful.

Rehi All! Rewelcome to Pixel Blog

Hello seekers!

I’ve been getting a fair amount of traffic lately, mostly from Pixel Bender searches and a few references from forums and other blogs. And the number of subscribers is steadily growing. I guess some of the stuff here is useful to someone. Hooray, I say!

(And of course by “fair amount of traffic” I don’t mean, like, enough hire an editor or start selling ad space. My ISP isn’t complaining yet about the load. I mean, enough traffic that you and I can still enjoy an intimate little shared pixel experience, as told with words and numbers.)

So this post is mostly just a quick blog reintroduction. And below is a cool little video I did last year that I’ve been meaning to document. Ok, let’s go.

accentSpotsW.jpg

Reintroduction

I started this blog a bit over a year ago, focusing mostly on After Effects techniques and scripts. Adobe After Effects is just about my favorite piece of software ever. So clean and elegant, so complete, and rather delightfully ROCK SOLID. I’m a software engineer myself, and can appreciate just how monumental that simple truth is.

Lately I’ve been having GREAT FUN with Adobe Pixel Bender. It’s so satisfying to rapidly implement a complex function and see it in action. Also: math. Yay.

Perhaps prematurely, I’m thinking in this coming year of 2009, I’ll be getting back to After Effects and techniques… and of course announcements of updates to my free plugins, scripts, and Pixel Bender kernels. If this is the sort of thing you like, too, please consider subscribing.

accentSpotsB.jpg

A Retro-tv Treatment

And now, some pixels. Here’s a little video I did last year as part of a “fundraiser” for my friend Briya. She injured her ankle playing roller derby in Santa Cruz, and we helped pay for her ambulance ride.

onTv400b.mov

click for
/pixelblog/content/2008/misc/onTv400b.mov

I grew up staring at our black and white tv set, and tried to capture that feeling here. I think, often, various “retro” image treatments are too aggressive on the degradation. Black and white tv in the 1960’s was actually quite sharp! I tried to keep that feeling here. Here’s the recipe I used.

  1. Character generator. Old tv production had only a few effects available. I used a “character generator” here, white text at about 80% opacity. In the olden days, they rarely used shadow or background to enforce contrast; if the text was over something light-colored, it was just harder to read, sorry!
  2. Picture in picture. I also drop in a rectangular insert image, flat. Notice both the insert and the text only flash, no fading or morphing. That came later.
  3. The telethon look. This was the fun part, of course. I videotaped about 45 seconds each of three different actors sitting at my kitchen table, in front of our red curtain. That’s it! In After Effects, these are shoved next to each other and lined up in rows. It’s amazing how forgiving our eyes are. Yes, you can see that it’s all wrong. But it’s also oh-so-right.
  4. Curved glass tube. I added some arbitrary mesh distortion, suggestive of a glass picture tube. But tubes also get magnetized this way and that. (Or at least, in the 1960’s, mine did, because I played with magnets on it.) It adds an interesting travel to the image.
  5. Transmission loss. To add “ringing” and “aliasing” to the image, something I keenly remember from seeing television, I used my plugin called omino_diffusion, superimposed slightly over the original and blurred. It somewhat simulates the analog behavior of errors and their correction, since it proceeds left to right just like the scanning of the vacuum tube.
  6. Brevity. And of course, the most important trick here is to keep it short, to reduce the time one might have to ponder the image and question it too closely…
  7. I had worked up a “tv-turning-off” dotsweep, also. There’s something wonderfully dramatic about the old CRT dotfall… Modern tv’s just “turn off” and that’s that, but the old disappearing dot was an event providing real closure. But for this piece, I went with looping.

    And good night.

Pixel Bender: A Gradient… and Some Math

Featuring mix(), clamp(), and dot().

Very often I need a simple linear-gradient in After Effects, and end up sing the four-color gradient because that’s all I can find. And so, here, for your perusal, is a Pixel Bender implementation of a Linear Gradient Generator.

After that, we’ll see the code, and after that, a quick review of the math.

Here is the .swf. (With some improvements on the Pixel Bender viewer — you can drag any float2 parameters as points, now.)

gradient.swf

click for
http://omino.com/pixelblog/wp-content/uploads/2008/10/gradient.swf

Isn’t that fun? Well, I’m easily amused.

The Code

Here’s the Pixel Bender code.



kernel Gradient
{
    output pixel4 dst;
    parameter float2 p1<minValue:float2(0,0);maxValue:float2(400,400);defaultValue:float2(10,10);>;
    parameter float2 p2<minValue:float2(0,0);maxValue:float2(400,400);defaultValue:float2(130,130);>;

    parameter float3 color1<defaultValue:float3(0,0,0);>;
    parameter float3 color2<defaultValue:float3(1,1,1);>;

    void evaluatePixel()
    {
        float2 co = outCoord();

        // shift everything relative to p1.
        float2 uv = co - p1;
        float2 xy = p2 - p1;

        // the math.
        float g = dot(uv,xy) / dot(xy,xy);
        g = clamp(g,0.0,1.0);

        // the color.
        dst.a = 1.0;
        dst.rgb = mix(color1,color2,g);
    }
}

The Math

I’m ok at math, but not always fluent in it. I can remember what a matrix is, but not necessarily exactly what a cross-product is. Maybe you’re like me. In which case this quick run through the math and logic behind the gradient fill will be quite useful in your own Pixel Bender bending!

And be assured, a few pages of high-school-algebra-style scribblings, and the occasional google (How do I invert a rotation again? What’s the formula for perspective?) really can lead to workable results. Good clean fun!

Let’s go.

Consider a trivial gradient, where our two control points are at (0,0) and (1,0). That would be easy! Just take the x-value of any pixel, and that’s your color. (That is, the position on the ramp between your two gradient colors.)

trivialGradient.png

By the way, this picture is from Ron Avitzur’s “Graphing Calculator”. The story of its development is legendary; less well known is that it’s actually a very powerful and useful tool.

I found the easiest way to think about a general two-point gradient was to ask, “How do we rotate and scale our control points back to this trivial gradient?” And let’s assume that the first control point is always at (0,0).

Here is matrix for a basic rotation, which moves any input point by a rotation around (0,0):

gradientEq1.jpg[1]

A rotate-and-scale matrix looks like that, times a constant on each element.

We want to think of our general gradient as a transformation on the trivial gradient. Let’s say our second control point is (X,Y), and our first control point is (0,0) as mentioned above. The rotate-and-scale matrix being applied, conceptually, is:

gradientEq2.jpg[2]

To figure out the 0-to-1 trivial position of any of our input points, we need to invert it. A matrix inversion looks like:

gradientEq3.jpg[3]

So, we invert the second equation [2] by plugging it in to [3] and get:

gradientEq4.jpg[4]

Now, let’s call each pixel position of our output (U,V). For our gradient, we actually don’t care about the resulting Y position; just X gives us our gradient value. So we get:

gradientEq5.jpg[5]

Now, the definition of the dot product of (A1,A2,A3,…) and (B1,B2,B3,…) is (A1B1 + A2B2 + A3B3 + …). So, from the above, UV+XY is, conveniently, (U,V) dot (X,Y). Similarly, X2 + Y2 is (X,Y) dot (X,Y).

And now, when you read this part of the code a second time, it should be much clearer what’s going on:

    void evaluatePixel() {
        float2 co = outCoord();

        // shift everything relative to p1.
        float2 uv = co - p1;
        float2 xy = p2 - p1;

        // the math.
        float g = dot(uv,xy) / dot(xy,xy);
        g = clamp(g,0.0,1.0);

        // the color.
        dst.a = 1.0;
        dst.rgb = mix(color1,color2,g);
    }

Simple and useful!

Next up, soon, more cubes.

Handy Scripts

Tasks Beget Subtasks

That’s always how it is, I’m trying to do something, but then a new jig or tool is needed along the way.

Just lately I’m finally “remastering” some ancient (80’s) video of my own. Captured it off VHS video in 2004, been sitting on my hard disk since then. Tragically, the capture introduced some awful drift between audio and video. I probably used iMovie for a 30 minute capture, just like they say not to.

Why am I using AE for this? Because I haven’t upgraded the stupid final cut pro to the stupid expensive intel version, because I stupidly missed the $50 upgrade special window.

And as long as I’m complaining: How come AE doesn’t have some fine-numeric control for time-bumping the layers?? Ok. So it goes.

But meanwhile, I need some fine-control to shift the layers left and right.

I’m thinking, should I write a script for this? But something tickles my memory. A yes, this is just the sort of thing that can be found on Jeff Almasol’s most excellent redefinery blog and scripts collection. Many useful scripts there; solid work-a-day workflow helpers. Also, exquisitely coded. Excellent style, thrilling examples, and so forth.

Happily, redefinery’s rd:scooter was just the tool to nudge things back into place!

After nudging around my 30 minute audio and video layers, I wanted to snip out just the 2 minutes for the particular song-section. But the in- and out-points were far off to the left and right of my dinky 3 minute comp. So I wrote a script panel for this last bit:

I tried to keep it nice and narrow, to fit in easily with the other built-in palettes. It’s ugly, but then it worked so I stopped coding & used it. Click here or on the picture to get it from my scripts collection.

After Effects Scripting Bug

Ah yes, there’s a bug in After Effects CS3’s scripting that I came across. If you set layer.inPoint = t; it also sets the outpoint! My workaround was like so:

	// bug? setting in seems to corrupt out. save and fix.
	var outPoint = layer.outPoint;
	layer.inPoint = myComp.time;
	layer.outPoint = outPoint;

This workaround should be safe even after they fix the scripting bug. (Not sure where to report Adobe bugs…)

So… Then What?

And lastly, some excerpts from the product of this endeavor: Vintage 1986-era animation loops done with Macromind’s Videoworks ! Orchestrated with my own long-forgotten music software, “Synthestra” (MIDI) and P-Drum (sample player), both for the Apple II, distributed by Dan Retzinger’s company, Decillionix.

Check it out. 30 seconds of techno-stalgia.

C5zZ-9Impnk

click for
http://www.youtube.com/v/C5zZ-9Impnk&hl=en&fs=1&rel=0

« Previous Page« Previous entries « Previous Page · Next Page » Next entries »Next Page »