Jump to content

PAC Optimization & Compression Methods


Recommended Posts

Dark
This post was recognized by Dark!

Jun Nagase was awarded the badge 'Helpful' and 10 points.

Optimization & Compression

Optimization and Compression of PAC models and textures.

 

Good evening class, today we will look at how to optimize and compress our PACs for the benefits of everyone.

There are various levels of complexity, and some measures are more involved than others.

 

First to be said however, the Golden Rule is, and always will be, that less is always less, and more is always more.

 

There is no getting around that having less = smaller PAC, and having more = bigger PAC. Rather than try a dozen different things to try to compress your PAC, it might be worth considering if you really need all those items, or at least if some of them can be substituted with something else.

This thread will mostly be focusing on the models and textures, and less so on optimizing events and PAC structure etc.

 

 

 

Texture Compression

 

First we'll go over some rules for textures when it comes to importing them into the format Gmod uses.

Gmod uses two file types to render textures; VMT (Valve Material Type) and VTF (Valve Texture Format).

To edit these, we need VTFEdit.

You can find it here.

 

VMT Files
 

Spoiler

Valve Material Type files are simple text files that tells gmod where to find the textures and how to render them.

They'll include the diffuse texture itself, and sometimes Normal maps and Environment/Specular maps which we'll cover under the VTF section.

They then dictate how to render these, for example with the Phong options. Phong options tells gmod whether to render the object's as reflective, and how reflective it is, and the intensity of the reflection, et cetera.

Mostly, we don't touch the VMT files for PAC other than to remove unnecessary file references, specifically to stuff like normalmaps or specular maps.

VMT Example.png

 

Here for example, we have all 3 primary types of textures you'll see referenced;

$basetexture, aka the texture you always have.

$bumpmap, aka the normalmap (bump and normal isn't really the same thing but works all the same here)

$phongexponenttexture, aka specular maps. Specular is -usually- represented with the $phongexponenttexture option, however $envmap is also sometimes used. They're not quite the same thing, but do sorta the same thing in the end and is the same thing for our purposes.

 

Optimization Techniques

 

--Deleting less necessary textures--

First, if you delete a .vtf texture and don't also delete it's reference in the .vmt text file, you'll get a pink&black checkers overlay of varying intensity on your model. Always remember to delete the line in the .VMT that refers to the texture you're deleting.

 

Usually the first thing you want to remove if you're trying to cut down a PAC size is the specular map.  That's the $phongexponenttexture and/or $envmap lines. Delete those, and replace with $phongexponent 2 (or any number that looks good, usually a low number unless it's like, an eyeball.) if you still want the texture to be reflective. Most models wont lose much from having the specular texture removed, at least for PAC.

Don't forget to also delete the VTF file that it references, since it isn't needed anymore. In the screenshot above, that would be the Eyes_s.vtf file.

 

Secondly, you might want to delete the $bumpmap line. This has a bigger impact on the model, and it's easy for a model to become a lot uglier if you remove this. Usually it's more worth it to downscale the texture instead, which we'll cover later. In this case, simply delete the line. There's nothing to replace it with. Again, don't forget to delete the referenced VTF texture as well.

 

Lastly, if there are any textures referenced other than the three primary ones mentioned above, it's almost certain that they're not necessary for PAC and removing them is a fairly safe bet. The only exception might be $detail textures, they tend to be very small textures that add small-scale detail (hence the name), and can really help bring some detail onto otherwise low resolution textures. Up-close, they can add a lot to the visual quality of the texture when balanced right, for virtually no added size.

 

A small change you could make is also removing $nocull lines if the texture you're working with isn't transparent. Experiment on your own. Removing this line will slightly reduce the render cost of the texture. It's nit-picky level stuff though, so don't sweat it.

 

 

VTF Files

Spoiler

Valve Texture Format files, or VTFs for short, are the bread and butter of the textures used in gmod, and all source games.

They are the actual textures themselves, and are the ones subject to the most size bloat. They are often far larger than even the model files, and is where you can most likely cut the most out of your PAC size.

 

Optimization Techniques

 

There are a few things we can do to reduce the size of a VTF file. Some of them require more work than others, and some of them impact the visual quality more than others.

 

-- Downscaling Texture Sizes & Formatting --

Theory

The first and perhaps easiest thing you can do to significantly reduce the size of your PAC is to simply reduce the size of the textures involved.

Rule of thumb for VTF textures: They must be a power of 2. That means 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 and 2048. Any other sizes and VTFEdit will tell you to fuck off and do it again. Keep this in mind when you resize a texture.

 

Generally you'll never want textures above 2k, and that's pushing it. You should only, very sparingly, use 2k textures for something you really want to show off. Most of the time even then, you can make do with 1k textures. Also keep in mind that just because the Diffuse $basetexture is one size, does not mean it's normalmap and specular maps have to be the same sizes. They can be smaller and still function.

1k textures should be used for textures that require some level of detail to them. Look at the texture and consider if you can cut it down, usually you can.

512 is a good size for most textures, and oft strikes a good balance between quality and optimized size.

Textures for very small items or very flat textures can safely be taken lower without fear of much quality reduction. Completely flat textures, ie just a single color, should be taken down to 8x8 or 16x16.

 

 

Practice

To downscale a texture with VTFEdit, you simply double-click a VTF file and it should boot up VTFEdit. Then hit CTRL+E to export it, and select your preferred image file type. Usually JPG is good for images with no alpha/transparency, and PNG is good for images with alpha/transparency. If you're uncertain, just pick PNG and try your way forward.

Then, resize them in your image editing software of choice. A good free choice might be paint.net. Paint might even be able to do it. It's quite easy to do.

Then, with VTFEdit open, hit CTRL+i to import, and select your newly resized file.

 

-- Reformatting --

A slightly more technical addition to your resizing is to also reformat the texture. There's not much to it, honestly.

There are two types you need to know of: DXT1 and DXT5.

VTF Import Options Example.png

 

DXT1 Format is for images without alpha/transparency. That is to say, the texture is not see-through anywhere. You do not want this format for things like glasses or anything where there is transparency involved. Google what image transparency is if you're uncertain.

DXT5 Format is for images with alpha/transparency. Partially see-through textures, textures that has holes etc.

Hair textures are a good example of textures that usually have some transparency.

Again, google if you're uncertain.

 

If your image does not contain any transparency, import with DXT1 Format in both the Normal Format and Alpha Format fields, as pictured in the screenshot above. If your image does contain alpha, use DXT5 for both fields.

 

DXT1 is significantly smaller in file size, a ~5100kb texture in DXT5 format will reduce to ~2730kb in DXT1 format.

How do you know if your texture is DXT1 or DXT5 to begin with you ask?

VTF Info Example.png

When you open the VTF texture in VTFEdit, navigate to the 'Info' tab as pictured in the above screenshot. It will display the Format, in this case displaying DXT1.

Once you've picked either DXT1 or DXT5, simply hit OK and wait for the texture to show up and the menu to go away. VTFEdit might freeze momentarily whilst it imports.

 

 

Okay, now you've imported the new texture. Now hit CTRL+S to save it, and save it on top of the VTF texture you want to replace (though, maybe back it up somewhere outside your PAC folder first). Hit "Yes" when prompted with whether you want to overwrite.

There you go, you should hopefully have a significantly smaller texture now.

 

 

-- Mipmaps --

Another thing you can do when importing a texture is to uncheck the "Generate Mipmaps" checkbox on the Import menu, as pictured above under Reformatting.

This however does have a noticable change on how the texture appears at range, and may also increase the render weight of the texture at range. It's a little uncertain if it does or not.

Basically what mipmaps are, is a series of smaller versions of the texture that are auto-generated and treated with a few effects such as de-sharpening upon importing of a texture. These smaller images are then saved as part of the larger image's data in the VTF file.

Their purpose is to significantly increase the smoothness and general appearance of textures when viewed at range.

It works a lot like a model's LODs. As you move further away from the texture, it switches to a lower-resolution version that has some desharpening effects applied to it.

Despite it being lower resolution, it actually serves to improve the look of the texture by largely eliminating the sort of rugged, sharp-ish artifacting that will occur otherwise(google Moiré pattern), as the small details of the texture aren't visible at range anyway. Example below.

MIPMAP example.png

 

The scarf below has 'Generate Mipmaps' disabled. It might be hard to spot, but it is slightly more jagged and sharp-ish looking than the above scarf which has default import options. It's slightly more unsightly and not as pretty, though for a scarf it isn't a big deal since it has a lot of 'holes' anyway, curtesy of being knit. It'll be more obvious on other textures.

This may be slightly more graphically intensive however, as the game now has to render the full resolution texture at all times rather than a lower resolution variant at range. However, whether this is actually a factor or not is up in the air. Time may tell.

 

The upside is, you cut a bit off the size of the image. A ~2700kb texture will reduce to ~2000kb. If you're really starved for size, you could try importing your textures into VTFEdit with 'Generate Mipmaps' disabled.

 

 

 

 

Other Textures

Other texture options are available in PAC, namely importing JPG or PNG files through the Material slots using URLs to places like imgur or dropbox.

It should be noted however that these externally imported textures do not benefit from many of the filtering effects VTF textures benefit from and so likely wont look as good, and it's uncertain if these non-native texture types require more processing power to render than native VTF textures do.

It's recommended to make use of VTFs for your PACs, however if you're experimenting or whatever, it's not the end of the world to make use of a few JPG or PNG urls.

Though if you want to experiment and want quick view of your results, VTF and VMT files in singleplayer do update live in-game if they're mounted normally (aka in the materials folder, or in the materials folder of an addon in the Addons folder).

 

 

Models

Models are the backbone of a lot of PACs and provide a lot of unique opportunities to add character and aesthetic to your character when used right. They are however also subject to some, albeit usually more involved, options for optimization.

 

Bodygroups

Spoiler

Removing Unnecessary Bodygroups

Removing unnecessary bodygroups from a model is a slightly more involved process than fiddling with textures.

You'll need Crowbar. Blender might make the process easier too, or harder.

 

Often, not all bodygroups available to a model are used in a PAC. In such case, you can optimize your PAC both in terms of size and in terms of processing power required to render the model through removing unnecessary bodygroups.

First step is to open Crowbar and get it set up.

Under the Set Up Games tab, select Garry's Mod and fill out the directories. It should look something like this.

Crowbar Directory Example.png

 

Pay attention to the exact paths after 'common', as the GarrysMod folder has another folder named garrysmod inside it- which is not where you'll want to set some of your paths or it'll yell at you later. GarrysMod (with capital letters) > bin is where most of them will go.

Now, switch to the 'Decompile' tab and set your MDL input: path to the model you want to cut down.

Set the Output to: path to a new folder, keep it somewhere near the PAC folder so you can find it easily in the future should you want to work on it again later.

Then you should be able to simply hit "Decompile" and it'll spit out the model's contents into the specified folder.

 

 

.qc file

Now you're faced with navigating the bodygroups. This can be a little confusing at first, but once you've wrapped your brain around the process you'll see it isn't as daunting as it might seem at first.

First thing you want to do is open up the .qc file. It's a simple text file you can open with notepad or any other text viewer of your choice. I usually use Notepad++.

Now you're met with a text structure not unlike that of a VMT file.

There are a fair number of things that can be cut out of a .qc file but knowing exactly what will and will not break things takes some time to learn, so for now we'll simply focus on the bodygroups and skinfamilies.
 

$bodygroup "name"
{
	studio "bodygroup 1.smd"
	studio "bodygroup 2.smd"
	blank
}

Bodygroups will look something like the above. The $bodygroup "name" is what you'll see printed in the bodygroup tool in-game when switching between bodygroups. Essentially, any $bodygroup group you don't need period you can remove from the .qc file. The whole section as pictured above must be taken out.

The .smd files are the actual models that the final model will comprise of. They combine into one like the power rangers to become one functional model.

If you only need one/some of the bodygroup options in a $bodygroup, you can remove the studio bodygroup lines you don't need until it looks like above. Even if there's only one bodygroup option you need from that bodygroup, you have to leave it in it's $bodygroup. There's not much option in a single-option body group but hey, it needs to be there or you wont have that piece of the model when we compile it again.

 

 

Now you've cut away the bodygroups you don't need. Next is $texturegroups, often called skinfamilies.

They're basically the texture variant of a bodygroup. They first list the default texture, then the texture options afterwards on the same line.

If you don't need them, you can cut out the $texturegroup lines as well.

 

 

Before you save, at the very top, change the name of the model at $modelname. If it's "thotmodel.mdl" change it to something like "thotmodelpasta.mdl" to differentiate it from the default model. Also save it as a new .qc file instead of overwriting it, in case you need the original. Again, rename it to something similar that differenciates it from the original.

 

 

 

Now save the file and go into the 'Compile' tab of Crowbar and find the .qc file you just saved, and select it.

Make sure the game is set to Garry's Mod and that the output folder path looks right.

Then simply try the 'Compile' button.

If it fails, read the console lines it spits out and try to bugfix your way through it. Crowbar often doesn't like any "ikrule" tags for whatever reason, and for PAC we can safely remove any 'ikrule' references in the .qc file without any worry.

If it continues to fail, contact your nearest PAC Moderator (no don't, just contact Jun) and we'll work our way through it.

Once it successfully compiles, it'll spit out a model with only the pieces you've left in and should hopefully be smaller in size now than before.

 

 

If you're uncertain which smd files you should or shouldn't include because the names are retarded not very specific, you can install SourceTools in Blender and import the .smd files into Blender to see them. Both are free. You can find tutorials on how to do this, or if demand is high enough I'll update this thread with the how-to eventually.

This is also how you open the models in blender to edit them yourself, and you can then export them as .smd files so they can be compiled into a final model.

 

Other .qc file options

Spoiler

For PAC, a lot of .qc options are really just unnecessary since we're not working with models that will actually ragdoll (usually) or really interact with the world in any way. They'll just be attached to our playermodels.

So, here's a few examples of lines that can be removed relatively safely. Keep in mind, removing said lines may result in gmod crashing if you try to spawn them as normal props in singleplayer.

You can't spawn them as props through PAC so they shouldn't crash anyone there. These crashes are generally physics related, and PAC objects don't have physics applied in the traditional sense.

 

The below lines can generally be safely removed, as well as similar lines. Some are necessary (not any of the ones featured below of course), some are not. Crowbar's console will yell and scream at you that it's missing something when compiling if you remove something that needs to be there.

They may reduce the model size somewhat. Results vary.

Again, if you get stuck trying to get it to compile, throw a DM at Jun and we'll find time to try to work it out.

 

$illumposition -0.019 -0.882 37.487

$eyeposition 0 0 70

	eyeball "eye_right" "ValveBiped.Bip01_Head1" -1.211840 -3.185527 67.337190 "eyeball_recon_r" 1 2 "iris_unused" 1.25
	eyeball "eye_left" "ValveBiped.Bip01_Head1" 1.227100 -3.119358 67.402696 "eyeball_recon_l" 1 -2 "iris_unused" 1.25


	mouth 0 "mouth" "ValveBiped.Bip01_Head1" 0 1 0

$attachment "eyes" "ValveBiped.Bip01_Head1" 3.4 -3.4 -0.62 rotate 0 -80.1 -90
$attachment "mouth" "ValveBiped.Bip01_Head1" 0.8 -5.8 -0.15 rotate 0 -80 -90
$attachment "forward" "ValveBiped.forward" 0 0 0 rotate 0 0 0
$attachment "primary" "ValveBiped.Bip01_Spine2" 10.44 -5.1 -4.88 rotate -11.71 179.79 3.52
$attachment "lfoot" "ValveBiped.Bip01_L_Foot" 0 5.2 0 rotate 0 0 0
$attachment "rfoot" "ValveBiped.Bip01_R_Foot" 0 5.2 0 rotate 0 0 0
$attachment "muzzle_flash" "ValveBiped.Bip01_L_Hand" 0 0 0 rotate 0 0 0

$cbox 0 0 0 0 0 0

$bbox -29.275 -9.386 -2.542 29.312 16.192 77.155

$hboxset "default"
$hbox 1 "ValveBiped.Bip01_Head1" -1.25 -6.5 -3.19 8.25 3.5 3.31
$hbox 4 "ValveBiped.Bip01_L_UpperArm" 0 -2.75 -2.75 12.51 1.75 2.25
$hbox 4 "ValveBiped.Bip01_L_Forearm" 0 -2.19 -2.38 13 1.81 1.62
$hbox 4 "ValveBiped.Bip01_L_Hand" 0.06 -2 -1.5 4.06 1 2.5
$hbox 5 "ValveBiped.Bip01_R_UpperArm" 0 -3 -2.25 12.39 2 2.75
$hbox 5 "ValveBiped.Bip01_R_Forearm" -0.5 -2.2 -1.55 12.5 1.8 2.45
$hbox 5 "ValveBiped.Bip01_R_Hand" 0.06 -2 -2.5 4.06 1 1.5
$hbox 6 "ValveBiped.Bip01_L_Thigh" 0 -3.75 -3.25 17.85 3.75 3.25
$hbox 6 "ValveBiped.Bip01_L_Calf" 0 -3.51 -3.28 15.64 3.49 2.72
$hbox 6 "ValveBiped.Bip01_L_Foot" -1.07 -2 -2.84 5.04 5 2.16
$hbox 6 "ValveBiped.Bip01_L_Toe0" -0.5 -3 -2.19 2.5 0 2.46
$hbox 7 "ValveBiped.Bip01_R_Thigh" 0 -3.75 -3.25 17.85 3.75 3.25
$hbox 7 "ValveBiped.Bip01_R_Calf" 0 -3.51 -2.82 15.64 3.49 3.18
$hbox 7 "ValveBiped.Bip01_R_Foot" -1.06 -2.01 -2.28 5.05 4.99 2.72
$hbox 7 "ValveBiped.Bip01_R_Toe0" -0.5 -3 -2.6 2.5 0 2.1
$hbox 3 "ValveBiped.Bip01_Pelvis" -7.5 -5.5 -6 7.5 8.5 5
$hbox 2 "ValveBiped.Bip01_Spine2" -2.5 -2.5 -7 14.5 7.5 7
$skipboneinbbox

$sectionframes 30 101

$ikchain "rhand" "ValveBiped.Bip01_R_Hand" knee 0.707 0.707 0
$ikchain "lhand" "ValveBiped.Bip01_L_Hand" knee 0.707 0.707 0
$ikchain "rfoot" "ValveBiped.Bip01_R_Foot" knee 0.707 -0.707 0
$ikchain "lfoot" "ValveBiped.Bip01_L_Foot" knee 0.707 -0.707 0

	ikrule "rhand" release contact 0 fakeorigin 0 0 0 fakerotate 0 0 0 floor 0 height 0 radius 0 range 0 0 101 101 target 0
	ikrule "lhand" release contact 0 fakeorigin 0 0 0 fakerotate 0 0 0 floor 0 height 0 radius 0 range 0 0 101 101 target 1
	ikrule "rfoot" release contact 0 fakeorigin 0 0 0 fakerotate 0 0 0 floor 0 height 0 radius 0 range 0 0 101 101 target 2
	ikrule "lfoot" release contact 0 fakeorigin 0 0 0 fakerotate 0 0 0 floor 0 height 0 radius 0 range 0 0 101 101 target 3

	$jointconstrain "ValveBiped.Bip01_L_Thigh" x limit -30 30 0
	$jointconstrain "ValveBiped.Bip01_L_Thigh" y limit -41 41 0
	$jointconstrain "ValveBiped.Bip01_L_Thigh" z limit -90 135 0

$maxeyedeflection 13

$eyeposition 0 0 70

 

 

Model Format

Gmod is a Source 1 game, and so it's natural format is .mdl files.

PAC allows the use of .obj imports, however as this isn't the native model format for the Source engine, you'll be increasing the render costs of the model by not-insignificant amounts.

Not generally a huge deal for a few smaller items, but always strive to use .mdl models when possible especially for larger and more complex models. They'll end up looking better anyway.

Importing models from Blender to Gmod isn't generally that difficult. I might post a tutorial here at some point, but others do exist online that you can seek out if you want to start shifting models into gmod the proper way.

 

 

 

 

This thread will be updated with time as more things come up.

If you need any help, you can find Jun in the SSTRP.net discord as "Jun", search "Auntie Atago~#0048" if you can't find me.

  • Like 2
Link to comment
Guest
This topic is now closed to further replies.
×
×
  • Create New...