• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Infinite_Gamer · Mar 16, 2015 at 09:43 AM · c#noiserandom gen

[Answered](C#) Simplex Noise and Negative Coordinates

Hello Unity Community;

I am trying to make a tile map game where the worlds are randomly generated. I have mostly everything working, but I ran into a problem. When I put negative coordinates into the simplex noise I am using, it doesn't like them. So a just made a quick fix and just put an absolute around the negative coordinates, this just made the noise flip on the axis. I knew that wasn't going to be a complete fix, I just did it so I could work and other things. But now I am returning to this problem.

I have been researching a way to fix it, but I can't find a way that actually works. If anyone knows how to fix this problem without the noise being flipped please let me know. Thanks in advanced :D

Here is my Script to get the noise using UnityEngine; using System.Collections; using SimplexNoise;

 [System.Serializable]
 public class BiomeGeneration
 {
     //It is flipped in the negative directions
 
     public Chunk ChunkGeneration(Chunk chunk, Vector2 offSet)
     {
         //The division by the Chunk.chunkSize gets the position needed for the Noise
         float noise = GetNoise(chunk.position.x / Chunk.chunkSize, chunk.position.y / Chunk.chunkSize, 0.01f, offSet, 50);
 
         chunk.renderer.material.color = new Color(noise, noise, noise);
 
         return chunk;
     }
 
     public static float GetNoise(int x, int y, float scale, Vector2 offSet, int max)
     {
         //The abs make it flip
         float noise = (Noise.Generate(Mathf.Abs(x * scale) + offSet.x, Mathf.Abs(y * scale) + offSet.y)) * (max / 2);
         return noise;
     }
 }


and here is the Simplex noise Script(just in case you need it) Sorry it is really long //using UnityEngine; // System.Collections;

 //public class Noise : MonoBehaviour
 //{
 
 namespace SimplexNoise
 {
     /// <summary>
     /// Implementation of the Perlin simplex noise, an improved Perlin noise algorithm.
     /// Based loosely on SimplexNoise1234 by Stefan Gustavson <http://staffwww.itn.liu.se/~stegu/aqsis/aqsis-newnoise/>
     /// 
     /// </summary>
     public class Noise
     {
         /// <summary>
         /// 1D simplex noise
         /// </summary>
         /// <param name="x"></param>
         /// <returns></returns>
         public static float Generate(float x)
         {
             int i0 = FastFloor(x);
             int i1 = i0 + 1;
             float x0 = x - i0;
             float x1 = x0 - 1.0f;
             
             float n0, n1;
             
             float t0 = 1.0f - x0*x0;
             t0 *= t0;
             n0 = t0 * t0 * grad(perm[i0 & 0xff], x0);
             
             float t1 = 1.0f - x1*x1;
             t1 *= t1;
             n1 = t1 * t1 * grad(perm[i1 & 0xff], x1);
             // The maximum value of this noise is 8*(3/4)^4 = 2.53125
             // A factor of 0.395 scales to fit exactly within [-1,1]
             return 0.395f * (n0 + n1);
         }
         
         /// <summary>
         /// 2D simplex noise
         /// </summary>
         /// <param name="x"></param>
         /// <param name="y"></param>
         /// <returns></returns>
         public static float Generate(float x, float y)
         {
             const float F2 = 0.366025403f; // F2 = 0.5*(sqrt(3.0)-1.0)
             const float G2 = 0.211324865f; // G2 = (3.0-Math.sqrt(3.0))/6.0
             
             float n0, n1, n2; // Noise contributions from the three corners
             
             // Skew the input space to determine which simplex cell we're in
             float s = (x+y)*F2; // Hairy factor for 2D
             float xs = x + s;
             float ys = y + s;
             int i = FastFloor(xs);
             int j = FastFloor(ys);
             
             float t = (float)(i+j)*G2;
             float X0 = i-t; // Unskew the cell origin back to (x,y) space
             float Y0 = j-t;
             float x0 = x-X0; // The x,y distances from the cell origin
             float y0 = y-Y0;
             
             // For the 2D case, the simplex shape is an equilateral triangle.
             // Determine which simplex we are in.
             int i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
             if(x0>y0) {i1=1; j1=0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1)
             else {i1=0; j1=1;}      // upper triangle, YX order: (0,0)->(0,1)->(1,1)
             
             // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
             // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
             // c = (3-sqrt(3))/6
             
             float x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
             float y1 = y0 - j1 + G2;
             float x2 = x0 - 1.0f + 2.0f * G2; // Offsets for last corner in (x,y) unskewed coords
             float y2 = y0 - 1.0f + 2.0f * G2;
             
             // Wrap the integer indices at 256, to avoid indexing perm[] out of bounds
             int ii = i % 256;
             int jj = j % 256;
             
             // Calculate the contribution from the three corners
             float t0 = 0.5f - x0*x0-y0*y0;
             if(t0 < 0.0f) n0 = 0.0f;
             else {
                 t0 *= t0;
                 n0 = t0 * t0 * grad(perm[ii+perm[jj]], x0, y0); 
             }
             
             float t1 = 0.5f - x1*x1-y1*y1;
             if(t1 < 0.0f) n1 = 0.0f;
             else {
                 t1 *= t1;
                 n1 = t1 * t1 * grad(perm[ii+i1+perm[jj+j1]], x1, y1);
             }
             
             float t2 = 0.5f - x2*x2-y2*y2;
             if(t2 < 0.0f) n2 = 0.0f;
             else {
                 t2 *= t2;
                 n2 = t2 * t2 * grad(perm[ii+1+perm[jj+1]], x2, y2);
             }
             
             // Add contributions from each corner to get the final noise value.
             // The result is scaled to return values in the interval [-1,1].
             return 40.0f * (n0 + n1 + n2); // TODO: The scale factor is preliminary!
         }
         
         
         public static float Generate(float x, float y, float z)
         {
             // Simple skewing factors for the 3D case
             const float F3 = 0.333333333f;
             const float G3 = 0.166666667f;
             
             float n0, n1, n2, n3; // Noise contributions from the four corners
             
             // Skew the input space to determine which simplex cell we're in
             float s = (x+y+z)*F3; // Very nice and simple skew factor for 3D
             float xs = x+s;
             float ys = y+s;
             float zs = z+s;
             int i = FastFloor(xs);
             int j = FastFloor(ys);
             int k = FastFloor(zs);
             
             float t = (float)(i+j+k)*G3; 
             float X0 = i-t; // Unskew the cell origin back to (x,y,z) space
             float Y0 = j-t;
             float Z0 = k-t;
             float x0 = x-X0; // The x,y,z distances from the cell origin
             float y0 = y-Y0;
             float z0 = z-Z0;
             
             // For the 3D case, the simplex shape is a slightly irregular tetrahedron.
             // Determine which simplex we are in.
             int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
             int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
             
             /* This code would benefit from a backport from the GLSL version! */
             if(x0>=y0) {
                 if(y0>=z0)
                 { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; } // X Y Z order
                 else if(x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } // X Z Y order
                 else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } // Z X Y order
             }
             else { // x0<y0
                 if(y0<z0) { i1=0; j1=0; k1=1; i2=0; j2=1; k2=1; } // Z Y X order
                 else if(x0<z0) { i1=0; j1=1; k1=0; i2=0; j2=1; k2=1; } // Y Z X order
                 else { i1=0; j1=1; k1=0; i2=1; j2=1; k2=0; } // Y X Z order
             }
             
             // A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
             // a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
             // a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
             // c = 1/6.
             
             float x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords
             float y1 = y0 - j1 + G3;
             float z1 = z0 - k1 + G3;
             float x2 = x0 - i2 + 2.0f*G3; // Offsets for third corner in (x,y,z) coords
             float y2 = y0 - j2 + 2.0f*G3;
             float z2 = z0 - k2 + 2.0f*G3;
             float x3 = x0 - 1.0f + 3.0f*G3; // Offsets for last corner in (x,y,z) coords
             float y3 = y0 - 1.0f + 3.0f*G3;
             float z3 = z0 - 1.0f + 3.0f*G3;
             
             // Wrap the integer indices at 256, to avoid indexing perm[] out of bounds
             int ii = Mod(i, 256);
             int jj = Mod(j, 256);
             int kk = Mod(k, 256);
             
             // Calculate the contribution from the four corners
             float t0 = 0.6f - x0*x0 - y0*y0 - z0*z0;
             if(t0 < 0.0f) n0 = 0.0f;
             else {
                 t0 *= t0;
                 n0 = t0 * t0 * grad(perm[ii+perm[jj+perm[kk]]], x0, y0, z0);
             }
             
             float t1 = 0.6f - x1*x1 - y1*y1 - z1*z1;
             if(t1 < 0.0f) n1 = 0.0f;
             else {
                 t1 *= t1;
                 n1 = t1 * t1 * grad(perm[ii+i1+perm[jj+j1+perm[kk+k1]]], x1, y1, z1);
             }
             
             float t2 = 0.6f - x2*x2 - y2*y2 - z2*z2;
             if(t2 < 0.0f) n2 = 0.0f;
             else {
                 t2 *= t2;
                 n2 = t2 * t2 * grad(perm[ii+i2+perm[jj+j2+perm[kk+k2]]], x2, y2, z2);
             }
             
             float t3 = 0.6f - x3*x3 - y3*y3 - z3*z3;
             if(t3<0.0f) n3 = 0.0f;
             else {
                 t3 *= t3;
                 n3 = t3 * t3 * grad(perm[ii+1+perm[jj+1+perm[kk+1]]], x3, y3, z3);
             }
             
             // Add contributions from each corner to get the final noise value.
             // The result is scaled to stay just inside [-1,1]
             return 32.0f * (n0 + n1 + n2 + n3); // TODO: The scale factor is preliminary!
         }
         
         public static byte[] perm = new byte[512] { 151,160,137,91,90,15,
             131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
             190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
             88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
             77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
             102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
             135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
             5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
             223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
             129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
             251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
             49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
             138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
             151,160,137,91,90,15,
             131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
             190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
             88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
             77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
             102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
             135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
             5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
             223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
             129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
             251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
             49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
             138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 
         };
         
         private static int FastFloor(float x)
         {
             return (x > 0) ? ((int)x) : (((int)x) - 1);
         }
         
         private static int Mod(int x, int m)
         {
             int a = x % m;
             return a < 0 ? a + m : a;
         }
         
         private static float grad( int hash, float x )
         {
             int h = hash & 15;
             float grad = 1.0f + (h & 7);   // Gradient value 1.0, 2.0, ..., 8.0
             if ((h & 8) != 0) grad = -grad;         // Set a random sign for the gradient
             return ( grad * x );           // Multiply the gradient with the distance
         }
         
         private static float grad( int hash, float x, float y )
         {
             int h = hash & 7;      // Convert low 3 bits of hash code
             float u = h<4 ? x : y;  // into 8 simple gradient directions,
             float v = h<4 ? y : x;  // and compute the dot product with (x,y).
             return ((h&1) != 0 ? -u : u) + ((h&2) != 0 ? -2.0f*v : 2.0f*v);
         }
         
         private static float grad( int hash, float x, float y , float z ) {
             int h = hash & 15;     // Convert low 4 bits of hash code into 12 simple
             float u = h<8 ? x : y; // gradient directions, and compute dot product.
             float v = h<4 ? y : h==12||h==14 ? x : z; // Fix repeats at h = 12 to 15
             return ((h&1) != 0 ? -u : u) + ((h&2) != 0 ? -v : v);
         }
         
         private static float grad( int hash, float x, float y, float z, float t ) {
             int h = hash & 31;      // Convert low 5 bits of hash code into 32 simple
             float u = h<24 ? x : y; // gradient directions, and compute dot product.
             float v = h<16 ? y : z;
             float w = h<8 ? z : t;
             return ((h&1) != 0 ? -u : u) + ((h&2) != 0 ? -v : v) + ((h&4) != 0 ? -w : w);
         }
     }
 }
 
 //}
Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image maccabbe · Mar 17, 2015 at 05:31 PM 0
Share

I second using a positive coordinate system You can use uint ins$$anonymous$$d of int and have your center at 2,147,483,647 (or whatever your current max coordiante is) ins$$anonymous$$d of 0 so you can go equal amount in both directions without breaking anything.

The biggest problem I see with using ints is that if you use bitwise operators you have to take into account how ints treat negative numbers. A good simplification of the problem is that, positive ints start at 0x00000000 and increase to 0x0FFFFFFF while negative numbers start at 0xFFFFFFFF and decrease to 0xF0000000. To me, it seems easier to change the coordinate system then deal with that.

avatar image Infinite_Gamer · Mar 18, 2015 at 01:22 AM 0
Share

Okay. I kind of didn't want to just keep the world positive, but if it works it works for me. Thanks for your thoughts on this.

:D

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

is there a way to replace script-made object to a custom one? 1 Answer

How to generate mountains on procedural terrain? 0 Answers

Game optimization using .SetActive() slowing down game. 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges