Propper++

From Valve Developer Community
Jump to: navigation, search
English (en)Português do Brasil (pt-br)Русский (ru)Translate (Translate)

The Propper++ Propper++ tool in Hammer++ allows you to convert brushwork into model geometry, or merge model geometry together. It serves as a complete replacement for the old Propper tool.

The Propper++ interface

Setup

Before using the tool, the StudioMDL executable must be configured in Tools -> Options -> Build Programs -> MDL executable. This is the compiler that will output new models for the engine.

Warning.pngWarning:If using Garry's Mod Garry's Mod, it does not have a 64-bit StudioMDL yet. You must use the 32-bit one, which is inside the bin folder rather than bin/win64.
If you get a command failure later with return code 0x2, this is why.
Warning.pngWarning:If using Team Fortress 2 Team Fortress 2, the 64-bit StudioMDL is currently non-functional. You must use the 32-bit one, which is inside the bin folder rather than bin/x64.

Basic usage

Brushes

First, select the brushes you want to turn into models. If you want them to be combined into 1 model rather than individual models, you need to group them first, either via the Group tools or by converting them into a brush entity. Then open Propper++ in the Tools -> Propper++ menu or with Ctrl + Shift + P keybind.

You'll see a bunch of options. You don't need to worry about most of these except for the Model Path + Name option at the top. The name at the end will be the name given to your model. Change it to something appropriate for your model, like mycoolchair.

Collision will be automatically generated. If you don't want collision, set Entity name as physics mesh to blank.

Press Build + Compile, and the brushes should now be successfully turned into a model after the compiler finishes.

The old brush geometry will be saved into the Propper visgroup. This can be used to preserve or recover the original geometry if needed.

Note.pngNote:Remember! Since these are custom assets, you need to ensure they are packed into your map when you share it with other people. Tools like CompilePal or VIDE can do this for you.
Warning.pngWarning:Be careful with converting very complicated brush geometry (hundreds or thousands of faces total etc). This will generate complex collision that may end up lagging the server. In this case, you should either split the geometry up, or specify another group of brushes as the simplified collision model using the Entity name as physics mesh setting.
Icon-Bug.pngBug:Non-FGD brush entities will not be recognized by Propper++.  [todo tested in?]

Prop scaling

In addition to converting brushes, Propper++ supports conversions or merging with selected models too. Models that are run through Propper++ will have their skins, body groups and scaling baked in. A useful application of this is to quickly scale prop_static entities in games that don't support it, without the old tedious way of decompiling and then recompiling models.

To scale a prop_static uniformly, change it into a prop_dynamic first so you can change the Model Scale, or add the modelscale keyvalue with SmartEdit disabled.

Tip.pngTip:In Hammer++ Hammer++ with a prop selected in 3D view, hold Ctrl and scroll the mouse wheel to change the model scale in increments of 0.5. Holding Shift will scale it in smaller increments of 0.05.

Alternatively, change the Scale option in the Propper++ menu. You can use negative values here to mirror the prop along an axis.

Merging brushes and models

It's also possible to combine both brushes and models together. To do this, you need to group the selection using the Group tools and then run the tool as normal.

Advanced usage

Editing before compiling

It can be useful to edit the generated model files to add extra options such as $texturegroup or to further edit the meshes. Propper++ supports this by having a two-step process, Build and then Compile.
Usually both steps are run at the same time, but they can be individually run too.

  • Build will generate the QC and SMD files for the model.
  • Compile sends the generated files to the model compiler and then replaces the selection (if enabled).

Therefore you can press Build-Only, edit the files, and then Compile-Only to send it to the compiler.

Tip.pngTip:Use the Explore button to open the folder containing the generated files quickly.

Adjusting model origin or illumposition

By default, the generated model's origin and illum position is placed at the center of the selected geometry's bounding box.

If using the Propper++ tool on a brush entity, and the entity has an origin keyvalue, that value will be used instead.

The illum position can be overriden by specifying a custom lighting origin on any selected model. Propper++ will read the first one it finds and use that as the new $illumposition.

Confirm:What about when using the tool on groups of entities, potentially including prop entities? Can the origin be set via some other method then?

Adding skins

For more info about adding skins, see $texturegroup.

Open your custom QC that was created by Propper++ and add this following code somewhere in the file:

$cdmaterials "models/mycustomfolder" "models/lorem/mycustomfolder2"
$texturegroup "skinfamilies"
{
	{ "default_texture"  } // Skin 0 - Default
	{ "custom_texture_1" } // Skin 1
	{ "custom_texture_2" } // Skin 2
	{ "custom_texture_3" } // Skin 3
	[...]
}

the default (skin 0) should be the default texture and skin 1-32 should be the texture you want to replace.

If you want to replace more textures than 1 texture you can add this following code:

$cdmaterials "models/mycustomfolder" "models/lorem/mycustomfolder2"
$texturegroup "skinfamilies"
{
	{ "(1)random_texture" "(2)random_texture" [...] } // Random textures that are default
	{ "baggagecarousel04" "helicopter_news2"  [...] } // Example
	{ "baggagecarousel04" "acvent05"          [...] } // Example
	{ "acunit01"          "acvent05"          [...] } // Example
	[...]
}

The first column will replace the first default texture (1), while the second column will replace the second texture (2)

Mass conversion

When multiple groups of brushes are selected, each of these will be converted into their own individual models. A warning will appear in the Propper++ menu when mode is active. The model names will have a numerical suffix appended automatically when generating.

Displacements

Displacements can also be converted by Propper++. However unlike brushes, collision will not be built for them. This is intentional as auto-generated collision models for displacements would be very costly and potentially cause server lag (every triangle needs to be its own convex collision piece). If you require collisions for displacements, built a simplified one from brushes and specify it using the Entity name as physics mesh setting.

Another limitation is that blended textures will also not appear after conversion, as models don't support any vertex blending.

Static prop combine

Performance comparison of 240 static prop trees on an empty maps using no settings, fade distances and then with Propper++ combine.
A cluster of boxes shown with r_colorstaticprops 1. This is a good candidate for combining to reduce 3 drawcalls into 1.

Propper++ can also be used to combine props for optimization, similar to Static Prop Combine in newer games. A demonstration of the performance gain from merging static props together is shown on the right.

Combining improves performance by reducing draw calls. Draw calls in a nutshell are how the CPU tells your GPU to render something. However, this communication is costly and modern games usually aim to reduce draw calls as much as possible. Every prop in the game will issue a new draw call. If there is multiple materials in a prop, a new draw call is issued for each material. By combining props, draw calls are reduced. Valve claimed that by employing static prop combine in their CS:GO maps (which are very heavy on static prop usage), they gained a 40% performance improvement.

When considering models for merging, make sure to follow these principles:

  • You should only merge models that share the same materials, otherwise you will not get any benefit from static prop combine. Different materials still have to issue a new draw call. For example, don't merge a tree with a box, but do merge boxes with other boxes.
  • Merge models that are within "clusters" or within vicinity of each other. Merging models will expand the bounding box and make it less likely to be culled when behind areaportals or out of view etc.
  • Avoid merging models that have collision and are very spread out from each other, as the physics engine cannot optimize this efficiently. Disable collision meshes if you need to do this, or build simplified ones with tool textured brushes.
  • Don't combine across shadows unless the models support per-vertex lighting (i.e. none of the materials have $bumpmap, $normalmap, or $phong.) The combined prop will only sample lighting from its center and this may look awkward across a shadow divide. Alternatively, split the combined prop in half along the shadow boundary so both sides receive correct lighting.

To easily identify clusters of props that you can merge, use the r_colorstaticprops 1 command in-game. Each unique color of a prop means they are issuing a new draw call. After merging props, you will notice that they share the same color (which is good).

If you are encountering bad lighting with the combined props, such as it turning very dark, this may be because of the lighting origin being embedded inside geometry. To fix this, assign a lighting origin entity which is in a more favorable spot.

Performance comparison of 240 static prop barrels. Each has 1 LOD level that halves the triangle count. Shown with LODs on, off and Propper combined with no LODs.
Note.pngNote:Beware that merging a lot of props can lead to your map file sizes being bloated. However if your game supports BSP compression, this won't be too much of an issue as the combined props have a very good compression ratio.
Note.pngNote:The engine has a vertex limit per mesh. However, Propper++ will automatically split the model into mesh chunks after 65535 vertices.
Note.pngNote:LODs are not preserved. However, most of the time they aren't too important especially on today's hardware. Combining props will give a significantly better improvement, see the comparison on the right.
Warning.pngWarning:Merging a lot of detailed models may cause the model compiler to fail or crash. If that happens, try only merging half of the selection and then do the other half separately.

Lightmapping static props

Note.pngNote:This feature is only useful for branches of Source that support static prop lightmaps, namely Source 2013 Multiplayer Source 2013 Multiplayer, Team Fortress 2 Team Fortress 2, and Garry's Mod Garry's Mod.

In the aforementioned branches of the engine, prop_static supports having a lightmap generated by VRAD. However this comes with major limitations:

  • Props with overlapping UVs or multiple materials do not get lightmapped correctly.
  • Brush geometry converted into models can't be lightmapped correctly due to distorted UVs.
  • Materials that use $bumpmap or $phong cannot be lightmapped.

The Lightmap Atlas bypasses all these limitations. It takes the selection of models and/or brushes, and generates a singular non-overlapping UV (an 'atlas') for the whole model, and then projects the textures onto it. It strips away bumpmap and phong as well from the material automatically.

To use this feature, first enable Generate atlas.

Change the width and height of the atlas as desired. This will wildly vary depending on how your geometry looks, how many you are merging etc, so experiment with this. Keep it at a power of 2. Higher resolutions will have better texture quality, but come with bigger file sizes. This is not the size of the lightmap, that is separately defined in the prop_static settings later.

There is 4 formats to choose from: DXT1, DXT5, RGB888, RGBA8888. DXT formats are compressed, the others aren't and hence come with better quality but much bigger file size. DXT1 and RGB888 have no alpha channel which saves file size. You shouldn't use DXT5 or RGBA8888 unless you need the alpha channel preserved (perhaps for something like $envmap masking later).

Finally, the option for bilinear filtering can be turned off for a 'sharper' texture look, however this is subjective and depends on the texture and model. Some look better without this and others don't. Usually you should keep this on.

After building the model, it will now be ready for lightmapping. See the prop_static page for more details. If the texture looks too blurry, increase the atlas resolution or reduce the number of props you are combining together.

Atlas textures are saved to the Material Path + the Model Name if you want to inspect how they look.

Baking blended textures from displacements is currently not supported.

Warning.pngWarning:Reminder that prop lightmaps are not only costly for file size and VRAM usage, but also for VRAD compile time. Use this sparingly.
Warning.pngWarning:Brush faces take up a lot of area in the atlas because they are big and are tiling. This can lead to everything else such as models becoming disproportionately blurry in the atlas. It's best to stick to models only when possible. If you need to use brush faces, nodraw as many faces as possible so they aren't present in the atlas.

Options

  • Model Path + Name

This is the directory and name of the model that will be generated. It is relative to the game's models directory, so for example with Garry's Mod, "propper/mycoolchair" will generate the model into this location:

.../steamapps/GarrysMod/garrysmod/models/propper/mycoolchair.mdl

Any $vmf markers will be replaced with the current VMF name. This is useful for organization and to prevent conflicts between maps if they happen to share the same model name.

  • Add incremental suffix if already existing MDL name is found

When enabled, if a MDL with the same name as the Model Path + Name is found to already exist, an incremental suffix will be added to the model name (such as _0, _1.. .etc). The suffix will be incremented until a non-conflicting name is found. This is useful to prevent accidentally overriding existing models, as the files would not be recoverable afterwards. Disable this option if you specifically want to override a model with new files (alternatively you can also just delete the existing MDL file).

  • Source file directory

This is where the files required for the model compiler will be placed. Similar to above, this can be either relative to the game's directory or you can put in a full path to anywhere on your drive. It supports $vmf markers as well. Example with Garry's Mod, "modelsrc/propper/rpassets" will put the source files, which consist of SMD and QC files, in this location:

.../steamapps/GarrysMod/garrysmod/modelsrc/propper/rpassets/[files]

  • Material path

This is the directory where converted materials will be placed. Brush materials usually use LightmappedGeneric shaders which are not compatible with models, so Propper++ will convert these shaders into VertexLitGeneric. Like before, it is relative to the game directory but inside the materials folder, and it supports $vmf markers. Example with Garry's Mod, "models/propper/rpassets" will generate materials into this location:

.../steamapps/GarrysMod/garrysmod/materials/models/propper/[files]

  • Entity name as physics mesh

This allows you to specify what named entity should be used as the collision model. This is useful to make simplified physics models for very complex geometry. Setting this to $self will use the selected entity as the collision model. Setting it to blank will generate no collision. Entity names will not work when multiple groups of solids are selected.

  • Entity classname

If Create entity after compile is enabled, this will replace the selection with a new entity that has the generated model set.

  • Surfaceprop

The $surfaceprop for the model. If blank, the texture that covers the most area will be selected automatically as the surface prop. If models are in the selection, it will use the surfaceprop of the most occuring model.

  • Scale

The scaling along X, Y and Z for the model. Negative values are supported and will apply a correction to flip faces into the right direction.

  • Mass

Overrides mass if not blank. Otherwise, it's calculated automatically by the model compiler with $automass.

  • Smoothing angle

Smooths brush vertex normals that are less than this angle apart, similar to -smooth in VRAD. 0 disables smoothing. Useful for round shapes like cylinders, etc.

  • Relocate materials

If enabled, moves brush materials into the folder specified by the Material path. This prevents normal materials from being overriden by the new converted ones.

  • Rename shaders

If enabled, LightmappedGeneric, WorldVertexTransition and Water shaders will be renamed to VertexLitGeneric.

  • $concave collision

Enables $concave collision models. If disabled, the model compiler will 'shrinkwrap' the model to create a new collision model.

  • Remove bad collision faces

Tiny or thin brush faces can cause issues when compiling the collision. This will automatically remove such faces (simply adds $remove2d to the $collisionmodel)

  • Skip nodraw faces

Skips nodraw faces from being added to the visual geometry. They are still added to the collision model though.

  • Wait for keypress after compile

If set, waits for a keypress before closing the compiler window output. Useful to check for warnings or errors.

  • Create entity after compile

If enabled, this will replace the selection with a new entity that has the generated model set.

  • Move selection to 'Propper' visgroup

If enabled, the selection is preserved to the visgroup named 'Propper' after compiling.

  • $casttextureshadows

Adds the $casttextureshadows command to the QC. Useful to have transparent shadows working in VRAD (with -textureshadows) without having to add the model into lights.rad manually.

  • Lightmap Atlas

See the advanced usage section above.

Keyvalues

The following KVs are used by Propper++:

Origin (origin) <origin>
If there is only one entity in a given group, the origin KV is used to override the output SMD model's origin.
Pitch Yaw Roll (Y Z X) (angles) <angles>
Orientation of the output SMD model.
Name (targetname) <targetname>
Lighting Origin (lightingorigin) <targetname>
Set the $illumposition based upon the origin of the defined named entity.
Model (model) <model path>
MDL to use.
Skin (skin) <integer>
Skin of the MDL to use.
Bodygroup (body) <integer>
Bodygroup of the MDL to use.
Uniform Model Scale (modelscale) <float>
Scale the output SMD model uniformly on all axes.