ForestPaint User Guide

In this guide, i'm going to show you how to use the "ForestPaint" asset, what it can do, and how the basic workflow looks like.
The package (both full and demo) also comes with an example terrain (the same terrain used in this guide).

If you have opened this Html document from the package, there might be an updated version at

Setting up the painter

First, drag your terrain mesh into the scene (or whatever mesh you want to paint trees onto), if you haven't already.
Navigate to the gameobject, which has the MeshFilter and MeshRenderer components.
Add the component called "Tree Painter".

Adding the component

The first thing that is going to happen, is that the component makes a copy of the terrain mesh and replaces the MeshFilter's mesh with it. (The copy is saved to ForestPaint/Generated/Geometry/) It happens because the models are reimported every startup, so any changes made to it will be lost. Plus it also works as a backup.

The tree painter uses vertex colors to mark the mesh (where you want trees, and which type), therefore it is going to replace all vertex colors with white (in the duplicate). If your mesh had vertex colors, just change the MeshFilter's mesh back to the original, after the forest mesh has been built.

There sould be a warning at the top of the component:
"Material isn't using the 'ForestPaint Demo/ForestPaint - Shadow/FOREST' pass. Painting will take effect, however you won't see any trees."

Adding the component

Let's fix it!

Create a new material, select a shader like "ForestPaint/ForestPaint - shadow" and drag it onto the terrain.

Adding the component

If the warning remains, turn off graphics emulation (Edit -> Graphics Emulation -> No Emulation).

After it's done, let's take a look at the Tree Painter component.

Component UI

Page 1: Shader setup

Adding the component

On the first page "Shader Setup" the general (non tree specific) shader properties can be set, like the terrain texture.
On the first two pages you are adjusting shader properties. You can also use the material inspector to make these changes. Changes made via this component can not be undone / redone with Ctrl+Z and Ctrl+Y.

Some properties, that might need explanation:

Height variation Height of the trees can be randomized.
Height of individual trees might diviate from the 'Tree Height' (page 2) with the magnitude of [this] (world space).
Width variation Width of individual trees might diviate from the 'Tree Width' (page 2) with the magnitude of [this] (world space).
Color variation How much the brightness of individual trees might vary.
Position variation How much individual trees are going to be offsetted in a random direction (world space).
Trees are offsetted in triangle plane. High values might result in flying trees.
Rotation variation Only effects top view
Rotatiaon of individual tree tops will be rotated by the maximum of [this] degrees.
Density multiplier Multiplies the painted tree density.
If it's zero, there are no trees.
Facing direction change distance When the camera is far away from a tree, it is going to be facing the position the camera.
If the camera is close enough to the tree (not further then [this]), it's going to be facing in the opposite direction the camera is facing. Rotation is only applied on the Y axis. (Trees won't pitch)
Transition start Facing direction will start transitioning, when the camera is closer then [this].

Page 2: Edit trees

Adding the component

On the second page, "Edit Trees", properties of tree types can be set. There are 3 tree slots (1 in the demo).

Some properties, that might need explanation:

Top billborad height The relative height of the top-view billboard.
A height of 0 means that, the top-view billboard is at the bottom of a tree, a height of 1 meains, it's at the top of the tree.
Side-Top change angle When the depression angle of the camera is greater than [this] (in degrees), the top-view billboard will be rendered instead of the side-view one.
When the built forest mesh is rendered, the side-view billboard isn't going to be disabled.

Page 3: Paint trees

Adding the component

The third page is the painting screen. You can select which type of tree you want to paint, how dense you want it to be, and you can also set the radius of the brush (world space).
To erease trees (paint trees with a density of 0), hold down Shift.
The Ctrl + Z and Ctrl + Y hotkeys are not going to work. Use the undo / redo buttons instead.

Page 4: Build mesh

Adding the component

The fourth page does two things. It shows you the statistics (how many trees you have painted, broken down to each type and combined) and it let's you build your forest into a mesh (might result in multiple meshes).

Building meshes is only available in the full version. In the demo version, this page only shows you the statistics.

Some properties, that might need explanation:

Mesh vertex limit Maximum number of vertices in a mesh. If a mesh would need more vertices, it's going to be split into multiple meshes.
Only 16 bit meshes can be built procedrally, so the limit can't be greater than 65536
Erease existing If true, existing meshes, gameobjects and materials are going to be overwritten.
If false, generated meshes, gameobjects, materials are going to be added to the existing ones.
Cast shadows I've written two shaders that can render these forest meshes. One casts shadow, one doesn't.
if true, the shadow casting shader is going to be used.


Once the material has been set up, we can start painting.
To enter paint mode, press "Start Painting". You can paint using the left mouse button. Holding down Shift will set the density 0, entering erease mode. Releasing Shift will set the density back to it's last value. The density is relative to the vertex density of the mesh. If you can't find the needed density, try subdividing / unsubdividing your mesh.

Adding the component

After having painted a few trees, you might want to go back to the tree editing tab, to fine-tune some properties (height, side-top change angle, correction colors, ect.).
You can't undo / redo the painting process by pressing Ctrl + Z / Ctrl + Y. Use the UI buttons instead. "Clear all" can also be undone.

Adding the component

Building meshes

Only available in the full version.

If you are done with the painting, you can keep using the geometry shader to draw your forests, or you can build the forests into a mesh / meshes (a must for mobile platforms).
With forest meshes, you can paint more than 3 tree types. Just paint the first 3 than build, clear all, paint some other type of trees and build another mesh (make sure that "Erease existing" is disabled).

Adding the component

When the build process is done, it's going to set the density multiplier to 0. At this point, there is no need for the duplicated terrain mesh, or the newly created material. You can change them back.

The forest meshes are saved to ForestPaint/Generated/TreeMesh/[ID] and the materials to ForestPaint/Generated/TreeMaterial/[ID]. The ID is in the name of your terrain mesh (the duplicated one).

Adding the component

And we are done!

Adding the component Adding the component

Making a custom shader support trees.

You can make your own shader support trees, by adding:

UsePass "ForestPaint/ForestPaint - Shadow/FOREST"

Plus if you want the trees to cast shadows:

UsePass "ForestPaint/ForestPaint - Shadow/FORESTSHADOW"

For these passes to operate correctly, you also need to add a few ShaderLab properties:

_Ambient("Ambient light", range(0, 2)) = 0.6
_LightIntensity("Light intensity", range(0, 1)) = 0
_Color("Color", Color) = (1,1,1,1)
_GrayscaleFactor("Grayscale", Range(0, 1)) = 0.4
_ShadowAmount("Shadow amount", Range(0, 1)) = 0.5
_ShadowDistance("Shadow Distance (From Quality Settings)", Float) = 50
_TreeChangeMinHeight("Side-top change min. height", Float) = 10
_TargetDirChangeDst("Within this range trees will be facing view dir. instead of camera pos.", Float) = 100
_DirChangeTransition("Facing transition length ( ^ )", Float) = 10

_Tree1Tex("Tree side texture", 2D) = "white" {}
_Tree1SideColor("Tree Side color", Color) = (1,1,1,1)
_Tree1TopTex("Tree top texture", 2D) = "white" {}
_Tree1TopColor("Tree Top color", Color) = (1,1,1,1)
_Tree1RelativeTopHeight("Relative top height", Range(0., 1.)) = 0.5
_Tree1ChangeAngle("Side-top change angle", Range(0, 90)) = 70
_Tree1Height("Tree height", Float) = 20
_Tree1Width("Tree width", Float) = 12

_Tree2Tex("Tree side texture", 2D) = "white" {}
_Tree2SideColor("Tree Side color", Color) = (1,1,1,1)
_Tree2TopTex("Tree top texture", 2D) = "white" {}
_Tree2TopColor("Tree Top color", Color) = (1,1,1,1)
_Tree2RelativeTopHeight("Relative top height", Range(0., 1.)) = 0.5
_Tree2ChangeAngle("Side-top change angle", Range(0, 90)) = 70
_Tree2Height("Tree height", Float) = 20
_Tree2Width("Tree width", Float) = 12

_Tree3Tex("Tree side texture", 2D) = "white" {}
_Tree3SideColor("Tree Side color", Color) = (1,1,1,1)
_Tree3TopTex("Tree top texture", 2D) = "white" {}
_Tree3TopColor("Tree Top color", Color) = (1,1,1,1)
_Tree3RelativeTopHeight("Relative top height", Range(0., 1.)) = 0.5
_Tree3ChangeAngle("Side-top change angle", Range(0, 90)) = 70
_Tree3Height("Tree height", Float) = 20
_Tree3Width("Tree width", Float) = 12

_HeightVary("Height variation", Range(0., 10.)) = 3
_WidthVary("Width variation", Range(0., 10.)) = 2
_TreeColorVary("Tree color variation", Range(0, 1)) = 0
_Density("Density multiplier", Range(0., 2.)) = 1
_PosVary("Placement variation", Range(0, 40)) = 0
_RotVary("Rotation variation", Range(0, 1)) = 0.3

Known issues and workarounds

Tree type limit

In the geometry shader, there are only 3 slots for tree types.

The workaround has already been mentioned in the Building meshes section. By disabling "Erease existing" on the Build mesh page, you can stack up the forest meshes of different tree types.

Tree shadows aren't received (PC)

While on android it works fine, when building for PC, the "ForestPaint - Shadow" shader doesn't receive it's own tree shadows.

If you don't want to build meshes, but to use the geometry shader and you need shadows, add a new material to the MeshRenderer. The first material is going to render the trees, so change shader to "ForestPaint - Only Trees + Shadow". The second material is going to render the terrain. The shader can be "ForestPaint - FallBack" or whatever you like. This way the tree shadows cast by the first material are going to be rendered by the second one.

Adding the component

ForestPaint User Guide