Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Tree It - Free Foliage and Tree Creation Software

Discussion in 'General Discussion' started by JamesArndt, Apr 23, 2020.

  1. JamesArndt

    JamesArndt

    Unity Technologies

    Joined:
    Dec 1, 2009
    Posts:
    2,912
    Came across this free tool and thought it might be useful for some of the game developers in these forums. It does export both OBJ and FBX and will import into Unity. It does export some PBR maps, but as far as my knowledge not all of them. So there may be a bit of manual texture setup on your part. I also believe you may have to tweak the normals of the leaves so as to soften the lighting on them (spherical normals).

    "Tree It is an easy-to-use real time 3D tree generator for the simple creation of your very own 3D tree models and foliage. All model exports are 100% free to use with any engine/projects."

    https://www.evolved-software.com/treeit/treeit





    And a short video clip showing off some of the built-in library trees that can be worked off of. Not too bad.

     
  2. CityGen3D

    CityGen3D

    Joined:
    Nov 23, 2012
    Posts:
    680
    I'm a big fan and now use this for CityGen3D trees.

    I made some notes somewhere about the workflow I used to get them into Unity, so if anyone runs into any problems I'd be happy to share my workflow, in case it helps.
     
  3. BIGTIMEMASTER

    BIGTIMEMASTER

    Joined:
    Jun 1, 2017
    Posts:
    5,181
    I've used this briefly. It is not as robust as Speedtree, however as mentioned in the first post it has one major advantage: you can export as obj/fbx. To do that with Speedtree you have to pay $1000 for a special license.
     
    JamesArndt likes this.
  4. EternalAmbiguity

    EternalAmbiguity

    Joined:
    Dec 27, 2014
    Posts:
    3,144
    Can it be used real-time/integrated into Unity directly in any way?
     
  5. CityGen3D

    CityGen3D

    Joined:
    Nov 23, 2012
    Posts:
    680
    Yes, looking at my notes again, they mainly covered my workflow for using the CityGen3D mesh batching to batch the tree into one mesh and retain multiple materials for bark and leaves, which is just something I wanted to do to reorganise the prefab a bit. So they probably aren't all that helpful in generic terms.

    But basically yes, you can just import the resulting FBX from TreeIt and do whatever you want with it inside your project, so it's a great tool for easy tree generation and it has lots of different species already setup.
     
  6. N1warhead

    N1warhead

    Joined:
    Mar 12, 2014
    Posts:
    3,884
    Could always just import into Unity and go to the package manager and get the FBX Exporter and bam there you go lol. But not sure if the actual speedtree exporter gives any benefits - too expensive for me to afford that special license lol.
     
  7. EternalAmbiguity

    EternalAmbiguity

    Joined:
    Dec 27, 2014
    Posts:
    3,144
    Sorry. I was wondering if models can be generated on the fly. Say if one was doing proc-gen terrain creation at runtime. With some kind of Unity asset or C# package.
     
  8. JamesArndt

    JamesArndt

    Unity Technologies

    Joined:
    Dec 1, 2009
    Posts:
    2,912
    Hey I just saw your tool! Love it, will have to look into what you've created there too. Glad the tree creator has been useful for you and I personally wouldn't mind you sharing any workflow tips at all (concerning getting these trees into Unity).
     
    Lobotomiac and CityGen3D like this.
  9. CityGen3D

    CityGen3D

    Joined:
    Nov 23, 2012
    Posts:
    680
    Oh I see what you mean. I'm not aware of any scriptable tree creation functionality in TreeIt, I think you have to use the TreeIt executable and export your models.

    Having said that, it's very easy to create variations of a tree species just by changing the random seed value in TreeIt, then exporting them as models and setting up Unity prefabs. For most proc gen scenarios I imagine you'd likely want to use a limited number of pre generated trees anyway to take advantage of GPU instancing.
     
    EternalAmbiguity likes this.
  10. CityGen3D

    CityGen3D

    Joined:
    Nov 23, 2012
    Posts:
    680
    Thanks very much. I've just released a new demo video of me driving around a CityGen3D scene, which includes TreeIt trees

    Please take a look at my Work In Progress thread in my signature for more info.

    When I actually looked at my TreeIt notes they were very rough and involved using CityGen3D specific mesh batching, so I'm not sure they are much use really.
    If I recall correctly, TreeIt trees have two meshes one for bark and one for leaves. Whereas I batched the output to be one mesh with two submeshes.

    I think the only generic things that I noticed worth mentioning was that I had to tweak the scale a bit in Unity import (I think by factor of 10). Not sure that was an issue with my TreeIt export settings though.

    I also made a note to "invert specular map in paint program", but that probably depends on which PBR workflow you use.

    I also noted to export in FBX and not OBJ, although I forgot to state why, but I seemed to get better results :)
     
    JamesArndt likes this.
  11. sankalp32O5

    sankalp32O5

    Joined:
    Apr 10, 2022
    Posts:
    3
    Can i have a look on your notes or your workflow on treeit, iam trying to use it in my small game but having issues with leaves they are very thin but when i look those trees in treeit thouse leaves are completely fine and fluffy
    Iam using acacia tree preset http://www.evolved-software.com/treeit/treelibrary
     
  12. CityGen3D

    CityGen3D

    Joined:
    Nov 23, 2012
    Posts:
    680
    Hi,

    The raw notes wouldn't be of any use to you as when I looked back they contained too many details specific to my project. However I summarized all the useful points in my previous message above.

    I think the issue you are having is most likely down to the shader you are using to render the tree leaves. I use a custom double sided shader using the Better Shaders asset, which ensures the leaf polys are visible from both sides.

    So if you are just using a standard Lit shader you probably just need to change it to a suitable foliage shader.
    Hope this helps!
     
  13. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,864
    Tree it was around since dbpro days, and the tree/leaf shaders are already there in the sys/treeit folder. If you check the shaders, you will see vertex color.xz is for wind and color.y is for fluttering. If you check the unity terrainengine.cginc and libraries, they use smiliar math for wind animation. So, its possible to write a new shader compatible with the tool.

    It would be much better for smart unity people to buy this tool from this guy and get rid of the tree creator completely.
     
  14. Gekigengar

    Gekigengar

    Joined:
    Jan 20, 2013
    Posts:
    705
    This would cause conflict of interest with SpeedTree being a part of Unity service.
     
  15. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,864
    I meant the tree creator, not speedtree.
    Speedtree is a must for individual trees, but also the billboard trees are required for huge areas. Anyways, TreeIt is usable as is.
     
  16. impheris

    impheris

    Joined:
    Dec 30, 2009
    Posts:
    1,511
    tree it is fairly old now and the dev is kind of cool, i asked him to add branch flares and he did it very fast and good and also you can create plants, it is a very nice free tool, at least for low - mid poly count

    EDIT: i do not recommend to use the presets, because most of the time those are not well compatible with the newer version of tree it, but create trees and recreate those presets is very easy
    Untitleaaaad.jpg
     
  17. KRGraphics

    KRGraphics

    Joined:
    Jan 5, 2010
    Posts:
    4,436
    I've been looking for a foliage generator and rod looks pretty cool
     
  18. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,864
    These simple soft-occlusion bark and leaf shaders give it a great looking wind animation with the TreeIt vertex colors.
    Bark shader:
    Code (CSharp):
    1. // Upgrade NOTE: replaced '_CameraToWorld' with 'unity_CameraToWorld'
    2.  
    3. Shader "TOZ/Nature/Bark" {
    4.     Properties {
    5.         _Color("Main Color", Color) = (1,1,1,0)
    6.         _MainTex("Main Texture", 2D) = "white" {}
    7.         _BaseLight("Base Light", Range(0, 1)) = 0.35
    8.         _AO("Amb. Occlusion", Range(0, 10)) = 2.4
    9.  
    10.         // These are here only to provide default values
    11.         [HideInInspector] _TreeInstanceColor("TreeInstanceColor", Vector) = (1,1,1,1)
    12.         [HideInInspector] _TreeInstanceScale("TreeInstanceScale", Vector) = (1,1,1,1)
    13.         [HideInInspector] _SquashAmount("Squash", Float) = 1
    14.     }
    15.  
    16.     SubShader {
    17.         Tags { "RenderType" = "TreeOpaque" "Queue" = "Geometry" "IgnoreProjector"="True" "DisableBatching"="True" }
    18.  
    19.         Pass {
    20.             Lighting On
    21.  
    22.             CGPROGRAM
    23.             #include "UnityBuiltin2xTreeLibrary.cginc"
    24.             #pragma vertex vert
    25.             #pragma fragment frag
    26.             #pragma multi_compile_fog
    27.  
    28.             sampler2D _MainTex;
    29.  
    30.             v2f vert(appdata_tree v) {
    31.                 v2f o;
    32.                 UNITY_SETUP_INSTANCE_ID(v);
    33.                 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    34.                 //TerrainAnimateTree(v.vertex, v.color.w);
    35.     v.vertex.xyz *= _TreeInstanceScale.xyz;
    36.     v.vertex = AnimateVertex(v.vertex, v.normal, float4(v.color.xy, v.color.zw));
    37.     v.vertex = Squash(v.vertex);
    38.    
    39.                 float3 viewpos = UnityObjectToViewPos(v.vertex);
    40.                 o.pos = UnityObjectToClipPos(v.vertex);
    41.                 o.uv = v.texcoord;
    42.  
    43.                 float4 lightDir = 0;
    44.                 float4 lightColor = 0;
    45.                 lightDir.w = _AO;
    46.  
    47.                 float4 light = UNITY_LIGHTMODEL_AMBIENT;
    48.  
    49.                 for(int i = 0; i < 4; i++) {
    50.                     float atten = 1.0;
    51.                     #ifdef USE_CUSTOM_LIGHT_DIR
    52.                         lightDir.xyz = _TerrainTreeLightDirections[i];
    53.                         lightColor = _TerrainTreeLightColors[i];
    54.                     #else
    55.                         float3 toLight = unity_LightPosition[i].xyz - viewpos.xyz * unity_LightPosition[i].w;
    56.                         toLight.z *= -1.0;
    57.                         lightDir.xyz = mul((float3x3)unity_CameraToWorld, normalize(toLight));
    58.                         float lengthSq = dot(toLight, toLight);
    59.                         atten = 1.0 / (1.0 + lengthSq * unity_LightAtten[i].z);
    60.  
    61.                         lightColor.rgb = unity_LightColor[i].rgb;
    62.                     #endif
    63.  
    64.                     float diffuse = dot(v.normal, lightDir.xyz);
    65.                     diffuse = max(0, diffuse);
    66.                     diffuse *= _AO * v.tangent.w + _BaseLight;
    67.                     light += lightColor * (diffuse * atten);
    68.                 }
    69.  
    70.                 light.a = 1;
    71.                 o.color = light * _Color * _TreeInstanceColor;
    72.  
    73.                 #ifdef WRITE_ALPHA_1
    74.                     o.color.a = 1;
    75.                 #endif
    76.  
    77.                 UNITY_TRANSFER_FOG(o, o.pos);
    78.                 return o;
    79.             }
    80.  
    81.             fixed4 frag(v2f i) : SV_Target {
    82.                 fixed4 col = i.color;
    83.                 col.rgb *= tex2D(_MainTex, i.uv.xy).rgb;
    84.                 UNITY_APPLY_FOG(i.fogCoord, col);
    85.                 UNITY_OPAQUE_ALPHA(col.a);
    86.                 return col;
    87.             }
    88.             ENDCG
    89.         }
    90.  
    91.         Pass {
    92.             Name "ShadowCaster"
    93.             Tags { "LightMode" = "ShadowCaster" }
    94.  
    95.             CGPROGRAM
    96.             #include "UnityCG.cginc"
    97.             #include "TerrainEngine.cginc"
    98.             #pragma vertex vert
    99.             #pragma fragment frag
    100.             #pragma multi_compile_shadowcaster
    101.  
    102.             struct a2v {
    103.                 float4 vertex : POSITION;
    104.                 float3 normal : NORMAL;
    105.                 fixed4 color : COLOR;
    106.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    107.             };
    108.  
    109.             struct v2f {
    110.                 V2F_SHADOW_CASTER;
    111.                 UNITY_VERTEX_OUTPUT_STEREO
    112.             };
    113.  
    114.             v2f vert(a2v v) {
    115.                 v2f o;
    116.                 UNITY_SETUP_INSTANCE_ID(v);
    117.                 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    118.                 //TerrainAnimateTree(v.vertex, v.color.w);
    119.     v.vertex.xyz *= _TreeInstanceScale.xyz;
    120.     v.vertex = AnimateVertex(v.vertex, v.normal, float4(v.color.xy, v.color.zw));
    121.     v.vertex = Squash(v.vertex);
    122.                 TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
    123.                 return o;
    124.             }
    125.  
    126.             float4 frag(v2f i) : SV_Target {
    127.                 SHADOW_CASTER_FRAGMENT(i)
    128.             }
    129.             ENDCG
    130.         }
    131.     }
    132.  
    133.     Dependency "BillboardShader" = "Hidden/Nature/Tree Soft Occlusion Bark Rendertex"
    134.     Fallback Off
    135. }
    136.  
    Leaf shader:
    Code (CSharp):
    1. Shader "TOZ/Nature/Leaf" {
    2.     Properties {
    3.         _Color("Main Color", Color) = (1,1,1,1)
    4.         _MainTex("Main Texture", 2D) = "white" {}
    5.         _Cutoff("Alpha cutoff", Range(0.25,0.9)) = 0.5
    6.         _BaseLight("Base Light", Range(0, 1)) = 0.35
    7.         _AO("Amb. Occlusion", Range(0, 10)) = 2.4
    8.         _Occlusion("Dir Occlusion", Range(0, 20)) = 7.5
    9.  
    10.         // These are here only to provide default values
    11.         [HideInInspector] _TreeInstanceColor("TreeInstanceColor", Vector) = (1,1,1,1)
    12.         [HideInInspector] _TreeInstanceScale("TreeInstanceScale", Vector) = (1,1,1,1)
    13.         [HideInInspector] _SquashAmount("Squash", Float) = 1
    14.     }
    15.  
    16.     SubShader {
    17.         Tags { "RenderType" = "TreeTransparentCutout" "Queue" = "AlphaTest" "IgnoreProjector"="True" "DisableBatching"="True" }
    18.         Cull Off
    19.         ColorMask RGB
    20.  
    21.         Pass {
    22.             Lighting On
    23.  
    24.             CGPROGRAM
    25.             #include "UnityBuiltin2xTreeLibrary.cginc"
    26.             #pragma vertex vert
    27.             #pragma fragment frag
    28.             #pragma multi_compile_fog
    29.  
    30.             sampler2D _MainTex;
    31.             fixed _Cutoff;
    32.  
    33.             v2f vert(appdata_tree v) {
    34.                 v2f o;
    35.                 UNITY_SETUP_INSTANCE_ID(v);
    36.                 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    37.                 //TerrainAnimateTree(v.vertex, v.color.w);
    38.     v.vertex.xyz *= _TreeInstanceScale.xyz;
    39.     v.vertex = AnimateVertex(v.vertex, v.normal, float4(v.color.xy, v.color.zw));
    40.     v.vertex = Squash(v.vertex);
    41.                 float3 viewpos = UnityObjectToViewPos(v.vertex);
    42.                 o.pos = UnityObjectToClipPos(v.vertex);
    43.                 o.uv = v.texcoord;
    44.  
    45.                 float4 lightDir = 0;
    46.                 float4 lightColor = 0;
    47.                 lightDir.w = _AO;
    48.  
    49.                 float4 light = UNITY_LIGHTMODEL_AMBIENT;
    50.  
    51.                 for(int i = 0; i < 4; i++) {
    52.                     float atten = 1.0;
    53.                     #ifdef USE_CUSTOM_LIGHT_DIR
    54.                         lightDir.xyz = _TerrainTreeLightDirections[i];
    55.                         lightColor = _TerrainTreeLightColors[i];
    56.                     #else
    57.                         float3 toLight = unity_LightPosition[i].xyz - viewpos.xyz * unity_LightPosition[i].w;
    58.                         toLight.z *= -1.0;
    59.                         lightDir.xyz = mul((float3x3)unity_CameraToWorld, normalize(toLight));
    60.                         float lengthSq = dot(toLight, toLight);
    61.                         atten = 1.0 / (1.0 + lengthSq * unity_LightAtten[i].z);
    62.  
    63.                         lightColor.rgb = unity_LightColor[i].rgb;
    64.                     #endif
    65.  
    66.                     lightDir.xyz *= _Occlusion;
    67.                     float occ =  dot (v.tangent, lightDir);
    68.                     occ = max(0, occ);
    69.                     occ += _BaseLight;
    70.                     light += lightColor * (occ * atten);
    71.                 }
    72.  
    73.                 o.color = light * _Color * _TreeInstanceColor;
    74.                 o.color.a = 0.5 * _HalfOverCutoff;
    75.  
    76.                 UNITY_TRANSFER_FOG(o, o.pos);
    77.                 return o;
    78.             }
    79.  
    80.             fixed4 frag(v2f i) : SV_Target {
    81.                 fixed4 col = tex2D( _MainTex, i.uv.xy);
    82.                 col.rgb *= i.color.rgb;
    83.                 clip(col.a - _Cutoff);
    84.                 UNITY_APPLY_FOG(i.fogCoord, col);
    85.                 return col;
    86.             }
    87.             ENDCG
    88.         }
    89.  
    90.         Pass {
    91.             Name "ShadowCaster"
    92.             Tags { "LightMode" = "ShadowCaster" }
    93.  
    94.             CGPROGRAM
    95.             #include "UnityCG.cginc"
    96.             #include "TerrainEngine.cginc"
    97.             #pragma vertex vert
    98.             #pragma fragment frag
    99.             #pragma multi_compile_shadowcaster
    100.  
    101.             sampler2D _MainTex;
    102.             fixed _Cutoff;
    103.  
    104.             struct a2v {
    105.                 float4 vertex : POSITION;
    106.                 float3 normal : NORMAL;
    107.                 fixed4 color : COLOR;
    108.                 float4 texcoord : TEXCOORD0;
    109.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    110.             };
    111.  
    112.             struct v2f {
    113.                 V2F_SHADOW_CASTER;
    114.                 float2 uv : TEXCOORD1;
    115.                 UNITY_VERTEX_OUTPUT_STEREO
    116.             };
    117.  
    118.             v2f vert(a2v v) {
    119.                 v2f o;
    120.                 UNITY_SETUP_INSTANCE_ID(v);
    121.                 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    122.                 //TerrainAnimateTree(v.vertex, v.color.w);
    123.     v.vertex.xyz *= _TreeInstanceScale.xyz;
    124.     v.vertex = AnimateVertex(v.vertex, v.normal, float4(v.color.xy, v.color.zw));
    125.     v.vertex = Squash(v.vertex);
    126.                 TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
    127.                 o.uv = v.texcoord;
    128.                 return o;
    129.             }
    130.  
    131.             float4 frag(v2f i) : SV_Target {
    132.                 fixed4 texcol = tex2D(_MainTex, i.uv);
    133.                 clip(texcol.a - _Cutoff);
    134.                 SHADOW_CASTER_FRAGMENT(i)
    135.             }
    136.             ENDCG
    137.         }
    138.     }
    139.  
    140.     // This subshader is never actually used, but is only kept so
    141.     // that the tree mesh still assumes that normals are needed
    142.     // at build time (due to Lighting On in the pass). The subshader
    143.     // above does not actually use normals, so they are stripped out.
    144.     // We want to keep normals for backwards compatibility with Unity 4.2
    145.     // and earlier.
    146.     SubShader {
    147.         Tags {
    148.             "Queue" = "AlphaTest"
    149.             "IgnoreProjector"="True"
    150.             "RenderType" = "TransparentCutout"
    151.         }
    152.         Cull Off
    153.         ColorMask RGB
    154.         Pass {
    155.             Tags { "LightMode" = "Vertex" }
    156.             AlphaTest GEqual [_Cutoff]
    157.             Lighting On
    158.             Material {
    159.                 Diffuse [_Color]
    160.                 Ambient [_Color]
    161.             }
    162.             SetTexture [_MainTex] { combine primary * texture DOUBLE, texture }
    163.         }
    164.     }
    165.  
    166.     Dependency "BillboardShader" = "Hidden/Nature/Tree Soft Occlusion Leaves Rendertex"
    167.     Fallback Off
    168. }
    169.  
     
    Voronoi, carking1996 and mgear like this.
  19. impheris

    impheris

    Joined:
    Dec 30, 2009
    Posts:
    1,511
    Hi, thank you for sharing this, i have a noob question xD, how i use those scripts?
     
  20. HaryySto

    HaryySto

    Joined:
    Nov 23, 2022
    Posts:
    2
    By the way, there are cool services for analyzing source code.
    Tried?
    Something like AppRefactoring or Sourcery AI
     
  21. Voronoi

    Voronoi

    Joined:
    Jul 2, 2012
    Posts:
    571
    It's a shader, not a script. Create a new shader file, open it and copy/paste the code.