Tutorial: Offsetting Texture Scale Using Vertex Painting
I had a problem last week. I needed to be able to vary a texture from a straight grid to one of variable sizes. I had considered using a larger texture, but when your surface area as large as mine was, it became clear that I’d be using a 4096 x 4096 or larger. So instead I looked to using vertex painting to vary the texture size and thus, breakup the design. The result is a vertex material that can vary the size of the texture using a single vertex color channel.
Part I: The setup & forward logic chain
Before I setup the material i’d like to explain some of the logic I used here. In order to use vertex painting to modify UV coordinates, the values need to be clamped to ranges. This way we can paint at several different intensities between 0.0 and 1.0 and get different sizes without warping the UV’s. I decided to use 0.25, 0.5 and 0.75 as both my painting ranges and my UV multiplication values. This means the brighter the paint color, the smaller my UV multiplier would be set making my image scale larger.
I started with a vertex color node and my clamp / multiplier constants of 0.25, 0.5 and 0.75. Two extra constants of 1 and 0 are added, and their purpose will be explained along the way. I also setup a test constant to manually plug numbers into for testing/demonstration purposes (when we are finished, it will be replaced with the vertex color node.)
Next we’ll setup a basic IF statement. Be sure to activate the box in the upper left corner of the If node to turn on real time display. Plug our test constant into the A slot and 0.25 into the B slot.
Now lets go over the logic of how this node works into our setup. We want to make sure anything below our smallest value, .25 in this case, doesn’t have anything done to its UV’s. The logic works like this: If the vertex color is less than 0.25, the end result will be 1 or no UV change. If the vertex color is greater than or equal to 0.25, the output will be zero, or off. Now this may seem weird that we’re using zero as an output, but this will make more sense in the next section. Plug zero into the A>B result slot and 1 into the A=B and A<B result slot.
As it stands now, if we paint a any value in our channel from zero to .24, we will multiply that UV section by 1, which will do nothing to scale our UV’s. Now lets add 3 more If nodes and get to building the rest of this chain.
Now we want to build our low range. Plug the test constant into the A slot. We want to see if the vertex color is greater than 0.25, so plug 0.25 in to the B slot.
As the If node’s comment indicates, we want anything between 0.25 and 0.54 to scale our UV’s by 0.75. This will make our scale 3/4th’s the size of the original. Therefore the logic for this node is if our vertex color is greater than or equal to 0.25, the end result will be 0.75. If the vertex color is less than 0.25, the end result will be zero or off. Plug 0.75 into the A>B slot and A=B slot and zero into the A<B slot.
Now if we dial our test constant up to 0.255, we can see the if nodes we connected change.
Next we’ll need to setup our mid and high range together. These sequences will have exactly the same logic as our low range sequence, making them easier to do. We’ll start by plugging our text constant into the A slot of the remaining two IF nodes. Plug 0.5 into the B of the Mid Range If node and 0.75 into the B of the High Range If node.
Since the logic the thee nodes is exactly the same, we can repeat the same pattern as the Low range if statement, we can plug up the nodes in exactly the same sequence. We’ll start by connecting zero to both of the A<B result slots.
Now we’ll connect up the remaining slots. Since 0.5 is the mid tone range starting point and the multiplier, it makes our life easy. Connect .5 to the A>B and A=B result slots. This will declare that when painting 0.5 or greater, that 0.5 will be our end result. The high range works exactly the same way, except we’re looking for a paint range of 0.75 or greater and using 0.25 as our end result. Connect 0.25 to the A>B and A=B result slots.
Dial up the test constant to 0.555. See how the midtone range value turns on? When we set the value to 0.755 the top if statement will change as well.
Part 2: the inverse logic chain
Now that the first part of the chain is complete, let me explain how the rest of this will work. Reset the Test Constant value to zero. See how the bottom if statement turns white while the rest go black? We’ve built up a clamping situation where as the vertex color increases, it activates the ranges in the if nodes of our forward logic chain outputting our ranges instead of zero. The problem now is only the bottom node works properly. The other three all turn on once their range is hit, but once their range is surpassed by another range there isn’t anything turning them off. This is where the inverse logic chain comes into play.
We’ll start by placing two more If nodes. This is because we’re only really interested in being able to turn off the Low and Mid ranges. The No-Paint Range node already works and nothing exceeds the high range.
For demonstration sake, I’ll set my Test Constant value to 0.555 . Connect it to the A slots of the two new if nodes. Connect the zero node to the A>B slots of both of the if nodes as well. This will make sense momentarily when we connect up the rest of the inputs.
We’ll start by going over the logic for the If node in the Low Range Check. Since both nodes are active, we want is to turn off (or black) the low range once it exceeds 0.54. To do this, we’ll be comparing this if node against the vertex color input and 0.5. If the vertex color is greater than 0.5, turn it off (or black.) If the vertex value is less than or equal to .5, allow the Low Range If node to pass through.
Now plug 0.5 into the B slot of the Low Range Check If node and the output of the Low Range If into the A=B and A<B slots.
The same logic applies to the Mid Range Check as well, except we’ll be plugging the 0.75 value for the B slot. Plug the Mid Range If into A=B and A<B slot. The If node should light up.
See whats going on here? If your still confused, reset the Test Constant to 0 and enter in values 0.255, then 0.555 the 0.755. See how at each end only one if node is a grey color while the others are all black? We’ve clamped our ranges in a manor that lets us tally the result of all the If nodes and add them up for our final UV multiplier.
Part 3: Setting up the UV multiplier
Place 3 add nodes and connect them up like so. It should become pretty clear how this system works now.
Swap out the Test Constant for a single vertex color channel. I’ll be using red for my setup. The cool thing is we setup all our If nodes with the vertex color channel as the A slot, so disconnecting and reconnecting this node is pretty painless. Because the vertex channel outputs 1 by default, the top node should be the final result.
Setup your texture sample with a Texture coordinate (with any desired base offsets) and multiply node.
As this setup currently stands, we’re going to have to flood fill our desired mesh black, otherwise when the material is applied we’ll see our maximum scale applied to the entire mesh.
Now paint away! Remember our ranges are .25 .5 and .75, so setting them in your color channel will produce the desired scale results.
I hope you found this a useful addition for your creative project.
Tutorial: UDK MipMaps for the Environment Artist.
Often times when importing a static mesh into an environment using the Unreal Development Kit, its easy to glaze over a setting that makes a real impact, especially in large scale environments.
What are Mipmaps?
As a texture becomes distanced from the player, the engine will swap out smaller version to better optimize the scene. Mips are calculated in steps, meaning a power of 2 resize of your imported texture from the textures original size to a very small thumbnail. This is done by default for every texture imported and set to the default of From Texture Group, which will use recommended settings from the LOD group you selected when importing the texture. While this is fine for a default, its hardly optimal for every situation. Take the following:
This dumpster looks good close up.
Yet from a distance we can see that it loses a lot of that detail.
While we can’t help the fact that the dumpsters texture resolution will go down in texture quality over distance, we can change the mipmaps settings so it degrades differently. Here is the same shot with a sharpen setting used over the default.
Notice the way the metals have more contrast to them instead of blending together. Since metals keep their contrast over distances, this will help us in making the mesh look more true to life over looking fuzzy and muddy.
Double clicking on a texture will bring up a list of settings. Down at the bottom, the mipmap settings can be found. I usually use one of three settings depending on the situation.
Sharpen – These are my most used settings. I generally use either Sharpen 5 or Sharpen 8 for many of my textures. The major difference between the sharpen values the is how they affect the dark areas of your texture. In many cases using a value above 8 can look weird or unnatural, however consider the case below:
This wall looks fuzzy when viewed from a distance. This is unfortunate because i’d like to show off all the dirt I painted into the texture. Changing the mip settings to sharpen 10 brought out a lot more of the ware.
No Mipmaps – This will disable mips all together, meaning your texture will show at the highest resolution no matter the distance. This is generally not recommended for general use, as it is an abuse of the texture pool. However, I’ve found that for portfolio uses it can be a useful kluge fix. Take the following example.
I built grass cards on low-poly planes using a 512 x 512 resolution. This means my mips blur and destroy my alpha and don’t give me a silhouette that works for what it is I needed to do. Since this piece was for show, I disabled the mips.
For what it is that I needed to do, this will work. However, this is not to be used on every texture. If you are trying to get better quality textures in your renders, use the –maxqualitymode startup parameter when launching the UDK game. To do this, right click on the UDK game icon and add -maxqualitymode at the end of the target line. (…\UDK.exe -MAXQUALITYMODE)
Blur – The only case I’ve found to use the blur settings is in image reflections for non real time reflections. Depending on the shader you have setup to do this, the difference may or may not make a dramatic impact.
LODGroup and LODBias settings
Setting the LOD group isn’t noticeable in game, but tells the engine some specific information about how to degrade the texture on more limited systems like consoles or mobile. Furthermore, each texture group has a max texture display setting reflected in the texture info section.
The max displayed in game can be adjusted using the LODbias setting. This can be used to step through the mips to display lower resolutions of a texture by default. These changes however, won’t be noticed until the package file is baked.
In closing, using sharpeing mip settings in some places can improve the contrast of your scene over greater distances and add some additional details to your overall renders. If you are looking for more information on Mips and there settings, I recommend looking in the following places on the UDN:
Tutorial: Setting Up Swarm for Multiple Machines
Recently I have run into situations where my MacBook Pro has taken far too long to build the lights on my UDK scene. For anyone who uses UDK, you may have seen that Swarm, Unreal’s lightmap processing tool for Lightmass, has the ability to distribute its workload across a network to other computers. When my build times got up to an hour for a preview, I decided to do some research on how to use the rest of the machines in my house to help decrease my lighting build times. However, in looking for tutorials on how to setup a swarm system came up with some confusing spots and scattered information. So here now is my own tutorial on how to setup Swarm to distribute work across the other computers in your network.
Setting Up Swarm Agent for Network Distribution
First and foremost, make sure the UDK is installed on all the machines you want to use in your Swarm network. Next, pick one machine (I use the least powerful machine I have) to act as the Swarm Coordinator, which will be the centralized hub of how information gets transferred across the network. Open up your UDK folder and navigate to binaries. There you will see the following:
First, Launch SwarmCoordinator.exe. This is a simple program that shows you which computers are connected to your network that can be used for lightmap processing.
The Coordinator only has three buttons: Restart QA agents, Restart All Agents (Swarm agents on other machines) and Restart Coordinator (which clears the list of connected agents from the list so they can re-connect). Right now there is nothing connected to the computer, which is OK for now. The important thing with Swarm Coordinator is that the program should be left running for as long as your going to do your rendering. Now, lets setup Swarm Agents to connect to the coordinator. In the same binaries folder as the SwarmCoordinator.exe, launch SwarmAgent.exe.
Setting Up Swarm Agent
In the settings tab, you will notice a section called Distributed Settings. Here is a quick breakdown on what everything does:
AgentGroupName: This is the group that this agent belongs to. Other agents with this name will be used when the coordinator distributes the workload. It can be left as Default.
AllowRemoteAgentGroup: This setting determines the group of agents that this agent can use when it processes information across the network. Agent groups can be set with the above AgentGroupName. Since we want to use the group of agents we’ve specified, change the value from DefaultDeployed to Default.
AllowRemoteAgentNames: This setting is a way to specify within the group of agents we are using which in particular we would like to use. These are the computer names, and can be separated with a ‘ ; ‘ if you wish to use multiples. However, I like to use all the power I can get, so we can specify a wild card or part or all of a name in a group using a ‘ * ‘. Using * on its own will use all names in a group. Replace the default setting of RENDER* with *.
AvoidLocalExecution: This bypasses the agent that executed the job from being used for processing the lightmap information. This can be handy if you want to use your computers capabilities for other tasks while it renders the job on the other machines on the network. This only works if the machine that launches the job has this parameter set. I keep this set to False.
CoordinatorRemotingHost: This parameter is the most important. This tells swarm where to find the computer using Swarm Coordinator. This can be entered in in the form on a computer name (case sensitive) or an ip address. For a home network, I tend to lean toward computers names.
EnableStandaloneMode: This setting will omit using any of the other agents and render only using your machine. This is quick way to return to the default way that swarm processes lightmaps. I keep it set to False.
So, knowing all of this, I change my settings to the following. For this example, I’m using an IP address over a computer name.
As I do this for each computer, the swarm coordinator will begin to populate with the users.
And thats pretty much it. Now when you build lights, the Swarm Coordinator will dictate how the job is spread out across the network. None of the other agents will have the colored bar in the Swarm Status tab, but their process can be monitored in the Log tab.
Finding Your IP Address
You can find your IP address quickly by opening command prompt (start -> search ->cmd) and typing ipconfig. You’ll want the number in the IPV4 address.
Finding Your Computer’s Name
Right click the My Computer icon and go to properties. The computer’s name is listed halfway down under computer name, domain and workgroup settings.
The developer menu allows you to control the job performance of Swarm and various other debugging settings. To enable the developer settings tap, go to DeveloperSettings -> ShowDeveloperMenu -> True. A new tab called Developer Settings.
In this menu, you can tweak the way in which Swarm will use the idle parts of your machine. If your taking over co-workers or siblings computers, you can use these settings so when a job is deployed, it doesn’t affect their use of the machine. Likewise, you can also set the remote job to use more of the computers resources by setting RemoteJobDefaultProcessPriority from Idle to Above Normal.