-
Notifications
You must be signed in to change notification settings - Fork 17
Feature Recoloring
Textures Unlimited features a shader based 'recoloring' system that can allow for run-time user controlled color changing of textures used for parts. This functions similar to armor-dying systems from MMOs, or vehicle painting setups from racing games.
The system has a few main parts that drive its functions:
- Mask Texture specifying areas that can be recolored by user, and which recoloring channel affects it
- User Specified Color and material Parameters (RGB, Metal, Smoothness)
- Per-recoloring region normalization parameters and optional full-material normalization texture inputs
- Meta/Gloss/Smoothness control mask - disable recoloring of specific parts of the model for specific channels
- MATERIAL system to specify shaders and materials
- COLOR block in texture sets to specify the default Main/Second/Detail colors to use
- Optional (but very useful) PartModule that can be added to parts to allow for user-recoloring on supported texture sets while in the VAB/SPH
It functions by replacing the color information in the original texture (and/or metallic/specular/smoothness) with the information supplied by the config file and/or selected by the user. The system will also attempt to extract any details that it can out of the original texture and mix these back in with the user specified color by using the provided normalization parameters and/or textures.
- Recoloring Mask - RGB Texture, where each channel represents a 'region'. R=Main, G=Second, B=Detail. Determines what parts of a texture are recolored by which controls in the UI.
- Recoloring Section - Corresponds to a single TUPartVariant or KSPTextureSwitch module. Contains a set of Main/Second/Detail regions in the GUI.
- Recoloring Region - Main / Second / Detail color selections -- each one is a 'region' that corresponds to a channel from the recoloring mask and a region selection in the recoloring GUI.
- Normalization Parameter - The value that when subtracted from a pixel of a texture will return the value of the details for that pixel, in a +/- 0 range. Basically the 'average' color of a region in the texture.
- Portions in the mask that are [R]ed will be controlled by the Main recoloring controls
- Portions in the mask that are [G]reen will be controlled by the Secondary recoloring controls
- Portions in the mask that are [B]lue will be controlled by the Detail recoloring controls
- Portions in the mask that are BLACK will use the values from the default textures (diff/metal/spec) for those pixels.
- [A]lpha channel should contain Luminance Normalization data if normalization is desired (Optional).
The following example will show how to create a recoloring setup for an existing full-colored textured model, as used in KSP. This will include creation of the main section mask, metallic mask and normalization masks, as well as creation of texture set configs. A stock model will be used in the tutorial, but the steps should be the same for any other models.
First, gather your source materials and tools. You will need the assets and tools listed below in order to follow this tutorial:
- Original Diffuse and Specular/Smoothness textures for the part (png/dds)
- Gimp, Photoshop, or any photo application capable of layer flipping, threshold-based flood-fill/select, and layer blending mode selection (screen and difference). More capabilities help. Gimp will be used in this tutorial.
- DDS conversion tools - either in your image editor, or stand alones. If your source textures are DDS, you will need to load them into your image editor somehow (pre convert, or built-in handling).
Create a new project in your image editor, RGBA, 32 bit, with the width and height of your source textures. Import the source normal and specular textures into the project.
If your specular/smoothness data is in the alpha channel of an existing texture, do the following to get it into a separate layer, and remove it from the RGB layers:
- Colors -> Components -> Decompose -> Select RGBA, ToLayers -> Enter/Proceed
- You should now have a new 'project' with four layers in it, one for each channel
- Colors -> Components -> Compose -> Select RGB, and for the input layers select the R,G,B from the decompose operation.
- You should now have a second new project, with the composited RGB layers in a single layer, with no alpha channel.
- Copy the alpha channel from step 2 into the new project as a new layer. Close the first two projects; you are done with them.
- You should now have a single project open (the newest one created), and it should contain two layers -- your diffuse RGB, and the specular/smoothness as a grayscale layer.
The metallic mask texture specifies what portions of a texture represent uncovered metallic materials in the model. A metallic mask should consist mostly of white or black values, with very few shades of gray (and when used, very close to either black or white). Most objects in the real world either -are- metallic, or they are -not-; there is very little inbetween.
The creation of this texture depends highly upon the layout and setup of the original source texture, the colors used, and if the specular/smoothness can be used to help in its creation. You may need to create this entirely by hand/manually, or wait until after the recoloring mask has been created and use it to help.
In this case, the source specular texture can be used to create most of the metallic mask, with only a few manual adjustments needed.
- Create a new copy of the specular map layer, hide the original and all other layers
- Colors -> Levels -> Value -> Adjust start, mid, and end-points to add contrast to the existing data; some loss of detail is acceptable, we can add it back in if absolutely needed.
Its not perfect, but will do. Use a brush/selection/fill tool to black out the windows, we actually don't want those to be metallic. If desired, add a few smudge/details from the original textures back in (diffuse and/or specular!) using various blending modes. Clean up any pixelated artifacts. Maybe invert the gradient in the windows and add it in, for a metallic-towards-the-edges effect (it'll look cool...).
The recoloring mask specifies what portions of the model the user can recolor from each of the user-input channels, and what portions of the original texture are used untouched.
Most diffuse textures only have one or two main colors in them, so we can generally use those to guide our mask creation, but you don't have to; you can create entirely new color patterns from the original texture if desired.
In this example, there is 'stock white' and 'stock gray' for the two main colors that we will use to guide or mask creation.
-
Create an empty layer, label it 'black-Background', flood fill it with solid black.
-
Create an empty layer, label it 'red-Main', flood-fill it with solid red (255,0,0). Will will delete portions of this layer later to un-mask parts of the stock texture (windows/etc)
-
Create a new empty layer, label it 'green-Second', and use the flood-select tool to select the gray areas from the original texture; adjust the tool's treshold values to get as much of the original as you can without too much bleed or artifacting. In this empty layer, fill your selected areas with full green (0,255,0)
-
Create a new empty layer, label it 'blue-Detail'. Paint any 'details' you want on your part into this layer -- examples might be racing stripes, or maybe some of the white panels in the original are adjustable separately. If your source texture has three primary colors to it, you may follow suit and use the detail channel for that color selection.
-
Delete/crop from the 'red-Main' layer any portions of the original texture that you do not want to be recolorable.
-
Un-needed if standard layered building of the masks is used? An important step after the basic mask is created is to normalize (in the vector terminology) the aliasing of edges between adjoining masked sections -- the sum value of the colors for R+G+B in any pixel should not exceed 255i/1.0f, or there will be artifacts in the rendering. A lower value is acceptable, but it will cause the original texture to 'bleed through'.
In order to normalize the mask, the following steps should be followed.
Recoloring of a fully masked pixel is accomplished through the following very simple method: Detail = originalTextureValueGrayscale - normalizationValue Output = userSelectedColor + detail
For each of the recolorable sections in the main texture (Main, Second, Detail), you need to specify the average luminance of the diffuse/metal/specular/smoothness textures. This is a single floating point value per section, which is applied against the original texture in order to extract details. The details are then added back onto the users' selected color for a section, and the results sent off to the render pipeline.
These normalization values are specified in each MATERIAL block that will use a recoloring shader. They are specifed in the following fashion (note that you will only need the inputs for your workflow; no need for _SpecularNorm if using a metallic shader).
MATERIAL
{
texture = _MaskTex,TU-Examples/mk2Cockpit/MK2-Cockpit-MASK
keyword = TU_RECOLOR
//recoloring parameters to control color normalization settings
vector = _DiffuseNorm,0.69,0.23,0.101
vector = _SmoothnessNorm,0.208,0.062,0.305
vector = _MetalNorm,0,0,1
vector = _SpecularNorm,0,0,0
}
Each parameter is a vector with three components (_DiffuseNorm), where each component corresponds to one of the recoloring sections; _DiffuseNorm.r corresponds to the Red recoloring mask (Main), _DiffuseNorm.g corresponds to the Green recoloring mask (Second), and _DiffuseNorm.b effects the Blue recoloring mask (Detail). When defining these in the config, they are specified in the fashion 'vector=_DiffuseNorm,RED,GREEN,BLUE' (with the same applying to the other normalization parameters).
There is an optional stand-alone tool in development that you will be able to use to determine starting values to use. Provide it the input textures (diffuse,metal,specular), set the channels mapping up as used in the shader, and it will output the normalization values to use in your config file (actually provides the entire copy/paste snippet to place into the MATERIAL blocks).
Normalization Mask Creation (advanced feature, optional, use normalization parameters for 'simple' setups)
Normalization masks provide the data that the recoloring system needs in order to extract the details from the original diffuse, metallic/spec color, and smoothness input textures. There is one normalization mask for each of those inputs, for a total of three masks to create. The method to create them is identical aside from varying the source texture that you work with.
First, gather your RGB diffuse, RGB spec color or grayscale metallic, and grayscale smoothness texture/layers. Need them all as individual layers for this to start; so if you have some in the alpha channels of the others, follow the previously outlined steps to get them as separate layers. For the RGB diffuse and/or RGB spec-color textures, convert them to a grayscale luminance texture.
Work on one input texture at a time, following these steps for each:
- For each main color section visible in the input luminance texture
- Create a new empty layer to work in, put it above the input texture you are working on. Set it to 'difference' blending mode. This will make the viewport display white in areas of large difference, and black in areas of no difference. This will give us an easy visual guage of how close our luminance mask is, and will show us exactly what details will remain (details will be white, everything else should be black.
- Use the flood select/color select tool to select portions of the original texture by their average color, and then flood-fill that selection on your new mask layer with an arbitrary gray color.
- Use the color->levels or color-> brightness/contrast tools to adjust the value of the selection in your new layer until the viewport displays black for the majority of the section.
- Hide the newly created layer, and go on to the next color/section.
- Once all sections are done, change the layers back to 'normal' blending mode, flatten them down, and compare it with the original source image. They should be very similar in form, with the new mask looking like the original minus any of the 'details' (bolts/shading/highlights/scratches/etc).
- This is the completed normalization mask for the channel. Save the layer for use later in compositing the textures, as the textures consist of multiple channels.