From cgwiki

Apart from Houdini, what are the most important things to a 3d artist? Animated gifs and a working bash shell of course, regardless of platform.


Creating animated gifs with licecap and gifcam

This is awesome and free for windows:

For OSX/Windows/Linux (via wine), licecap is also pretty good.

ffmpeg to generate gifs

Good guide to how to avoid dithering here, which involves running ffmpeg twice; once to generate a palette, the second to generate a gif using that palette.

Here's the important bits from that site in 2 lines:

ffmpeg  -i invideo.mp4 -vf "palettegen" -y out_palette.png
ffmpeg  -i invideo.mp4 -i out_palette.png -lavfi "paletteuse" -y out.gif

The following examples don't do the palette trick, but show off how baroque you can get with ffmpeg to do all sorts of resizing and manipulation. This one shows how to crop:

ffmpeg -i "pyro.%04d.jpg" -lavfi "fps=50,crop=in_w:in_h-85:0:0,scale=400:-1:flags=lanczos" -y out.gif
  • crop will use default width (in_h), and default height minus 85 pixels ( in_h-85), calculated from the top left corner (0,0).

This one drops every 2nd frame:

ffmpeg -i "pyro.%04d.jpg" -lavfi "select=mod(n\,2),setpts=N/(25*TB),crop=in_w:in_h-85:0:0,scale=300:-1:flags=lanczos" -y out.gif
  • select=mod(n\,2) -- every second frame, n is current frame, the \ is there to escape the comma
  • setpts=N/(25*TB) -- magic command I don't quite understand, but I know that it stops it holding frames. Ie, if the previous command was mod(n,10), it would get every 10 frames, but without the setpts call each of those would be held for 10 frames, rather than only playing for 1 frame.

ffmpeg to generate super small gifs

For maximum pidgin victory (where there's an 8k limit):

 ffmpeg -i input.gif -lavfi "fps=15,scale=20:-1:flags=lanczos" -y output.gif
  • fps is fps, obviously
  • scale=20:-1 the horizontal width is 20, the vertical will resize to suit.

Futzing with the fps and width can scrape most gifs under 8k.

Imagemagick/convert to make gifs

To my horror, I realised that my sweet 50fps mograph computationl art tumblr porn gifs were actually running at 24fps. Seems ffmpeg can't go any higher than that, despite specifying the framerate.

Had a go with convert (part of imagemagick) instead, and it lets you do 50fps in all its cpu melting glory. This command takes a sequence, resizes to 256x256 as its loading, then does a post-crop that lops off the lower 40 pixels. The delay of 2 means 2 miliseconds, ie 50fps.

convert -loop 0 -delay 2 flipbook/hexagon.*.jpg[256x256] -crop +0-40 hex2.gif

Super thorough notes on convert here:

Here's another one with a few more tricks:

convert -loop 0 -delay 4 flipbook/cubesmarch.*.jpg[256x210+80+80] +repage -level 0,60% -layers OptimizeTransparency +map cubesmarch.gif
  • -delay 4 4ms per frame, so 25fps
  • [256x210+80+80] define a crop window of 256x210, starting 80 from the left and 80 from the top
  • +repage actually do a crop (without this, it just masks out the rest of the image, which isn't very helpful)
  • -level 0,60% a levels command, map the blackpoint to 0, and white point to 60%
  • -layers OptimizeTransparency use transparency to try and get some savings. This brought a 1.8mb gif that was mostly white wireframes on black down to 1.4mb.
  • +map generate a single optimised colour palette for the full gif, otherwise it tries to generate one per frame, which costs in file size

Video conversion

ffmpeg to generate mp4 from image sequence

The basics, old skool style.

 ffmpeg -i "shot150_v06.%04d.jpg" -qscale 2 -r 10 -b 10M test.mp4

Here's a better way. I understand newer builds use libx264 by default now for mp4's, but I explicitly call it out of habit anyway. Assumes for 4 digit pad jpegs, no prefix on name:

 ffmpeg -f image2 -r 24 -i folder/%04d.jpg -vcodec libx264 output.mp4

If the sequence doesn't start at frame 1, you need to specify that:

ffmpeg -f image2 -start_number 1000 -i myimages.%04d.jpg -vcodec libx264 out.mp4

ffmpeg batch convert many .mov to .mp4 with bash

probably more elegant ways, but this'll do in a pinch:

 for i in *.mov; do ffmpeg -i "$i" -vcodec libx264 "${}.mp4"; done;


Or if you have a specific list of files in various locations, can put the files in a text file with a 'file' word prefix:

# this is a comment
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

And concat them all together:

ffmpeg -f concat -safe 0 -i mylist.txt -c copy output

mp4s have to have dimensions that are powers-of-twoish, this added filter rounds to the nearest power-of-two for otherwise tricky quicktimes:

for i in *.mov; do ffmpeg -i "$i" -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" -vcodec libx264 "${i%.avi}.mp4"; done;

and yet more options... disable audio export with -an, copy the video directly with -vcodec copy, and set a start and end with -ss HH:MM:SS -to HH:MM:SS.

ffmpeg -i very_long_movie.mp4 -ss 00:22:12 -to 00:23:50 -vcodec copy -an shortclip.mp4

and a handy trick when transferring big files and get a decent ETA on the command line:

rsync --progress /path/to/sourcefile /path/to/destination

h265 experiments and gearvr


Man the gearvr is temperamental. After much fiddling and reading of The Internet, this works well:

ffmpeg -i in_4k_360.mp4 -vf "scale=3080:2160" -vcodec libx265 out_360_bt.mp4

The results are remarkable; as h264 a 4min 4k video is about 400mb, the h265 is 40mb, and looks way better. Now to play with the quality settings a little more. Its very slow to encode though, but the results feel worth it. Interestingly, I found occasionally that cross-encoding from one mp4 to a h265 mp4 can break it (feels like metadata from the original video leaks into the new one, and breaks stuff). In that case, encoding clean from a jpg sequence makes it happy again. Must look into an easier way to scrub any bad metadata from the video, see if that keeps the gearvr happy.

In a recent update, h264 videos won't play on the oculus 360 video app if they don't have an audio track (h265 is unaffected, strange). Here's how to add a null aac audio track onto an existing h264 video:

ffmpeg -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=48000 -i invideo_tb.mp4 -shortest -c:v copy -c:a aac outvideo_tb.mp4

Note that top/bottom stereo requires the _tb suffx in the name, that's how oculus video knows to unpack it into stereo.

To do quick clips for testing specificy the start timecode with -ss, and the duration with -t. Ie, this starts 30 seconds in, and runs for 10 seconds:

ffmpeg -i input.mp4 -ss 00:00:30.0 -c copy -t 00:00:10.0 output.mp4

Or if lazy, can skip timecode and just use seconds. This starts at the start, runs for 5 seconds:

ffmpeg -i input.mp4 -ss 0 -c copy -t 5 output.mp4

To cut a stereo top/bottom video back into a mono 720p clip for avid and such:

ffmpeg -i in_stereo_tb.mp4 -filter:v "crop=in_w:in_h/2:0:0,scale=1280x720" -vcodec libx264 out_mono_720p.mp4

make ffmpeg less messy



to the arguments you give to ffmpeg, it stops all that super verbose output ffmpeg likes to vomit every time it runs.


Getting a shell under windows

Git bash is quick and simple, not as bloaty as cygwin, comes with all the major things you need (less vim cat curl git clone etc...)

Get a decent terminal by replacing cmd.exe with ConEmu

Bash is bash, and it runs within cmd.exe by default, the windows DOS shell. Use it for more than 30 seconds, you'll find cmd.exe is horrible. Can't resize it easily, copy paste is weird, ugh. ConEmu is a free cmd.exe replacement, much nicer. Tabs, resizable, better copy/paste etc.

Instructions for getting a 'conemu git bash here' context menu on folders can be found here:

My shell muscle memory always kicks in when I try to copy paste, on linux most shells allow you to double left-click to copy a word, triple left-click copies a line, middle click pastes. You can do this in conemu, in the prefs (win-alt-p), mark/copy, set the text selection mode to 'always'.

Python and git bash

Just install regular python, and append its path to your .bashrc:

export PATH

The best bash prompt ever

Don't question this, it just is. current directory in green, newline, prompt. Stick this in your .bashrc:

export PS1="\[\e[32m\]\w\[\e[m\]\\n\$ "

Looks like this (I pixellated the project path, but shows that the path is nice and easy to see and copy)


I never thought to look before, but now there's loads of interactive bash prompt builders online. Eg:

Make djv work with git bash

Again, just add the path, make an alias (I use rv cos old habits die hard)

PATH=$PATH:/c/python27:"/C/Program Files/djv-0.8.3-pre2_winxp-x64/bin"
export PATH
alias rv=djv_view.exe

There's still problems with calling it, you can't just do 'rv .' (it doesn't launch anything), and definitely not 'rv *' (it launches a separate djv for each image!). I suspect the * is interpreted by bash, so it just launches everything, while using hashes goes straight to djv. This works:

rv myimages.####.exr

Get a seqls/lseq/lss equivalent with pyseq

Pyseq is a python module that handles sequence listing, comes with a callable 'lss' command. Download it with git, install it, copy lss to your ~/bin folder

git clone git:// pyseq
cd pyseq/
python install
mkdir ~/bin
cp lss ~/bin

You get this after all that hard work:

$ lss
  1 .DS_Store
  1 Thumbs.db
  1 _tmpuntitled.png
150 shot150_v03.%04d.jpg 1-150
  2 shot150_v%02d 6-7
  1 tmp


Find a word in lots of files of specific type

grep --include=\*.{glsl,txt} -rnw '/path/to/somewhere/' -e "pattern"



rsync -havz source /path/to/destination
  • h human readable
  • a archive, recurse into folders
  • v verbose
  • z use compression
  • n dry run, handy to test what'll happen without actually doing the sync


I have my reasons.

Bookmarklet to embed jquery on the current page, so you can call it from the chrome interactive console:


Good quick intro:

$( '#header' ); // select the element with an ID of 'header'
$( 'li' );      // select all list items on the page
$( 'ul li' );   // select list items that are in unordered lists
$( '.person' );  // select all elements with a class of 'person'

Futzing with GWT tables in jQuery:

var thumbs = $('.tableThumbsPanel')