3d objects: .mesh files
Documentation on .mesh files and their properties.
Summary
Published: ??? by mana vortex Last documented edit: Sep 19 2024 by mana vortex
This page contains information on .mesh files and their properties.
Wait, that's not what I want!
See WKit Blender Plugin: Import/Export -> Meshes for a guide on export/import
To edit a mesh's appearance, check Changing materials, colors and textures
If you just want to use a textured material, check Using a textured material
To learn about mesh materials, see AMM: Textured items and Cyberpunk Materials using Custom Props
To hide parts of a mesh under different circumstances, check First Person Perspective Fixes
To stop copy-pasting so much, check ArchiveXL: dynamic materials
What's a mesh?
In the context of Cyberpunk, a mesh is the file that defines the and the of an object in the game world.
A mesh can have several submeshes, each of which has own material assignments. You can learn more about this on the sub-page for Submeshes, Materials and Chunks.
Mesh files for inanimate objects also tend to contain extensive physics parameters governing their physical weight and general behavior.
How the mesh is loaded
Meshes are loaded via Components (e.g. entGarmentSkinnedMeshComponent). Components are defined either in mesh entity files or in an .app file, where each appearance has its own components array.
For more information on this, please check Submeshes, Materials and Chunks -> Chunkmasks: partially hiding meshes
Shadows
There are two ways of adding shadows to meshes:
Component property
To make a mesh cast a real-time shadow, set the component's property castShadows
to Always
.
Depending on your geometry, this can impact performance.
Shadow mesh
Many meshes have dedicated shadow meshes, which have a much lower level of detail and will be hidden by default. You can open any clothing item's mesh entity to see this in action.
Mesh Preview
You can see which submesh is which in the Mesh Preview
tab after opening the mesh file:

With the boxes on the left, you can toggle submeshes on and off.
Material assignment
This section describes how you tell the game exactly how your mesh should look — the technical term for this is "material assignment". This section will hopefully remove all confusion about where those textures go, and how those pesky t-shirt appearances work.
If you just want to know how to assign or add a new material, skip ahead to Practice
To learn more about submeshes and chunkmasks, check Submeshes, Materials and Chunks
This page only contains mesh-specific information. Find more details on materials under Textures, Materials and Shaders
Theory
A mesh file has one or more appearances, which are used by components to define how a thing looks. Think of an appearance as a full package: this shirt is black, it has red stitches, and there's an Arasaka logo on it.
In general, the game does not change anything about these appearances.
Appearances
Each appearance is defined by an entry in the appearances
array at the top of the file.
Every appearance has one or more chunkMaterials,
which correspond to the item's individual submeshes
(the different parts it has in Blender). These entries are selected by name.
You can switch to the Mesh Preview tab to see those chunks. Here is how it looks:

Now, where are those materials coming from?
Definitions
These materials are defined in the materialEntries
list. Each materialEntry
holds the following properties:
the material's name (which you can use to assign chunkMaterials),
whether this is a local or an external material (more about this in Material instances below!),
the index of the material instance in the corresponding list
Material instances
Local material instances are situated inside the .mesh, either inside localMaterialInstances.materials
, or in preloadLocalMaterialInstances
.
They define a base material, and configure its properties.
The base material defines which shader template (.mt
/.remt
) will be used. Sometimes, this happens through a .mi
file — this is an external material (more about this later).
The values
array holds a list of properties which pass information to the shader, for example which diffuse texture to use, or that the entire t-shirt should be tinted red.
External materials
External materials are the same as local materials, but instead of a .mesh, they're sitting inside a .mi
file, so they can be re-used across multiple meshes without copy-pasting everything.
If a material is defined as external, it will be pulled in via file path through either externalMaterials
or preloadExternalMaterials
. For an example of this, take a look at hairs (e.g. ep1\characters\common\hair\hh_201_wa__dawn\hh_121_wa__dawn.mesh
) — they do not use local materials at all.
Alternatively, you can extend .mi
files by using them as the base material.
Mesh file: diagram
Here's an overview:

Practice
Now that you've learned how everything hangs together, let's take an actual look at this.
TL;DR: I just want to add a new material!
Summary:
Assign material for submesh in appearance -> chunkMaterials
Register the material by name in
materialEntries
Define the material in either
localMaterialInstances.materials
orexternalMaterials
Step 1: Appearances
An appearance
is the entry point into a mesh.
One appearance
has a number of chunkMaterials
, which tell Cyberpunk how they are supposed to look:

Wolvenkit will follow these entries to materialEntries, where they are defined:

The index
property in materialEntries will finally point at the material's instance, where you can find its properties. Depending on isLocalInstance
, that can be one of several places — find a list in Step 3: Material definition.
ChunkMaterials
You assign materials based on the "chunks" (the individual submeshes) inside a mesh. Open the mesh file in Wolvenkit and open the "appearances" array, then make sure that each of your submeshes has an entry inside the array.

Step 2: Material registry
Materials are registered in the array materialEntries
inside your mesh:

While you can mix external and local materials, you can not mix preloaded and non-preloaded ones. For details, see below.
index
numerical index of corresponding material in target list (as defined by isLocalInstance
)
isLocalInstance
Selects the material target list.
True: local material in localMaterialBuffer.materials
or preloadLocalMaterialInstances
False: material reference inexternalMaterials
or preloadExternalMaterials
For more information on this, see the page for local/external materials.
name
unique name of material, used to select the material via chunkMaterial
Preload… what?
Many of CDPR's early meshes use preloadLocalMaterialInstances
instead of localMaterialBuffer.materials
. As far as we are concerned, you can use the two interchangeably, but:
If you are using a mix of local and external materials, you must use the corresponding lists:
localMaterialBuffer.materials
externalMaterials
preloadLocalMaterialInstances
preloadExternalMaterials
If you mix the two, the materials outside of preload
… will appear as transparent the first 1-2 times you trigger your item's appearance.
Step 3: Material definition
A material's actual definition (instance) can be in a CMaterialInstance
inside the mesh or in a .mi
file in the project. Wolvenkit will display material names as defined in the materialEntries
, making it easier for you to see what's what.
For more details on material instances, check Textures, Materials and Shaders -> Definition: Material
MaterialInstance: The local material
The materials themselves are inside the array localMaterialBuffer.materials
(or preloadLocalMaterials
in case of older meshes).
You can't go wrong by using those. However, if you don't have any properties that are unique to your mesh or appearance (for example a custom normal map), you might consider creating and using an external material instead.
A material instance looks like this:

Material reference: reusing materials
A relative path to an external material, usually encapsulated in a .mi file. Use this if you don't need to add extra properties.
Last updated