SpeedTree
    Show / Hide Table of Contents

    Texture packing

    During game format exporting, the process of texture packing converts the artist-friendly material maps into the final game-formatted textures. For example, a common thing to do is have the color and opacity placed into one 4-channel RGBA texture.

    The Modeler comes with a number of different texture packers for various engines, depending on which version of the Modeler you are using. You can edit these or even make your own if you need something different.

    The Materials Bar with sample textures enlarged.

    Structure

    All texture packers are stored on disk in the /texture_packing/ directory. Each one consists of two files: an XML file describing the packer and the output, and a small shader that is run to fill the final textures up using the map information from the materials.

    <SpeedTreeTexturePacker> Shader - name of the shader file to use
    ForceTextures - Sets whether a texture is to be written even if it is empty or a solid color. This will make a very tiny texture instead of full-res to save of texture memory. If false, the color will be saved into the mesh, if possible.
    <Texture*> Suffix - suffix added to the filename for this texture
    Type - The type of data to write to disk or in the mesh/material file, depending on format:
    • "Auto" - The default value, the texture is examined to see if it changes. If so, it is a texture. If not, it is a color.
    • "Color" - Force this texture to write as a color in the mesh or material file rather than a texture.
    • "Texture" - Force writing a texture. If the data does not change, it will write a tiny texture. This option is the same as the global "ForceTextures" parameter.
    • "FullTexture" - Always write a full-resolution texture.
    MipGenerationFlag - Can be "None" (or missing), "AlphaIsOpacity", or "RgbIsNormal". These are flags to help the generation of mips be better for texture formats that store mips (DDS).
    Skip - Skip this texture entirely. Omitting a Texture tag will also skip it.

    The shader file is similar to a render mode shader, where you are writing a single function called by a bigger shader. However, for texture packing you will implement a TexturePacking() function whose input and output is a little different. The input consists of all of the maps from the material, already with texture/color adjustments applied, along with a few extra pieces of information and utilities (like noise).

      struct STexturePackingInput
      {
          float3        m_vColor;
          float     m_fOpacity;
          float3        m_vNormal;
          float     m_fGloss;
          float3        m_vSpecularColor;
          float     m_fMetallic;
          float3        m_vSubsurfaceColor;
          float     m_fSubsurfaceAmount;
          float     m_fAmbientOcclusion;
          float     m_fHeight;
          float3        m_vCustom;
          float3        m_vCustom2;
    
          float     m_fNoise;
    
          bool      m_bTwoSided;
          bool      m_bAtlas;
          bool      m_bBillboards;
    
          float2        m_vTexcoord;
      };
    

    The output structure simply contains all of the possible RGBA outputs (up to 16). The packing process tries to be as smart as possible when writing out the textures. If you only write .r, you will get a grayscale/luminance texture. If you only write .rgb you will get a 3 channel texture. And finally, if you write all .rgba, you will get a full 4 channel texture on disk.

      struct STexturePackingOutput
      {
          float4        m_vTexture0;
          float4        m_vTexture1;
          float4        m_vTexture2;
          float4        m_vTexture3;
          float4        m_vTexture4;
          float4        m_vTexture5;
          float4        m_vTexture6;
          float4        m_vTexture7;
          float4        m_vTexture8;
          float4        m_vTexture9;
          float4        m_vTexture10;
          float4        m_vTexture11;
          float4        m_vTexture12;
          float4        m_vTexture13;
          float4        m_vTexture14;
          float4        m_vTexture15;
      };
    

    Custom example

    In this example texture packer, we will write color and opacity into one texture, and normal and gloss into another. Our game requires normal maps with green flipped the other way from the SpeedTree Modeler (which is a common change to make).

    The XML file that describes this texture packer should be saved into a file called "Example.xml" in the /texture_packing directory. It describes the two textures that will be written, and also points to the shader to be used to fill them up.

      <?xml version="1.0" encoding="UTF-8"?>
      <SpeedTreeTexturePacker Shader="_Example.fx" ForceTextures="true" >
          <Texture0 Suffix="_Color" MipGenerationFlag="AlphaIsOpacity" />
          <Texture1 Suffix="_Normal" MipGenerationFlag="RgbIsNormal" />
      </SpeedTreeTexturePacker>
    

    The shader itself should be saved into a file called "Example.fx" to match the filename declared in the XML file. The green channel of the normal map is flipped before saving. Additionally, all processing in the Modeler is done in linear color space, so we must convert the color to sRGB color space before saving by using the LinearTosRgb utility function.

      void TexturePacking(STexturePackingInput sInput, inout STexturePackingOutput sOutput)
      {
          // color/opacity
          sOutput.m_vTexture0 = float4(LinearTosRgb(sInput.m_vColor), sInput.m_fOpacity);
    
          // normal/gloss
          sInput.m_vNormal.b = 1.0 - sInput.m_vNormal.b; // flipped green from the Modeler
          sOutput.m_vTexture1 = float4(sInput.m_vNormal, sInput.m_fGloss);
      }
    

    Once these files are saved, the new "Example" texture packer will be available in the game export dialog, and will produce the textures wanted during export.

    The game export dialog with the "Example" texture available in the Textures area. Enlarged pictures of the textures' files are also shown.

    Copyright © 2023 Unity Technologies
    • Legal
    • Privacy Policy
    • Cookies
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)
    "Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
    Generated by DocFX.