diff --git a/Runtime/Math/Geometry/Box3.cs b/Runtime/Math/Geometry/Box3.cs
index 8009cf4..78eeb57 100644
--- a/Runtime/Math/Geometry/Box3.cs
+++ b/Runtime/Math/Geometry/Box3.cs
@@ -11,11 +11,16 @@ namespace Rokojori
 
     public Vector3 center => ( max + min ) / 2f;
 
-   public static implicit operator Box3( Aabb aabb )
+    public static implicit operator Box3( Aabb aabb )
     {  
       return Box3.Create( aabb.Position, aabb.End );
     }
 
+    public static implicit operator Aabb( Box3 box )
+    {  
+      return new Aabb( box.min, box.size ); 
+    }
+
     public static Box3 FromPositionAndScale( Vector3 position, Vector3 scale )
     {
       var max = scale * 0.5f;
@@ -33,6 +38,8 @@ namespace Rokojori
       return b;
     }
 
+    public Vector3 size => max - min;
+
     
     public Box2 AsXZBox2()
     {
@@ -51,6 +58,12 @@ namespace Rokojori
       return point;
     }
 
+    public void EnsureYBounds( float minY, float maxY )
+    {
+      min.Y = Mathf.Min( minY, min.Y );
+      max.Y = Mathf.Max( maxY, max.Y );
+    }
+
     public float maxDistance => ( max - min ).Length();
 
     public static Vector3 Constrain( Vector3 point, Vector3 min, Vector3 max )
diff --git a/Runtime/Math/Geometry/Pose.cs b/Runtime/Math/Geometry/Pose.cs
index 77486c8..40e576c 100644
--- a/Runtime/Math/Geometry/Pose.cs
+++ b/Runtime/Math/Geometry/Pose.cs
@@ -35,6 +35,39 @@ namespace Rokojori
       
     }
 
+    public float y 
+    {
+      get => position.Y;
+      set { 
+        var p = position;
+        p.Y = value;
+
+        position = p;
+      } 
+    }
+
+    public float x 
+    {
+      get => position.X;
+      set { 
+        var p = position;
+        p.X = value;
+
+        position = p;
+      } 
+    }
+
+    public float z 
+    {
+      get => position.Z;
+      set { 
+        var p = position;
+        p.Z = value;
+
+        position = p;
+      } 
+    }
+
     Basis _basis;
 
     void Update()
diff --git a/Runtime/Math/Math3D.cs b/Runtime/Math/Math3D.cs
index 782ec36..3ffa643 100644
--- a/Runtime/Math/Math3D.cs
+++ b/Runtime/Math/Math3D.cs
@@ -261,6 +261,14 @@ namespace Rokojori
       return v;
     }
 
+     public static Vector3 SnapRoundedXZ( Vector3 v, float snapX, float snapZ )
+    {
+      v.X = MathX.SnapRounded( v.X, snapX );
+      v.Z = MathX.SnapRounded( v.Z, snapZ );
+
+      return v;
+    }
+
     public static Vector3 SnapCeiled( Vector3 v, Vector3 snapping )
     {
       v.X = MathX.SnapCeiled( v.X, snapping.X );
@@ -325,6 +333,7 @@ namespace Rokojori
       return new Vector3( 0, y, z );
     }
 
+   
 
 
     public static Vector3 Lerp( Vector3 a, Vector3 b, float lerp )
diff --git a/Runtime/Math/MathX.cs b/Runtime/Math/MathX.cs
index 57a6a25..c08b571 100644
--- a/Runtime/Math/MathX.cs
+++ b/Runtime/Math/MathX.cs
@@ -119,7 +119,7 @@ namespace Rokojori
     }
 
     public const float DegreesToRadians = Mathf.Pi / 180f;
-    public const float RadiansToDegreens = 180f / Mathf.Pi;
+    public const float RadiansToDegrees = 180f / Mathf.Pi;
 
     public static float AngleDelta( float degreesA, float degreesB)
     {
diff --git a/Runtime/Procedural/Assets/BillboardTree/BillboardTree.cs.uid b/Runtime/Procedural/Assets/BillboardTree/BillboardTree.cs.uid
new file mode 100644
index 0000000..3f059e2
--- /dev/null
+++ b/Runtime/Procedural/Assets/BillboardTree/BillboardTree.cs.uid
@@ -0,0 +1 @@
+uid://vbas64yqk13v
diff --git a/Runtime/Procedural/Mesh/MeshGeometry.cs b/Runtime/Procedural/Mesh/MeshGeometry.cs
index 6002c90..c6780b3 100644
--- a/Runtime/Procedural/Mesh/MeshGeometry.cs
+++ b/Runtime/Procedural/Mesh/MeshGeometry.cs
@@ -9,6 +9,7 @@ namespace Rokojori
 {
   public class MeshGeometry
   {
+    public string name = "";
     public List<Vector3> vertices = new List<Vector3>();
     public List<int> indices = new List<int>();
 
@@ -432,6 +433,12 @@ namespace Rokojori
       Initialize( normals, uvs, colors, uvs2 );
     } 
 
+    public MeshGeometry( string name, bool normals = true, bool uvs = true, bool colors = false, bool uvs2 = false )
+    {
+      this.name = name;
+      Initialize( normals, uvs, colors, uvs2 );
+    }
+
     public static MeshGeometry BillboardQuad( float size = 1 )
     {
       var hs = size / 2f;
diff --git a/Runtime/Procedural/Parametric/Plane/ClipMapPlaneMeshType.cs b/Runtime/Procedural/Parametric/Plane/ClipMapPlaneMeshType.cs
index 4ead8a0..17a5dff 100644
--- a/Runtime/Procedural/Parametric/Plane/ClipMapPlaneMeshType.cs
+++ b/Runtime/Procedural/Parametric/Plane/ClipMapPlaneMeshType.cs
@@ -7,6 +7,12 @@ using System;
 
 namespace Rokojori
 {
+  public enum ClipMapCellConstraints
+  {
+    Rounded_Integer_Divisions,
+    Only_MinLevel_PowersOfTwos
+  }
+
   [Tool]
   [GlobalClass]
   public partial class ClipMapPlaneMeshType:__PlaneMeshType__
@@ -18,54 +24,232 @@ namespace Rokojori
     public float minCellSize = 10;
 
     [Export]
-    public Curve cellSizeOverDistance = MathX.Curve( 0, 1 );
+    public float centerMeshRadius = 100;
+
     
-      
-    public override MeshGeometry GetMeshGeometry( float sizeX, float sizeZ )
+    [Export]
+    public ClipMapCellConstraints cellConstrains = ClipMapCellConstraints.Rounded_Integer_Divisions;
+
+
+    [Export]
+    public int meshDivisions = 8;
+
+    
+
+    [Export]
+    public Curve cellSizeOverDistance = MathX.Curve( 0, 1 );
+
+    
+
+    float xUnits;
+    float zUnits;
+    float sizeX;
+    float sizeZ;
+
+    Vector2 size;
+    Vector2 offset;
+
+    float maxDistance;
+
+    List<MeshGeometry> geometries;
+
+
+    public override List<MeshGeometry> GetMeshGeometries( float sizeX, float sizeZ )
     {
-      var xUnits = Mathf.Ceil( ( sizeX / 2 ) / maxCellSize ) * 2;
-      var zUnits = Mathf.Ceil( ( sizeZ / 2 ) / maxCellSize ) * 2;
+      geometries = new List<MeshGeometry>();
 
-      var mg = new MeshGeometry();
+      geometries.Add( new MeshGeometry( "Center" ) );
 
-      var size = new Vector2( xUnits * maxCellSize, zUnits * maxCellSize );
-      var offset = size / -2f;
-      var maxDistance = offset.Length();
+      for ( int i = 0; i < meshDivisions; i++ )
+      {
+        float angle = ( (float) i  / meshDivisions ) * 360f;
+        geometries.Add( new MeshGeometry( "Angle " + angle ) );
+      }
+
+      this.sizeX = sizeX;
+      this.sizeZ = sizeZ;
+
+      xUnits = Mathf.Ceil( ( sizeX / 2 ) / maxCellSize ) * 2;
+      zUnits = Mathf.Ceil( ( sizeZ / 2 ) / maxCellSize ) * 2;
+
+
+      size = new Vector2( xUnits * maxCellSize, zUnits * maxCellSize );
+      offset = size / -2;
+      maxDistance = Mathf.Min( sizeX, sizeZ ) / 2f;
 
       this.LogInfo( xUnits, zUnits );
       
-      for ( int i = 0; i < xUnits; i++ )
+      for ( int x = 0; x < xUnits; x++ )
       {
-        for ( int j = 0; j < zUnits; j++ )
+        for ( int z = 0; z < zUnits; z++ )
         {
-          var c = offset + new Vector2( i * maxCellSize, j * maxCellSize );
-          var s = c.Length() / maxDistance;
-
-          if ( cellSizeOverDistance != null )
-          {
-            s = cellSizeOverDistance.Sample( s );
-          }
-
-          s = Mathf.Lerp( minCellSize, maxCellSize, s );
-
-          Add( mg, c, s );
-      
+          Add( x, z );      
         } 
       }
 
-
-
-      return mg;
+      var g = geometries;
+      geometries = null;
+      return g;
     }
 
-    void Add( MeshGeometry mg, Vector2 center, float cellSize )
+    static float edgeTreshold = 0.000001f;
+
+    bool InRange( float value, float target )
     {
-      var numDivisions = Mathf.CeilToInt( maxCellSize / cellSize );
+      var e = edgeTreshold;
+      return Range.Contains( -e + target, e + target, value );
+    }
+
+    bool IsEdge( float value )
+    {
+      return InRange( value, 0 ) || InRange( value, 1 );
+    }
+
+    Vector2 CellOffset( int x, int z )
+    {
+      var c = offset + new Vector2( x * maxCellSize, z * maxCellSize );    
+
+      return c;
+    }
+    
+
+    float CellSize( int x, int z )
+    {
+      var c = CellOffset( x, z );          
+      var cL = c + new Vector2( 1, 1 ) * maxCellSize / 2;
+
+      var s = cL.Length() / maxDistance;
+
+      if ( cellSizeOverDistance != null )
+      {
+        s = cellSizeOverDistance.Sample( s );
+      }
+
+      s = Mathf.Lerp( minCellSize, maxCellSize, s );
+
+      return s;
+    }
+
+    int CellDivisions( int x, int z )
+    {
+      var cellSize = CellSize( x, z );
+      var divisions = Mathf.CeilToInt( maxCellSize / cellSize );
+
+      if ( ClipMapCellConstraints.Rounded_Integer_Divisions == cellConstrains )
+      {
+        return divisions;
+      }
+
+      if ( divisions == 1 || divisions == 2 )
+      {
+        return divisions;
+      }
+
+      var v = MathX.NextPowerOfTwo( divisions );
+
+      return v * v;
+    }
+
+    bool IsEdge( Vector2 value )
+    {
+      return IsEdge( value.X ) || IsEdge( value.Y );
+    }
+
+
+    static float SnapToClosest( float value, int lowDivs )
+    {
+      float stepSize = 1.0f / lowDivs;
+
+      float snappedValue = Mathf.Round( value / stepSize ) * stepSize;
+
+      return snappedValue;
+    }
+   
+    MeshGeometry GetMeshGeometry( Vector2 center )
+    {
+      if ( center.Length() < centerMeshRadius )
+      {
+        return geometries[ 0 ];
+      }
+
+      var angle = MathX.RadiansToDegrees * center.Angle();
+      var index = Mathf.RoundToInt( angle / 360f * meshDivisions -0.5f );
+      index = MathX.Repeat( index, meshDivisions ); 
+      return geometries[ index + 1 ];
+    }
+
+    void Add( int x, int z )
+    {       
+      var center = CellOffset( x, z );
+      var cellSize = CellSize( x, z );
+
+      var mg = GetMeshGeometry( center );
+
+      var numDivisions = CellDivisions( x, z );
+
+      var leftDivisions  = x == 0 ? -1 : CellDivisions( x - 1, z );
+      var rightDivisions = x == xUnits - 1 ? -1 : CellDivisions( x + 1, z );
+
+      var topDivisions    = z == 0 ? -1 : CellDivisions( x, z - 1 );
+      var bottomDivisions = z == zUnits - 1 ? -1 : CellDivisions( x, z + 1 );
+
+      var snapToLeft  = leftDivisions != -1 && leftDivisions < numDivisions;
+      var snapToRight = rightDivisions != -1 && rightDivisions < numDivisions;
+
+      var snapToTop = topDivisions != -1 && topDivisions < numDivisions;
+      var snapToBottom = bottomDivisions != -1 && bottomDivisions < numDivisions;
+    
+      // RJLog.Log( snapToLeft, snapToRight, snapToBottom, snapToTop );
+
 
       var sectionMG = MeshGeometry.CreateFromUVFunction( 
         ( uv ) =>
         {
           var pose = new Pose();
+          pose.position = Math3D.XYasXZ( uv ) * maxCellSize + Math3D.XYasXZ( center );
+
+          var isEdge = IsEdge( uv );
+
+          if ( ! isEdge )
+          {
+            return pose;
+          }
+
+          var before = pose.position;
+
+          var snappedUV = uv;
+
+          if ( ! ( InRange( uv.Y, 0 ) || InRange( uv.Y, 1 ) ) ) 
+          {
+            if ( snapToLeft && InRange( uv.X, 0 ) )
+            {
+              snappedUV.Y = SnapToClosest( snappedUV.Y, leftDivisions ); 
+            }
+
+            if ( snapToRight && InRange( uv.X, 1 ) )
+            {
+              snappedUV.Y = SnapToClosest( snappedUV.Y, rightDivisions );
+            }
+
+          }
+
+          if ( ! ( InRange( uv.X, 0 ) ||  InRange( uv.X, 1 ) ) ) 
+          {
+            if ( snapToTop && InRange( uv.Y, 0 ) )
+            {
+              snappedUV.X = SnapToClosest( snappedUV.X, topDivisions ); 
+            }
+
+            if ( snapToBottom && InRange( uv.Y, 1 ) )
+            {
+              snappedUV.X = SnapToClosest( snappedUV.X, bottomDivisions ); 
+            }
+
+          }
+
+          pose.position = Math3D.XYasXZ( snappedUV ) * maxCellSize + Math3D.XYasXZ( center );
+
+          // this.LogInfo( "Snapped", before, ">>", pose.position );
 
           return pose;
 
diff --git a/Runtime/Procedural/Parametric/Plane/Plane.cs b/Runtime/Procedural/Parametric/Plane/Plane.cs
index a422cbf..372a7f6 100644
--- a/Runtime/Procedural/Parametric/Plane/Plane.cs
+++ b/Runtime/Procedural/Parametric/Plane/Plane.cs
@@ -8,67 +8,104 @@ namespace Rokojori
   [Tool]
   [GlobalClass]
   public partial class Plane:Node3D
-  {      
+  {     
+    [ExportToolButton( "Update Mesh")]
+    public Callable UpdateMeshButton => Callable.From( () => UpdateMesh() );
+    
+    public readonly EventProperty<float> _width = new EventProperty<float>();
     [Export]
-    public float width { get => _width; set { _width = value; UpdateMesh(); }  }
-    float _width = 200;
+    public float width { get => _width.value; set => _width.value = value; }
 
     
+    public readonly EventProperty<float> _height = new EventProperty<float>();
     [Export]
-    public float height { get => _height; set { _height = value; UpdateMesh(); } }
-    float _height = 200;
+    public float height { get => _height.value; set => _height.value = value; }
 
-    
     [Export]
-    public __PlaneMeshType__ type { get => _type; set { _type = value; UpdateMesh(); } }
-    __PlaneMeshType__ _type;
+    public bool extendBoundingBox = true;
+
+    [Export]
+    public float boundingBoxMinY = 0;
+
+    [Export]
+    public float boundingBoxMaxY = 1;
+    
+    public readonly EventProperty<__PlaneMeshType__> _type = new EventProperty<__PlaneMeshType__>();
+    [Export]
+    public __PlaneMeshType__ type { get => _type.value; set { _type.value = value; } }
 
     [Export]
     public Material material;
 
     [Export]
-    public MeshInstance3D outputMesh;
-
+    public MeshInstance3D[] meshes;
 
     [Export]
-    public bool initialized 
-    { 
-      get => _initialized; 
-      set { if ( _initialized ) { return; }  _initialized = true; UpdateMesh(); }  
-    }
-    
-    bool _initialized;
+    public bool snapXZ = true;
 
-    void UpdateMesh()
+    [Export]
+    public float snappingDistance = 100;
+
+    [Export]
+    public Vector3 snapOffset = Vector3.Zero;
+
+
+    [ExportGroup( "Debug Info")]
+    [Export]
+    public int numTriangles;
+
+    
+    public override void _Process( double delta )
     {
-      if ( ! _initialized )
+      if ( ! snapXZ )
       {
         return;
       }
 
+      GlobalPosition = Math3D.SnapRoundedXZ( GlobalPosition, snappingDistance, snappingDistance );
+    }
+
+
+    void UpdateMesh()
+    {
       if ( _type == null )
       {
         return;
       }
 
+      numTriangles = 0;
       this.LogInfo( "Creating mesh" );
 
-      var mg = _type.GetMeshGeometry( width, height );
+      var mgs = _type.value.GetMeshGeometries( width, height );
 
-      if ( outputMesh == null )
+      meshes = new MeshInstance3D[ mgs.Count ];
+
+      Nodes.DestroyChildren( this );
+
+      for ( int i = 0; i < mgs.Count; i++ )
       {
-        outputMesh = this.CreateChild<MeshInstance3D>();
+        var mg = mgs[ i ];
+        
+        var outputMesh = this.CreateChild<MeshInstance3D>( mg.name );
+        outputMesh.Mesh = mg.GenerateMesh();
+
+        if ( extendBoundingBox )
+        {
+          var extendedBounds = (Box3) outputMesh.Mesh.GetAabb();
+          extendedBounds.EnsureYBounds( boundingBoxMinY, boundingBoxMaxY );
+          outputMesh.CustomAabb = extendedBounds;
+        }
+
+        meshes[ i ] = outputMesh;
+
+        numTriangles += mg.numTriangles;
+
+        if ( material != null )
+        {
+          Materials.Set( outputMesh, material );
+        }
       }
-
-      outputMesh.Mesh = mg.GenerateMesh();
-
-      if ( material != null )
-      {
-        Materials.Set( outputMesh, material );
-      }
-
-      this.LogInfo( material, outputMesh, outputMesh.Mesh );
-
+      
     }
 
   }
diff --git a/Runtime/Procedural/Parametric/Plane/__PlaneMeshType__.cs b/Runtime/Procedural/Parametric/Plane/__PlaneMeshType__.cs
index a29bcbd..d21a788 100644
--- a/Runtime/Procedural/Parametric/Plane/__PlaneMeshType__.cs
+++ b/Runtime/Procedural/Parametric/Plane/__PlaneMeshType__.cs
@@ -11,7 +11,7 @@ namespace Rokojori
   [GlobalClass]
   public partial class __PlaneMeshType__:Resource
   { 
-    public virtual MeshGeometry GetMeshGeometry( float width, float height )
+    public virtual List<MeshGeometry> GetMeshGeometries( float width, float height )
     {
       return null;
     }
diff --git a/Runtime/Procedural/Textures/TextureCombiner/TextureCombinerRunner.cs.uid b/Runtime/Procedural/Textures/TextureCombiner/TextureCombinerRunner.cs.uid
new file mode 100644
index 0000000..1a0ec1c
--- /dev/null
+++ b/Runtime/Procedural/Textures/TextureCombiner/TextureCombinerRunner.cs.uid
@@ -0,0 +1 @@
+uid://ff6fmiujno23
diff --git a/Runtime/Shading/Library/Textures.gdshaderinc b/Runtime/Shading/Library/Textures.gdshaderinc
index 3ec7e61..04a3506 100644
--- a/Runtime/Shading/Library/Textures.gdshaderinc
+++ b/Runtime/Shading/Library/Textures.gdshaderinc
@@ -8,3 +8,66 @@ vec4 triplanarTexture( sampler2D sampler, vec3 weights, vec3 triplanerPosition )
 
 	return sample;
 }
+
+vec2 heightMapUV( vec3 worldPosition, vec3 terrainSize, vec3 terrainOffset )
+{
+  vec3 inTerrain = worldPosition - terrainOffset;
+  vec3 terrainUV = inTerrain / terrainSize;
+
+  return vec2( terrainUV.x, terrainUV.z );
+}
+
+vec4 fromHeightMap( sampler2D sampler, vec3 worldPosition, vec3 terrainSize, vec3 terrainOffset )
+{
+  vec3 inTerrain = worldPosition - terrainOffset;
+  vec3 terrainUV = inTerrain / terrainSize;
+
+  return texture( sampler, vec2( terrainUV.x, terrainUV.z ) );
+}
+
+vec4 fromHeightMapSmoothed( sampler2D terrain, vec2 terrainUV, vec2 kernelSize, float weightSmoothing )
+{
+  vec4 output = vec4( 0, 0, 0, 0 );
+
+  float sumW = 0.0;
+
+  for ( int i = -1; i < 2; i++ ) 
+  {
+    for ( int j= -1; j < 2; j++ )
+    { 
+      vec2 offset = vec2( kernelSize.x * float(i), kernelSize.y * float(j) );
+      float w = 1.0 / ( weightSmoothing + length( offset ) );
+      output += texture( terrain, terrainUV + offset ) * w; 
+
+      sumW += w;
+    }
+  }
+
+  return output / sumW;
+}
+
+
+vec3 heightMapDirection( sampler2D terrain, vec2 terrainUV, vec2 kernelSize, float normalScale )
+{
+  float hL = texture( terrain, terrainUV - vec2( kernelSize.x, 0 ) ).r * normalScale;
+  float hR = texture( terrain, terrainUV + vec2( kernelSize.x, 0 ) ).r * normalScale;
+  float hD = texture( terrain, terrainUV - vec2( 0, kernelSize.y ) ).r * normalScale;
+  float hU = texture( terrain, terrainUV + vec2( 0, kernelSize.y ) ).r * normalScale;
+
+  return vec3( hL - hR, hD - hU, 2.0 );
+}
+
+vec3 heightMapNormal( sampler2D terrain, vec2 terrainUV, vec2 kernelSize, float normalScale )
+{
+  return normalize( heightMapDirection( terrain, terrainUV, kernelSize, normalScale ) );
+}
+
+vec3 heightMapNormalSmoothed( sampler2D terrain, vec2 terrainUV, vec2 kernelSize, float normalScale, float kernelSpread )
+{
+  vec3 n0 = heightMapDirection( terrain, terrainUV, kernelSize, normalScale ); 
+  vec3 n1 = heightMapDirection( terrain, terrainUV, kernelSize * kernelSpread, normalScale ) * 0.5;
+  vec3 n2 = heightMapDirection( terrain, terrainUV, kernelSize * kernelSpread * kernelSpread, normalScale ) * 0.25;
+
+  return normalize( n0 + n1 + n2 );
+}
+
diff --git a/Runtime/Shading/Library/Transform.gdshaderinc b/Runtime/Shading/Library/Transform.gdshaderinc
index d6a678e..6624dfe 100644
--- a/Runtime/Shading/Library/Transform.gdshaderinc
+++ b/Runtime/Shading/Library/Transform.gdshaderinc
@@ -47,6 +47,16 @@ vec3 worldToLocalDirection( vec3 _VERTEX, mat4 _MODEL_MATRIX )
   return ( mw * vec4( _VERTEX, 1.0 ) ).xyz;
 }
 
+vec3 worldToViewDirection( vec3 direction, mat4 _VIEW_MATRIX )
+{
+  mat4 mw = _VIEW_MATRIX;
+  mw[ 3 ][ 0 ] = 0.0;
+  mw[ 3 ][ 1 ] = 0.0;
+  mw[ 3 ][ 2 ] = 0.0;
+  mw[ 3 ][ 3 ] = 1.0;
+
+  return ( mw * vec4( direction, 1.0 ) ).xyz;
+}
 
 vec3 extractScale( mat3 _MODEL_NORMAL_MATRIX )
 {
diff --git a/Runtime/Shading/Properties/Vector2IPropertyName.cs.uid b/Runtime/Shading/Properties/Vector2IPropertyName.cs.uid
new file mode 100644
index 0000000..0cd7641
--- /dev/null
+++ b/Runtime/Shading/Properties/Vector2IPropertyName.cs.uid
@@ -0,0 +1 @@
+uid://ctpdwmseds08
diff --git a/Runtime/Shading/Shaders/Billboards/QuadBillboard/QuadBillboard.gdshader.uid b/Runtime/Shading/Shaders/Billboards/QuadBillboard/QuadBillboard.gdshader.uid
new file mode 100644
index 0000000..4debe63
--- /dev/null
+++ b/Runtime/Shading/Shaders/Billboards/QuadBillboard/QuadBillboard.gdshader.uid
@@ -0,0 +1 @@
+uid://bmyf1o4fx8en2
diff --git a/Runtime/Shading/Shaders/Billboards/QuadBillboard/QuadBillboardMaterial.cs.uid b/Runtime/Shading/Shaders/Billboards/QuadBillboard/QuadBillboardMaterial.cs.uid
new file mode 100644
index 0000000..527a133
--- /dev/null
+++ b/Runtime/Shading/Shaders/Billboards/QuadBillboard/QuadBillboardMaterial.cs.uid
@@ -0,0 +1 @@
+uid://dbbl2m0i06ysm