Modding:How To Find A Virtual Texture: Difference between revisions

From bg3.wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(16 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{PageSeo
|title=Modding Resources
|description=This page is a hub for everything related to Modding Baldur's Gate 3. Check out the following guides to learn how to mod BG3.
|image=Modding_resources.webp
}}{{Modding box}}{{Modding sidebar}}
A virtual texture is essentially a digital box that BG3 uses to store textures in so they load quicker. This is good for the game's performance, but not so good if you want to extract and edit them. So here is how to extract them.
This tutorial requires Modder's Multitool, LSLib v19 and a knowledge of how to find things with the multitool.
This tutorial requires Modder's Multitool, LSLib v19 and a knowledge of how to find things with the multitool.


===How to find the mesh===
You may also find [https://docs.google.com/spreadsheets/d/135XWkGCZ1A7hn4yW1Gt3i7MGfx-RsgKfLPGbHdXKbNg/edit?usp=sharing this spreadsheet] helpful.
First thing you need to find the item is its name -the exact item name it has. For example, 'The Deathstalker Mantle'.  
 
Put the name(or the NPC's name, to lead you to their CharacterVisuals entry) in the modder's multitool index search. This should lead you to its entry in the english.loca file.


Take the handle (a handle is h[string of numbers], similar to an UIID) and search that.
===How to find the mesh name===
You can skip this step if you know the mesh name. The wiki has many item pages with the File names included. [[The Deathstalker Mantle]], for example.  


This should lead you to the ''roottemplate'' of the item. (if it doesnt have one in the roottemplate, it's in the parenttemplate's file instead)
* First thing you need to find the item is its '''name''' - the exact item name it has. For example, 'The Deathstalker Mantle'. Put the '''name''' (or the NPC's name, to lead you to their CharacterVisuals entry) in the modder's multitool index search. This should lead you to its entry in the english.loca file, where you can find the '''handle.'''
* Take the '''handle''' (a handle is h[string of numbers], similar to an UUID) and search that. For example, The Deathstalker Mantle's handle is ''hb7ee75e7g15f1g42a7gacf3gafe7628d8b10''. This should lead you to the ''RootTemplate'' of the item. (If it doesn't have an entry in the RootTemplate, it's in the ParentTemplate's file instead.)
* You can then find its mesh '''mapkey'''. Search that and you should find the meshes lsx entry, which will lead you to the mesh name. For example, The Deathstalker Mantle's mesh name is ''UNI_DarkUrge_Bhaal_Cloak''.


You can then find its mesh mapkey. Search that and you should find the meshes lsx entry.(You can skip the above if you know the mesh name.)
=== Finding the GTexFileName with the mesh name ===
You will need to find the GTexFileName in order to find the correct virtual texture to extract. So search the mesh name in the search index in Multitool.  


=== Finding it with the mesh name ===
You may need to append it with HUM_M_ instead of whatever race you are looking for, as '''most of the universal gtex are under HUM M meshes.''' The same applies with HUM F and meshes that are different on the female to the male.  
Search the mesh name in the search index.  


You may need to append it with HUM_M_ instead of whatever race you are looking for, as most of the universal gtex are under HUM M meshes. The same applies with HUM F and female specific meshes. Some meshes also share textures with other versions of the mesh, so you may need to remove the ''_a'' or ''_broken'' (for example) appendage if you aren't getting any matches.
Some meshes also share textures with other versions of the mesh, so you may need to remove the ''_a'' or ''_broken'' (for example) appendage if you aren't getting any matches.


We like ''''HUM_M_ARM_Bandit_C_Body'''<nowiki/>' so we search this in the multitool.
For example, we like ''''HUM_M_ARM_Bandit_C_Body'''<nowiki/>' so we search this in the multitool.


It has an entry in '''Shared\Public\Shared\Content\Assets\Characters\Humans\[PAK]_Male_Armor\_merged.lsf''<nowiki/>' so we click '''convert & open''' for that.
It has an entry in '''<nowiki/>'Shared\Public\Shared\Content\Assets\Characters\Humans\[PAK]_Male_Armor\_merged.lsf''<nowiki/>' ''''' so we click ''convert & open'' for that.


We CTRL+F '''HUM_M_ARM_Bandit_C_Body''' and find a mesh entry for it.
We CTRL+F '''HUM_M_ARM_Bandit_C_Body''' and find a mesh entry for it.
Line 37: Line 45:
  '''                  <attribute id="Name" type="LSString" value="HUM_M_ARM_Bandit_C_Body" /> (bolded for importance!)'''
  '''                  <attribute id="Name" type="LSString" value="HUM_M_ARM_Bandit_C_Body" /> (bolded for importance!)'''


 
We scroll down to the end of the mesh entry and find the Objects.
We scroll down and find


         <attribute id="LOD" type="uint8" value="0" />
         <attribute id="LOD" type="uint8" value="0" />
      '''<attribute id="MaterialID" type="FixedString" value="57a6fd6e-c00d-60eb-5e52-31560b95332b" />'''
      '''<attribute id="MaterialID" type="FixedString" value="57a6fd6e-c00d-60eb-5e52-31560b95332b" />''' <!-- This is the material ID -->
          <attribute id="ObjectID" type="FixedString" value="HUM_M_ARM_Bandit_C_Body.HUM_M_ARM_Bandit_C_Body_Mesh.0" />
          <attribute id="ObjectID" type="FixedString" value="HUM_M_ARM_Bandit_C_Body.HUM_M_ARM_Bandit_C_Body_Mesh.0" />
             </node>
             </node>


The material ID is what we need. We scroll back up to the start of the file and search that.
This material ID (57a6fd6e-c00d-60eb-5e52-31560b95332b) is what we need. We scroll back up to the very start of the '''_merged.lsf '''(materials are usually near the top) and CTRL+F for that.


We find
We find:


                  <node id="Resource">
                  <node id="Resource">
Line 54: Line 61:
                     <attribute id="MaterialType" type="uint8" value="22" />
                     <attribute id="MaterialType" type="uint8" value="22" />
                   <attribute id="Name" type="LSString" value="HUM_M_ARM_Bandit_A_Body" />
                   <attribute id="Name" type="LSString" value="HUM_M_ARM_Bandit_A_Body" />
And we do see that it shares a texture with the other bandit models.
                  [material continues, cut for length]
 
We scroll down to the end of the material, past the vector parameters and we find the VirtualTextureParameters ID:
At the end of the material we find


              <node id="VirtualTextureParameters">                     
              <node id="VirtualTextureParameters">                     
Line 66: Line 72:
             <attribute id="ParameterName" type="FixedString" value="virtualtexture" />
             <attribute id="ParameterName" type="FixedString" value="virtualtexture" />
                </node>
                </node>
 
So we search d53fa1a1-aa8e-2564-1077-42f6c36086c5. Luckily for us, it is in the same file. (If it isn't, you may need to search the multitool for it.)
 
So we search d53fa1a1-aa8e-2564-1077-42f6c36086c5. Luckily for us it is in the same file. (If it isn't you may need to search the multitool with it.
 


  <node id="Resource">
  <node id="Resource">
Line 85: Line 88:
                 </node>
                 </node>


b049a62336641c449903f6ec8b4dae67 is the correct string. Now you can extract it from the virtual textures.
The GTexFileName, b049a62336641c449903f6ec8b4dae67, is the correct string. Now you can extract it from the virtual textures.
 
===Lslib===
Lslib v19 lets you unpack just specific gtp files via the gtex name.
 
Alternately you can just unpack all the VT into one folder and just search with Windows Search, but this is extremely file heavy and not recommended.
 


And we do see that it shares a texture with the other bandit models- it is the part under the armour. We will need to go back and extract the armour and accessories separately by looking at the materials under the different mesh chunks listed in the mesh entry.


=== Unpacking using Multitool ===
Now that you have your GTexFileName, you can extract the textures from VT. Search your GTexFileName (in this case: b049a62336641c449903f6ec8b4dae67) in the multitool. Select the file that's inside VirtualTextures and click on the Extract file icon.
[[File:SearchGTEXinmultitool.png|frameless|840x840px]]




Now go to your Multitool/UnpackedData/VirtualTextures folder and search for b049a62336641c449903f6ec8b4dae67.


[[File:SearchGTEXinvirtualtex.png|frameless|840x840px]]


Here are the three texture files you will need, in .dds format. The red underlined one is the PM (Physical Map), the green underlined one is the NM (Normal Map), and the purple underlined one is the (BM) Base Map. The PM is usually brighter colors, the NM is usually almost all blue, and the BM is usually very light with a sort of beige tone. We recommend copying all of these to your project folder and renaming them with the mesh name + _BM, _NM, or _PM, so it's easier to keep track of them later.


Congrats, you've successfully exported textures from VT and can now use them for your modding project!


===Lslib===
Lslib v19 also lets you unpack just specific gtp files via the gtex name.


Alternately you can just unpack all the VT into one folder and just search with Windows Search, but this is extremely file heavy and not recommended.


=== Remember Mipmaps ===
The extracting process strips the virtual textures of their mipmaps! Even if you are not editing some maps, you need to import them into GIMP(or any similar program) and resave with mipmaps to generate new ones if you are including them with your mod. [[Modding:Creating Outfit Textures|See here for save settings.]]


{{Modding navbox}}
[[Category:Modding guides]]
[[Category:Modding guides]]
[[Category:Armor modding]]

Latest revision as of 16:00, 26 March 2024

A virtual texture is essentially a digital box that BG3 uses to store textures in so they load quicker. This is good for the game's performance, but not so good if you want to extract and edit them. So here is how to extract them.

This tutorial requires Modder's Multitool, LSLib v19 and a knowledge of how to find things with the multitool.

You may also find this spreadsheet helpful.

How to find the mesh name[edit | edit source]

You can skip this step if you know the mesh name. The wiki has many item pages with the File names included. The Deathstalker Mantle, for example.

  • First thing you need to find the item is its name - the exact item name it has. For example, 'The Deathstalker Mantle'. Put the name (or the NPC's name, to lead you to their CharacterVisuals entry) in the modder's multitool index search. This should lead you to its entry in the english.loca file, where you can find the handle.
  • Take the handle (a handle is h[string of numbers], similar to an UUID) and search that. For example, The Deathstalker Mantle's handle is hb7ee75e7g15f1g42a7gacf3gafe7628d8b10. This should lead you to the RootTemplate of the item. (If it doesn't have an entry in the RootTemplate, it's in the ParentTemplate's file instead.)
  • You can then find its mesh mapkey. Search that and you should find the meshes lsx entry, which will lead you to the mesh name. For example, The Deathstalker Mantle's mesh name is UNI_DarkUrge_Bhaal_Cloak.

Finding the GTexFileName with the mesh name[edit | edit source]

You will need to find the GTexFileName in order to find the correct virtual texture to extract. So search the mesh name in the search index in Multitool.

You may need to append it with HUM_M_ instead of whatever race you are looking for, as most of the universal gtex are under HUM M meshes. The same applies with HUM F and meshes that are different on the female to the male.

Some meshes also share textures with other versions of the mesh, so you may need to remove the _a or _broken (for example) appendage if you aren't getting any matches.

For example, we like 'HUM_M_ARM_Bandit_C_Body' so we search this in the multitool.

It has an entry in 'Shared\Public\Shared\Content\Assets\Characters\Humans\[PAK]_Male_Armor\_merged.lsf' so we click convert & open for that.

We CTRL+F HUM_M_ARM_Bandit_C_Body and find a mesh entry for it.

  <node id="Resource">

                    <attribute id="AttachBone" type="FixedString" value="" />
                   <attribute id="AttachmentSkeletonResource" type="FixedString" value="" />
                   <attribute id="BlueprintInstanceResourceID" type="FixedString" value="" />
                   <attribute id="BoundsMax" type="fvec3" value="0.5363549 1.713599 0.176041" />
                    <attribute id="BoundsMin" type="fvec3" value="-0.5405712 0.6668076 -0.219203" />
                   <attribute id="ClothColliderResourceID" type="FixedString" value="" /> 
                   <attribute id="HairPresetResourceId" type="FixedString" value="" />
                   <attribute id="HairType" type="uint8" value="0" />
                   <attribute id="ID" type="FixedString" value="8e7bcc4a-2b65-d704-1cf0-a1a3bc8b8bd3" /> 
                   <attribute id="MaterialType" type="uint8" value="44" />
                  <attribute id="Name" type="LSString" value="HUM_M_ARM_Bandit_C_Body" /> (bolded for importance!)

We scroll down to the end of the mesh entry and find the Objects.

       <attribute id="LOD" type="uint8" value="0" />
    <attribute id="MaterialID" type="FixedString" value="57a6fd6e-c00d-60eb-5e52-31560b95332b" /> 
        <attribute id="ObjectID" type="FixedString" value="HUM_M_ARM_Bandit_C_Body.HUM_M_ARM_Bandit_C_Body_Mesh.0" />
           </node>

This material ID (57a6fd6e-c00d-60eb-5e52-31560b95332b) is what we need. We scroll back up to the very start of the _merged.lsf (materials are usually near the top) and CTRL+F for that.

We find:

                <node id="Resource">
                   <attribute id="DiffusionProfileUUID" type="FixedString" value="" />
                   <attribute id="ID" type="FixedString" value="57a6fd6e-c00d-60eb-5e52-31560b95332b" />
                   <attribute id="MaterialType" type="uint8" value="22" />
                 <attribute id="Name" type="LSString" value="HUM_M_ARM_Bandit_A_Body" />
                 [material continues, cut for length]

We scroll down to the end of the material, past the vector parameters and we find the VirtualTextureParameters ID:

            <node id="VirtualTextureParameters">                    
            <attribute id="Enabled" type="bool" value="True" />
            <attribute id="ExportAsPreset" type="bool" value="True" />
            <attribute id="GroupName" type="FixedString" value="Texture Map" />
         <attribute id="ID" type="FixedString" value="d53fa1a1-aa8e-2564-1077-42f6c36086c5" />
            <attribute id="Index" type="int32" value="0" />
            <attribute id="ParameterName" type="FixedString" value="virtualtexture" />
              </node>

So we search d53fa1a1-aa8e-2564-1077-42f6c36086c5. Luckily for us, it is in the same file. (If it isn't, you may need to search the multitool for it.)

<node id="Resource">

                   <attribute id="GTexFileName" type="FixedString" value="b049a62336641c449903f6ec8b4dae67" /> 
                   <attribute id="ID" type="FixedString" value="d53fa1a1-aa8e-2564-1077-42f6c36086c5" />
                   <attribute id="Localized" type="bool" value="False" />
                   <attribute id="Name" type="LSString" value="HUM_M_ARM_Bandit_A_Body" />
                   <attribute id="Prefetch" type="bool" value="False" />
                   <attribute id="PrefetchMipLevel" type="int8" value="-1" />
                   <attribute id="ReferencedColorSpaces" type="uint32" value="6" />
                   <attribute id="SourceFile" type="LSString" value="" />
                    <attribute id="VirtualTextureLayerConfig" type="uint32" value="3" />
                   <attribute id="_OriginalFileVersion_" type="int64" value="144115205255725056" />
               </node>

The GTexFileName, b049a62336641c449903f6ec8b4dae67, is the correct string. Now you can extract it from the virtual textures.

And we do see that it shares a texture with the other bandit models- it is the part under the armour. We will need to go back and extract the armour and accessories separately by looking at the materials under the different mesh chunks listed in the mesh entry.

Unpacking using Multitool[edit | edit source]

Now that you have your GTexFileName, you can extract the textures from VT. Search your GTexFileName (in this case: b049a62336641c449903f6ec8b4dae67) in the multitool. Select the file that's inside VirtualTextures and click on the Extract file icon. SearchGTEXinmultitool.png


Now go to your Multitool/UnpackedData/VirtualTextures folder and search for b049a62336641c449903f6ec8b4dae67.

SearchGTEXinvirtualtex.png

Here are the three texture files you will need, in .dds format. The red underlined one is the PM (Physical Map), the green underlined one is the NM (Normal Map), and the purple underlined one is the (BM) Base Map. The PM is usually brighter colors, the NM is usually almost all blue, and the BM is usually very light with a sort of beige tone. We recommend copying all of these to your project folder and renaming them with the mesh name + _BM, _NM, or _PM, so it's easier to keep track of them later.

Congrats, you've successfully exported textures from VT and can now use them for your modding project!

Lslib[edit | edit source]

Lslib v19 also lets you unpack just specific gtp files via the gtex name.

Alternately you can just unpack all the VT into one folder and just search with Windows Search, but this is extremely file heavy and not recommended.

Remember Mipmaps[edit | edit source]

The extracting process strips the virtual textures of their mipmaps! Even if you are not editing some maps, you need to import them into GIMP(or any similar program) and resave with mipmaps to generate new ones if you are including them with your mod. See here for save settings.