For direct access use https://forums.oldunreal.com
It's been quite a while since oldunreal had an overhaul, but we are moving to another server which require some updates and changes. The biggest change is the migration of our old reliable YaBB forum to phpBB. This system expects you to login with your username and old password known from YaBB.
If you experience any problems there is also the usual "password forgotten" function. Don't forget to clear your browser cache!
If you have any further concerns feel free to contact me: Smirftsch@oldunreal.com

Going procedural with Perlin

The section related to UnrealScript and modding. This board is for coders to discuss and exchange experiences or ask questions.
Post Reply
User avatar
Bleeder91[NL]
OldUnreal Member
Posts: 1062
Joined: Sun Oct 04, 2009 7:22 pm

Going procedural with Perlin

Post by Bleeder91[NL] »

I'm trying to mimic minecraft's procedural generation which has worked out well so far, apart from the constant crashing because of the overload of meshes/actors being drawn. My world's flat, however, and I would like to get some Perlin noise in here. I've tried 2 variants and tried my best converting them to Unrealscript, but both fail at doing what I want them to do.
What I need is a single function that I can give a vector location and it will return a float or int of the height that the Z axis will be. (no caves yet)

Short code from the Perlin wiki (Link):

Code: Select all

final function vector DotGridGradient(int iX, int iY, float X, float Y)
{
      local vector v1,v2;
      local float dX,dY;
      
      dX=X-iX; dY=Y-iY;
      v1.X=iY; v1.Y=iX; v1.Z=0;
      v2.X=iY; v2.Y=iX; v2.Z=1;
      return (dX*v1+dY*v2);
}
 
final function float Perlin(float X, float Y)
{
      local vector n0,n1;
      local float ix0, ix1;
      local int x0,x1,y0,y1;
      local float sX,sY;
      
      x0=int(X); x1=x0+1; y0=int(Y); y1=y0+1; sX=X-x0; sY=Y-y0;
      n0=DotGridGradient(x0, y0, X, Y); n1=DotGridGradient(x1, y0, X, Y);
      ix0=lerp(n0.X, n1.Y, sX);
      n0=DotGridGradient(x0, y1, X, Y); n1=DotGridGradient(x1, y1, X, Y);
      ix1=lerp(n0.X, n1.Y, sX);
      return lerp(ix0, ix1, sY);
}
This one keeps returning me numbers waaay higher/lower than I expected (-334895 to 664321 depending on vector distance from [0,0])

Long code from some other place([URL=http://www.scratchapixel.com/code.php?id=57&origin=/lessons/procedural-generation-virtual-worlds/perlin-noise-part-2]Link[/url]):

Code: Select all

function float GetMePerlin(vector p, optional out vector derivs)
{
      local int xi0,yi0,zi0, xi1,yi1,zi1;
      local float tx,ty,tz;
      local float u,v,w;
      local float x0,y0,z0,x1,y1,z1;
      local float a,b,c,d,e,f,g,h;
      local float du,dv,dw;
      local float k0,k1,k2,k3,k4,k5,k6,k7;
      
 xi0 = int(p.x) & 254;
 yi0 = int(p.y) & 254;
 zi0 = int(p.z) & 254;

 xi1 = (xi0+1) & 254;
 yi1 = (yi0+1) & 254;
 zi1 = (zi0+1) & 254;

 tx = p.x - int(p.x);
 ty = p.y - int(p.y);
 tz = p.z - int(p.z);

 u = quintic(tx);
 v = quintic(ty);
 w = quintic(tz);

// generate vectors going from the grid points to p
 x0 = tx; x1 = tx - 1;
 y0 = ty; y1 = ty - 1;
 z0 = tz; z1 = tz - 1;

 a = gradientDotV(byte(xi0+yi0+zi0), x0, y0, z0);
 b = gradientDotV(byte(xi1+yi0+zi0), x1, y0, z0);
 c = gradientDotV(byte(xi0+yi1+zi0), x0, y1, z0);
 d = gradientDotV(byte(xi1+yi1+zi0), x1, y1, z0);
 e = gradientDotV(byte(xi0+yi0+zi1), x0, y0, z1);
 f = gradientDotV(byte(xi1+yi0+zi1), x1, y0, z1);
 g = gradientDotV(byte(xi0+yi1+zi1), x0, y1, z1);
 h = gradientDotV(byte(xi1+yi1+zi1), x1, y1, z1);

 du = quinticDeriv(tx);
 dv = quinticDeriv(ty);
 dw = quinticDeriv(tz);

 k0 = a;
 k1 = (b - a);
 k2 = (c - a);
 k3 = (e - a);
 k4 = (a + d - b - c);
 k5 = (a + f - b - e);
 k6 = (a + g - c - e);
 k7 = (b + c + e + h - a - d - f - g);

derivs.x = du *(k1 + k4 * v + k5 * w + k7 * v * w);
derivs.y = dv *(k2 + k4 * u + k6 * w + k7 * v * w);
derivs.z = dw *(k3 + k5 * u + k6 * v + k7 * v * w);

return k0 + k1 * u + k2 * v + k3 * w + k4 * u * v + k5 * u * w + k6 * v * w + k7 * u * v * w;
} 

function float quinticDeriv(float t)
{
      return 30 * t * t * (t * (t - 2) + 1);
}

function float quintic(float t)
{
return t * t * t * (t * (t * 6 - 15) + 10);
}


function float gradientDotV(byte perm, float x, float y, float z)
{
      switch (perm & 15)
      {
            case 0: return x + y; // (1,1,0)
            case 1: return -x + y; // (-1,1,0)
            case 2: return x - y; // (1,-1,0)
            case 3: return -x - y; // (-1,-1,0)
            case 4: return x + z; // (1,0,1)
            case 5: return -x + z; // (-1,0,1)
            case 6: return x - z; // (1,0,-1)
            case 7: return -x - z; // (-1,0,-1)
            case 8: return y + z; // (0,1,1),
            case 9: return -y + z; // (0,-1,1),
            case 10: return y - z; // (0,1,-1),
            case 11: return -y - z; // (0,-1,-1)
            case 12: return y + x; // (1,1,0)
            case 13: return -x + y; // (-1,1,0)
            case 14: return -y + z; // (0,-1,1)
            case 15: return -y - z; // (0,-1,-1)
      }
} 
This one returns me 0 whatever I put in.

Obviously I have no idea what I'm doing and apart from being able to (hopefully) convert it correctly I am clueless as to what this thing actually does. So who's got the spare time to help me figure this one out? :D
Last edited by Bleeder91[NL] on Mon Jul 17, 2017 3:56 pm, edited 1 time in total.
Image
User avatar
Bleeder91[NL]
OldUnreal Member
Posts: 1062
Joined: Sun Oct 04, 2009 7:22 pm

Re: Going procedural with Perlin

Post by Bleeder91[NL] »

Third attempt with code for Simplex Noise. This one seems to be working well, though I need to smooth out the distribution a bit ([url=http://webstaff.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf]Link[/url]). I'll post a screenshot when I got it working right!

Code: Select all

//=============================================================================
// UCTerraGen. Procedural generation using Simplex Noise.
//=============================================================================
class UCTerraGen expands Actor abstract;
const F2=0.366025;
const G2=0.211324;

var const vector NoiseV[12];
var const int NoiseP[256];

final static function float Gener8(float xin, float yin)
{
      local float n0,n1,n2;
      local float s,t,X0,Y0,x0a,y0a;
      local float x1,y1,x2,y2,t0,t1,t2;
      local int i,j,i1,j1,ii,jj,gi0,gi1,gi2;
      
      // Noise contributions from the three corners
    // Skew the input space to determine which simplex cell we're in
    s = (xin+yin)*F2; 
      
      // Hairy factor for 2D
      i = int(xin+s);
      j = int(yin+s);
      t = (i+j)*G2;
      X0 = i-t; 
      
      // Unskew the cell origin back to (x,y) space
      Y0 = j-t;
      x0a = xin-X0; 
      y0a = yin-Y0;
      
      // Offsets for second (middle) corner of simplex in (i,j) coords
    if(x0a>y0a) { i1=1; j1=0; }
    else { i1=0; j1=1; } // lower triangle, XY order: (0,0)->(1,0)->(1,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
    x1 = x0a - i1 + G2; 
      
      // Offsets for middle corner in (x,y) unskewed coords
      y1 = y0a - j1 + G2;
      x2 = x0a - 1.0 + 2.0 * G2;
      y2 = y0a - 1.0 + 2.0 * G2;
      
      // Work out the hashed gradient indices of the three simplex corners
      ii = i & 255;
      jj = j & 255;
      gi0 = GetRandomNoiseP(ii   +GetRandomNoiseP(jj)) % 12;
      gi1 = GetRandomNoiseP(ii+i1+GetRandomNoiseP(jj+j1)) % 12;
      gi2 = GetRandomNoiseP(ii+1 +GetRandomNoiseP(jj+1)) % 12;
      
      // Calculate the contribution from the three corners
      t0 = 0.5 - x0a*x0a-y0a*y0a;
      if(t0
Last edited by Bleeder91[NL] on Wed Jul 19, 2017 11:31 am, edited 1 time in total.
Image
User avatar
Bleeder91[NL]
OldUnreal Member
Posts: 1062
Joined: Sun Oct 04, 2009 7:22 pm

Re: Going procedural with Perlin

Post by Bleeder91[NL] »

Alright, I got this now:

[img][/img]

I still have to address the issue of FPS and crashing due to the high amount of blocks being drawn...
1,572,864 blocks spawned in 201309ms. Seems legit.
Last edited by Bleeder91[NL] on Wed Jul 19, 2017 5:51 pm, edited 1 time in total.
Image
User avatar
BobIsUnreal
OldUnreal Member
Posts: 805
Joined: Mon Apr 12, 2010 12:34 am

Re: Going procedural with Perlin

Post by BobIsUnreal »

select all static mesh > convert to brush > rebuild , cry.
User avatar
Bleeder91[NL]
OldUnreal Member
Posts: 1062
Joined: Sun Oct 04, 2009 7:22 pm

Re: Going procedural with Perlin

Post by Bleeder91[NL] »

The thing is, the map itself is completely empty. This is spawned in real-time.
It has a random seed and spawns all the blocks on startup. All I need to do now is actually have it load/unload chunks because this drains my CPU extremely fast with multiple players. I can remove/build blocks already so the concept of minecraft in unreal is possible.
[img][/img]
I'm also not sure if I should stick with a normal mesh or go back to static. With static I seem to crash more often because of how many blocks are rendered at a time.
Last edited by Bleeder91[NL] on Thu Jul 20, 2017 6:38 am, edited 1 time in total.
Image
User avatar
dustinechoes849
OldUnreal Member
Posts: 480
Joined: Sat Feb 28, 2015 1:56 am

Re: Going procedural with Perlin

Post by dustinechoes849 »

That looks rad! :D
How did you implement placing/removing blocks? Does the DP's alt-fire place blocks (with primary destroying 'em)?
Last edited by dustinechoes849 on Thu Jul 20, 2017 8:25 am, edited 1 time in total.
Image
Image
Image
Image
Image
User avatar
Bleeder91[NL]
OldUnreal Member
Posts: 1062
Joined: Sun Oct 04, 2009 7:22 pm

Re: Going procedural with Perlin

Post by Bleeder91[NL] »

It's a quick experiment for now. LMB places, RMB destroys. walk+LMB is stone bricks. Terrain's grass on top, 3 layers of Dirt, then some Stone and Gravel and finally Bedrock at the bottom. Once I have chunkloading made I can look into caves and tools etc.
I have it running on my server.
Last edited by Bleeder91[NL] on Thu Jul 20, 2017 8:44 am, edited 1 time in total.
Image
User avatar
dustinechoes849
OldUnreal Member
Posts: 480
Joined: Sat Feb 28, 2015 1:56 am

Re: Going procedural with Perlin

Post by dustinechoes849 »

I have it running on my server.
what's the IP? :o
Last edited by dustinechoes849 on Fri Jul 21, 2017 3:51 am, edited 1 time in total.
Image
Image
Image
Image
Image
Post Reply

Return to “UScript Board”