Paint in 3D


DOCUMENTATION

Thank you for using Paint in 3D ❤️

If you haven't already, please consider writing a review. They really help me out!



How do I upgrade?

First, make sure you back up your project files.

Next, install the latest version.

If for some reason the latest updates breaks your project (e.g. errors in the console), then try deleting the root folder for this asset, and reinstalling it.

If it still doesn't work then go back to your previous version, and let me know what the errors are, so I can fix it.



Video Tutorials

In addition to the written documentation here, you can also find tutorial videos HERE.



Getting Started


Step 1

Any GameObject that has a MeshFilter + MeshRenderer or SkinnedMeshRenderer can be painted.

METHOD 1 Add the CwPaintableMesh component to your GameObject.
METHOD 2 Click the context menu (⋮ icon at the top right) of your MeshRenderer or SkinnedMeshRenderer component, and select the Make Paintable (Paint in 3D) option.

Once the CwPaintableMesh component has been added, you can click the Analyze Mesh button to see if your mesh is suitable for painting.



Step 2

Next, you need to pick which textures you want to paint.

Your MeshRenderer or SkinnedMeshRenderer component has the Materials array, which usually has one material. Each material is rendered using a shader, and each shader has a list of textures that it uses. Most shaders have the Albedo/Color texture, but some more advanced shaders can have a Normal Map texture, Emission texture, etc.

METHOD 1 Click the Add Paintable Texture button from the CwPaintableMesh component inspector.
METHOD 2 Add the CwPaintableMeshTexture component to your GameObject, alongside the CwPaintableMesh component.

You should now see the CwPaintableMeshTexture component added to your GameObject.

Inside this component, you can see the Slot setting. Next to this setting is a dropdown arrow button which you can click, and this allows you to pick from a list of all textures in your renderer.

For most objects, the default 0, _MainTex setting is all you need. But if you have multiple materials or need to do advanced painting you may need to change this. For example, to paint normal maps you may need to choose 0, _BumpMap or similar, the exact texture name depends on the shader/material.

NOTE  The URP/HDRP Lit shaders use the 0, _BaseMap texture slot for the albedo. The _MainTex slot is a fake slot only used for backwards compatibility‽

The rest of the settings should be OK at their default values for now.



Step 3

Paint in 3D comes with many ways to paint objects.

One simple method is to make a new GameObject, and add the CwHitScreen and CwPaintDecal components. These components will automatically work together, allowing you to paint using the mouse (or your finger if you run it on a mobile device).

NOTE  The CwHitScreen component uses raycasts, so your mesh must have colliders (e.g. MeshCollider) for it to know where to paint.

You can now adjust the CwPaintDecal settings to your liking. I recommend you at least change the Color or Texture, because the default paint color is white, and if you paint on a white texture then it may look like nothing is happening!

Once done, press play. You should now be able to click on your object in the Game window, and have the decal you paint on your object under the mouse.

For more advanced ways to paint I recommend you go through the demo scenes in the PaintIn3D/Examples folder and see how they're put together!



Presets

To save time, you can skip Step 1 & 2 by using the Presets system.




Mesh Analysis

When you make an object paintable, you add the CwPaintableMesh component.

Inside this component inspector is the Analyze Mesh button.

If you click this, then it will open the Mesh Analysis window with the current mesh you're trying to paint.


Paintable UV Maps

If your mesh is suitable for painting, it should look something like this.

As you can see, there are few overlapping triangles, few out of bounds triangles, few triangles with no UV, and the texture space is fairly well utilized.



Unsuitable UV Maps

If your mesh is NOT suitable for painting, it will look something like this.

As you can see, there are large areas of overlap in red, or many out of bounds triangles, or many triangles with no UV map.

In any of these scenarios, your mesh will need to be UV unwrapped before you can paint it.

NOTE  The Cube and Cylinder meshes that come with Unity are examples of meshes with unsuitable UVs, because they contain a lot of overlap.


Mesh Fixer

It's best to manually UV unwrap your meshes in your favorite 3D modeling software (e.g. Blender), because you will have full control over how it is unwrapped and can therefore give priority to certain areas and perhaps make better use of the texture space.

However, Paint in 3D comes with a tool to perform this UV unwrap for you.

To use it, click the Fix button at the top right of the Mesh Analysis window, and read the next tutorial section HERE.




Mesh Fixer

Paint in 3D comes with the Mesh Fixer tool, which allows you to UV Unwrap your mesh so it can be painted, and/or fix UV seams.

Method 1  Inside your paintable object's CwPaintableMesh component, click the AnalyzeMesh button, and click the Fix button at the top right.
Method 2  Find your mesh or model prefab in the Project window, right click it, and select the Create/CW/Paint in 3D/Mesh Fixer option.
Method 3  Right click in the Project window, select the Create/CW/Paint in 3D/Mesh Fixer option, and click the Meshes / Add button.

This will add a Mesh Fixer asset to your project.

Next to your mesh, you can click the Analyze Old button to see what the current non-fixed UV map looks like.


Coord

This setting allows you to choose which UV channel/coordinate you want to fix. For most meshes this should be set to First.



Recenter UV

For a mesh to be paintable, the UV data must be within the standard 0..1 range on the X and Y axes. However, some assets or mesh workflows put the meshes in slightly different ranges like 1..2 or 2..3, typically across the X axis.

When the UVs are recentered, it detects this scenario, and shifts the UVs to the typical 0..1 range.

NOTE  This setting is always on.
NOTE  If your mesh has UVs that have tiling and go well beyond the expected range (e.g. 3..9), then recentering will not work.


Generate UV

If you enable this setting, then your mesh will have entirely new UV data generated.



Fix Seams

If you enable this setting, then the UV island edges of your mesh will be extended so they can be painted without seams appearing.

NOTE  This will increase the amount of vertices/triangles in your mesh.


Generate

Once you're happy with your mesh fixer settings, you can click the Generate button.

This will make duplicates of all meshes in the Meshes list, process them based on your settings, and then save them as child assets of the mesh fixer.

Next to your mesh, you can click the Analyze New button to see what the new fixed UV map looks like.



Swap Meshes

If your scene contains CwPaintableMesh components that still use the old non-fixed meshes, then they will show up at the bottom of the mesh fixer under the SWAP MESHES list, allowing you to quickly update them.



Remap Texture

If you enable GenerateUV, then your meshes will have their UV data completely replaced with an entirely new layout.

This is fine if your meshes will then be painted from scratch. However, if your meshes originally had a texture, then those textures must be remapped to the new UV data.

To remap them, simply drag and drop your textures into the Remap Texture field one at a time. This will reveal a list of meshes you can use for the remapping, and once chosen you will be prompted to save the texture.

This remapping feature is very useful with low-poly style meshes, which are typically colored using an atlas style color palette, where the UV data for each triangle is flattened to a point on a specific color.




Secondary UV

If your mesh UV data isn't paintable, then using the Mesh Fixer is usually the best approach. However, in some scenarios you may want to keep the original mesh UV data, but still want to be able to paint your mesh.

In this scenario, another approach is to paint using the second channel of UV data. The second channel of UV data is usually used for lightmapping, but lightmap UVs are also perfect for painting.

To automatically generate this secondary UV data, you can enable the Generate Lightmap UVs setting in your model/mesh import settings. This will generate UV data suitable for painting, and they will be stored in the second UV channel.

NOTE  Most shaders (including all default Unity shaders) only read data from the first UV channel, so this new UV data won't be used. To use it, you must either use a shader that reads from the second UV channel instead of the first, or copy the new UV data from the second UV channel to the first.
NOTE  If you want to remove UV seams from this newly generated UV data, then you will have to run the second UV channel through the Seam Fixer tool.

Does Paint in 3D come with shaders that use the second UV channel?

Yes, Paint in 3D comes with several shaders designed to solve this issue.

If you want to keep your original shader/material that uses the first UV channel, then you can use the Paint in 3D / Overlay shader on top of your base material. Paint in 3D already comes with a pre-configured material called Overlay (Second UV Coord), which you can add on top of your base material. Keep in mind you will now be painting the second material (index 1), so you must update your CwPaintableMeshTexture component settings to target the second material slot index (1).

This technique is demonstrated in the UV Requirements / Automatic Overlay demo scene.

NOTE  If your mesh has multiple sub-meshes, then this technique won't work.

If you don't mind replacing your original shader/material, then the Paint in 3D / Solid shader can be used instead. This shader uses the first UV channel for base textures, and then allows you to override the albedo/opacity/smoothness/etc using secondary textures that use the second UV channel.

This technique is demonstrated in the UV Requirements / Automatic Secondary demo scene.

NOTE  The secondary/override textures in this shader use premultiplied alpha blending, so you should change your paint brushes to use the Premultiplied blending mode.
NOTE  You should expand the CwPaintableMeshTexture component's Advanced menu, and change the Conversion setting to Premultiply.


Can I use the second UV channel with the Standard shader?

Kind of. Using the following steps you can get it working using the detail texture. Just keep in mind this isn't the best solution, because it doesn't replace the albedo exactly.

Step 1 Select your material that uses the Standard shader, and change the Secondary Maps > UV Set setting to UV1.
Step 2 Select your CwPaintableMeshTexture component, and change the the Slot setting from _MainTex to _DetailAlbedoMap.
Step 3 Change the Channel setting to Second.
Step 4 Change the Shader Keyword setting to _DETAIL_MULX2.


How can I use the second UV channel with a different shader?

Most shaders only the first UV channel, so you will need to make an alternative shader that uses the second.

For example, instead of using uv_MainTex you use uv2_MainTex, or instead of using texcoord0 : TEXCOORD0, you use texcoord1 : TEXCOORD1.

NOTE  When painting using the second channel, you must set the CwPaintableMeshTexture > Channel setting to Second.

Paint in 3D comes with a range of shaders that allow you to specify the UV channel used (e.g. PaintIn3D/Opaque).




Presets

To make an object paintable, you must add and configure the CwPaintableMesh and CwPaintableMeshTexture components.

However, this can be time confusing to do if you have many objects, or a complex configuration.

To speed things up, Paint in 3D comes with the presets system.


Step 1

Select the Window/CW/Paintable Objects menu option.

This will open the Paintable Objects window.



Step 2

You can now select some GameObjects in the Scene or Hierarchy window.

Any GameObject or child GameObject you select that has a MeshFilter + MeshRenderer or SkinnedMeshRenderer will appear as a list in this window.



Step 3

Next to each GameObject will be the Make Paintable button.

If you click this, it will list all possible presets for this Renderer and Material's Shader type.

You can then choose one.



Custom Shader

Paint in 3D comes with presets for most of Unity's built-in shaders. However, if you've made your own shaders, or you have another asset with custom shaders, then you will have to add them to an existing preset.

All presets can be found in the Plugins/CW/PaintIn3D/Extras/Presets folder.

For example, the Basic - AA preset allows you to paint the _MainTex, which is usually the albedo (+ optional Alpha/Opacity). If you want to add your custom shader to this preset, then you can add it to the Shader Paths list.

If you're unsure what your shader is called, or want to add multiple shaders to this preset, then you can click the Find Shaders button, which will find all shaders in the current project that have all textures used by the preset (in this case of the Basic - AA preset, all shaders with _MainTex will be listed).



Custom Preset

If the presets that come with Paint in 3D aren't suitable for your project, then feel free to right click in the Project window, and select the Create/CW/Paint in 3D/Preset option.

This will add a new prefab to your project with the CwPreset, MeshFilter, MeshRenderer, and CwPaintableMesh components attached.

You must then set the ShaderPaths to include your shader, add all the CwPaintableMeshTexture components you want for this preset, and configure their Slot settings.

You can now use this preset from the Make Paintable button in the Paintable Objects window.




Fixing UV Seams

When you make complex 3d models it's inevitable your mesh will have UV seams, where one part of the texture is disconnected from another.

This normally isn't a problem with clever texturing, but when painting it can result in visual seams between these disconnected UV islands.


How do we fix them?

To fix these UV seams, Paint in 3D comes with a tool that can convert a normal mesh with UV seams into a fixed mesh without UV seams.

To access the tool, select any mesh in your project, click the context menu icon (⋮ button) at the top right, and select Fix Mesh (Paint in 3D).

This creates a seam fixer in your project, and automatically sets the Source mesh to the one you picked.

You can now press the Generate button to generate the fixed mesh.

If it was successful, you should see something like this in your Scene window:

Where the green lines are the original seams, and the blue lines are the new fixed seams. The blue lines should be outside of your original green lines. If your blue lines are overlapping then try reducing the Border setting a little, or the Threshold setting.

NOTE  Fixing seams adds vertices to your mesh. If your mesh was already close to the mesh vertex limit then this tool may not work for you.
NOTE  This tool isn't magic. If your original UV map is laid out poorly then this will won't fix it.


How do we use the fixed mesh?

The generated mesh will be placed as a child of the seam fixer in your Project window.

To use it, just drag and drop it from here into your MeshFilter or SkinnedMeshRenderer that uses this mesh.

NOTE  If your scene contains any CwPaintableMesh/CwPaintableMeshAtlas components using the original non-fixed mesh, then they will be listed at the bottom of the Mesh Fixer asset under the SWAP MESHES heading.


Auto Seam Fixer

If the above steps seem too tedious for you, then you can let Paint in 3D automatically do the seam fixing for you.

STEP 1 Select your paintable GameObject.
STEP 2 Find the CwPaintableMesh component in the inspector window.
STEP 3 Expand the Advanced settings.
STEP 4 Change the UseMesh setting to AutoSeamFix.

Your mesh will now be auto seam fixed just before you paint it for the first time.

NOTE  This technique doesn't allow you to adjust the seam fix settings.
NOTE  This technique has some performance overhead when you first paint your object, because the mesh must be seam fixed before it can be painted.

If either of these caveats is an issue, then I recommend you follow the previous section and manually seam fix the mesh.




Undo & Redo

Paint in 3D supports runtime undo & redo, but to save memory it's disabled by default.

To enable it, you need to follow these steps:


UndoRedo Setting

The first step is to select your CwPaintableMeshTexture components, and enable the UndoRedo setting.

If you're painting animated objects then you should set this to FullTextureCopy, but for most scenarios you can use LocalCommandCopy.

If you use the FullTextureCopy state mode then you must also set the State Limit setting. A value of 10 means you can undo paint operations 10 times, and then redo them 10 times. If you paint 11 times with this setting then your initial paint state will be deleted, and you will only be able to undo 10 times to your first paint operation.

You can read the CwPaintableMeshTexture documentation for more details.



Store States

The next step is to find your painting components, and enable the Store States setting.

This setting will automatically call the StoreState method on each CwPaintableMeshTexture in your scene, letting Paint in 3D know that you're about to paint on them.

For example, the CwHitScreen component has the StoreStates setting, as well as CwToggleParticles, and CwTapThrow.



Buttons

Finally, you can add the CwUndoAll and CwRedoAll components to your UI elements, and they will automatically be set up so when you click them they perform an undo or redo operation.

And that's it, your game should now have Undo & Redo paint functionality!



Memory Usage

Keep in mind that when using the FullTextureCopy mode, each undo/redo state is stored as a full texture state. This means that if your texture is 1024x1024 using the RGBA32 format, then each undo/redo state will consume 1024x1024x4 bytes of memory, or 4 megabytes.

If your game requires a lot of undo states and you want to reduce memory usage, then you should use the LocalCommandCopy mode instead, which will store a list of all paint commands (e.g. decal texture + paint orientation). This approach can reduce memory usage a lot, and it allows unlimited undo levels, but performing an undo requires rebuilding the texture from scratch, which can be slow if you have a lot of undo states. It also may not work correctly if your mesh is animated, because the paint will apply to different areas if your mesh has changed.



Manual Undo & Redo

The undo & redo functionality listed above works well for most games, but it's not suitable for all scenarios. To get full control you can manage it yourself using the following methods in the CwPaintableMeshTexture class:

Call StoreState before you apply paint to your objects.

Call Undo/Redo after, when you want to undo or redo.

These methods can also be accessed from the CwPaintableMeshTexture inspector context menu (⋮ button at top right), so you can test it from the editor.




Blend Modes

Blend modes allow you to change the way your painted pixels are applied to your textures.

If you're using in-editor painting, then you can right click a material to select it, and change the Blend Mode of the CwPaintDecal components you wish to modify.

If you're using in-game painting, then you can change the Blend Mode in the painting components (e.g. CwPaintSphere, CwPaintDecal).


Alpha Blend

This blend mode increases the alpha channel of your texture, and blends the RGB channels of your texture toward the color of your paint, based on the opacity of your paint.



Alpha Blend Inverse

This blend mode works similar to Alpha Blend, but it applies the blending in reverse.

This allows you to paint 'behind' the current painted areas, or fill them in.



Alpha Blend RGB

This blend mode works similar to Alpha Blend, but the alpha channel is not modified. This is ideal when you want to paint on only the solid parts of an already transparent texture.



Additive