Fake Highlight Rotation 0 Comments

2:44 PM by , under , , , ,

Bookmark and Share

A friend of mine is currently working on a project in which there is a ball rolling on the floor and he needs to move the highlight in order to correspond to a light source in the distance. I came up with a quick solution, and I thought I'd share it in case you cross upon something similar, because I feel that this is something quite common, but I wasn't able to find anything on the net. You can download the AEP file here if needed.

Here is the result:


Basically, I created a null that acted as the fake position of our light. Then, I used this null's position to calculate the distance from the highlight on the X and Y axes and theoretically made a right triangle. Using each axis information, I plugged it all into an inverse tangent equation to give me the correct angle that I wanted. Then I just added a multiplier to increase/decrease the amount of rotation.

In this AEP file, I have 4 layers. The ground, the ball, the reflection, and the null. I animated the ball moving around in an arc that roughly imitates my friend's animation.

Want you want to do next is make sure that the Anchor Point for the highlight is in the center of the ball, that way when we rotate it, it will do so inside the ball. Then make sure to parent the highlight to the ball. Afterwards you want to Alt-Click on the Rotation stopwatch in the highlight layer to open up an expression box and type in the following code:


adjc = sub(thisComp.layer("nullLightSource").transform.position[0],thisComp.layer("ball").transform.position[0])
opp = sub(thisComp.layer("nullLightSource").transform.position[1],thisComp.layer("ball").transform.position[1])

sidesratio = div(opp,adjc)

inversetan = Math.atan(sidesratio)*25


Let's break this code down a little. The variable adjc takes the X axis info from the null called "nullLightSource" and subtracts it from the X pos of the layer called "ball". Similarly, opp takes the difference from the Y info. sidesratio then plugs these two correctly into the inverse tangent equation Math.atan().
Then I added a multiplier of 25 at the end of inversetan simply because it looked good.

And voila! You now have a highlight rotating based upon the position of a null. I'm sure somebody can come up with an even cooler application to this, maybe a giant axe blade attached to the end of a pendulum?



edit post
Bookmark and Share

H.264 is one of the more beneficial codecs out there today, especially if your final delivery is to the web. It offers remarkable quality at a surprising small file size. It's one of my most used codecs. In fact, I rarely use anything else outputting to web, as Sorenson flash offers some really nice compression, but it often lacks at picking up the fine level of detail that I personally like to preserve. In my mind, it's so close to being the perfect codec, except for a problem that's been maddening people since its inception. I've been finding that when outputting from both After Effects and Nuke, the gamma is nearly always boosted, causing footage to look desaturated and milky, such as you might see when working in the wrong colorspace. The problem seems to lie with a hidden uneditable gamma tag within the movie file. There are plenty of solutions and "non-solutions" out there on teh interwebz, and all come with a mixed bag of results.

ProVideo Coalition's Chris Meyers article gives an excellent idea, pull H.264 to the side and use its free open-source alternative, x.264.
Mac users can get it via MacUpdate, and Windows users should try Free-codecs.com. Though I have been unsuccessful getting it to work in Windows, hopefully you will have some better luck.

Once installed, it should show up as another codec in your Standard Video Compression Settings.


Another article by PVC's Art Adams suggests rendering using an intermediate codec such as Animation and Photo-JPEG, and then exporting out of Quicktime using the open-source x.264 codec, in order to insure proper translation of the gamma tag, which I would highly recommend.

-----------------------

Another PVC writer, Mark Christiansen, points out that the gamma tag may be able to be stripped off with a neat little app from FuelVFX. "It requires a bit of hunting: hover your cursor over the red bar, select Software, and then click on the QTGammaStrip folder icon. Make sure you also download the ReadMe.txt file, as it includes (extremely) terse instructions on how to run it inside Terminal. " -Meyers.



-----------------------

Popularized by Andrew Kramer of VideoCopilot.net, this method involves altering some settings in Quicktime post-render, but comes with mixed results across the board. It seems that in VLC, the gamma will still be boosted, whereas in Quicktime, Safari, and Firefox the video shows up as it should.

H.264 Fix by AVillabon.


SOLUTION: After rendering into a QuickTime/h.264 file, open it up in QuickTime and select “Show Movie Properties.” Highlight the video track then click on the “Visual Settings” tab. Towards the bottom left you should see “Transparency” with a drop-down box next to it. Select “Blend” from the menu then move the “Transparency Level” slider to 100%. Choose “Straight Alpha” from the same drop-down and close the properties window and finally “Save.”

-----------------------

Hopefully the fine folks at Apple will fix this soon. Are there any other solutions that you would recommend?



edit post

SSS Fast Skin 0 Comments

6:13 PM by , under , , , , ,

Bookmark and Share

Seeing as how I have a midterm due on Wednesday, I've decided to take a break and switch over to Adv. Texturing and Lighting after two days of non-stop slaving away for Compositing for Production. I've been developing a better understanding of mr's fast sss skin shader, which has helped make some progress with Chimi. I'm working on getting his hair done right now, and I need a turntable rendered out by Wednesday. Here's some progress shots:









edit post

Render Sound in Nuke Part 2 4 Comments

11:19 PM by , under , , , , ,

Bookmark and Share

Earlier this week, I posted a super basic beginner's tutorial intro into manipulating scripts inside of Nuke, and gave you a handy little code that played a sound when your render was finished. Well, after a little trial and error, I managed to come up with a script that attaches itself to Nuke's Write node and adds a custom tab with the 'Render with Sound' function. I tried to mimic the original Write node's interface, but unfortunately due to the dynamic nature of the Write node and the various file extensions and video codecs that are interactively added, it tends to switch back and forth between tabs. Although, once you set your file extension and codec, you can switch back to the 'WriteSound' tab without it swapping back. If anyone knows a workaround to this, please let me know.

The final result:


As with the last post, to make this work, you need a .WAV sound file. Check out AT&T Labs and make your own if needed. Make sure to take note of its physical location on your drive.

We're going to be changing the user interface ever so slightly and to do that we'll need to tell Nuke to make some changes. The menu.py file specifies any customization to Nuke's interface, and is usually found in the default user plugins folder. The default locations for this folder are:

Win - 'C:/Documents and Settings/USER/.nuke/
Mac - '$HOME/.nuke/


If you can't find a menu.py file in these folders, go ahead and create your own by saving out of your favorite text editor. To get started, you will need to add the following code to your menu.py file.



import writeSound
writeSound.attachWriteSoundNode()


This tells Nuke to import the writeSound script, and inside of writeSound go ahead and execute the attachWriteSoundNode command.

Next, you will need the following bit of code. Go ahead and copy this into a new file in your text editor.



# Developed by Christian Castaneda
# chris@castanedafx.com
# This should create a custom write node that plays a sound when finished rendering
import nuke

nukeOriginalWriteSoundNode = nuke.createNode

def attachWriteSoundNode():
nuke.createNode = customWriteSoundNode

def customWriteSoundNode(node, knobs = "", inpanel = True):
if node == "Write":
writeNode = nukeOriginalWriteSoundNode( node, knobs, inpanel )
## attach our custom tab
createWriteSoundTab( writeNode )
return writeNode
else:
return nukeOriginalWriteSoundNode( node, knobs, inpanel )

def createWriteSoundTab(node):
#### create knobs
tabKnob = nuke.Tab_Knob('WriteSound')
channelKnob = nuke.Link_Knob('channels_name', 'channels')
fileKnob = nuke.Link_Knob('file_name', 'file')
proxyKnob = nuke.Link_Knob('proxy_name', 'proxy')
divideKnob = nuke.Text_Knob('')
colorKnob = nuke.Link_Knob('colorspace_name', 'colorspace')
preMultKnob = nuke.Link_Knob('premultiplied_name', 'premultiplied')
rawDataKnob = nuke.Link_Knob('raw data name', 'raw data')
viewsKnob = nuke.Link_Knob('views_name', 'views')
typeKnob = nuke.Link_Knob('file type name', 'file type')
orderKnob = nuke.Link_Knob('render_order_name', 'render order')
buttonKnob = nuke.PyScript_Knob('Render With Sound')

#### make links to the Original Write
channelKnob.setLink('channels')
fileKnob.setLink('file')
proxyKnob.setLink('proxy')
colorKnob.setLink('colorspace')
preMultKnob.setLink('premultiplied')
rawDataKnob.setLink('raw')
viewsKnob.setLink('views')
typeKnob.setLink('file_type')
orderKnob.setLink('render_order')

script = """
############ This section by Fredrik Brannbacka #############
##
## Make sure you set the sounds file path
macSound = 'PATH/TO/SOUND/FILE'
winSound = 'PATH/TO/SOUND/FILE'
def playSound():
if nuke.env["MACOS"]:
sys.path.append('/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python')
sys.path.append('/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python/PyObjC')
from AppKit import NSSound
sound = NSSound.alloc()
sound.initWithContentsOfFile_byReference_(macSound, True)
sound.play()
elif nuke.env["WIN32"]:
import winsound
winsound.PlaySound(winSound, winsound.SND_FILENAME|winsound.SND_ASYNC)

node = nuke.selectedNode()
if node.Class()=='Write':
start,end = nuke.getFramesAndViews('Render Range','%i,%i' % (nuke.root()['first_frame'].value(),nuke.root()['last_frame'].value()))[0].split(',',2)
if nuke.execute(node.name(),int(start),int(end)):
playSound()
"""

buttonKnob.setValue(script)

#### add knobs to node
for k in [tabKnob, channelKnob, fileKnob, proxyKnob, divideKnob, colorKnob, preMultKnob, rawDataKnob, viewsKnob, typeKnob, orderKnob, buttonKnob]:
node.addKnob(k)


Here's an important step to make sure that this works. You need to change the path of the sound file in the code, which should be lines 50/51. Specifically, you are looking for:

## Make sure you set the sounds file path
macSound = 'PATH/TO/SOUND/FILE'
winSound = 'PATH/TO/SOUND/FILE'


Once you're done editing the code, save it out in the same folder as menu.py with the filename of 'writeSound.py'.

Restart Nuke and feel free to enjoy the wonderful bliss that is audible renders. Ahhhhh.



edit post

Render Sound in Nuke 0 Comments

11:44 AM by , under , , , , ,

Bookmark and Share

Often times I find myself meandering while my comps are rendering. I'm a lost stray soul trekking through the long forgotten desolate land that is my desk. I'm usually planning my next comp, stretching after hours of being desk-bound, wondering if that moldy thing in that corner there is growing and will eventually take over me, and more than likely browsing the internet. But how will I ever know when my renders are complete? Fear not, for we can make Nuke do whatever we please, that's the beauty of scripting. Thanks to Dotcommer, quite a talented classmate, who started this thread at VFXTalk, and thanks to smaragden for coming up with this excellent solution.

First, you will need a .WAV sound file. If you don't have an arsenal of beeps and chimes at your disposal, I recommend going to AT&T text-to-speech labs and create your own personal saying. Mine praises and worships me, and thinks I should run for President of the Galaxy. Once you have it, make sure you take note of its physical location on your drive.

Next, you'll need this snippet of code:

macSound = 'PATH/TO/SOUND/FILE'
winSound = 'PATH/TO/WAVE/FILE'
def playSound():
if nuke.env["MACOS"]:
sys.path.append('/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python')
sys.path.append('/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python/PyObjC')
from AppKit import NSSound
sound = NSSound.alloc()
sound.initWithContentsOfFile_byReference_(macSound, True)
sound.play()
elif nuke.env["WIN32"]:
import winsound
winsound.PlaySound(winSound, winsound.SND_FILENAME|winsound.SND_ASYNC)

node = nuke.selectedNode()
if node.Class()=='Write':
start,end = nuke.getFramesAndViews('Render Range','%i,%i' % (nuke.root()['first_frame'].value(),nuke.root()['last_frame'].value()))[0].split(',',2)
if nuke.execute(node.name(),int(start),int(end)):
playSound()


Feel free to use whatever text or script editor you prefer, for this example I'll be using the script editor within Nuke. Go ahead and copy and paste the code into the Script Editor. If you don't see the Script Editor by default, right-click on any one of the content menus to select it.



In the first two lines of code, enter the entire path name of your .WAV file in the specified space. For example, since I'm using Windows, I'll change the second line of code to:


winSound = 'E:/Documents and Settings/Christian/RenderSound.wav'


Since we're going to be using this quite often, let's go ahead and save it somewhere where we can easily access it again. Click on Save Script and save it with a .PY extension:



Now if you ever wanted to use this script again, you could easily load it by pressing the Load Script icon.



Now here's the money part, with your Write Node selected, go ahead and run the script. You can run it by either pressing the icon or the hotkey which is Ctrl-Enter.



If it worked, you should get a little pop-up asking you which frames you would like to render.



As far as I can tell, this doesn't work with single frame renders and executing multiple write nodes in your Nuke script.

I hope this works for you, feel free to let me know if you have any questions.



edit post