<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Toadstorm Nerdblog</title>
	<atom:link href="http://www.toadstorm.com/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.toadstorm.com/blog</link>
	<description></description>
	<lastBuildDate>Tue, 01 May 2012 00:54:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>motion trails in houdini, part 3</title>
		<link>http://www.toadstorm.com/blog/?p=193</link>
		<comments>http://www.toadstorm.com/blog/?p=193#comments</comments>
		<pubDate>Mon, 30 Apr 2012 21:38:40 +0000</pubDate>
		<dc:creator>toadstorm</dc:creator>
				<category><![CDATA[Houdini]]></category>
		<category><![CDATA[houdini]]></category>
		<category><![CDATA[trails]]></category>

		<guid isPermaLink="false">http://www.toadstorm.com/blog/?p=193</guid>
		<description><![CDATA[Okay, now for the last part of this tutorial: We&#8217;re going to turn the motion trails effect into a Digital Asset, which a single node with inputs, outputs and parameters (just like any other node) that can be shared with other artists. The network we made to create the effect is big and ugly, and <a href='http://www.toadstorm.com/blog/?p=193'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Okay, now for the last part of this tutorial: We&#8217;re going to turn the motion trails effect into a Digital Asset, which a single node with inputs, outputs and parameters (just like any other node) that can be shared with other artists. The network we made to create the effect is big and ugly, and no one in their right mind would want to copy and paste that whole thing from scene to scene and start jumping across the SOP and CHOP networks and look for individual nodes to tweak parameters. Digital Assets let us package everything together nicely.</p>
<p><span id="more-193"></span></p>
<p>The first thing to do is to select all the nodes currently in your geometry network (inside the &#8220;trails&#8221; object), and click the little icon shaped like a box to create a &#8220;Subnet&#8221; object (see Fig. 1). This groups your whole network together into a nice little package, complete with inputs and an output.</p>
<div id="attachment_194" class="wp-caption alignleft" style="width: 160px"><a href="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_08.jpg"><img class="size-thumbnail wp-image-194" title="h_trails_tut_08" src="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_08-150x118.jpg" alt="" width="150" height="118" /></a><p class="wp-caption-text">Fig. 1</p></div>
<p>Double-click the Subnet to see your original network. The first thing you will probably notice is that there are four little boxes in your network called &#8220;Sub-Network Input #1-4.&#8221; These are placeholders for the four inputs you saw on the Subnet node itself. Whatever you plug into the input #1 of your Subnet will then output from the box labelled &#8220;Sub-Network Input #1.&#8221; We&#8217;ll only be using the first input here, since the only shape information we need is the object we&#8217;re emitting trails from. Connect the output of Sub-Network Input #1 to the first input of your network, which should be the Time Blend SOP.</p>
<p>Now we need to start going through our network and looking for attributes that we&#8217;ll want to be controlling. This part will take a while, since it&#8217;s not necessarily obvious which channels you&#8217;ll want to have control over from the very start, but fortunately it&#8217;s a pretty easy process once you&#8217;ve done it a few times.</p>
<p>Going down the network, the first parameter we&#8217;ll want control over is the Seed parameter of the Sort SOP. This controls the random seed that determines which points are selected for emission. In order to control this parameter, first we have to go back up to the Subnet node, and start adding parameters. Select the Subnet node, go to your Parameters window and click the little icon shaped like a gear, then choose &#8220;Edit Parameter Interface.&#8221; You can also just right-click the Subnet node and choose &#8220;Edit Parameter Interface&#8221; from there. What you&#8217;ll get is a big scary window that looks like Fig. 2.</p>
<div id="attachment_195" class="wp-caption alignleft" style="width: 160px"><a href="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_09.jpg"><img class="size-thumbnail wp-image-195" title="h_trails_tut_09" src="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_09-150x150.jpg" alt="" width="150" height="150" /></a><p class="wp-caption-text">Fig. 2</p></div>
<p>On the left side is a list of parameter types: Buttons, floating point numbers, strings, integers, vectors, etc. In the middle is the existing parameter structure of your selected node, which right now is just four String parameters grouped together under the &#8220;root&#8221; of the parameter interface. On the right side are the settings for the selected parameter. You won&#8217;t be able to edit the built-in Subnet parameters quite yet, but you can add as many of your own as you like.</p>
<p>Since the Seed attribute is an integer, start by dragging an Integer parameter from the left pane into the center pane. If you were to click &#8220;Apply&#8221; at the bottom right now, you&#8217;d see a new parameter pop up in your Parameters view, with a label &#8220;Label&#8221; and a value of zero, with a slider next to it. We can change those values using the right-hand Parameter Description pane. The &#8220;Name&#8221; is the parameter name as Houdini sees it. Let&#8217;s call it &#8220;pointsSeed.&#8221; The Label is what the user sees, so type something a little prettier like &#8220;Random Seed.&#8221; The last thing to do here is set a range, since by default the slider will only go from zero to ten, which is not very many values for a random seed. Check &#8220;Range&#8221; and then set the maximum value to something huge, like 10,000. Hit &#8220;Accept&#8221; and your Parameter view should update to reflect the new changes.</p>
<p>Now we have to connect this parameter to the Seed value of our Sort SOP inside the Subnet. We could type in the channel name manually, but it&#8217;s much easier to just right-click the new Random Seed channel we made in the Parameter view, and select &#8220;Copy Parameter.&#8221; Next, jump inside the Subnet and select the Sort SOP. Right-click the Seed parameter and select &#8220;Paste Copied Relative References.&#8221; The expression for this value will appear as something like <code>ch("../../pointsSeed")</code>, which is looking for a channel called &#8220;pointsSeed&#8221; on the parent of the Sort SOP (which is the Subnet node) and returning its value. Now we can control this from the Subnet! On to the next parameter.</p>
<p>There are a lot of parameters on the POP Network that we&#8217;ll want control over: the Start Time, Preroll Time, Random Seed (again), and Oversampling parameters all have potential to be tweaked by the user. Jump back to the Subnet, open the Edit Parameter Interface window, and create four new controls: Start Time (float, variable name <em>startTime</em>), Preroll Time (float, variable name <em>prerollTime</em>), Random Seed (integer, variable name <em>seed</em>), and Oversampling (integer, variable name <em>oversampling</em>). If you want to set default values for any of these parameters (to match the ones that work for your current simulation, for example), you can go to the Channels tab of the Parameter Description pane and set a default. Once the parameters are all added, then you can copy each parameter and then paste the relative reference to the appropriate channels on the POP Network node.</p>
<p>Another way to create parameters on your Subnet is to create them based on another node that already exists. This is really handy for more complicated control structures such as dropdown menus. As an example, let&#8217;s say we want a control that can choose the type of noise that affects our waveform (sparse, hermite, etc). The original channel is in the &#8220;noise1&#8243; CHOP in our CHOPnet. Under the Create Parameters pane of the Edit Parameter Interface window, go to the &#8220;From Nodes&#8221; tab and find the noise1 node inside your CHOPnet. Open up the tree view, and inside you will find several folders of parameters. In the &#8220;Noise&#8221; folder, there is a channel called &#8220;Type&#8221; (variable name &#8220;function&#8221;), which is the channel we want. Simply drag this into your Existing Parameters pane, and a copy of that control will be added to your interface (Fig. 3).</p>
<div id="attachment_196" class="wp-caption alignleft" style="width: 160px"><a href="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_10.jpg"><img class="size-thumbnail wp-image-196" title="h_trails_tut_10" src="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_10-150x150.jpg" alt="" width="150" height="150" /></a><p class="wp-caption-text">Fig. 3</p></div>
<p>It would be really tedious for me to write out instructions for every single parameter, so you can figure out which parameters to add to the interface on your own. Don&#8217;t forget that you&#8217;ll need some channels from inside your POP network (to control forces and the like), and you&#8217;ll need to control some other channels in your CHOP network as well as from some of the other nodes in your geometry context.</p>
<p>Now let&#8217;s do some fancy shit.</p>
<p>Let&#8217;s say you don&#8217;t always want to output extruded polygons from your network&#8230; you might sometimes want just NURBS curves, or maybe you want just the original points that made up the trails. It&#8217;s not hard to just wire a Geometry ROP to different points in the network to save out the geometry you want, but if this network is going to exist as a neat little package, it&#8217;s best to just have that single output.</p>
<p>To do this, we can use a <strong>Switch</strong>SOP. The switch allows you to wire as many inputs as you want into it, and it will output the result of one of those inputs based on the &#8220;Select Input&#8221; parameter. Now all you have to do is wire connections from the appropriate parts of your network to the Switch SOP. I like using Null SOPs to visually represent each possible output of the network: for example, for the &#8220;points only&#8221; output, I would create a Null SOP and wire the output of the POP network to it, then name it &#8220;OUTPUT_POINTS.&#8221; Then drag OUTPUT_POINTS off to the side somewhere, and wire it to the Switch SOP. See Fig. 4 for an example; my network has a few extra nodes in it that I haven&#8217;t mentioned in this tutorial but the green highlighted nodes are the outputs, each connected to the &#8220;switch_outputType&#8221; Switch SOP.</p>
<div id="attachment_199" class="wp-caption alignleft" style="width: 160px"><a href="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_11.jpg"><img class="size-thumbnail wp-image-199" title="h_trails_tut_11" src="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_11-150x150.jpg" alt="" width="150" height="150" /></a><p class="wp-caption-text">Fig. 4</p></div>
<p>Now to build a control for this switch. Go back out to the Subnet and edit the parameter interface. Create an Ordered Menu control, and name it &#8220;outputType.&#8221; In the Parameter Description pane, you can then create a number of options, each with a &#8220;Token&#8221; value, which is basically an array index, and a label. The order in which these appear depends on the order of inputs into your Switch SOP. If the first input of your switch is &#8220;OUTPUT_POINTS,&#8221; then you should assign the first menu item with a token of zero and a label like &#8220;Points.&#8221; Then apply the new parameter, right-click it in the Parameters window, copy the parameter, dive into your Subnet, and paste the relative reference to the &#8220;Select Input&#8221; parameter of your Switch SOP. Now when you change the Output Type control, your new node should change its output entirely.</p>
<p>We can use this same switch setup for other things in the network, too. Let&#8217;s say the user might want to emit from very specific points on the model, instead of at random. Instead of defining a group of random points using the Sort SOP, we&#8217;ll need to have an alternate path that accepts a list of points. To do this, we&#8217;re going to create a Group SOP right next to the &#8220;randomPoints&#8221; Group SOP we set up earlier. Connect the output of the Trail SOP to the first input of your new group. The group name will need to be the same as the randomPoints group, since the POP Network is looking for that point group by name, so even though this group is for ordered points, it still might be named &#8220;randomPoints.&#8221; A little confusing, but whatever. Make sure your new group is a point group. Now create a Switch SOP, and connect both of your point group SOPs to it. Make sure the randomPoints group is the first input. Then connect the output of this switch to the first input of the Point SOP below. See Fig. 6 for an example of the network.<a href="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_13.jpg"><img class="alignleft size-thumbnail wp-image-201" title="h_trails_tut_13" src="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_13-150x150.jpg" alt="" width="150" height="150" /></a></p>
<p>Next, we have to create an interface for this. We&#8217;ll need some kind of option menu to choose which of these groups we want to use, and then we&#8217;ll need some kind of control to define which points we want to emit from if we&#8217;re using specific points. Create another &#8220;Ordered Menu&#8221; type control, and set the first index as &#8220;Random,&#8221; and the second as &#8220;From Group.&#8221; Then create a new string control and name it &#8220;groupPattern.&#8221; Set the label as &#8220;Pattern.&#8221; Now we have to connect these parameters to your network. Close the Edit Interface window, and copy the &#8220;Emission Method&#8221; control, then paste the relative reference to the &#8220;Select Input&#8221; of your new switch. Do the same for the &#8220;groupPattern&#8221; control, and paste the reference to the &#8220;Pattern&#8221; slot of your new Group SOP. Now if you select &#8220;From Group&#8221; as your emission method and then type a list of points into the &#8220;Pattern&#8221; control, your network should emit trails from the points you specified. Keep in mind you&#8217;ll need to adjust the &#8220;Number of Trails&#8221; control accordingly, or you&#8217;ll get some weird results.</p>
<p>Your custom node is just about done. By this time you probably have a ton of controls, which may or may not look pretty hideous and disorganized. There are a number of ways you can clean up the interface, the simplest of which is to create folders to house your controls. In the Edit Parameter Interface window, you can drag Folders into the Existing Parameters window, and then organize your controls under labelled folders. Separator controls are also good for dividing controls into groups that don&#8217;t warrant their own folders. You can see an example of this structure in Fig. 5.</p>
<div id="attachment_200" class="wp-caption alignleft" style="width: 160px"><a href="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_12.jpg"><img class="size-thumbnail wp-image-200" title="h_trails_tut_12" src="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_12-150x150.jpg" alt="" width="150" height="150" /></a><p class="wp-caption-text">Fig. 5</p></div>
<p>One last trick. If you select a control in the Edit Interface window, at the bottom of the Parameter Description window you&#8217;ll see a section for &#8220;Interface Options.&#8221; There are a couple of text fields here for &#8220;Disable When&#8221; and &#8220;Hide When,&#8221; which allow you to set rules for when the control is visible. The syntax is a bit weird, and not particularly well-documented, but it&#8217;s simple enough once you have an example or two.</p>
<p>One of your controls is probably the thickness of the polygon tubes that are generated. You don&#8217;t need to have access to this control unless your network is set to actually output these tubes; if you created the Switch setup then there is a chance you will only be outputting curves or points. The parameter we created earlier that drives the output type is called &#8220;outputType,&#8221; and in my network it ranges from 0 to 3. Values 0 and 1 are for points and curves, respectively, while 2 and 3 are for polygons and polygons &amp; curves. The thickness parameter, then, only needs to be accessible if outputType is greater than 2. For the &#8220;Disable When&#8221; string, then, type this expression in:</p>
<p><code>{ outputType &lt; 2}</code></p>
<p>The expression needs to be contained in curly braces, and the &#8220;outputType&#8221; variable isn&#8217;t called like a local variable would be, but otherwise the syntax is simple enough. Now the control will be disabled if it&#8217;s not needed. You could apply this same idea to other parameters in your interface, such as the number of polygon divisions, or to the &#8220;Pattern&#8221; control to make it disappear when you&#8217;re emitting from random points.</p>
<p>The last thing to do is to save your fancy new subnet as a Digital Asset. With the Subnet selected, right-click and choose &#8220;Create Digital Asset.&#8221; You can choose an operator name and label, and then choose 1 minimum input and 1 maximum output. Once that&#8217;s done, you can drop copies of your network down like anything else! If you want to edit an asset that&#8217;s already been created, you can right-click a copy of the node and select &#8220;Allow Editing of Contents.&#8221; To save changes you&#8217;ve made back to the node&#8217;s definition, right-click and choose &#8220;Save Operator Type,&#8221; then choose &#8220;Match Current Definition&#8221; to make the node read-only again.</p>
<p>That&#8217;s it for this tutorial. If you want to check out my build of the network for Houdini 12, it&#8217;s right <a href="http://www.toadstorm.com/freebies/QFR_motion_trails.otl">here</a>. As always, comment away if you have any questions or if there are any inaccuracies.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.toadstorm.com/blog/?feed=rss2&#038;p=193</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>updated maya to FBX export script</title>
		<link>http://www.toadstorm.com/blog/?p=188</link>
		<comments>http://www.toadstorm.com/blog/?p=188#comments</comments>
		<pubDate>Fri, 27 Apr 2012 23:55:07 +0000</pubDate>
		<dc:creator>toadstorm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.toadstorm.com/blog/?p=188</guid>
		<description><![CDATA[I just wrote out a new version of the Maya to FBX export script, this time in Python, and with a lot of bugs and instabilities cleaned up. It auto-detects deforming vs. non-deforming objects, and exports each type of object to a separate FBX, optionally from a selection. Everything is baked into world space so <a href='http://www.toadstorm.com/blog/?p=188'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I just wrote out a new version of the Maya to FBX export script, this time in Python, and with a lot of bugs and instabilities cleaned up. It auto-detects deforming vs. non-deforming objects, and exports each type of object to a separate FBX, optionally from a selection. Everything is baked into world space so there are no complications with unexpected transforms. </p>
<p>The new script is on the <a href="http://www.toadstorm.com/blog/?page_id=40" title="Scripts">scripts</a> page, in place of the old MEL one.</p>
<p>Post a comment if you have any questions&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.toadstorm.com/blog/?feed=rss2&#038;p=188</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>motion trails in houdini, part 2</title>
		<link>http://www.toadstorm.com/blog/?p=174</link>
		<comments>http://www.toadstorm.com/blog/?p=174#comments</comments>
		<pubDate>Fri, 20 Apr 2012 02:26:36 +0000</pubDate>
		<dc:creator>toadstorm</dc:creator>
				<category><![CDATA[Houdini]]></category>
		<category><![CDATA[houdini]]></category>
		<category><![CDATA[trails]]></category>

		<guid isPermaLink="false">http://www.toadstorm.com/blog/?p=174</guid>
		<description><![CDATA[Now that the initial trails setup is done, it&#8217;s time to get the audio effect in there. CHOPs in Houdini (channel operators) are really, really powerful, but they&#8217;re often the last part of the program that anyone touches. They can turn simple motion and effects into much, much more complex effects pretty easily. I still <a href='http://www.toadstorm.com/blog/?p=174'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Now that the initial trails setup is done, it&#8217;s time to get the audio effect in there. CHOPs in Houdini (channel operators) are really, really powerful, but they&#8217;re often the last part of the program that anyone touches. They can turn simple motion and effects into much, much more complex effects pretty easily. I still am unaware of the vast majority of things you can do with CHOPs, but I hope this example will be a good start for anyone who&#8217;s trying to learn Houdini&#8230;</p>
<p><span id="more-174"></span></p>
<p>Anyways. Starting from the geometry network we were in before, it&#8217;s time to make a <strong>chopnet</strong> manager. Double-click to jump into the channels context. Set one of your panes to &#8220;Motion View&#8221; if you don&#8217;t have it open already. Now lay down a <strong>file</strong> CHOP. You can import all kinds of information into a CHOP network, but in this case we&#8217;re going to use an audio file. Houdini seems to have trouble with some .MP3 files, so you might be better off using a .WAV file or converting an .MP3 to a .WAV. You can leave everything else at the default. If your music doesn&#8217;t start right at the beginning of the track, you can append a <strong>Shift</strong> CHOP and change the &#8220;Start&#8221; parameter to move the audio back a few seconds.</p>
<p>Another aside: to preview audio in Houdini, you need to click the little icon in the bottom-right corner that looks like a speaker, set the mode to &#8220;Scrub,&#8221; and point to a CHOP or a file you want to play while the timeline plays.</p>
<p>Now, if you hold middle-click on your File or Shift CHOP, you&#8217;ll likely see two audio channels: chan0 and chan1. Those are stereo channels. We don&#8217;t really need both of those channels, so append a <strong>Delete</strong> CHOP and delete chan1. It&#8217;ll save a little time later on when we need to do a few operations down the line.</p>
<p>Next up, we want to compute the amplitude of our audio. To do that, append an <strong>Envelope</strong> CHOP. You can mess around with the Envelope Width later on. It&#8217;s not a bad idea to resample the audio by checking &#8220;Resample Envelope&#8221; and setting your sample rate to something reasonably high, depending on your audio and whether your Common settings for the CHOP are in frames or seconds. Audio curves can get pretty dense depending on the original sample rate, and you really typically don&#8217;t need that level of fidelity. Again, this can be adjusted more later on.</p>
<p>Now append a <strong>Trigger</strong> CHOP. The Trigger is meant to take channel data and turn it into distinct &#8220;attacks&#8221;: if you&#8217;re familiar with MIDI, you&#8217;ll know the &#8220;attack, sustain, decay, release&#8221; structure. What we&#8217;re looking for is for the value of this curve to be zero except when a &#8220;beat&#8221; is happening, in which case we want a very fast ramp-up to a value of 1.0 (the attack), a brief hold at 1.0 (the sustain), and a slightly slower tapering off back to zero (the decay/release). The &#8220;Trigger Threshold&#8221; parameter controls what amplitude is the minimum for activating the trigger. You&#8217;ll need to mess with this value the most to control when a beat happens. You&#8217;ll probably also need to adjust the Envelope Width and Sample Rate on the Envelope CHOP. Keep tweaking the sliders around on both the Envelope and Trigger CHOPs until you have a curve that looks something like the one in Fig. 1.</p>
<div id="attachment_177" class="wp-caption alignleft" style="width: 160px"><a href="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_05.jpg"><img class="size-thumbnail wp-image-177" title="h_trails_tut_05" src="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_05-150x150.jpg" alt="" width="150" height="150" /></a><p class="wp-caption-text">Fig. 1</p></div>
<p>Next up, we&#8217;re going to take this trigger information and use it to blend between two other channels: a channel with a constant value of zero, and a generated noise channel. When I originally created this effect, I wanted to use the actual waveform of the audio to displace the motion trails, but the real waveform just didn&#8217;t look that good. Generated noise had the pattern I was looking for, and was a little easier to control, so that&#8217;s the setup we&#8217;re using here. You could use a real waveform if you wanted to in place of the generated noise, feel free to experiment.</p>
<p>Start by creating a <strong>Wave</strong> CHOP (in the same CHOP network, but not connected to the previous CHOPs). I used a Triangle type wave, but you can use whatever you think looks best. The Period of the wave is probably going to need to be very small unless your scene scale is huge, try starting with a value of 0.05. Everything else is relatively unimportant right now.</p>
<p>We&#8217;re going to mix up this waveform with a little noise. Create a <strong>Noise</strong> CHOP (don&#8217;t append it to the Wave CHOP). I used Sparse noise, but again play around with the types and see what you like. I set the Period to 0.005, and the Amplitude to 4.</p>
<p>We also need to make a channel that&#8217;s going to act as the blender between these other two channels. Create a <strong>Channel</strong> CHOP. Add just one channel, you can name it &#8220;blend&#8221; or whatever you want. The type should be float, and the size is 1. Set the value to 0.5 for now, you&#8217;ll be adjusting it later. Finally, we&#8217;re going to tie all three of these channels together with a <strong>Blend </strong>CHOP. The channel that drives the blend amount (using a range from 0 to 1, like a ramp) needs to be the first input, so connect your Channel CHOP to the Blend first. Then connect your Wave and Noise CHOPs to the Blend. Make sure to turn on &#8220;Omit First Weight Channel,&#8221; since we only want to use it as a blender, not as actual channel information.</p>
<p>You should end up with a channel looking something like the one in Fig. 2. It&#8217;s a waveform that&#8217;s slightly blended with a noise pattern, enough to make it a little more visually interesting. You can control how much noise is in the curve by adjusting the &#8220;value0x&#8221; of the Channel CHOP you created from 0 (no noise) to 1 (entirely noise).</p>
<div id="attachment_178" class="wp-caption alignleft" style="width: 160px"><a href="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_06.jpg"><img class="size-thumbnail wp-image-178" title="h_trails_tut_06" src="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_06-150x150.jpg" alt="" width="150" height="150" /></a><p class="wp-caption-text">Fig. 2</p></div>
<p>Next  up, we need to extend this generated pattern so that it lasts as long as we need it to, so just append an <strong>Extend</strong> CHOP and set the Right Behavior to &#8220;Cycle.&#8221; The noise is irregular enough that nobody is likely to notice a repeating pattern in the motion trails.</p>
<p>So now we have two separate channels&#8230; a trigger channel that goes from zero to one based on the amplitude of the music, and a waveform channel that generates the visible pattern we want. Now what we need to do is have the waveform channel scaled by this trigger channel, so that the waveform is only really visible when the trigger is activated. To do this, we&#8217;ll just multiply the channels together using a <strong>Math</strong> CHOP. Set the Combine CHOPs to &#8220;Multiply.&#8221; If your channels from the Trigger and the Extend CHOPs are named the same, you can set the Match By parameter to &#8220;Channel Name.&#8221; Otherwise, if you only have one channel in each of those nodes, &#8220;Channel Number&#8221; is fine. Under the Mult-Add tab, the other setting to play with is &#8220;Multiply,&#8221; which will multiply the result of the Math CHOP by a scalar. This is effectively the amplitude of your final curve. Your curve should look something like Fig. 3 here.</p>
<div id="attachment_180" class="wp-caption alignleft" style="width: 160px"><a href="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_07.jpg"><img class="size-thumbnail wp-image-180" title="h_trails_tut_07" src="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_07-150x150.jpg" alt="" width="150" height="150" /></a><p class="wp-caption-text">Fig. 3</p></div>
<p>We&#8217;re almost done with the CHOP network. It&#8217;s good practice to name your channel something useful, so append a <strong>Rename</strong> CHOP and rename your channel from whatever it&#8217;s currently named (likely &#8220;chan0&#8243; or &#8220;chan1&#8243;) to &#8220;waveform.&#8221; Then append a <strong>Null</strong> CHOP. Nulls are great for exporting data, since you can easily see them in dropdown lists if you name them in capital letters, and you don&#8217;t have to worry about other connections to your network breaking later on if you need to append extra nodes to your network. Name the Null CHOP something like &#8220;CHOP_OUT.&#8221;</p>
<p>Now we have to jump back to the POP network you made earlier. Go inside the POP Network. We&#8217;re going to insert a few nodes between the Force POP and the Drag POP we made earlier. First, we need to define exactly which points we&#8217;re going to be moving for each frame. We don&#8217;t want to move the points that have just been emitted, since that would push the start of the trails away from the body, which would look weird. Instead, let&#8217;s make a group out of particles that have been alive just a little bit longer than that&#8230; say, three frames. Append a <strong>Group</strong> POP. Set the Group Name to &#8220;displaceGroup.&#8221; Under the Rule tab, check &#8220;Enable&#8221; and set the rule to <code>$AGE == 3/$FPS</code>. This means that the group will evaluate to include only particles whose were born exactly three frames ago ($AGE gives you the particle&#8217;s age in seconds, so we divide it by the $FPS variable to get frames).</p>
<p>Now to the good part&#8211; we&#8217;re actually going to take this group of particles and translate them based on the value of that CHOP network. Append a <strong>Position</strong> POP. This node lets us manually define the position of any particle. Set the Source Group to &#8220;displaceGroup.&#8221; For this example, we&#8217;re only going to modify the Y-coordinate of these points, since we&#8217;re looking at this animation from the side. If you have the inclination, you could move the points instead along the normal for each point, or use a VOP POP to handle the translation in VOPs, but I&#8217;ll stick to the slightly easier-to-understand Position POP. Leave the x and z position values to $TX and $TZ, which are the current coordinates of the particle. For the y position, input the following expression: <code>$TY+chopf("../../chopnet1/CHOP_OUT/waveform",$FF)</code></p>
<p>This expression looks a bit ugly if you&#8217;re not used to using them, but it really isn&#8217;t that complex. We are taking the existing Y-coordinate of each particle, $TY, and adding the value of the channel we created in the CHOPnet at the current frame. The <code>chopf()</code> expression looks for the path to a CHOP channel, which, relative to our current path, is &#8220;../../chopnet1/CHOP_OUT/waveform&#8221;, and then wants a frame, which we set to the current frame as a floating-point value ($FF).</p>
<p>If you try playing the simulation now, you should see your particles being bumped around by the audio channels! Just a few more things to do before the effect is totally finished.</p>
<p>There will be situations where the particles get way too close to each other, especially when the emitter isn&#8217;t moving fast enough. To alleviate this problem somewhat, we can give the particles a sort of electrical charge, forcing them apart. To do this, append an <strong>Interact</strong> CHOP. Set the Particle Radius to &#8220;Use Supplied Radius&#8221; and the Effect Radius to &#8220;Use Supplied Radius.&#8221; The Particle Radius is the virtual radius of the particle, almost like a collision radius. The Effect Radius is a sort of padding around the particle, within which the particle&#8217;s electrical charge can be felt. You can set your own values for the two radii- I used 0.2 for the Particle Radius, and 0.5 for the Effect Radius. The settings will depend on your scene scale and motion. Under the Behavior tab, you can set your Force Multiplier to scale back the repulsion force a little bit, maybe to 0.3 in all directions. Finally, under the Defaults tab, check &#8220;Override Charge&#8221; and set the charge to 1. This means that all particles will have a positive charge, and since particles with similar charges repel (think magnets) the particles will push away from each other if they bunch up too close. The settings on this tab will have to be messed with a bit in order to get good results&#8211; settings that are too high will result in your trails exploding.</p>
<p>Try your simulation now! If the audio bumps are a little too big, try adjusting the final amplitude of your CHOP channel (the post-multiplier in your Math CHOP). If they happen too often or not often enough, check your Envelope CHOP. If they fall off too quickly or start too slow, adjust your Trigger CHOP.</p>
<p>There are a lot of settings to mess with, and it&#8217;s really annoying to have to jump all over your networks to adjust these things, so the next part of this tutorial will show you how to package this whole effect into a single node, with an interface that controls all these parameters in one place. You can then save that node to your own personal library and use it anywhere you like, or share it with other Houdini users. As always, if something doesn&#8217;t work right or if you have any questions, feel free to comment away.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.toadstorm.com/blog/?feed=rss2&#038;p=174</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>motion trails in houdini, part 1</title>
		<link>http://www.toadstorm.com/blog/?p=159</link>
		<comments>http://www.toadstorm.com/blog/?p=159#comments</comments>
		<pubDate>Sat, 14 Apr 2012 00:21:51 +0000</pubDate>
		<dc:creator>toadstorm</dc:creator>
				<category><![CDATA[Houdini]]></category>
		<category><![CDATA[effects]]></category>
		<category><![CDATA[houdini]]></category>
		<category><![CDATA[trails]]></category>

		<guid isPermaLink="false">http://www.toadstorm.com/blog/?p=159</guid>
		<description><![CDATA[I haven&#8217;t posted in a long time mostly because I&#8217;ve been spending the majority of the last month devouring Houdini tutorials on the internet. Houdini is capable of handling incredibly complex visual effects, and its node-based architecture makes it ideal for effects R&#38;D&#8230; if you can get past the learning curve. I&#8217;ve never seen a <a href='http://www.toadstorm.com/blog/?p=159'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I haven&#8217;t posted in a long time mostly because I&#8217;ve been spending the majority of the last month devouring Houdini tutorials on the internet. Houdini is capable of handling incredibly complex visual effects, and its node-based architecture makes it ideal for effects R&amp;D&#8230; if you can get past the learning curve. I&#8217;ve never seen a more complicated-looking program.</p>
<p>Anyways, after beating my head against the wall for the better part of a month I&#8217;ve finally started making sense out of this program, and I want to share an effect I&#8217;ve been researching for an upcoming spot, and turn this into a sort of tutorial for dealing with particle systems, creating objects on the fly, and manipulating shapes using audio. Later on I&#8217;ll also go over how to make the effect into a &#8220;digital asset,&#8221; meaning packaging the effect into a single node with its own interface that you can then use for other shots or share with other artists.</p>
<p>I really dislike video tutorials so I&#8217;m going to try to write this one out. The first segment will be about creating the trails, the second will be about modifying the trails using CHOPs, and the third will be about repackaging the effect as a digital asset and building an interface.</p>
<p>Anyways, here&#8217;s the effect we&#8217;re creating:</p>
<p><iframe src="http://player.vimeo.com/video/40316525" width="616" height="384" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></p>
<p>I realize it kind of all turns to spaghetti in the end, but that could probably be fixed with a little more fine-tuning, and I wanted to show a little complexity to the effect. Hit the jump for a big huge post about how this is done.</p>
<p><span id="more-159"></span></p>
<p>So, how do we make this? I am going to assume you know the very basics of Houdini, like how to make an object and animate it from place to place. If you&#8217;re like me and took a really long time to understand all the &#8220;OP&#8221; lingo, here&#8217;s a quick rundown:</p>
<ul>
<li>SOP = surface operator (a node relating to geometry, in the &#8220;obj&#8221; context)</li>
<li>POP = particle operator (a node relating to a particle network, or POPNet, in the &#8220;part&#8221; context)</li>
<li>CHOP = channel operator (a node that modifies channel information such as an animation curve or an audio clip, in the &#8220;ch&#8221; context)</li>
<li>ROP = render operator (a node that outputs images, geometry caches, etc, in the &#8220;out&#8221; context)</li>
</ul>
<p>There are other OPs (DOPs, VOPs, SHOPs, etc.) but we won&#8217;t be using any of those here. Anyways, back to business.</p>
<p>First, you need an animated shape. I imported an FBX sequence that I had laying around, it comes as a mocap example built into Maya. You could import your own sequence, or just quickly animate a shape from point A to point B in Houdini, it doesn&#8217;t necessarily need to deform.</p>
<p>Once you have your animated geometry into place, it&#8217;s time to build the effect. I like to keep effects in separate geometry nodes, and use the Object Merge SOP to import my necessary source shapes into my effect network. Keeps things separated and clean. Create a <strong>Geometry</strong> scene object, and dive inside. The first thing to do is create an <strong>Object Merge</strong> SOP, and point it to your animated shape. Make sure the &#8220;Transform&#8221; setting is set to &#8220;Into This Object&#8221; so that any transforms are properly inherited.</p>
<p>Next, we need to create velocity information for our animated shape. We want the particles that will form the trails to inherit some of the animated motion. In order to do that, you append a <strong>Trail</strong> SOP, and set it to &#8220;Compute Velocity.&#8221; Now if you look at your point information in the Details View, you should see some information in v[x], v[y] and v[z].</p>
<p>Next, we want to define what points on the geometry are going to emit particles. To do this, we have a couple options: we could manually define a point group using a <strong>Group Geometry</strong> SOP, or we could select a random assortment of points. We&#8217;ll eventually set the network up to do both, but for now let&#8217;s select a fixed number of random points, since it gives us the chance to learn about a few more SOPs. First, we&#8217;ll append the <strong>Sort</strong> SOP in Point mode, with Point Sort set to Random. If you look at the details view and use the Bypass flag (the yellow one) on the Sort SOP to turn it off and on, you&#8217;ll see the point order change randomly according to the Seed parameter. We can adjust the Seed parameter to pick a different grouping of points later on, if we don&#8217;t like what&#8217;s chosen with the default Seed of 0. Once the points are randomized, then we can just take the first few points and define that as our source group for the particles. To do this, append a <strong>Group Geometry</strong> SOP and set it to &#8220;Group by Range.&#8221; We&#8217;ll start with point 0, and end with the number of trails you want, minus 1, since 0 is the first point index. Let&#8217;s start with three trails, so set the end of your range to 2. You can name the group whatever you want&#8230; I&#8217;m calling mine &#8220;randomGroup.&#8221;</p>
<p>One thing you&#8217;ll commonly see with groups is the expression $OS. $OS returns a string equal to the name of the current operator. If your Group SOP is labelled &#8220;myGroup,&#8221; and the Group Name parameter is set to $OS, then your group name will also by &#8220;myGroup.&#8221; It&#8217;s good practice to do this with Group SOPs so that you can quickly see what group is being created without having to actually click on the node and check the parameters.</p>
<div id="attachment_160" class="wp-caption alignleft" style="width: 160px"><a href="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_01.jpg"><img class="size-thumbnail wp-image-160" title="h_trails_tut_01" src="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_01-150x150.jpg" alt="" width="150" height="150" /></a><p class="wp-caption-text">Fig. 1</p></div>
<p>Now we have motion information from the geometry, and a group of points to use as the particle source, so we&#8217;re ready to create the particle network. Append a <strong>POP Network</strong> SOP, with your Group SOP connecting to the first input of the POP Network. Here&#8217;s what the shape network looks like so far (see Fig. 1).</p>
<p>Dive into the POP network. First, we need an emitter. Since we&#8217;re emitting from a group of points on a geometry, we&#8217;ll use the <strong>Source</strong> POP. Set the Emission Type to &#8220;Points (random)&#8221; and the Source Group to &#8220;randomPoints&#8221; or whatever you named your point group earlier. Your geometry source is the &#8220;First Context Geometry,&#8221; which just means &#8220;whatever is plugged into the first input of the POP Network node.&#8221;</p>
<p>Under the Birth tab of the Source POP, we&#8217;ll need to change a few things. We want to emit one particle, per point, per frame. We&#8217;ll use Impulse birth instead of Constant, since it&#8217;s a little easier to emit an exact number of particles per frame this way. Set Constant Activation to 0, and then set Impulse Activation to <code>$FF &gt; 1</code>. This expression means that as long as the frame number ($FF means &#8220;frame number&#8221; as a floating point number) is greater than 1, the expression evaluates as &#8220;True,&#8221; and the Source node will emit a number of particles every frame equal to the Impulse Birth Rate if Impulse Activation is anything other than 0 (or &#8220;False&#8221;).</p>
<p>The Impulse Birth Rate is next. While we could manually set this to be 3 (the same number of trails we want), it will get a little cumbersome later on if we want to change our number of trails and have to update both this number, and the End Range number on the Group SOP we created earlier. So let&#8217;s just reference that End Range parameter using an expression instead. You can go back out of the POP Network, select the Group SOP, right-click the End Range value and select &#8220;Copy parameter&#8221;, then go back to the Impulse Birth Rate, right-click and select &#8220;Paste Copied Relative Reference,&#8221; and then add a &#8220;+1&#8243; at the end, or you can just create the expression manually. Either way, it should look like this: <code>ch("../../randomPoints/rangeend") + 1</code>. The <code>ch()</code> expression evaluates a channel on another SOP, in this case, the randomPoints Group SOP. We add the +1, again, because our point array starts with an index of zero.</p>
<p>Finally, under the Attributes tab, we need to set Inherit Velocity to some small number. Setting it to 1, while it can be physically accurate, is probably going to result in particles flying all over the place if your object moves too quickly, so let&#8217;s start with 0.1 or 0.2 for now. That means that new particles born from a source point will multiply the source point&#8217;s v[xyz] values by this fraction and apply the new value as the initial velocity of the particle.</p>
<p>Next, let&#8217;s add a little bit of gravity. We want the trails to feel as if they&#8217;re underwater, so the force won&#8217;t be too heavy, but a little bit gives the motion a nice touch. Gravity is pretty simple: append a <strong>Force</strong> POP, and set the Y component of the force to be something like -0.1 (actual physical gravity is about -9.8 along the Y-axis).</p>
<p>Now let&#8217;s add a bit of drag, to slow down the movement of the particles. This will really create that &#8220;underwater&#8221; motion effect. Append a <strong>Drag</strong> POP, and leave the Scale at 1.0 for now. Set the Output flag (the blue one) to this Drag POP, and let&#8217;s back out and see what we&#8217;re getting so far. Rewind and play forward for a few seconds or so.</p>
<div id="attachment_161" class="wp-caption alignleft" style="width: 160px"><a href="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_02.jpg"><img class="size-thumbnail wp-image-161" title="h_trails_tut_02" src="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_02-150x150.jpg" alt="" width="150" height="150" /></a><p class="wp-caption-text">Fig. 2</p></div>
<p>Your simulation may vary, but based on what we have here (Fig. 2), we can already notice a few things: the particles are definitely inheriting motion from the source object, and they&#8217;re emitting from random points on the surface, but there aren&#8217;t nearly enough points to define those nice sharp curves we&#8217;re going to need later on, especially when the source object is moving quickly. To get more particles to emit per frame, we&#8217;re going to need to use oversampling. You might think that we could just double or triple the Impulse Activation rate, but all that would mean is more points being emitted all at once, and we actually want to emit particles during sub-frames. The Impulse Activation will actually emit particles every time the operator &#8220;cooks&#8221; (I lied earlier about it emitting per-frame), so if we oversample the particle network, we&#8217;ll get particles emitted according to the motion on during sub-frames as well. Try turning up your Oversampling on the POP Network to 3 or 4, and you should see more particles right away.</p>
<div id="attachment_162" class="wp-caption alignleft" style="width: 160px"><a href="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_03.jpg"><img class="size-thumbnail wp-image-162" title="h_trails_tut_03" src="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_03-150x150.jpg" alt="" width="150" height="150" /></a><p class="wp-caption-text">Fig. 3</p></div>
<p>If you have very fast movement in your object, though, and we&#8217;re emitting particles during sub-frames, we also need our geometry to be evaluated at sub-frames. Otherwise you might notice that particles will be emitted in small, tight groups during fast movement. To calculate the position of deforming geometry at sub-frames, we can use the <strong>Time Blend</strong> SOP. Put the Time Blend right before the Trail SOP in your network. Now your object should be sending out nice, detailed, smooth trails of particles, like the next example (Fig. 3).</p>
<p>Now let&#8217;s try making these points into a line. We need to make a point group out of each line individually somehow, or else we&#8217;re going to end up with a disordered tangle of lines. We need to create an attribute on these points that is somehow unique to each individual point on the emission surface. Fortunately, this is fairly easy, though not obvious. Go back to the <strong>Source</strong> POP, and turn on &#8220;Add Origin Attribute.&#8221; If you rewind and play through a few frames, and then check out the Details View, you&#8217;ll see that each particle has an &#8220;origin&#8221; value between 0 and 2 (or however many trails you&#8217;re creating minus one). We can use this attribute to group each line of points together, though we&#8217;ll have to get this attribute out at the SOP level first.</p>
<p>Go back outside the POP Network and hold middle-click on it. You&#8217;ll see that there is definitely an attribute named &#8220;origin,&#8221; but unfortunately we don&#8217;t actually have access to it yet. Why? I have no idea. Fortunately we can easily gain access to it by creating a new attribute here in the SOP context with the same exact name. Append an <strong>Attribute Create</strong> SOP, and set the attribute&#8217;s name to &#8220;origin.&#8221; Now we can actually refer to this value later on in the network.</p>
<p>Now, to use this origin value to make our groups. There is a very powerful SOP made for just this reason, called the <strong>Partition</strong> SOP. Append this to the network. Set the Entity parameter to &#8220;Points,&#8221; since we&#8217;re making point groups. The Rule parameter is the important one here: it defines how our new groups are going to be named. We want one group for each set of points that have the same &#8220;origin&#8221; attribute. Since we didn&#8217;t set a custom variable mapping for &#8220;origin&#8221; in the AttribCreate SOP, the way to reference that attribute in expressions is just $ORIGIN. The Rule parameter, then, will be <code>linePointGroup_$ORIGIN</code>. If you middle-click the Partition SOP, you&#8217;ll see that a number of point groups will have been created, each named linePointGroup_#, where # is the origin value. So now we have a group for each line of particles!</p>
<p>Now we have to connect the dots. The <strong>Add</strong> SOP has a perfect function for this. Append an Add SOP, and set the top tab to &#8220;Polygons.&#8221; Enable &#8220;Remove Unused Points,&#8221; and set the mode to &#8220;By Group.&#8221; Set the Add mode to &#8220;Each Group Separately.&#8221; Now you just have to define the group name. Since we want one line drawn for each group, we can use a wildcard to send all the groups out at once. Set the Group parameter to <code>linePointGroup_*</code> and you should have solid lines drawn through your points.</p>
<p>Next let&#8217;s convert these lines to NURBS curves. Append a <strong>Convert</strong> SOP and set Convert To to &#8220;NURBS Curve.&#8221; The rest of the settings should be okay at their defaults. Almost there! We want nice, even divisions along this curve for when we turn it into polygon geometry, so let&#8217;s append a <strong>Resample</strong> SOP and set the length to 0.1 or 0.2.</p>
<p>Let&#8217;s do a little cleanup. We&#8217;re going to delete all of the groups we&#8217;ve created so far and make new groups out of the polygon geometry we&#8217;re about to create. Append a Group SOP, uncheck the &#8220;Create Group&#8221; box and switch over to the Edit tab. Under the Delete option, enter * to delete all groups.</p>
<p>Now we&#8217;re going to create some new groups. We have three (or some number) of NURBS curves, and each one is a primitive. Each primitive has its own number, which you can refer to in expressions with the variable $PR. So if we want to make a primitive group out of each curve, we can once again use the <strong>Partition</strong> SOP to group them. Set the Entity to &#8220;Primitives,&#8221; and your rule is <code>linePrimGroup_$PR</code>. We&#8217;ll use these new primitive groups in just a second. First, we have to actually make these curves into geometry.</p>
<p>Append a <strong>PolyWire</strong> SOP. This lofts a circle over the length of each curve. The Wire Radius parameter controls the thickness of the wire, and the Divisions parameter controls the number of sides the circle has. If there isn&#8217;t enough resolution along the U direction of the curve, go back to your Resample SOP and decrease the Length parameter.</p>
<p>Unfortunately, we just lost all of our group information when we created this new geometry, but there is an easy way to get it back. Append a <strong>Group Transfer</strong> SOP. The PolyWire SOP goes into the first input since we are transferring group information TO this object. The Partition SOP just before the PolyWire SOP goes into the second input, which is what we are transferring FROM. The Group Transfer SOP will transfer group information by proximity, so all of the primitives (polygon faces) in each wire will be placed into the same group as the original NURBS primitive.</p>
<div id="attachment_163" class="wp-caption alignleft" style="width: 160px"><a href="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_04.jpg"><img class="size-thumbnail wp-image-163" title="h_trails_tut_04" src="http://www.toadstorm.com/blog/wp-content/uploads/2012/04/h_trails_tut_04-150x150.jpg" alt="" width="150" height="150" /></a><p class="wp-caption-text">Fig. 4</p></div>
<p>That&#8217;s about everything for the first part. If you wanted to export this geometry, you could add a Geometry ROP and export a .bgeo sequence, or try your luck with the FBX exporter. Or, if you have Realflow, or the Realflow plugin for Maya, you can use <a href="http://tmdag.com/Hotl/RF_mesh_exportOTL_v0.6.otl" target="_blank">this OTL</a> to export .bin sequences. Before you export, it&#8217;s not a bad idea to append an <strong>Attribute</strong> SOP to the end of the chain and delete any attributes you don&#8217;t need. For me personally, I deleted everything except the normals by using this string under &#8220;Delete Attributes&#8221; in the Point tab: <code>* ^N</code>. This basically means &#8220;delete everything but don&#8217;t delete N (normals) information.&#8221; Your SOP network, from the POP Network down, should look something like the next example (Fig. 4).</p>
<p>Next up, distorting these trails with audio information using CHOPs!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.toadstorm.com/blog/?feed=rss2&#038;p=159</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>python in maya standalone</title>
		<link>http://www.toadstorm.com/blog/?p=136</link>
		<comments>http://www.toadstorm.com/blog/?p=136#comments</comments>
		<pubDate>Thu, 23 Feb 2012 05:48:57 +0000</pubDate>
		<dc:creator>toadstorm</dc:creator>
				<category><![CDATA[Maya]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[maya]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[subprocess]]></category>

		<guid isPermaLink="false">http://www.toadstorm.com/blog/?p=136</guid>
		<description><![CDATA[I&#8217;ve been working on some tools recently that open groups of Maya scenes in batch mode, running Python or MEL operations on each file (for example, to quickly add a render layer and apply materials to a large group of objects at once, or to get the names of all the references in a scene) <a href='http://www.toadstorm.com/blog/?p=136'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on some tools recently that open groups of Maya scenes in batch mode, running Python or MEL operations on each file (for example, to quickly add a render layer and apply materials to a large group of objects at once, or to get the names of all the references in a scene) and then either returning data or saving the file. This sort of thing could be done in the usual windowed Maya interface, but this is slow and means the user has to sit there and watch Maya open a bunch of files, run operations and all that. Running scripts on lots of files at once is much faster if you&#8217;re running Maya in standalone (&#8220;batch&#8221;) mode.</p>
<p>There are other, more informative posts on how to get Python running in standalone mode (I learned a lot from <a href="http://www.chadvernon.com/blog/resources/python-scripting-for-maya-artists/python-in-maya/" target="_blank">this one in particular</a>), but the gist of it is that you start by running /bin/mayapy.exe, and then initialize the Maya Python interpreter by calling the following function:</p>
<pre class="brush: python; title: ; notranslate">
import maya.standalone as standalone
standalone.initialize(name='python')</pre>
<p>Once that&#8217;s done you can start scripting like normal, starting with <code>import maya.cmds as cmds</code> and working from there. Some commands are not available in standalone mode, especially anything to do with UI.</p>
<p>Anyways, while working on a script that is meant to process huge heaps of unsorted Maya files, I realized that crashes were going to be a frequent problem when opening ancient, broken scenes, so I couldn&#8217;t just load an instance of Maya in standalone mode from a script and let it run through everything in a loop. I needed to be able to process one file at a time, and then either return some useful information if the process is successful, or let me know if Maya crashes so I can avoid that file later on or at least mark it.</p>
<p>To do this, I used Python&#8217;s <a href="http://docs.python.org/library/subprocess.html" target="_blank">subprocess</a> module. Again, I&#8217;m not going to go into a ton of detail about the module, it&#8217;s pretty complicated, but I&#8217;ll give a quick example of how I&#8217;m using it to return information from a Maya process when I am calling the script from Maya (or any other program, really).</p>
<p>Let&#8217;s say I want this script to add a new render layer to several scenes, and add all meshes in each scene to that new layer. First, I&#8217;ll write the script that actually creates the layer and assigns objects.</p>
<pre class="brush: python; title: ; notranslate">
import sys
import maya.standalone as std
std.initialize(name='python')
import maya.cmds as cmds
filename = sys.argv[1]
layername = sys.argv[2]
</pre>
<p>The <code>sys.argv[1]</code> and <code>sys.argv[2]</code> are easy ways to pass variables to an external script. <code>sys.argv[n]</code> just means the nth command line argument, so <code>sys.argv[1]</code> is the first command-line argument when running the script (after calling for the script name, for example, by running mayapy.exe yourScript.py). When we call this script, we&#8217;ll pass it a file to open, and a layer name to add.</p>
<pre class="brush: python; title: ; notranslate">
def addRenderLayer(filename,layername):
    cmds.file(filename,o=1)
    newLyr = cmds.createRenderLayer(name=layername,empty=1,makeCurrent=1)
    meshes = cmds.ls(type='mesh')
    xforms = []
    for i in meshes:
        xf = cmds.listRelatives(i,p=1)[0]
        xforms.append(xf)
        cmds.editRenderLayerMembers(layername,xforms)
        cmds.file(s=1,f=1)
    sys.stdout.write(newLyr)
    return newLyr

addRenderLayer(filename,layername)
</pre>
<p>Here we&#8217;re creating an empty render layer based on the &#8220;layername&#8221; argument, then we&#8217;re getting all the meshes in the scene. In most scenes, people add <em>transforms</em> to render layers, not their individual shape nodes, so we&#8217;ll do this by creating an empty list &#8220;xforms,&#8221; then going through each mesh in a loop and finding their first related transform node (hence the <code>listTransforms(i,p=1)[0]</code> since <code>listTransforms </code>returns a list) and appending it to &#8220;xforms,&#8221; then adding &#8220;xforms&#8221; to the new render layer. Then we just save the file and return the name of the layer (I just like having return values for my functions).</p>
<p>We also write the name of the new layer to <code>stdout</code>. I&#8217;ll go into more detail about this later, but it lets us send information back to the program that calls this script later on.</p>
<p>Save this file as makeNewLayer.py somewhere in your default scripts directory.</p>
<p>Next, we&#8217;re going to make the process that we run from Maya&#8230;</p>
<pre class="brush: python; title: ; notranslate">
import maya.cmds as cmds
import subprocess
# replace mayaPath with the path on your system to mayapy.exe
mayaPath = 'c:/program files/autodesk/maya2011/bin/mayapy.exe'
# replace scriptPath with the path to the script you just saved
scriptPath = 'c:/users/henry/desktop/addRenderLayer.py'
def massAddRenderLayer(filenames,layername):
    for filename in filenames:
        maya = subprocess.Popen(mayaPath+' '+scriptPath+' '+filename+' '+layername,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
        out,err = maya.communicate()
        exitcode = maya.returncode
        if str(exitcode) != '0':
            print(err)
            print 'error opening file: %s' % (filename)
        else:
            print 'added new layer %s to %s' % (out,filename)
</pre>
<p>Okay, a lot going on here. The <code>subprocess.Popen</code> function is calling mayapy.exe with three parameters: first, the script we want to run (makeNewLayer.py) followed by the two arguments that script wants (the filename and the layer name), then the input stream and the output stream which are both set to <code>subprocess.PIPE</code>. I&#8217;m not quite knowledgeable enough about the subprocess module to go into specifics, but basically when you run a process there are three &#8220;streams&#8221;: the input, output and error streams, usually called <code>stdin</code>,<code>stdout </code>and <code>stderr</code>. When you set the input and output streams to <code>subprocess.PIPE</code> when calling <code>Popen()</code>, you can be sure that the process will receive any input stream you give it (which we are not doing here; instead we&#8217;re using the <code>sys.argv </code>method shown above) and also communicate back any output it gives.<br />
The next procedure, <code>communicate()</code>, returns two variables: <code>stdout </code>and <code>stderr</code>. We can use this for debugging or monitoring progress. Normally in the Maya script editor, if your script fails for whatever reason, you will get some kind of (possibly) useful information back from an error. However, you won&#8217;t have any idea what goes wrong with a subprocess unless you are listening to the error stream.<br />
<code>communicate()</code> does a couple other awesome things. First, and most importantly, it waits for the subprocess to complete before continuing with your script. This is REALLY IMPORTANT, as you definitely don&#8217;t want a script like this to continue running until the process is finished. Second, it sets a few variables on the <code>Popen()</code> object, one of which is <code>Popen.returncode</code>. If you have ever slogged through Maya render logs and noticed lines like &#8220;Maya exited with status: 210&#8243; or &#8220;Maya exited with status: 0,&#8221; those numbers are exit codes. Status 0 means the program exited normally; any other exit code means something went wrong. Since I want to be notified if something goes wrong when opening or editing a scene, I check to see if <code>Popen.returncode</code> is anything other than zero, and if it is, I print out the error stream and leave a notice that says something went wrong. If everything worked, I just want to know that it worked, and so I print a string. Since I wrote the output layer to <code>sys.stdout</code>, when I read <code>stdout </code>from the subprocess, I get the name of the newly created layer. I do this since the layer might not come out with exactly the name I wanted if another node in the scene had the same name as the new layer!</p>
<p>I&#8217;ve been using the subprocess module along with Maya standalone more and more as I make more complex applications. It&#8217;s incredibly useful to be able to process many files at a time&#8230; if you get any good ideas, you know where to post them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.toadstorm.com/blog/?feed=rss2&#038;p=136</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>applying displacement in vray</title>
		<link>http://www.toadstorm.com/blog/?p=134</link>
		<comments>http://www.toadstorm.com/blog/?p=134#comments</comments>
		<pubDate>Mon, 30 Jan 2012 23:20:10 +0000</pubDate>
		<dc:creator>toadstorm</dc:creator>
				<category><![CDATA[Maya]]></category>
		<category><![CDATA[Shading]]></category>
		<category><![CDATA[displacement]]></category>
		<category><![CDATA[maya]]></category>
		<category><![CDATA[vray]]></category>

		<guid isPermaLink="false">http://www.toadstorm.com/blog/?p=134</guid>
		<description><![CDATA[I was just talking to a colleague about his problems using displacement maps with VRay, and then remembered my confusion when I first tried to work with them. So here&#8217;s a post about it! Normally in Maya/mental ray, when you want to apply a displacement map you just create a displacement material and connect it <a href='http://www.toadstorm.com/blog/?p=134'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I was just talking to a colleague about his problems using displacement maps with VRay, and then remembered my confusion when I first tried to work with them. So here&#8217;s a post about it!</p>
<p>Normally in Maya/mental ray, when you want to apply a displacement map you just create a displacement material and connect it to the shading group you want displaced. If you want to adjust the amount of displacement, you actually grade the image itself by adjusting the color gain and offset on the file node. It&#8217;s simple, it works, whatever.</p>
<p>You can still apply displacement like that in VRay, but there is a better and more flexible way to handle it using VRayDisplacement sets. They&#8217;re kind of like VRayObjectProperty sets, but they act as a sort of container for displacement settings instead of generic render settings and object IDs. In order to use these sets, you want to select the objects to displace with a single map, and go to <strong>Create &gt; V-Ray &gt; Apply single VRayDisplacement node to selection</strong>. A set will be created, visible in the Outliner.</p>
<p>Next up is to assign a displacement texture to the set. This means you don&#8217;t have to connect a displacement shader to any shading group; the set will handle that connection.  When you select this set, the Attribute Editor will give you just two options: a checkbox saying &#8220;override global displacement,&#8221; and a plug for a displacement material. Check the box on, and then connect a texture to the displacement material (not a <em>material</em>, but a <em>texture</em>). I usually run a file texture through a Luminance node first to make the connection easier (file.outColor &#8211;&gt; luminance.value), unless I&#8217;m using a vector displacement map in which case I&#8217;m using color information instead of just luminance or alpha.</p>
<p>So where are all the displacement options? You have to add them. If you don&#8217;t change anything, the displacement will use the default values set in the VRay render settings under Settings &gt; Default Displacement and Subdivision. This defaults to an edge length of 4 pixels, a maximum subdivision number of 256 (this is <em>a lot of subdivisions!!</em>), and a displacement amount of 1.0 (which is usually way too high). These are terrible values for most scenes, the displacement will look grossly exaggerated and it will take forever to render.</p>
<p>In order to tweak the settings, you need to add the appropriate attributes to the VRayDisplacement set. With the set selected, open the Attribute Editor and select <strong>Attributes &gt; V-Ray &gt; Displacement Control</strong> and <strong>Attributes &gt; V-Ray &gt; Subdivision and Displacement Quality</strong>. Now you have a ton of options to play with, the most important of which are Displacement Amount (color gain), Displacement Shift (color offset), Edge Length, and Max Subdivs. I recommend starting with a displacement amount of 0.1-0.5, and a max subdivs of maybe 16-32 before starting to increase those settings.</p>
<p>I have no idea why these attributes have to be added manually, but hell, it&#8217;s still better than mental ray.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.toadstorm.com/blog/?feed=rss2&#038;p=134</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>pole vector constraint moves joints?</title>
		<link>http://www.toadstorm.com/blog/?p=129</link>
		<comments>http://www.toadstorm.com/blog/?p=129#comments</comments>
		<pubDate>Sat, 28 Jan 2012 00:01:15 +0000</pubDate>
		<dc:creator>toadstorm</dc:creator>
				<category><![CDATA[Maya]]></category>
		<category><![CDATA[Rigging]]></category>
		<category><![CDATA[maya]]></category>
		<category><![CDATA[rigging]]></category>

		<guid isPermaLink="false">http://www.toadstorm.com/blog/?p=129</guid>
		<description><![CDATA[I&#8217;ve been working on a set of tools for making flexible, twistable arms and legs quickly. I haven&#8217;t rigged in a long time, so this has been an arduous process, but I&#8217;ll post notes about what I run into along the way. One problem that I remember having over and over (since I&#8217;ve never rigged <a href='http://www.toadstorm.com/blog/?p=129'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on a set of tools for making flexible, twistable arms and legs quickly. I haven&#8217;t rigged in a long time, so this has been an arduous process, but I&#8217;ll post notes about what I run into along the way.</p>
<p>One problem that I remember having over and over (since I&#8217;ve never rigged frequently enough to ever learn the correct method) is that when applying an IK handle to a joint chain, and then applying a pole vector constraint to that IK handle, the joints can sometimes move subtly. It&#8217;s not always a big deal, but it can be a problem when you&#8217;re trying to have multiple matching skeletons for FK and IK control, and suddenly your rotations don&#8217;t line up anymore.</p>
<p>The fix, as it turns out, is really easy. Before you apply the pole vector constraint, you need to place your controller (whatever is going to drive the pole vector) exactly between the start of the IK chain, and the end effector, e.g., the shoulder and the wrist. This is quickly done by selecting the start and end joints, and then the controller, and creating a point constraint (do not maintain offset). Then delete the constraint. Next, use an aim constraint to point the controller directly at the middle joint (say, the elbow). Delete the constraint. Then you just need to move the controller along its pointing axis a little ways, to push it away from the bones. For example, if your aim vector for the constraint was +X, then push your controller a few units forward in its local X axis. Now you can create the pole vector and the joints shouldn&#8217;t snap at all.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.toadstorm.com/blog/?feed=rss2&#038;p=129</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>gamma-correcting image planes</title>
		<link>http://www.toadstorm.com/blog/?p=124</link>
		<comments>http://www.toadstorm.com/blog/?p=124#comments</comments>
		<pubDate>Sun, 30 Oct 2011 01:31:27 +0000</pubDate>
		<dc:creator>toadstorm</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.toadstorm.com/blog/?p=124</guid>
		<description><![CDATA[For those of you who like to use a linear workflow in Maya, you might notice that once you apply a lens shader (mental ray) or an overall gamma setting (vray) to your scene with gamma 2.2, while your gamma-corrected textures might look great, your image planes will be washed out. This is a pain <a href='http://www.toadstorm.com/blog/?p=124'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>For those of you who like to use a linear workflow in Maya, you might notice that once you apply a lens shader (mental ray) or an overall gamma setting (vray) to your scene with gamma 2.2, while your gamma-corrected textures might look great, your image planes will be washed out. This is a pain when you&#8217;re trying to use a plate as a reference for lighting your scenes. There is a way to gamma correct image planes, but the setup takes a few more steps and it&#8217;s somewhat counter-intuitive. Thanks, Maya!</p>
<p>The first thing to do once you attach an image plane to the camera is to switch the &#8220;Type&#8221; attribute from &#8220;image&#8221; to &#8220;texture.&#8221; Once you do this, you can attach a regular File node to the texture, and set up your image sequence attributes on the file node if you are using a sequence.</p>
<p>The next step is to connect the file node to a gammaCorrect node&#8230; create a gammaCorrect node, set the gamma in all three channels to 0.454 (or whatever the inverse of your current gamma is if you&#8217;re not correcting to 2.2) and then connect the outColor of the file node to the &#8220;value&#8221; of the gammaCorrect node.</p>
<p>The last step is the tricky part. Try connecting the output of the gammaCorrect node to the imagePlane node&#8230; where does it go in the Connection Editor? Maya decided that you, the user, should be sheltered from this most dangerous input, and it&#8217;s been hidden by default. Turn on &#8220;show hidden&#8221; on the right side of the Connection Editor, and then connect the outValue of the gammaCorrect node to the &#8220;texture&#8221; input of the imagePlane.</p>
<p>I don&#8217;t really understand why this has to be so difficult in Maya, but the same could be said about a lot of this program.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.toadstorm.com/blog/?feed=rss2&#038;p=124</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>creating a UV pass for use in post</title>
		<link>http://www.toadstorm.com/blog/?p=117</link>
		<comments>http://www.toadstorm.com/blog/?p=117#comments</comments>
		<pubDate>Thu, 27 Oct 2011 02:05:02 +0000</pubDate>
		<dc:creator>toadstorm</dc:creator>
				<category><![CDATA[Maya]]></category>
		<category><![CDATA[Shading]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[UV]]></category>

		<guid isPermaLink="false">http://www.toadstorm.com/blog/?p=117</guid>
		<description><![CDATA[A lot of After Effects compositors like to use a plugin to allow texture substitution on objects, called Re:Map. You render out a special color pass from your 3D scene, and then the plugin uses those colors to wrap a flat image onto the object, basically allowing you to re-texture in post. A lot of <a href='http://www.toadstorm.com/blog/?p=117'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>A lot of After Effects compositors like to use a plugin to allow texture substitution on objects, called Re:Map. You render out a special color pass from your 3D scene, and then the plugin uses those colors to wrap a flat image onto the object, basically allowing you to re-texture in post.</p>
<p>A lot of people in the past have asked me or others to find the material you&#8217;re supposed to use to render this pass from Maya. There are different ways to make it, but by far the easiest is to just use a place2dTexture node and a surface shader (or a VrayLightMtl, if that&#8217;s your thing).</p>
<p>Connect the place2dTexture.outU &#8211;&gt; surfaceShader.outColorR. Then connect place2dTexture.outV &#8211;&gt; surfaceShader.outColorG.</p>
<p>That&#8217;s it. Apply the material to everything and you&#8217;re done. In VRay, you don&#8217;t even need a material if you want to save a render layer; just create a VrayExtraTex element on your render layer and connect the place2dTexture outputs to the ExtraTex element in the same manner.</p>
<p>The setup is really easy but there are a few things to watch out for. First of all, if your UV&#8217;s are distorted, then any texture you place on it is going to be distorted. So you need good UV&#8217;s. If you&#8217;re using simple rectangular billboards, make sure the UV&#8217;s are normalized (you can normalize UV&#8217;s in the UV Texture Editor). Also, the image quality will suffer if you aren&#8217;t rendering to a floating point file format&#8211; 32-bit floating point images are best to avoid artifacting.</p>
<p>One other subtle thing to watch out for. If you are using a linear workflow when you render (and you should be!) it&#8217;s easy to screw up this render and end up with weirdly warped images. This render should NOT be gamma-corrected in any way, so disable your lens shaders if you&#8217;re in mental ray, and set your gamma to 1.0 and turn off &#8220;linear workflow&#8221; if you&#8217;re in VRay. It&#8217;s hard to see, but take a look at the difference between a linear render of this pass and an sRGB (gamma 2.2) render:</p>

<a href='http://www.toadstorm.com/blog/?attachment_id=118' title='uv_linear'><img width="150" height="150" src="http://www.toadstorm.com/blog/wp-content/uploads/2011/10/uv_linear-150x150.jpg" class="attachment-thumbnail" alt="uv_linear" title="uv_linear" /></a>
<a href='http://www.toadstorm.com/blog/?attachment_id=119' title='uv_srgb'><img width="150" height="150" src="http://www.toadstorm.com/blog/wp-content/uploads/2011/10/uv_srgb-150x150.jpg" class="attachment-thumbnail" alt="uv_srgb" title="uv_srgb" /></a>

<p>The image on the left is the correct one. Using a color-corrected UV pass will cause your substituted textures in After Effects to appear very warped around certain edges.</p>
<p><span style="color: #808080;">(I&#8217;ve made this mistake way too many times.)</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.toadstorm.com/blog/?feed=rss2&#038;p=117</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New job!</title>
		<link>http://www.toadstorm.com/blog/?p=114</link>
		<comments>http://www.toadstorm.com/blog/?p=114#comments</comments>
		<pubDate>Tue, 11 Oct 2011 23:31:27 +0000</pubDate>
		<dc:creator>toadstorm</dc:creator>
				<category><![CDATA[Maya]]></category>
		<category><![CDATA[gentleman scholar]]></category>
		<category><![CDATA[mustache]]></category>
		<category><![CDATA[pipeline]]></category>

		<guid isPermaLink="false">http://www.toadstorm.com/blog/?p=114</guid>
		<description><![CDATA[I recently took a staff position at the up-and-coming Gentleman Scholar Studios in Santa Monica. I&#8217;ll be their &#8220;Technical Director,&#8221; which more or less means I&#8217;ll be doing more of the same old scripting, lighting and materials. Which is totally fine with me&#8230; these guys are gonna be big. Also on a positive note&#8230; the Maya <a href='http://www.toadstorm.com/blog/?p=114'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I recently took a staff position at the up-and-coming <a href="http://www.gentscholar.com" target="_blank">Gentleman Scholar Studios</a> in Santa Monica. I&#8217;ll be their &#8220;Technical Director,&#8221; which more or less means I&#8217;ll be doing more of the same old scripting, lighting and materials. Which is totally fine with me&#8230; these guys are gonna be big.</p>
<p>Also on a positive note&#8230; the Maya pipeline system I&#8217;ve developed here at Scholar, &#8220;Mustache,&#8221; is now fully production-ready, and being used for several simultaneous 3D spots right now! It&#8217;s taken a long time to work out the bugs, and there&#8217;s still plenty more, but it&#8217;s made jobs that would have previously been impossible to manage a comparatively painless procedure. I&#8217;ll be posting more later about the more unique features of Mustache and why nobody here wants to work without it anymore.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.toadstorm.com/blog/?feed=rss2&#038;p=114</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

