Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Voxeland - Voxel Terrain Tool

Discussion in 'Assets and Asset Store' started by Wright, Jun 25, 2013.

  1. digitalerr0r

    digitalerr0r

    Joined:
    Sep 15, 2013
    Posts:
    25
    Hi!
    Thanks for this great asset! I'm doing some research on using this in my project. The project is using Obsive First Person Controller (https://opsive.com/assets/first-person-controller/) for character movement.

    Are there some more information on how the Shift World property works? What is being moved when the threshold is met? It seems when I hit the threshold (I set it to 100), the Voxeland object starts moving away very fast, and keeps moving into the infinity. Probably because, for some reason like Obsive positioning system keeps track of where the player should be, it keeps re-detecting the threshold every frame after it's met for the first time.

    I also notice that in the Voxeland demo scene, if I enable Shift World and set the threshold to 150, strange stuff happens when the threshold is met.

    Anyone had luck getting this to work with the Obsive character controllers? Or with the demo?

    Is it possible to use your own floating origin system, or customize how it works in Voxeland?
     
    Last edited: Feb 15, 2020
  2. Amenophis-Memnon

    Amenophis-Memnon

    Joined:
    Sep 22, 2016
    Posts:
    4
    Hi!
    Thanks you so much for this awesome asset!

    I have a trouble with the integration of MegaSplat. I've follow the tutorial on YouTube and it works great!
    But i dont understand how to apply the MegaSplat shader to the Horizon mesh

    I've follow the same step as the terrain but it do not work the horizon is always flat and not use the correct texture.

    Please, help me to deal with that.
     
  3. Prod212

    Prod212

    Joined:
    Dec 13, 2017
    Posts:
    17
    Hi, we are getting this issue with the mesh terrain where there seems to be visible seams around single blocks as you can see in the image below. I have made sure that the mesh margin is larger or the same as the relax iteration but we still get this issue. Does anyone have an idea on how to fix this?

    upload_2020-3-23_15-4-21.png
     
  4. CitrusBranch

    CitrusBranch

    Joined:
    Feb 3, 2020
    Posts:
    1
    Sorry, I know this is an old thread, but wasn't sure where would be better to post this. I'm getting strange shadow effects even from the default Voxeland created object.

    Here is a quick 8 second video showing what's happening, and I'm just not sure where to start with this:


    This happens in play mode as well as in the editor and built versions. Usually in play mode it isn't noticeable at first and grows over time, turning into significant flashing of the terrain.

    Also, this definitely is related to shadows; if I turn shadows off from the directional light, the issue goes away.

    Edit: Found that this seems to also be related to infinite terrain, as if I do a limited terrain of size 900 (haven't tried other sizes yet) the flashing does not occur.

    If anyone has any idea what's causing this, I'd really appreciate the pointer!
     
    Last edited: Apr 1, 2020
  5. flow-

    flow-

    Joined:
    Apr 19, 2015
    Posts:
    165
    I know this bug, It's a bug with the Legacy Render Pipeline, I saw this bug occur as well on different scenes on my side and have nothing to do with voxeland as I got this bug also on a different system and shader without any voxeland

    As far as I know, does it have something to do with the Shadow Distance and the angle of the Directional Light.

    ---> Video but embed does not work
    https://imgur.com/a/JXdhk65



    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _



    Also, I'm working on a "Pseudo" Low Poly Generator for Voxeland, and I will share it with the community once it's ready ( Probably next week )
     

    Attached Files:

    Last edited: Apr 8, 2020
    mrs26 and Chemanel like this.
  6. flow-

    flow-

    Joined:
    Apr 19, 2015
    Posts:
    165
    As some of you guys already notice have I worked on a Low Poly Mesh Generator for Voxeland...



    Low Poly Generator
    for
    Voxeland 5



    2020-04-08 03_23_13-Window.jpg 2020-04-08 03_26_16-Window.jpg 2020-04-08 03_25_06-Window.jpg




    How to Set it Up:

    1. Copy and Create the Script​
    Code (csharp):
    1.  
    2. using System;
    3. using System.Collections.Generic;
    4. #if UNITY_EDITOR
    5. using UnityEditor;
    6. #endif
    7. using UnityEngine;
    8. using Voxeland5;
    9.  
    10. namespace Fox.Flow
    11. {
    12.     [ExecuteInEditMode]
    13.     public class LowPolifyVoxeland : MonoBehaviour
    14.     {
    15.  
    16.         #region Editable_Variables
    17.  
    18.         [Header( "Settings" )]
    19.         [Tooltip( "Makes Enable the whole transformation" )]
    20.         [SerializeField] private bool UseLowPolyMesh = true;
    21.         [Space]
    22.  
    23.         [Tooltip( "The Seed for the Randomization, if any Randomization is used" )]
    24.         [SerializeField] private int HighPolyIncreaseRandomizationSeed = 123456;
    25.  
    26.         [Header( "Edges" )]
    27.         [Tooltip( "If using Edge Transformation the Edges gets transformed outside or inside of the blocks" )]
    28.         [SerializeField] private bool UseEdgesTransformation = true;
    29.         [Tooltip( "Lower means more chance of edges having a Introverted or Extroverted shape" )]
    30.         [Range( 0, 6 )]
    31.         [SerializeField] private byte HighPolyIncreaseEdges = 1;
    32.  
    33.         [Space]
    34.         [Tooltip( "Edges which are gets effected by the Edge Transformation" )]
    35.         [SerializeField] private Edges RelativeEdges = Edges.C;
    36.         [Range( 0f, 1.5f )]
    37.         [Tooltip( "Multiplier to create Edges which goes inside the shape" )]
    38.         [SerializeField] private float IntrovertedEdgeValueMultiplier = 0.5f;
    39.         [Range( 0f, 3f )]
    40.         [Tooltip( "Multiplier to create Edges which goes outside the shape" )]
    41.         [SerializeField] private float ExtrovertedEdgeValueMultiplier = 1f;
    42.  
    43.         [Header( "Flat Look" )]
    44.         [Tooltip( "If using Flat Surface the faces are not rounded anymore" )]
    45.         [SerializeField] private bool UseFlatSurface = true;
    46.  
    47.         [Tooltip( "Lower means more chance of having a flat surface on the blocks" )]
    48.         [Range( 0, 6 )]
    49.         [SerializeField] private byte HighPolyIncreaseFlatSurface = 0;
    50.  
    51.         #endregion
    52.  
    53.         #region Helper_Variables
    54.         // INSTANCES
    55.         private static Dictionary<Voxeland, LowPolifyVoxeland> instances = new Dictionary<Voxeland, LowPolifyVoxeland>();
    56.         [HideInInspector] public Voxeland _voxeland;
    57.         private static Dictionary<Voxeland, Quaternion> voxelandRotations = new Dictionary<Voxeland, Quaternion>();
    58.  
    59.         [Flags]
    60.         public enum Edges
    61.         {
    62.             A = 1,
    63.             B = 2,
    64.             C = 4,
    65.             D = 8
    66.         }
    67.         #endregion
    68.  
    69.         #region Instance_Logic
    70.  
    71.         protected void Awake()
    72.         {
    73.             CheckForInstances();
    74.         }
    75.  
    76.         protected void OnEnable()
    77.         {
    78.             CheckForInstances();
    79.         }
    80.  
    81.         protected void OnDisable()
    82.         {
    83.             RemoveInstance();
    84.         }
    85.  
    86.         protected void OnDestroy()
    87.         {
    88.             RemoveInstance();
    89.         }
    90.  
    91.         protected void LateUpdate()
    92.         {
    93.             CheckForInstances();
    94.         }
    95.  
    96.         private void CheckForInstances() {
    97.             if ( _voxeland == null )
    98.             {
    99.                 _voxeland = this.GetComponent<Voxeland>();
    100.                 if ( _voxeland == null )
    101.                 {
    102.                     _voxeland = FindObjectOfType<Voxeland>();
    103.                 }
    104.             }
    105.             if ( _voxeland != null && instances.ContainsKey( _voxeland ) == false )
    106.             {
    107.                 instances.Add( _voxeland, this );
    108.  
    109.                 // ALSO ROTATIONS
    110.                 voxelandRotations.Add( _voxeland, _voxeland.transform.rotation );
    111.             }
    112.             else if ( _voxeland != null && instances.ContainsKey( _voxeland ) )
    113.             {
    114.                 if ( instances[ _voxeland ] == null ) instances[ _voxeland ] = this;
    115.  
    116.                 // ALSO ROTATIONS
    117.                 voxelandRotations[ _voxeland ] = _voxeland.transform.rotation;
    118.             }
    119.         }
    120.  
    121.         private void RemoveInstance() {
    122.             if ( _voxeland == null ) return;
    123.             if ( instances.ContainsKey( _voxeland ) ) instances.Remove( _voxeland );
    124.             if ( voxelandRotations.ContainsKey( _voxeland ) ) voxelandRotations.Remove( _voxeland );
    125.         }
    126.  
    127.         public static LowPolifyVoxeland GetValidInstance( Voxeland voxeland ) {
    128.             if ( instances.ContainsKey( voxeland ) ) return instances[ voxeland ];
    129.             else return null;
    130.         }
    131.  
    132.         #endregion
    133.  
    134.         public static void LowPolyMesh( ChunkMesh.Face[] faces, Vector3[] verts, Voxeland voxeland )
    135.         {
    136. #if WDEBUG
    137.                 if(!ThreadWorker.multithreading) Profiler.BeginSample ("Generate Low Poly Mesh");
    138. #endif
    139.  
    140.             var _instance = GetValidInstance( voxeland );
    141.  
    142.             if ( _instance == null || _instance != null && !_instance.UseLowPolyMesh ) { return; }
    143.  
    144.             // NEW CALCULATION
    145.             _instance.LPFaceCalulation( faces, verts, voxelandRotations[ voxeland ] );
    146.  
    147. #if WDEBUG
    148.                 if (!ThreadWorker.multithreading) Profiler.EndSample ();
    149. #endif
    150.         }
    151.  
    152.         #region New_Calulation
    153.  
    154.         private void LPFaceCalulation( ChunkMesh.Face[] faces, Vector3[] verts, Quaternion voxelandRotation )
    155.         {
    156.  
    157.             Quaternion up = voxelandRotation * Quaternion.LookRotation( Vector3.up );
    158.             Quaternion down = voxelandRotation * Quaternion.LookRotation( Vector3.down );
    159.             Quaternion right = voxelandRotation * Quaternion.LookRotation( Vector3.right );
    160.             Quaternion left = voxelandRotation * Quaternion.LookRotation( Vector3.left );
    161.             Quaternion forward = voxelandRotation * Quaternion.LookRotation( Vector3.forward );
    162.             Quaternion backward = voxelandRotation * Quaternion.LookRotation( -Vector3.forward );
    163.  
    164.             HashSet<Vector3> editedTriesForTriangles = new HashSet<Vector3>();
    165.  
    166.             for ( int i = 0; i < faces.Length; i++ )
    167.             {
    168.                 ChunkMesh.Face face = faces[ i ];
    169.  
    170.                 Quaternion faceRotation;
    171.                 CalculateRotations( face, out faceRotation, up, down, right, left, forward, backward );
    172.  
    173.                 bool IsRandomTriangleRatio;
    174.                 Vector3 FaceCenterPoint;
    175.                 EditTrianglesEdges( face, verts, editedTriesForTriangles, faceRotation, out IsRandomTriangleRatio, out FaceCenterPoint );
    176.             }
    177.  
    178.             for ( int i = 0; i < faces.Length; i++ )
    179.             {
    180.                 ChunkMesh.Face face = faces[ i ];
    181.  
    182.                 bool IsRandomFlatSurfaceRatio;
    183.                 EditEdgeSidesAndCenters( face, verts, editedTriesForTriangles, out IsRandomFlatSurfaceRatio );
    184.             }
    185.         }
    186.  
    187.         #region Main_Functions
    188.  
    189.         private void CalculateRotations( ChunkMesh.Face face, out Quaternion faceRotation, Quaternion up, Quaternion down, Quaternion right, Quaternion left, Quaternion forward, Quaternion backward )
    190.         {
    191.  
    192.             // dir
    193.             // 0 UP
    194.             // 1 DOWN
    195.             // 2 RIGHT
    196.             // 3 LEFT
    197.             // 4 FORWARD
    198.             // 5 BACK
    199.  
    200.             faceRotation = Quaternion.identity;
    201.  
    202.             if ( face.coord.dir == 0 ) faceRotation = up;
    203.             if ( face.coord.dir == 1 ) faceRotation = down;
    204.             if ( face.coord.dir == 2 ) faceRotation = right;
    205.             if ( face.coord.dir == 3 ) faceRotation = left;
    206.             if ( face.coord.dir == 4 ) faceRotation = forward;
    207.             if ( face.coord.dir == 5 ) faceRotation = backward;
    208.         }
    209.  
    210.         private void EditTrianglesEdges( ChunkMesh.Face face, Vector3[] verts, HashSet<Vector3> editedTriangles, Quaternion faceRot, out bool IsRatio, out Vector3 faceCenter )
    211.         {
    212.  
    213.             float distanceCenter = getAverageDistanceToMidPoint( verts[ face.cornerNums.a ], verts[ face.cornerNums.b ], verts[ face.cornerNums.c ], verts[ face.cornerNums.d ] ) * 0.001f;
    214.             if ( distanceCenter < 0.05f ) distanceCenter = 0.15f;
    215.             faceCenter = verts[ face.centerNum ] + faceRot * ( -Vector3.forward * distanceCenter );
    216.  
    217.             int byteIndex = face.coord.x + face.coord.y + face.coord.z;
    218.             IsRatio = HighPolyIncreaseEdges == 0 ? true :( ( byteIndex + HighPolyIncreaseRandomizationSeed ) % HighPolyIncreaseEdges ) == 0;
    219.  
    220.             if ( !UseEdgesTransformation ) return;
    221.  
    222.             bool upOrDownRatio = ( ( byteIndex + HighPolyIncreaseRandomizationSeed ) % 2 ) == 0;
    223.  
    224.             if ( IsRatio && ( upOrDownRatio && ExtrovertedEdgeValueMultiplier < 0.01f || upOrDownRatio == false && IntrovertedEdgeValueMultiplier < 0.01f ) == false && face.coord.dir != 0 )
    225.             {
    226.  
    227.                 if ( RelativeEdges.HasFlag( Edges.A ) )
    228.                 {
    229.                     if ( !editedTriangles.Contains( verts[ face.cornerNums.a ] ) )
    230.                     {
    231.                         float distance = Vector3.Distance( verts[ face.cornerNums.a ], faceCenter ) + 0.001f;
    232.  
    233.                         Quaternion cToA = Quaternion.LookRotation( verts[ face.cornerNums.a ] - faceCenter );
    234.  
    235.                         verts[ face.cornerNums.a ] += cToA * ( Vector3.forward * ( distance * ( upOrDownRatio ? ( ExtrovertedEdgeValueMultiplier ) : ( IntrovertedEdgeValueMultiplier ) ) ) * ( upOrDownRatio ? 0.5f : -0.5f ) );
    236.  
    237.                         editedTriangles.Add( verts[ face.cornerNums.a ] );
    238.                     }
    239.                 }
    240.                 if ( RelativeEdges.HasFlag( Edges.B ) )
    241.                 {
    242.                     if ( !editedTriangles.Contains( verts[ face.cornerNums.b ] ) )
    243.                     {
    244.                         float distance = Vector3.Distance( verts[ face.cornerNums.b ], faceCenter ) + 0.001f;
    245.  
    246.                         Quaternion cToB = Quaternion.LookRotation( verts[ face.cornerNums.b ] - faceCenter );
    247.  
    248.                         verts[ face.cornerNums.b ] += cToB * ( Vector3.forward * ( distance * ( upOrDownRatio ? ( ExtrovertedEdgeValueMultiplier ) : ( IntrovertedEdgeValueMultiplier ) ) ) * ( upOrDownRatio ? 0.5f : -0.5f ) );
    249.  
    250.                         editedTriangles.Add( verts[ face.cornerNums.b ] );
    251.                     }
    252.                 }
    253.                 if ( RelativeEdges.HasFlag( Edges.C ) )
    254.                 {
    255.                     if ( !editedTriangles.Contains( verts[ face.cornerNums.c ] ) )
    256.                     {
    257.                         float distance = Vector3.Distance( verts[ face.cornerNums.c ], faceCenter ) + 0.001f;
    258.  
    259.                         Quaternion cToC = Quaternion.LookRotation( verts[ face.cornerNums.c ] - faceCenter );
    260.  
    261.                         verts[ face.cornerNums.c ] += cToC * ( Vector3.forward * ( distance * ( upOrDownRatio ? ( ExtrovertedEdgeValueMultiplier ) : ( IntrovertedEdgeValueMultiplier ) ) ) * ( upOrDownRatio ? 0.5f : -0.5f ) );
    262.  
    263.                         editedTriangles.Add( verts[ face.cornerNums.c ] );
    264.                     }
    265.                 }
    266.                 if ( RelativeEdges.HasFlag( Edges.D ) )
    267.                 {
    268.                     if ( !editedTriangles.Contains( verts[ face.cornerNums.d ] ) )
    269.                     {
    270.                         float distance = Vector3.Distance( verts[ face.cornerNums.d ], faceCenter ) + 0.001f;
    271.  
    272.                         Quaternion cToD = Quaternion.LookRotation( verts[ face.cornerNums.d ] - faceCenter );
    273.  
    274.                         verts[ face.cornerNums.d ] += cToD * ( Vector3.forward * ( distance * ( upOrDownRatio ? ( ExtrovertedEdgeValueMultiplier ) : ( IntrovertedEdgeValueMultiplier ) ) ) * ( upOrDownRatio ? 0.5f : -0.5f ) );
    275.  
    276.                         editedTriangles.Add( verts[ face.cornerNums.d ] );
    277.                     }
    278.                 }
    279.             }
    280.         }
    281.  
    282.         private void EditEdgeSidesAndCenters( ChunkMesh.Face face, Vector3[] verts, HashSet<Vector3> editedTriangles, out bool IsRatio )
    283.         {
    284.             bool isA = editedTriangles.Contains( verts[ face.cornerNums.a ] );
    285.             bool isB = editedTriangles.Contains( verts[ face.cornerNums.b ] );
    286.             bool isC = editedTriangles.Contains( verts[ face.cornerNums.c ] );
    287.             bool isD = editedTriangles.Contains( verts[ face.cornerNums.d ] );
    288.  
    289.  
    290.             int byteIndex = face.coord.x + face.coord.y + face.coord.z;
    291.             IsRatio = HighPolyIncreaseFlatSurface == 0 ? true : ( ( byteIndex + HighPolyIncreaseRandomizationSeed ) % HighPolyIncreaseFlatSurface ) == 0;
    292.  
    293.             if ( isA )
    294.             {
    295.                 verts[ face.sideNums.a ] = flattenSideNumber( verts[ face.cornerNums.a ], verts[ face.cornerNums.b ] );
    296.                 verts[ face.sideNums.d ] = flattenSideNumber( verts[ face.cornerNums.d ], verts[ face.cornerNums.a ] );
    297.  
    298.                 if ( UseFlatSurface && IsRatio )
    299.                 {
    300.                     // CENTERS
    301.                     verts[ face.centerNum ] = middleCenterNumber( verts[ face.cornerNums.a ], verts[ face.cornerNums.b ], verts[ face.cornerNums.c ], verts[ face.cornerNums.d ] );
    302.  
    303.                     // SIDES
    304.                     if ( !isC )
    305.                     {
    306.                         verts[ face.sideNums.b ] = flattenSideNumber( verts[ face.cornerNums.b ], verts[ face.cornerNums.c ] );
    307.                         verts[ face.sideNums.c ] = flattenSideNumber( verts[ face.cornerNums.c ], verts[ face.cornerNums.d ] );
    308.                     }
    309.                 }
    310.             }
    311.             if ( isB )
    312.             {
    313.                 verts[ face.sideNums.b ] = flattenSideNumber( verts[ face.cornerNums.b ], verts[ face.cornerNums.c ] );
    314.                 verts[ face.sideNums.a ] = flattenSideNumber( verts[ face.cornerNums.a ], verts[ face.cornerNums.b ] );
    315.  
    316.                 if ( UseFlatSurface && IsRatio )
    317.                 {
    318.                     // CENTERS
    319.                     verts[ face.centerNum ] = middleCenterNumber( verts[ face.cornerNums.a ], verts[ face.cornerNums.b ], verts[ face.cornerNums.c ], verts[ face.cornerNums.d ] );
    320.  
    321.                     // SIDES
    322.                     if ( !isD )
    323.                     {
    324.                         verts[ face.sideNums.c ] = flattenSideNumber( verts[ face.cornerNums.c ], verts[ face.cornerNums.d ] );
    325.                         verts[ face.sideNums.d ] = flattenSideNumber( verts[ face.cornerNums.d ], verts[ face.cornerNums.a ] );
    326.                     }
    327.                 }
    328.             }
    329.             if ( isC )
    330.             {
    331.                 verts[ face.sideNums.c ] = flattenSideNumber( verts[ face.cornerNums.c ], verts[ face.cornerNums.d ] );
    332.                 verts[ face.sideNums.b ] = flattenSideNumber( verts[ face.cornerNums.b ], verts[ face.cornerNums.c ] );
    333.  
    334.                 if ( UseFlatSurface && IsRatio )
    335.                 {
    336.                     // CENTERS
    337.                     verts[ face.centerNum ] = middleCenterNumber( verts[ face.cornerNums.a ], verts[ face.cornerNums.b ], verts[ face.cornerNums.c ], verts[ face.cornerNums.d ] );
    338.  
    339.                     // SIDES
    340.                     if ( !isA )
    341.                     {
    342.                         verts[ face.sideNums.d ] = flattenSideNumber( verts[ face.cornerNums.d ], verts[ face.cornerNums.a ] );
    343.                         verts[ face.sideNums.a ] = flattenSideNumber( verts[ face.cornerNums.a ], verts[ face.cornerNums.b ] );
    344.                     }
    345.                 }
    346.             }
    347.             if ( isD )
    348.             {
    349.                 verts[ face.sideNums.d ] = flattenSideNumber( verts[ face.cornerNums.d ], verts[ face.cornerNums.a ] );
    350.                 verts[ face.sideNums.c ] = flattenSideNumber( verts[ face.cornerNums.c ], verts[ face.cornerNums.d ] );
    351.  
    352.                 if ( UseFlatSurface && IsRatio )
    353.                 {
    354.                     // CENTERS
    355.                     verts[ face.centerNum ] = middleCenterNumber( verts[ face.cornerNums.a ], verts[ face.cornerNums.b ], verts[ face.cornerNums.c ], verts[ face.cornerNums.d ] );
    356.  
    357.                     // SIDES
    358.                     if ( !isB )
    359.                     {
    360.                         verts[ face.sideNums.a ] = flattenSideNumber( verts[ face.cornerNums.a ], verts[ face.cornerNums.b ] );
    361.                         verts[ face.sideNums.b ] = flattenSideNumber( verts[ face.cornerNums.b ], verts[ face.cornerNums.c ] );
    362.                     }
    363.                 }
    364.             }
    365.  
    366.             if ( UseFlatSurface && IsRatio )
    367.             {
    368.                 if ( !isA && !isB && !isC && !isD )
    369.                 {
    370.                     // SIDES
    371.                     verts[ face.sideNums.a ] = flattenSideNumber( verts[ face.cornerNums.a ], verts[ face.cornerNums.b ] );
    372.                     verts[ face.sideNums.b ] = flattenSideNumber( verts[ face.cornerNums.b ], verts[ face.cornerNums.c ] );
    373.  
    374.                     verts[ face.sideNums.c ] = flattenSideNumber(  verts[ face.cornerNums.c ], verts[ face.cornerNums.d ] );
    375.                     verts[ face.sideNums.d ] = flattenSideNumber(  verts[ face.cornerNums.d ], verts[ face.cornerNums.a ] );
    376.  
    377.                     // CENTER
    378.                     verts[face.centerNum] = flattenSideNumber( verts[ face.cornerNums.a ], verts[ face.cornerNums.c ] );
    379.                 }
    380.             }
    381.         }
    382.  
    383.         #endregion
    384.  
    385.         #region Helper_Functions
    386.  
    387.         private Vector3 flattenSideNumber( Vector3 edgeA, Vector3 edgeB )
    388.         {
    389.             float sideDistance = Vector3.Distance( edgeA, edgeB );
    390.             if ( sideDistance > 0.001f )
    391.             {
    392.                 Quaternion sideRot = Quaternion.LookRotation( edgeB - edgeA );
    393.  
    394.                 return edgeA + sideRot * Vector3.forward * sideDistance * 0.5f;
    395.             }
    396.             else
    397.             {
    398.                 return edgeA;
    399.             }
    400.         }
    401.  
    402.         private Vector3 middleCenterNumber( Vector3 edgeA, Vector3 edgeB, Vector3 edgeC, Vector3 edgeD )
    403.         {
    404.            return calculateAverageVector( new Vector3[] { edgeA, edgeB, edgeC, edgeD } );
    405.         }
    406.  
    407.         private Vector3 calculateAverageVector( Vector3[] vArray )
    408.         {
    409.             if ( vArray.Length == 0 )
    410.                 return Vector3.zero;
    411.             float x = 0f;
    412.             float y = 0f;
    413.             float z = 0f;
    414.             for ( int i = 0; i < vArray.Length; i++ )
    415.             {
    416.                 x += vArray[ i ].x;
    417.                 y += vArray[ i ].y;
    418.                 z += vArray[ i ].z;
    419.             }
    420.             return new Vector3( x / vArray.Length, y / vArray.Length, z / vArray.Length );
    421.         }
    422.  
    423.         private float getAverageDistanceToMidPoint( Vector3 edgeA, Vector3 edgeB, Vector3 edgeC, Vector3 edgeD )
    424.         {
    425.  
    426.             Vector3 midPoint = calculateAverageVector( new Vector3[] { edgeA, edgeB, edgeC, edgeD } );
    427.  
    428.             return ( Vector3.Distance( edgeA, midPoint ) + Vector3.Distance( edgeB, midPoint ) + Vector3.Distance( edgeC, midPoint ) + Vector3.Distance( edgeD, midPoint ) ) / 4f;
    429.         }
    430.  
    431.         #endregion
    432.  
    433.         #endregion
    434.     }
    435.  
    436.     #region Editor
    437.  
    438. #if UNITY_EDITOR
    439.     [CustomEditor(typeof(LowPolifyVoxeland))]
    440.     public class LowPolifyVoxelandEditor : Editor
    441.     {
    442.         LowPolifyVoxeland script;
    443.  
    444.         public override void OnInspectorGUI()
    445.         {
    446.             base.OnInspectorGUI();
    447.  
    448.             if ( script == null )
    449.             {
    450.                 script = target as LowPolifyVoxeland;
    451.             }
    452.  
    453.             if ( script._voxeland != null )
    454.             {
    455.                 GUILayout.Space( 25f );
    456.                 if ( GUILayout.Button( "Rebuild Voxeland" ) )
    457.                 {
    458.                     script._voxeland.Rebuild();
    459.                 }
    460.             }
    461.         }
    462.     }
    463. #endif
    464.  
    465.     #endregion
    466. }
    2. Add this Line in Chunk.cs ​
    Code (csharp):
    1.  
    2. // EDITED
    3.             Fox.Flow.LowPolifyVoxeland.LowPolyMesh( faces, verts, voxeland );
    4.  
    5.  
    NOTE: You need to add these lines in "CalculateMesh()" under "RelaxMesh" like in this image shown:
    2020-04-08 03_29_50-.jpg

    3. Add Low Polify Voxeland under your existing Voxeland

    4. Rebuild the Chunks



    NOTE: Best values are 2 Relax Strength 1 Relax Iteration ( <- Found in the Voxeland.cs Settings ) and the default values of the Low Polify Voxeland Script, but that's just my personal preference..


    Thanks for your time :)
     
    Last edited: Apr 9, 2020
    mrs26 likes this.
  7. Wright

    Wright

    Joined:
    Feb 26, 2013
    Posts:
    1,805
    I've got a bug report saying that Voxeland asset crashes on import in Unity 2019.3.7f1 on Mac. I'll try to look into this as soon as get to my mac or at least set up remote connection with it.
    Will look into the seam issue too btw.

    This seems to be related with the floating point precision. Usually changing light's near and far plane settings helps to find the right bias between black artifacts and shadow disappearing for small objects on the big worlds.

    Excellent work! Feel free to publish it on the Asset Store, it deserves it!
    However instead of modifying chunk.cs I can add an event here in the next version.
     
    mrs26 likes this.
  8. BrettBibby

    BrettBibby

    Chief Product Officer Unity Technologies

    Joined:
    Mar 24, 2017
    Posts:
    7
    I'm the one that reported the bug, glad it's landed with you. I don't know if they also told you but we found that removing/unchecking these two files in the popup window before import allows the asset to import without crashing Unity 2019.3.7:
    “Assets/Voxeland/TextureArrayInspector/Demo/BumpMap.asset”
    and “Assets/Voxeland/TextureArrayInspector/Demo/MainTex.asset”
     
    P_Jong likes this.
  9. flow-

    flow-

    Joined:
    Apr 19, 2015
    Posts:
    165
    Thanks :)
    Well, I will see if this script gets much attention and maybe I publish it on the Asset Store for free, we will see...
    And an event would be Amazing, this would quite simplify the process for new Developer.


    Also Updated the Script to a newer recent version, here the change Log from recent Feedback:

    - Made the variable names more clear
    - Changed Edge Transformation Randomization also to always have effect if needed
    - Added Randomization for the Flat Surface
    - Added Unregister of the Instance on Disable and Destroy
    - Edge Transform Enum is now with the Flags Attribute to select more edges at once

    I updated the code of the Low Polify Voxeland Script here: https://forum.unity.com/threads/voxeland-voxel-terrain-tool.187741/page-49#post-5683954

    But for now, I let it be how it is and focus on my game for now as this also requires attention.
     
    mrs26 likes this.
  10. mrs26

    mrs26

    Joined:
    Sep 13, 2018
    Posts:
    12
    Hey Wright,
    a while ago you sent me a new "Data.cs" with a fix for my problem with the artifacts that appeared when using the smooth brush. Just wanted to ask you when the fix will make it into the official Voxeland asset.
     
  11. CodexofRome

    CodexofRome

    Joined:
    Oct 11, 2015
    Posts:
    41
    I'm interested in finding a tool to create a mine/tunnel system. I need to have both vertical shafts and sloping tunnels. There doesn't need to be any connection to an exterior terrain. Would you recommend Voxeland for this kind of layout?
     
  12. scottpkane94

    scottpkane94

    Joined:
    Aug 24, 2019
    Posts:
    27
    I'm trying to use Voxeland with MapMagic (which is working nicely), how can I use Vegetation Studio Pro output in MapMagic with a Voxeland terrain? is there a way to convert the top level mesh into a Terrain so that the terrain can be added in Vegetation System Pro?
     
  13. scottpkane94

    scottpkane94

    Joined:
    Aug 24, 2019
    Posts:
    27
    Can anyone answer please? From what I can tell, the problem is that the Voxeland chunks don't always have a mesh assigned which means when I set Voxeland as a "Raycast Terrain" in VS Pro, there is no collider for the raycast to hit, causing there to be no objects spawned on the terrain.
     
  14. scottpkane94

    scottpkane94

    Joined:
    Aug 24, 2019
    Posts:
    27
    Actually they do spawn but only if I disable/re-enable the VS Pro system, is there some event in Voxeland I can use to know when a new chunk has loaded around the camera?
     
  15. scottpkane94

    scottpkane94

    Joined:
    Aug 24, 2019
    Posts:
    27
    So I have been able to get assets to spawn through VS Pro onto the Voxeland terrain by adding the VS Pro "Raycast Terrain" component to the Voxeland object and enabled "Copy Components to Chunk" which causes the VS Pro package assets to spawn in the world but causes lag spikes when moving between chunks. This also doesn't hook up to the MapMagic VS Pro output node, so cannot use scatter objects from MapMagic to use VS Pro with Voxeland.

    Please can I get some support?
     
  16. visualjump3d

    visualjump3d

    Joined:
    Jun 6, 2014
    Posts:
    9
    Hi !!! can i also use Voxel with MicroSplat terrain?
     
  17. Victor_cross

    Victor_cross

    Joined:
    Dec 16, 2015
    Posts:
    41
    Hey Wright Any chance of there being a paid Multiplayer plugin for voxeland and mapmagic with a saving capacity?
     
  18. Radu392

    Radu392

    Joined:
    Jan 6, 2016
    Posts:
    210
    Has anyone figured how to use lightmapping with this asset? Been going over previous pages but couldn't find much.

    Things I tried:

    Used Unity's FBX Exporter from the package manager on a child chunk. The mesh turned out fine, except for the tangents. I had to go into the mesh settings and set tangents to 'None' in order to get real time lighting to work. I turned on 'Generate Lightmap UVs' then started baking my new static chunk, but it just turns out black with a very faint white near the light source. That faintness doesn't change no matter what intensity I select.

    This is how it looks like with tangents enabled (realtime light intensity 200):



    This is how it looks like without tangents (realtime light intensity 5):



    Finally, this is how it looks like when baked (tangent settings or light settings doesn't change the outcome):

     
  19. Imakhiil

    Imakhiil

    Joined:
    Oct 11, 2013
    Posts:
    60
    Hi. Is Voxeland compatible with Mapmagic 2?
     
    rickcollette likes this.
  20. Zante

    Zante

    Joined:
    Mar 29, 2008
    Posts:
    405
    Does voxeland support mesh brushes and can it produce terrain verticality similar to the examples shown below? (From Trackmania 2)







    See the start of this video for more info, I asusme it's also using a voxel-based solution rather than a mesh-based one?

     
  21. dajnooo

    dajnooo

    Joined:
    Feb 22, 2019
    Posts:
    10


    Im getting some strange shapes every time I use Voxeland with Map Magic 1. How can I fix this?

    Also how can I get grass with Map Magic and Voxeland? I added grass and gave it a texture and connected it to the grass node in MM like this:


    Is there something else I need to do? There's no tutorial so I have to ask here.

    @Wright
     
    Last edited: Jun 16, 2020
  22. qpuilie

    qpuilie

    Joined:
    Jan 14, 2020
    Posts:
    48
    Hello,I have a question about the map data.
    My Map size is 300*300,but the map I saved is 16M in size.
    even though i set param "pinnedOnly" is true,the file size is 1M.
    It's terrible to send 1M data on the net.
    can you give my some hints?thanks!

    this is my save code:
     

    Attached Files:

  23. iraway

    iraway

    Joined:
    Dec 2, 2015
    Posts:
    5
    Hey there, I have a pretty straightforward setup with MagMagic 1 powering the generation of a Voxeland terrain. So far seems to be working well, my AI can traverse it fine and I am able to walk across it with a third party TPS style controller just fine.

    The issue I'm running into is that any raycasts that I attempt to do to the terrain seem to be failing. The rays just go through the terrain, when cast from above. I'm trying to use this to determine exactly what height to place some custom objects at but haven't been able to get it to work so far. Is there something with the way the chunk meshes are created that would be expected to make this not work?

    Thanks for your work, very good stuff.
     
unityunity