Your online Softimage Educational Resource

The blog has been online for more than 4 years and there’s still not a single post even remotely related to the delicious brew called coffee… Perhaps it will someday, but in the meantime you can read the articles about Softimage. Most of the material are tutorials and Q&As I’ve written for 3D World Magazine sometime between today and 2003. If you have any questions please don’t hesitate sending me an email.


Thanks to Letterbox Animation Studios for hosting all the scene files.

Make sure you visit their Redi-Vivus.com for 100s of hours of free XSI video tutorials.

Sunday, July 31, 2011

ICE destruction

Whether it’s alien lasers, judgment day prophecies or just that really cool thingy that will self-destruct messages in five seconds, having a tool that can turn an object into dust for whatever reason can certainly become handy in the VFX demanding times of today. Anyone who has ever worked on a VFX shot knows that the second you start relaying on key framing the effect by hand the chances of the director all of a sudden changing his mind and want it to go in another direction is one hundred percent. And that is if we're being optimistic. So the goal is to design a tool that is flexible enough to change the object getting disintegrated and the factor setting of the effect without relying on you manually setting keyframes.

Prior to the introduction of ICE this would certainly be a challenging task and probably not something you would set up with your computer in the basement. But times have changed and we're now post the introduction so this is exactly what we're going to do.


While the visual nature of ICE makes it a fantastic
tool for prototyping you should at least get the basic concept on paper before going wild in the ICE Tree. There are four main components in creating the effect. The first is to initialize the disintegration. In the following walkthrough you'll be using a simple particle cloud, but this can easily be swapped with any object by replacing a single node. Once initialized, the effect should gradually spread across the surface throwing debris into the air. Rather than tessellating the object to hold an ridiculous amount of tiny polygons and disintegrate them you will use a separate particle cloud to create the debris. There are several reasons why you want to use separate entity for this but the most important is flexibility. The quantity, size, color, etc of the debris can all be changed on the fly without having to revert to the original geometry. But since you're not breaking up the actual mesh it will still be visible in rendered image, so you'll need to create a matte to mask the exact same part of the surface that's being dissolved.


The project files used in this tutorial can be found at:http://dl.dropbox.com/u/3834689/CaffeineAbuse/ICE_Vaporize.zip

STAGE ONE
Initialize the destruction
In the following walkthrough you'll be using a simple particle system, which for your convenience has already been created, to set off the disintegration of the object. This can however be replaced with any other object simply by replacing the Get Initialize_Dissolve node in the ICE Tree with your objects of choice. To set off the disintegration you'll calculate the distance between each of the particles and the surface of the object. If the distance is within the specified threshold, it's a "hit" and the object will start to disintegrate at the exact location of the respective particle. To store the data you'll use a custom attribute, which is declared in a none simulated ICE Tree and evaluated using a simulated ICE Tree. The first frame of your scene is considered to be the initial state and is used to initialize the simulation. As a result no data will be written at this frame. As you'll read data from the simulation, this may cause instability. This is fixed by forcing the simulation to start one frame prior to the scene.

01 Create the ICE Tree
Open the Road_Sign.scn scene. Select the Road_Sign object , press [Alt] + [9] to open an ICE Tree view. From the Create menu choose ICE Tree. Get a Set Data node, open the PPG and enter Self.Dissolve as the Reference. This will create a custom attribute named Dissolve. Rather than using the actual name, the "self" token refers to the object to which the ICE Tree is applied to. Get a Scalar node, set the Value to 0 and connect its Result output the Self.Dissolve input of the Set Data node. Connect the Set Data node to the Port1 of the ICE Tree.

02 Get the point position
From the Create menu choose Simulated ICE Tree. Press [8] to open an Explorer and set the scope to Environments. Click on the Simulation Time Control icon to open the PPG. Uncheck the Use start frame checkbox in the Scene Time section and in the Time Reference section, set the Offset to 0. Change the scope in the Explorer to Scene and drag and drop the Initialize_Dissolve into the ICE Tree. Get a Get Closest Location node and connect the Value output of the Initialize_Dissolve node to the Geometry input of the Get Closest Location node. Get a Get Data node, open its PPG and enter Self.PointPosition in the reference textbox.

03 Calculate the closest points
Connect the Value output of the node to the Position input of the Get Closest Location. Open the Get Closest Location PPG and check the Enable Cutoff Distance checkbox and set the value to 1. This will limit the evaluation of the node to points that are within 1 units from particles. The Get Closest Location node can be used to retrieve a variety of information, but the one you're currently interested in is the points on Road_Sign's surface that are closest to particles.

04 Output the closest points
Get another Get Data node and connect the Location output of the Get Closest Location node to the Source input. Open the Get Data PPG and enter PointPosition as the reference. Note that you're not using the "self" token here. The data you want to get is not the point position of every point of you mesh , but the position of the points retrieved by the Get Closest Location node.

05 Calculate the distance
By subtracting the position of each of these points with the position of the points on the mesh you'll effectively calculate the distance between them. Get a Subtract node and connect the value output of the PointPosition to the First input and the Self.PointPosition to the Second input. The distance it currently exposed as vector values and you want the length of each of these vectors. If the length is less than a specified value that part of the surface has been hit and will start to dissolve.

06 Create a custom attribute
Get a Length node and a Less Than node. Connect the Result of the Subtract node to the Vector input of the Length node and the Result of the Length node to The First input of the Less Than node. Open the PPG of the Less Than node and enter 1 as the Second value. Get a Set Data node, open the PPG and enter Self.Dissolve as the reference. This will create a custom attribute named Dissolve and store whichever information feed into it.

07 Setting the value
Get a Scalar node, set its Value to 0.5 and connect the Result output to the Self.Dissolve input of the Set Data node. Before finalizing the branch it's important to understand how the graph is evaluated. While you could use the length directly to set the Dissolve value it wouldn't give the expected result. The ICE Tree is evaluated from left to right and from top to bottom. This means that the distance between the particles and the surface will be calculated at every frame , and since the their distance changes at every frame, so would the Dissolve value.

08 If statement
The only thing you're interested in is if the distance between the points and particles are within one unit (the value specified in the Less Than node) or not. If it is you want to set the Dissolve value and initialize the disintegration. If it's not, you're really not interested and you don't want to do anything. Get a If node. Connect the Result output of the Less Than node to the Condition input and connect the Execute output of the Set Data node to the If True input. Connect the Result output of the If node to the Port1 input of the ICE Tree.


STAGE TWO

Growing the Dissolve value over time
The Dissolve attribute just created is essentially what controls the entire effect. A value of 0 and the surface is intact, whereas a value of 1 means the surface is completely disintegrated. To gradually increasing the value from 0 to 1 you need to get the current value and add to it. However, you can't start adding the same value to all of the points as this would disintegrate the entire surface simultaneously. So you first need to determined if the disintegration has been initialize and if so, on what location on the surface. Once you have that information you can get the neighboring points of that location and making the Dissolve value spread from there.

09 Get the neighbors
Get a Get Neighbors node and a Get Data node. The Get Neighbors node will return an array, which is essentially a collection of objects or values, of the position of the connected points. In this scenario it will return a list of the position of each of the points on the geometry and their respective Dissolve value. Connect the Points output of the Get Neighbors to the Source Input of the Get Data node.

10 Calculating the array average
Open the Get Data PPG and enter Dissolve as the reference. Since you know all the points position and their individual Dissolve value you can also get the surface average Dissolve value. Get an Get Array Average node and connect the Value output of the Get Dissolve node to its Array input. By calculating the average Dissolve value of the neighbor and adding it to the current value you'll get a new Dissolve value.

11 Blending the values
Get a Get Data node and enter Self.Dissolve as the Reference. Then get a Blend node. The Blend node will output the sum of the values you feed in to it. As described earlier the ICE Tree is evaluated at each frame. By blending the current Dissolve value of each of the points with the average of their neighbors, their individual Dissolve value will increase for each frame of the animation. This will result in the Dissolve value spreading across the surface over time.

12 Increase over time
Connect the Value output of the Self.Dissolve to the Value1 input of the Blend node and the Result output of the Get Array Average node to the Blend node's Value2 input. Since you're adding the burn value of the current frame on top of the value of the previous frame, theoretically the value will eventually increase it to infinitive. While this surely could be an interesting way of passing time it's not very useful in this situation.

13 Clamping the values
You only need to know if a point is completely dissolved, not at all or somewhere in between the two. Get a Clamp node and connect the Result output of the Blend node to the Value input of the Clamp node. Open the Clamp node's PPG and set the Limit 2 to 1. Get a Set Data node and enter Self.Dissolve as the Reference. Connect the Result of the Clamp node to the Self.Dissolve input of the Set Data node and the Execute output of the Set Data node to the New(Port1)... input of the ICE Tree.


STAGE THREE

Creating the debris cloud
The sole purpose of the cloud is make it appear as if it's the actual surface that is disintegrating and getting the initial state is the key to success. One of the problem you're facing is how to emit the particles. If you open the Emit from Surface PPG you'll see that the Particle Emission Rate Type is set to Number of Particles Per Second. While this is precisely what you want, there is a slight problem with it - it will emit particles from the entire surface for the entire duration of the animation. But what you want is to emit particles only from the specific area and at the exact time it's being dissolved. Once that part of the surface is dissolved the emission must stop.

14 Apply a texture map
Make sure you have the Road_Sign object selected, and from the Get > Property > Texture Map menu choose Texture Map. The texture map enables you to control parameters in the scene, such as the particles color, using an image file. In the clip section of the PPG, click the New button and choose the RoadSign_TextureMap image on the disk. You also need to specify a projection to use, so in the UV Property section, select the UV_Texture_Projection.

15 Create the debris cloud
From the Get > Primitive > Point Cloud menu choose Empty and name it Debris. With the pointcloud selected, click the Refresh button in the ICE Tree View to update it and from the Create menu choose Simulated ICE Tree. Get a Emit from Surface node and connect its Emit output to the Port1 of the ICE Tree node. Press [8] to open an Explorer and drag and drop the Road_Sign object into the ICE Tree. Connect the Value output of the Road_Sign node to the Emitter1 input of the Emit from Surface node.

16 Emit particles
Open the Emit from Surface PPG Change the Shape to Disk. These will essentially act as points but allows you to set a size. Set the Rate to 50 000 or so and the Size to 0.05. For the final render you'll need to increase the Emission Rate to a couple of millions and decrees the Size even further. Note that the rate is the number of particles emitted per second and not the actual count of particles. For the purpose of interaction it's recommended that you keep it rather low while you're trying out the different settings.

17 Propagate the Dissolve value
Get a Get Data node and enter Self.EmitLocation as the reference. As the name might imply, the node enables you to retrieve data from the exact location where each particle is emitted. Get another Get Data node and enter Dissolve as the Reference. The Get Data node remains red cause the attribute Dissolve is associated to the Road_Sign and doesn't mean anything to the particle cloud just yet. Connect the value output of the Self.EmitLocation node to the source input of the Get Dissolve node.

18 Filter the emission
With the Dissolve value being propagated to the particles, you can use the value to filter the emission. If the Dissolve value is 0, the location is still intact and therefore shouldn't emit any particles. The same goes if the Dissolve value is 1, but for the reason that the location is completely dissolved so there's no surface left to disintegrate. Get a In Range node and connect the Value output of the Get Dissolve node to its Value input.

19 Setting the in range
Open the In Range PPG and set the Min to 0.1 and the Max to 0.9 to maximize the emission span. Get a Not node and a Delete Point node. Connect the Result output of the In Range node to the Value input of the Not node and Result output of the Not node to the Deleted input of the Delete Point node. Any particles that are not within the range specified in the In Range node will get deleted.

20 Delete unwanted points
Connect the Delete output of the Delete Point node to the Execute on Emit1 input of the Emit from Surface node. As the branch is executed at the time of emission, it will only affect the particles being emitted at that exact point in time. Any particle being emitted prior or after that will not be affected. This will drastically reduced the number of actual particles even if the Emission Rate is high, which is why you need to really crank it up for the final render.

21 Getting the point normals
If you were just emitting points the rotation of the particles wouldn't matter since they're, well, just points. But if you're emitting any other shape or object, it's vital that they are correctly align with the surface they're emitted from. Get a Get Data node, enter PointNormal as the Reference and connect the Value output of the Self.EmitLocation to the Source input of the Get PointNormal node. If you know the point normal you can convert it to a rotation value which can then be used to set the particles orientation.

22 Set Particle Orientation
Get a Direction to Rotation node and a Set Particle Orientation node. Connect the Value output of the Get PointNormal node to the Point At input of the Direction to Rotation node and then the Rotation output of the Direction to Rotation node to the Orientation input of the Set Particle Orientation node. And finally, the Execute output of Set Particle Orientation node to the New(Execute on Emit1)... input of the Emit from Surface node.

23 Set the particle color
The final piece of information you want to retrieve from the EmitLocation is the color value. Get a Get Texture Map Color node and a Set Particle Color node. Connect the Value output of the Get Self.EmitLocation to the InputLocation of the Get Texture Map Color node. Then connect its Color output to the Color input of the Set Particle Color node. Connect the Execute output of the Set Particle Color node to the New(Execute on emit1) input of the Emit from Surface node.

24 Set particle age limit
As the Road_Sign dissolves into tiny debris you'll eventually want them to disappear into thin air. This is done by giving each particle a unique age limit and then altering their size as a percentage of their lifespan. Get a Set Particle Age Limit and connect the Execute output to the New(Execute on emit1) of the Emit from Surface node. Get a Turbulize Value by Range node and connect the Value output to the Age Limit input of the Set Particle Age Limit node. Open the Turbulize node and set the Min Value to 3, the Max to 5 and increase the Turbulence Scale to 0.5.

25 Change the size by age
Get a Get Data node and a Set Data node. Enter Self.Size as the reference for both of them. Get a Modulate Value by Age Percentage node and connect the Value output of the Get Self.Size to its Base Value input. The default shape of the f-curve will keep the particles at their initial size when they're born and gradually scale them to zero as they reach the end of their life. Connect the Value output of the Modulate node to the Self.Size of the Set Data node and the Execute output of the Set Data node to the New(Port1)... input of the ICE Tree node.

26 Adding forces
Get an Add Forces node and connect its Execute output to the New (Port2)... input of the ICETree node. Get a Turbulize Value by Range node and connect it to the Force1 input of the Add Forces node. Open the PPG and change the Min Value for all three axis's to -3, the Max Value to 3 and increase the Turbulence Scale to 5. Check the Animated checkbox and set the Animation Speed to 0.5 and the Complexity to 10. The turbulence will scatter the particles randomly in all direction but you also want to push them away from the Road_Sign.

27 Simulate the particles
Get a Wind force and Connect it to the New (Force1)... input of the Add Forces node. Open the Wind Force PPG and set the Wind Direction to 0 on the X axis and to 1 on the Y. For the forces to work you need the ICE Tree to be simulated, so get a Simulate Particles node and connect it to New (Port3)... of the ICETree. As the particles reach the end of their life they won't be visible anymore , so you might as well delete them. Get a Delete Particle at Age Limit node and connect the Execute output to New (Port4)... of the ICETree.

STAGE FOUR

Preparing the scene for rendering

Whether to render the individual elements in different pass to composite and revel them with mattes in post production comes down to the complexity of the scene and what want do with it. In most everyday situation (if there is such a thing in VFX shot) you can save yourself the extra steps by incorporating the matte inside the material. The dissolve value created in the ICE Tree can easily be passed on to the Render Tree as well. By using an additional gradient you can then fine-tune the falloff to sharpen the edges of the transparency.

28 Shading the particles
With the Debris cloud selected, from the Get > Material menu choose Blinn and Press [7] to open the Render Tree. The particles have already been assign their individual colors in the ICE Tree, so you just need to retrieve that information and plug it into the shader. Get a Color Attribute node, open the PPG and set the Attribute to color and connect it to the Ambient and Diffuse input of the Blinn.

29 Add a weight map
Select the Road_Sign and from the Get > Property menu choose Weight Map. Open the ICE Tree for the Road_Sign. Get a Get Data node and enter Self.Dissolve as the reference. Get a Set Data node. Open the PPG and enter self as the reference before clicking the Explore button. In the tree, expand the Polygon Mesh > Clusters > WeightMapCls > Weight_Map and select the Weights node. Connect the Get Self.Dissolve value to the Weights input of the Set Data and the Set Data to New (Port2)... of the ICETree.

30 Create a matte
With the Road_Sign still selected, press [7] to open the Render Tree and get a Scalar Map Lookup node. Open the PPG and select the Weight_Map(WeightMap) as the Map. Rather than animating the transparency of the surface (which would require raytracing) you can make use of the Sprite shader. Get a Sprite shader and connect it to the Surface and Shadow input of the Material node. Open the PPG and change the Stencil Mode to Intensity and check the Enable Matte checkbox. Then connect the Blinn to the Input of the Sprite node. From the Mixers category (important), get a Gradient node and connect the Scalar Map Lookup to the input of the Gradient node and the gradient to the matte input of the Sprite node. Open the Gradient PPG and click the White/Black preset button. This will get the values from the weight map and use these as a matte for the Road_Sign surface.


Read the full post>>

Tuesday, July 5, 2011

Create dimples when particles collide with the surface

Just a few years ago (or versions of Softimage if you will) this type of effect would require a fair amount of time and patience and certainly wasn’t something you would whisk together in three little steps. By using ICE there’s actually very little information you need to extract from the scene in order to create the dimples. You obviously need to find the whereabouts of the particles and the points on the geometry you want to dent but that’s about it.


The project files used in this tutorial can be found at:http://dl.dropbox.com/u/3834689/CaffeineAbuse/Dent_by_particle.zip

Extract particle’s positions
Open the scene Dent_Geometry_by_Particles.scn from this issues CD. Select the grid and press [Alt] + [9] to open an ICE Tree. From the Create menu choose Simulated ICE Tree. Press [8] to open an Explorer and drag and drop the PointCloud into the ICE Tree. Get a Get Closest Location on Geometry node and a Get Data node. Connect the [PointCloud]:Value —> Geometry1:[Get Closest Location on Geometry]. Open the Get Closest Location on Geometry PPG and set the Cutoff Distance to 0.5. Connect [Get Closest Location on Geometry]:Location to the Source:[Get Data]. Open the Get Data PPG and type PointPosition as reference. The next step is to extract the position for each point on the grid and calculate the distance between the grids points’ position and the particles.
Control the magnitude
Get a Get Data node and type self.PointPosition as reference. Get a Get Distance Between and a Rescale node. Connect [Get self.PointPosition]: Value —> First:[Get Distance Between] and [Get PointPosition]:Value —> Second:[Get Distance Between]. Connect [Get Distance Between]: Result—> Value:[Rescale] and open its PPG. The Rescale node will be used to control the magnitude of the dents. A high value will make the effect of the collision more severe whereas a low value will make it more subtle. The output of the Get Distance Between node is a positive value which means you’ll need to invert it to push the geometry inward rather than outwards. Change the Target End value to -0.35.
Deforming the geometry
Get a Get Data node and set the reference to self.PointNormal Get a Multiply by Scalar node. Connect [Get self.PointNormal]:Value —> Value:[Multiply by Scalar] and [Rescale]:Result—> Factor:[Multiply by Scalar]. This will determine the in which direction the points will be pushed. Get another Get Data node and set the reference to self.PointPosition. Get an Add node and connect the Value output of the [Get self.PointPosition] to the Value1 input of the [Add] and the Result [Multiply by Scalar] to the Value2. Get a Set Data node and set the reference to self.PointPosition. Connect [Add]:Result —> self.PointPosition:[Set Data node] and [Set Data]:Execute —> Port1:[ICE Tree]


Read the full post>>

Wednesday, June 15, 2011

Procedural orange skin

There’s a vast variety of oranges and citrus fruits, each with their distinguished color, shape and texture. But they can all be created using the same basic set of nodes.
Open the scene orange.scn, select the Orange and press [7] to open a Render Tree. From the Nodes > Texture menu get a Cell Scalar node and open its PPG. Many of the changes made to the nodes are subtle and may be hard to see solely relying on the shaderball. To get a better view of how the values affect the output you can temporary connect the current node directly to the Surface input of material node and draw a render region in the viewport. Change the Fill Color to 0 (zero) and the Border color to 0.8 to create the first set of dark dimples. Increase the Minimum Contrast to 0.35 and the Maximum to 0.65 to give it a more circular shape and lower the Bias to 0.1 Switch to the Texture Support tab. Change the Pre-Scale to Small Noise and set the Scale to 1.5

Get a new Cell Scalar node and set the Fill color to 0 and the Border color to 0.8. Change the Min to 0.3, the Max to 0.8 and the Bias to 0.1. Switch to the Texture Support tab. Set the Pre-Scaling to Small Noise and the Scale to 0.75. From the Nodes > Math menu, get a Scalar Basic node (leave the default math Operation at Add) and connect the first Cell_Scalar node to input1 and the second to input2. Get another Scalar Basic node and connect the first scalar math node to input1 and open the PPG. Set the Input 2 value to 2 and change the Operation to Divide. By first adding the two cell’s value and then dividing them you’ve effectively calculated the average of the two.

From the Nodes > Mixers menu get a Gradient node. Connect the output of the Divide node to input of the Gradient node and open the PPG. Click the Black/White Preset button to remove all but two markers. Change the color of black marker to a medium orange color, such as R:0.07, G:0.47, B:0.85. Set the color of the white marker to a slightly brighter more vivid orange, R:1, G:0.6, B:0.

Get a Cloud node (Nodes > Texture Generators) and a Texture Space Generators node (Nodes > Texture Space Generators). Open the Texture Space Generator PPG and select the Spatial projection. Close the PPG and connect it to the coord input of the 3D_Cloud and open the Cloud PPG. Increase the Level Decay to 0.85 and the Frequency Multiplier to 3. Set the Color 1 to a vivid orange R:0.9, G:0.61, B:0 and Color 2 to a somewhat darker R:0.92, G:0.45, B:0.1. Get a Mix 2 Colors node (Nodes > Mixers), open the PPG and set the Weight to RGBA: 0.35. Connect the 3D_cloud to the base_color input and the Gradient to the color1 input.
Connect the Mix_2colors node to the Ambient and Diffuse input of the Blinn node.

Get a Fractal Scalar node (Nodes > Texture) and open the PPG and set the Contrast Clamp Minimum to 0 and the Maximum to 1. Switch to the Noise tab and increase the Recursion Level to 5. Set the Scaledown to 3.3 and the Gain/Smooth to 1.5 and close the PPG. Get a Bumpmap node (Nodes > Bump) and connect the Fractal_Scalar node to its input. Open the PPG and set the Bump Scale to 0.05 and the Sample Spacing to 0.005. Get another Bumpmap node and set the Scale to 0.025 and the Sample Spacing to 0.015. Connect the Divide node to the input of connect the previous bumpmap node to its bump input. Connect the Bumpmap node to the Bump Map input of the Material node.

The project files used in this tutorial can be found at:http://dl.dropbox.com/u/3834689/CaffeineAbuse/OrangeSkin.zip
Quick tip
While you have the dimples in place you do need a touch of sub surface scattering to sell your orange. Get a Fast Sub-Surface Scattering node (in the Illumination category) and connect the Gradient node to the Diffuce_Color input. Connect the SSS node to the Material input of the Material node.


Read the full post>>

Tuesday, May 31, 2011

Using individual textures in shared materials

The texture maps, which hold both the actual texture and the UV Coordinates, are assigned directly to the object.

The reason you apply the same material on multiple objects in the first place is usually because you want them to be exactly the same. That’s pretty much the definition of sharing the very same material. With that being said, let’s discuss how you can setup a shared material but still being able to control parts of it on a per object basis. While this answer confines to using an individual texture, there’s nothing stopping you from adding additional individuality. But then again, if you really want completely different appearance for each and every object you’re probably better of using separate materials in the first place.

Start by opening the scene tubes.scn from this issues DVD. Select the first tube, tube_No1, and from the Get > Material menu choose Blinn. Select the other two tubes and from the Get > Material menu choose Assign Material and pick the first tube to assign the same material. Select the first tube again and from the From the Get > Property > Texture Map menu choose Texture Map. In the Clip section of the Texture Map PPG, click the New button and select New From File… from the menu. Brows to the project folder on the DVD, select the tube_No1.pic image and click OK. In the UV Property section, click the drop down list and select the Tube_UV. Close the PPG. Texture Maps are commonly used to control specific parameters in a scene, such as hair color, particle emission or restricting the areas affected by deformers, using an image. And as such they’re generally not used to actually texture an object. The main difference between the ‘traditional way’ of using an image node in the Render Tree and using the texture map is that the texture map property sits on the geometry/object rather than being part of the material. Repeat the same procedure for tube_No2 and tube_No3 but choose their respective image.

Select any of the tubes and press [7] to open a Render Tree. From the Nodes > Map Lookups menu choose Color. The color map lookup node enables you to extract different types of data from the object, such as a texture map, and use it as a color value in the Render Tree. In the Map_lookup_color PPG, click the Map dropdown list and choose Texture_Map. The texture map lookup of the material is shared between all the objects but since their actual texture maps are unique, they will get assigned an individual texture. Connect the Map_lookup_color node to the Diffuse and Ambient input of the Blinn node.

The project files used in this tutorial can be found at:http://dl.dropbox.com/u/3834689/CaffeineAbuse/Individual_Textures_Shared_Materials.zip

While the texture maps are commonly used to control attributes of an operator rather than using it as an actual texture, there is no reason it can’t be used as such.

Quick tip
An object isn’t limited to using a single texture map, so for additional images such as bumpmaps, simply add a second texture map with respective images and a Color Lookup to use it in the Render Tree.


Read the full post>>

Tuesday, March 15, 2011

How to offset point position in ICE

In order to offset the particles along their individual axis’s you need to determine their current position and in witch direction they’re oriented.

Start a fresh scene and from the Get > Primitive > Polygon Mesh menu choose icosahedron (any dummy object will do) and set the Geodesic Frequency to 4 to make it a bit smoother. With the icosahedron still selected, press [4] to switch to the Simulate toolbar and from the ICE > Create menu choose Emit Particles from Selection. With the pointcloud selected, press [Alt]+[9] to open an ICE Tree.

Open the Emit from Surface PPG and change the Rate type from Number of Particle per Second to Total Number of Particles and Size to 0.5 or so. By default, the shapes of the points are set to (which may not be totally unexpected) just points. While this is sufficient to determine their position, there’s no way to tell their size or in which direction they’re oriented. So for clarity, change the Shape to Cone. In the Orientation section of the PPG, check the Align to Surface Normal checkbox.

In order to offset you need to extract their current position, which direction they’re oriented and then add the offset along their respective axis. For this to happen, you’ll need to add a few nodes. Get a Get Closest Location on Geometry node, a Multiply by Scalar node, an Add node, a Get Point Position node and finally a set Point Position node.

Start by connecting the Get icosahedron node to the Geometry1 input of the Closest Location on Geometry node. There’s a lot of information that can be extracted from this node, but the one you’re currently interested in is the normal or direction. So connect the Normal output to the Value input of the Multiply by Scalar node and the Multiply by Scalar node to the Value2 input of the Add node. The add node will obviously add a value but you first need to too tell it what it should be added to, which is the original position of each point. So connect the Get Point Position to the Value1 of the Add node. While the ICE Tree is just about finished it will not have any effect on the actual could just yet, as you haven’t told it what to do with the information. Connect the Add node to the Position input of the Set Point Position node and connect the Point Position node to the Port2 Input of the ICE Tree node. The node controlling the actual offset is the Factor value in the Multiply by Scalar node. While you can control it directly in its PPG, it will be far easier to “read” your tree if you use a separate node. Get a Scalar node and connect it to the Factor input of the Multiply by Scalar node. Open the Scalar PPG and set your desired offset.

The project files used in this tutorial can be found at:
http://www.redi-vivus.com/Caffeineabuse/Offset_PointPosition.zip

If your different sizes particles and want compensate for it, you can use a second Add node and add the particle size to the scalar value before connecting it to the Factor input.

Quick tip
Your ICE Tree currently lives in the Simulation Stack which means your offset will be applied every frame. To avoid this you can move the ICE Tree to any of the other stacks, such as the Animation. Press the right arrow in the ICE Tree menu to display the Explorer and drag and drop the ICETree operator to any of the stacks below the Simulation.


Read the full post>>

Friday, February 18, 2011

Stretchy bones in ICE

If the distance between the root and the effector is greater that the sum of the length of the bones the chain should stretch.

Open the scene Stretchy_Bones from this issues DVD. Select the Stretchy_Bones null object and press [Alt] + [9] to open an ICE Tree. From the Create menu choose ICE Tree to create an empty ICE Tree. The idea of stretchy bones or limb stretching is quite simple. If the distance between the root and the effector is greater than the sum of the bones, the bones should stretch. But if the distance is less, the bones should stay unaffected at their default length.

Get a Get Data node and double-click on it to open its PPG. Click the Explorer button and expand the tree root > Kinematics > Global Transform and select the Pos. Get a second Get Data node and type eff.kine.global.pos in the Get Data textbox to get the position for the effector as well. The next step is to calculate the distance between the two objects, so get a Get Distance Between node. Connect the root.kine.global.pos node to the First input of the Get Distance Between node and the eff.kine.global.pos node to the Second input.

Get a Scalar node, open its PPG and enter 4 as the Value. This will set the default length of the First_Bone. Get a second Scalar node and set its value to 3. This will be the default length of the Second_Bone. Get an Add node and connect the first Scalar node to its Value1 input and the second Scalar node to its Value2 input.

Get a Greater Than (>) node, an If node and two Divide by Scalar nodes. Connect the Get Distance Between node to the First input of the Greater Than node and the Add node to the Second input. Connect the Greater Than node to the Condition input of the If node.

To set the new length for each bone you must first determine the ratio of the individual bone’s length and the distance of the root and effector. Connect the Add node to the Value input of the first Divide by Scalar nodes and the Scalar node (with the value 4) to the Divide By input. Then connect the Divide by Scalar node to the Divide By input of the second Divide by Scalar node. Connect the Get Distance Between node to the Value input. Connect the Divide by Scalar node to the If True input of the If node. Connect the Scalar node (with the value 4) to the If False input.

Get a Set Data node and connect the If node to the Value input and open its PPG. Click the Explorer button and expand the Root > Bone > Chain Bone and click the Length. Connect the Set Data node to the Port1 input of the ICE Tree.

To set the length of the Second_Bone repeat the procedure, but use the second Scalar node (with the value 3). Please use the screenshot as reference.

The project files used in this tutorial can be found at:
http://www.redi-vivus.com/Caffeineabuse/Stretchy_Bones.zip


To calculate the new length for each bone you must first determine the ratio of the individual bone’s length and the distance of the root and effector.

Quick tip
The technique used is by no means limited to two bone chains. To use more bones simply add the corresponding Scalar nodes to the Add node, use the Divide by Scalar to get the division factor and connect it to the Set Data node.


Read the full post>>