BERNARDLEBEL.COM > TUTORIALS > SOFTIMAGE|XSI

Individual Textures On Shared Materials

By Bernard Lebel

 

In XSI, you can share materials using groups, and share textures on these groups using shared texture projections. All this is nice and sweet, but it becomes trickier when you want to share the material but not the textures. You may use weight maps, it will stop working as soon as the objects are animated in space. The technique shown in this tutorial allows you to use individual textures on shared materials.

Download the project folder here.


Initial setup - Adding textures - Partitions and overrides - Final notes


1- Initial setup

Create three primitive. It doesn't matter what primitives you create. Place them next to each other, again, their placement doesn't matter.

 

Select all the objects, and do MCP > Group. This will create a group with the objects.

 

Now we will apply a material. With the group still selected, do Get > Material > Lambert.
This will apply the material to the group, so it is inherited by all the groups members.
You can see this by expanding the group node in the Explorer. The material node will have a little B overlapping, this means that the material is propagated to members.

 

Now we will apply a texture projection, so the objects in the group will receive textures. With the group still selected, do Get > Property > Texture Projection > XY.

As with the material, this will apply a shared texture projection. It will take the form of a texture support placed around all the objects.
However, the texture support will not appear under the group node, but rather under the scene root. Even putting the objects and the group under a model won't change that.


2- Adding textures

We will now add the textures to our objects.
Select the material node, under the group node.
Open the Render Tree.

All we have is a Lambert node connected in a material node. We will add all the textures we need in this Render Tree, and later we will define what object uses what texture.

You can add your own textures, or you can use the three textures included in the project folder (they are pretty low resolution).

First, create a Mix_8colors node (Nodes > Mixers > Mix 8 colors).

 

Connect the Mix_8colors node into the Ambient and Diffuse inputs of the Lambert node.

 

Now, create the Image nodes by doing Nodes > Texture > Image once, then click with the middle-mouse button two times on the Nodes button. This will create two more Image nodes.

Then connect each Image node in the Mix_8colors node, in as shown below:

You could rename the image nodes according to wich object they are intended for. For example, the first Image node could be renamed Sphere, because the texture you'll connect in it will affect only the sphere object. It's up to you.

 

Now will add our textures. Open a floating Browser by hitting 5.
Browse to the Pictures folder, and drag-n-drop the images from there to the Render Tree.

 

Then connect the three texture nodes in the appropriate Image nodes.

 

Now, we need to adjust the Mix_8colors node. Double-click it to open its property page.
First, make sure that Layer 1, Layer 2 and Layer 3 are checked. This will enable the texture we have connected.
Then, put all Weight colors to white, so each layer will be 100% opaque. You can close the property page.


3- Partition and overrides

Now the interesting part begins.
What we are gonna do is to place all three objects in a individual partition, and then build an identical override on each partition. This override will consist of three parameters, all the same type. What they will override is the In Use check box of the Mix_8colors nodes. Then, you'll just need to check the overrides checkboxes to define wich object receive wich texture.

Select the cube, and do Render > Pass > Parition > New. This will put the selected object in a new partition.
Rename this parition Cube.

 

Now do the same with the grid. Click with the middle mouse button on Partition and rename the partition Grid.
Finally, do the same for the sphere, and rename the partition Sphere. You could have simply renamed the Background_Objects_Partition, since it contains only the sphere, but since you may add other objects, you are better to leave it intact and create a dedicated partition instead.

Now open the Script Editor. We will need it for two reasons:
1) There is a bug in the logged command when you add boolean overrides. This bug forces you to modify the command and rebuild the override.
2) This will speed up the overrides creation. We will create the override once, and use the Script Editor to perform the operation on the other partitions.

Oh and before we move on, make sure your scripting langage, in the User Preferences, are set to VBScript.

Select the Cube partition.
Do Get > Property > Override. This will add the override property to the partition.
In the override property page, click on Add Parameters...
Browse in the pop-up Explorer through this path: cube > Material (Group) > Surface > Lambert > diffuse > Mix_8colors > inuse1
Select inuse1, and click outside the pop-up Explorer. This will add an entry to the override.

In the override ppg, you should have something like that:

We were expecting a checkbox, as "inuse" parameters take the form of checkboxes in the interface. But we get this weird thing.
This is because there is a bug in the command that XSI logs, and we have to manually run a corrected command.

So in the upper part of the Script Editor (called the History Log), you should have something like this:

AddProp "Override"

SIAddEntryToOverride "Passes.Default_Pass.Cube.Override", "cube.Material.Lambert.Mix_8colors.inuse1"

For the command to work, we have to add a ,2 at the end of the second line. So with the correction, the command will look like that:

SIAddEntryToOverride "Passes.Default_Pass.Cube.Override", "cube.Material.Lambert.Mix_8colors.inuse1", 2 

To make the correction, select the two above lines in the History Log, then drag-n-drop them onto the Script Editor (the lower part). Then add the characters at the end of the second line.
Now delete the override from the partition, and hit the run button on the Script Editor. This will reapply the override, and then will add the right entry. The resulting override ppg should look like that:

This is exactly what we need. Now, checking this checkbox will enable the first layer of the Mix_8colors node, unchecking it will disable it.

But we are not done yet. What we need is to add a similar entry for each layer the Mix_8colors node has. Scripting will speed up things for us.
Delete the override from the partition.

In the Script Editor, copy the second line two times. All we need now is to changes one character.
In the third line, at the end of the line, change inuse1 to inuse2.
In the fourth line, change inuse1 to inuse3.
The script should look like that:

AddProp "Override"

SIAddEntryToOverride "Passes.Default_Pass.Cube.Override", "cube.Material.Lambert.Mix_8colors.inuse1",    2

SIAddEntryToOverride "Passes.Default_Pass.Cube.Override", "cube.Material.Lambert.Mix_8colors.inuse2",    2

SIAddEntryToOverride "Passes.Default_Pass.Cube.Override", "cube.Material.Lambert.Mix_8colors.inuse3",    2

Now if you run this script, you will get an override with three checkboxes.

Check or uncheck the checkboxes as you want, leave only one checked. The one that is checked will allow the first layer texture to show on the cube.

Now we need to add the same override to the other partitions. We will modify our script.
First, change the Cube words to Grid, since we want to override to affect the Grid partition.
Second, change the .Override to .Override1. There can't be overrides with the same name in a scene.
Third, change the words cube. to grid.

The final command should like that:

AddProp "Override"

SIAddEntryToOverride "Passes.Default_Pass.Grid.Override1", "grid.Material.Lambert.Mix_8colors.inuse1",    2

SIAddEntryToOverride "Passes.Default_Pass.Grid.Override1", "grid.Material.Lambert.Mix_8colors.inuse2",    2

SIAddEntryToOverride "Passes.Default_Pass.Grid.Override1", "grid.Material.Lambert.Mix_8colors.inuse3",    2

Select the Grid partition and run the script. This time, leave the second checkbox checked.
Finally, to do it with the sphere partition, you need to change the script once again, using the same logical approach: Cube and cube becomes Sphere and sphere respectively, and Override becomes Override2.

AddProp "Override"

SIAddEntryToOverride "Passes.Default_Pass.Sphere.Override2", "sphere.Material.Lambert.Mix_8colors.inuse1",    2

SIAddEntryToOverride "Passes.Default_Pass.Sphere.Override2", "sphere.Material.Lambert.Mix_8colors.inuse2",    2

SIAddEntryToOverride "Passes.Default_Pass.Sphere.Override2", "sphere.Material.Lambert.Mix_8colors.inuse3",    2

This time, select the Sphere partition and run the script. Leave only the third checkbox checked.

And we are done! If you render, you'll see that all objects have a different texture, but the same material.


4- Final notes

Texture projections
If you select the group, open the Render Tree, open an Image node, you'll see that you can't assign a projection to anything. The projection drop down menu is empty.
However, if you select any individual object, open the Render Tree, open an Image node, you'll see that you can assign a texture projection. So even if the material is shared, you can assign the textures to each object's own projection. You can also edit this projection in the Texture Editor and even freeze it.

This projection was provided by the projection we originally created at the beginning of this turorial. Now if we freeze the projection on each object, the common texture support will disappear, and each object will have is own explicit UVs.

Texture number
If you have many components of your surface that you'd like a texture to drive, for example, diffuse, specular color, specular decay and so on, then you will multiply the amount of work required. Each component will require a Mix node, and this means one override entry per additional texture. Scripting may save the day.

Object number
If you have a larger number of objects, it becomes more tedious to apply this setup. You will have to create a lot of partitions, and more advanced scripting will become suited for such task. With a large amount of objects, you are better to simply copy the material from one object to another, and change the textures. You can use proxy parameters to link the various parameters of materials together. Also, note that if you apply one material on a large group of objects, the override property pages might become confusing, since you'll have many entries, all named In Use.

Scene exchange
Because the setup require overrides on partitions, saving a material to a .preset file and loading on a new scene or exchanging models between scenes will become tricky. At that point, you will definitely need a good script that rebuilds the partitions with overrides quickly with a minimum of input from you. If scripting is not an option, it is better to put the material on each object instead of sharing it.