If you haven't already, please consider writing a review. They really help me out!
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.
Yes, LWRP/URP is fully supported.
After you've set a scriptable rendering pipeline in your Graphics settings:
If you decide to go back to the standard rendering pipeline, then you can click the Switch To Standard Pipeline button.
Yes, just follow the same steps as the above tutorial.
The biggest difference between HDRP and all other rendering pipelines is how the lighting is handled. To make most demo scenes render correctly, you must:
If the scene contains a light (e.g. a star), then you can:
These modifications should more or less fix the lighting in all the demo scenes. Keep in mind these are just example settings for demo purposes, you can then tweak these to get the exact look you desire.
If you encounter any issues with this then let me know so I can improve them.
Yes, Paint in 3D is compatible with almost all custom shaders/materials.
The only requirement is that the texture you want to paint must be rendered to your mesh using the mesh UV data (e.g. uv, uv2, texcoord, texcoord2), which should be true for most shaders.
Keep in mind that shaders that perform minor modifications to the UV should still work, but the paint may appear slightly offset, depending on the level of UV modification performed. Minor modifications would include parallax mapping shaders, tessellated displacement, heat distortion, etc. If you want to paint these kinds of shaders/materials, then I recommend adding some kind of effect to your object while painting (e.g. particle effects) to disguise the offset.
The reason for this requirement is that Paint in 3D applies paint to your mesh using the mesh UV data. Paint in 3D doesn't know how your shader is modifying the UV data, so any shader modifications to the UV will be ignored and there will be a discrepancy between where the texture is painted, and where it actually maps to when rendered with your custom shader.
Yes, this asset has been developed and tested in VR, and supports both multi-pass & single-pass rendering modes.
Demo scenes like VR HVLP and VR Pen show you how to implement painting using Unity's XR system. While these demo scenes don't have integrations for third party VR systems (e.g. VRTK), integrating them yourself should be easy enough, as the components are designed to work using any system that support inspector events, and thus they shouldn't require any code changes.
Most of the example components and scenes that come with Paint in 3D are designed for mouse/touch inputs. For example the P3dHitScreen component uses mouse and touch data to paint, so it will not work in VR.
To paint in VR, you can use the P3dHitBetween component, which allows you to paint between two Transform points. The Paint Between demo scene shows you how to use it, and you can apply the same approach to your VR tool. Most of the example scenes can be modified to work in VR with this change alone.
Alternatively, the P3dHitNearby component can be used, which will paint anything near the current GameObject. The Asteroid Holes demo scene shows you how this can be used.
Keep in mind that by default both of these components paint continuously with the same pressure/strength. If you want to be able to toggle painting on and off, or associate your VR trigger pressure with paint pressure, then you will have to write a simple script to connect the two together. If you want to be able to preview the painting without applying it (e.g. when not pulling the trigger), then you will have to control the Preview setting yourself.
Yes, while in play mode open the Window/Paint in 3D from the top menu bar.
On the Scene tab you can see a list of paintable objects in your scene, with a list of their materials, and a list of their textures. Next to the texture name you want to save, you can click the Export button, and save it to your project as a .png file.
This can be done at runtime too from the P3dPaintableTexture component, using the GetPngData() method.
Yes, all of the non-VR comonents should work automatically in either input system.
If you're using the VR components then you must manually create a PlayerInput component, bind some VR controls to an input, and use the events to send the CallbackContext information to the P3dVrManager component.
The VR examples use the P3dInputAxis component to send (legacy) input axis data to functions like P3dVrManager.SetLeftTrigger, and you can replace these using the new system.
Any GameObject that has a MeshFilter + MeshRenderer or SkinnedMeshRenderer can be painted.
Next, you need to mark which textures you want to paint. Your MeshRenderer or SkinnedMeshRenderer component has the Materials array, and each texture used by these materials can be painted.
You should now see the P3dPaintableTexture component added to your GameObject.
Inside this component, you can click the dropdown to the right of the Slot setting, allowing you to pick from a list of materials and texture slots.
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.
The rest of the settings should be OK at their default values for now.
The P3dPaintableTexture component takes over the texture slot of the material you specify, which means all other objects using this material will see the same paint. To fix this you must make sure the material is turned into a unique clone before your paintable textures are applied.
You should now see the P3dMaterialCloner component added to your GameObject.
Finally, make sure the P3dMaterialCloner.Index setting matches your P3dPaintableTexture.Slot index. For example, if your slot is 0, _MainTex, then your Index should also be set to 0.
Paint in 3D comes with many ways to paint objects.
One simple method is to make a new GameObject, and add the P3dHitScreen and P3dPaintDecal 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).
You can now adjust the P3dPaintDecal 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/InGame/Examples folder and see how they're put together!
To open the main Paint in 3D window, click on Window > Paint in 3D from the top menu bar.
If you only want to paint objects in-editor, then I recommend you make a new scene. This is because painting data is stored in the scene, and you may not want to modify your main scene to include this. You can then copy+paste or drag+drop the objects you want to paint in this new scene.
If you want to remove paint data from your scene then look at the Scene tab, and click the X next to each paintable object.
Make sure you're on the Scene tab inside the Paint in 3D window.
Any GameObjects eligible for painting will appear here. If you don't see any, then you must select some in either the Scene or Hierarchy windows.
For a GameObject to be eligible for painting it must have the Skinned Mesh Renderer or MeshFilter + MeshRenderer components.
To add it to your painting scene, simply click the Make Paintable button next to it.
After you make a paintable object, you can see a list of its materials in the Scene tab. On the right side you can click the Preset button to open a list of preset configurations available for this material, which allows you to pick how you want to paint it.
If you don't see any presets, then you can make your own in the PaintIn3D/InEditor/Presets folder. You can add your material or shader to an existing preset, duplicate one and modify it, or right click and select Create/Paint in 3D/Preset to create one from scratch. To understand how to set up a preset, I recommend you read the Getting Started - In Game tutorial, as the steps are the same.
If you don't want to use a preset, then you can double click your paintable object to select it in the scene, and you can manually add the P3dMaterialCloner and P3dPaintableTexture components.
After you add a material preset, you will see a list of textures that will be painted. If you want to save these textures in your project then you can click the Export button to the right, and choose a place to save them. The saved textures will be in .png format.
Make sure you're on the Paint tab.
At the top you can see 3 boxes: Tool, Material, and Shape.
If you click the Tool box, then you can choose a paint tool. These control how the paint is applied in the scene (e.g. dots, line, triangles).
If you click the Material box, then you can choose a paint material. These define a set of textures that allow you to paint a type of surface (e.g. brick, dirt, chrome).
If you click the Shape box, then you can choose the paint shape. These change the shape of the material as you paint, giving more interesting edges.
If you enable the Override Camera setting, then you can control the game view camera using:
After you've painted your textures, you can click the Export All button at the bottom of the Paint in 3D window. This will automatically save all previously exported textures with the current paint state.
For Paint in 3D to work, the mesh you want to paint must have UV data. Not only that, but for best results the UV data shouldn't have overlapping areas (e.g. no mirroring), or exceed the 0..1 range (e.g. no texture tiling).
If your mesh fails any of these requirements, then I recommend you modify the UV data in your favorite 3d modelling program (e.g. Blender).
Unity can automatically do it for you. Just keep in mind that doing it manually will allow you to achieve better results.
To automatically generate UV data, you can enable the Generate Lightmap UVs setting in your mesh import settings. This will generate UV data suitable for painting, and they will be stored in 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 P3D 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 P3dMaterialCloner and P3dPaintableTexture component settings to target the second material slot index (1).
This technique is demonstrated in the UV Requirements / Automatic Overlay demo scene.
If you don't mind replacing your original shader/material, then the P3D 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.
Paint in 3D comes with the Coord Copier tool, which allows you to do this.
To use this tool, select your mesh in the Project window, and click the context menu (gear) icon at the top right of the inspector, and select the Coord Copier (Paint in 3D) option.
Your Project window should now contain a Coord Copier (YOUR_MESH_NAME) prefab, and you can click Generate to copy the coords over.
The generated mesh with the copied coords is now placed as a child of the Coord Copier prefab, and you can drag and drop it into your Mesh Filter or Skinned Mesh Renderers.
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.
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.
Paint in 3D comes with a range of shaders that allow you to specify the UV channel used (e.g. P3d Opaque).
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:
The first step is to select your P3dPaintableTexture 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 P3dPaintableTexture documentation for more details.
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 P3dPaintableTexture in your scene, letting Paint in 3D know that you're about to paint on them.
For example, the P3dHitScreen component has the StoreStates setting, as well as P3dToggleParticles, and P3dTapThrow.
Finally, you can add the P3dUndoAll and P3dRedoAll 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!
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.
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 P3dPaintableTexture 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 P3dPaintableTexture inspector context menu (gear icon at top right), so you can test it from the editor.
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 (see the seams around the shoulders on the zombie image).
The blue lines in this image show you the UV seams:
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 (gear) at the top right, and select Fix Seams (Paint in 3D).
This creates a seam fixer in your project, and automatically sets the Source mesh to the one you picked.
If you want to see the result of the seam fixing, set the Debug Scale setting to 10 or so.
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.
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.
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 P3dPaintDecal 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. P3dPaintSphere, P3dPaintDecal).
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.
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.
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.