If you look at the code, I put in several "levels" of color (for height obviously) if you set the noise to be colored. This way you can create a very simple version of a diffuse map for the same greyscale noise for a heightmap. You could add more levels, change the color, use noise functions on the color its self, etc. The result of combing a greyscale image, and the same image only colored, then with a detail material with a noisy sand-like texture for detail looks great on a terrain in game.
Give it at least 10 seconds to display something when you run the program, it will take time with the default settings.
The parameters you can mess with in the main code without screwing anything are grouped just under int main().
NoiseSize - the image size. Keep it the same size as the window size..or smaller.
NoiseZoom - This determines how close you are to the noise, the higher you set this the smaller the noise shapes will be.
Octaves - This acts kinda like my color technique in the header file, the higher, the more detail, 5 is too high to be honest. The higher, expect longer times to generate the noise, because it's going to be going over the same code that many more times per pixel = long time.
Persistence - Like NoiseZoom, but much more leathal. Keep this a double number in most cases other wise you'll end up with images like you get when you don't have a signal on older tvs.
Colored - Self explanatory. Grey-scale, or not. 0 = grey-scale.
If I had a site to upload pics to display here I'd upload a few results.
Now, this is only rough code, the parameters may be hard to understand and the like. If you have questions about the code, ask.
Here it is:
This is a header file.
Code: Select all
#include "iostream"
#include "math.h"
#include "irrlicht.h"
using namespace std;
using namespace irr;
using namespace core;
using namespace io;
using namespace video;
using namespace scene;
namespace Noise
{
inline double FindNoise(int seed, double x,double y);
inline double Interpolate(double a,double b,double x);
ITexture* Render_Clouds(int seed, bool colored,int w,int h,double zoom,int oct,double p,int r,int g,int b,IVideoDriver* driver);
int Live(int seed, bool colored,int w,int h,double zoom, int octaves ,double p, int r, int g, int b,IVideoDriver* driver);
double SmoothNoise(int seed, double x,double y);
double InterpolateNoise(int seed, double x, double y);
double DNoise(double x);
};
inline double Noise::DNoise(double x)
{
int n = (int(x)<<13) ^ int(x);
//return (double)( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & Ox7fffffff) / 1073741824.0);
int nn=(n*(n*n*60493+19990303)+1376312589)&0x7fffffff;
return 1.0-((double)nn/1073741824.0);
};
inline double Noise::FindNoise(int seed, double x,double y)
{
int n=(int)x+(int)y*57;
n=(n<<13)^n;
int nn=(n*(n*n*seed+19990303*seed)+1376312589)&0x7fffffff;
return 1.0-((double)nn/1073741824.0);
};
inline double Noise::Interpolate(double a,double b,double x)
{
double ft = x * 3.1415927;
double f = (1.0-cos(ft)) * 0.5;
return a * (1.0-f) + b * f;
};
double Noise::SmoothNoise(int seed, double x,double y)
{
int smooth = 1;
int cr = 16;
int si = 8;
int cn = 4;
double corners = ( FindNoise(seed, x-smooth, y-smooth)+FindNoise(seed, x+smooth, y-smooth)+FindNoise(seed, x-smooth, y+smooth)+FindNoise(seed, x+smooth, y+smooth) ) / cr;
double sides = ( FindNoise(seed, x-smooth, y) +FindNoise(seed, x+smooth, y) +FindNoise(seed, x, y-smooth) +FindNoise(seed, x, y+smooth) ) / si;
double center = FindNoise(seed, x, y) / cn;
return corners + sides + center;
};
double Noise::InterpolateNoise(int seed, double x, double y)
{
double integer_X = int(x);
double fractional_X = x - integer_X;
double integer_Y = int(y);
double fractional_Y = y - integer_Y;
double v1 = SmoothNoise(seed, integer_X, integer_Y);
double v2 = SmoothNoise(seed, integer_X + 1, integer_Y);
double v3 = SmoothNoise(seed, integer_X, integer_Y + 1);
double v4 = SmoothNoise(seed, integer_X + 1, integer_Y + 1);
double i1 = Interpolate(v1 , v2 , fractional_X);
double i2 = Interpolate(v3 , v4 , fractional_X);
return Interpolate(i1 , i2 , fractional_Y);
};
int r, g, b;
ITexture* Noise::Render_Clouds(int seed, bool colored,int w,int h,double zoom, int octaves ,double p, int r, int g, int b,IVideoDriver* driver)
{
double total = 0;//FindNoise(rand(),rand());
ITexture* File = 0;
bool water = false;
IImage* NoiseMap =
driver->createImage(ECF_R8G8B8,dimension2d<u32>(h,w));
u8 * ff=(u8 *)NoiseMap->lock();
for(int y=0;y<h;y++)
{
for(int x=0;x<w;x++)
{
total = 0;
for(int a=0;a<octaves-1;a++)//This loops trough the octaves.
{
double frequency = pow(2.0,a);//This increases the frequency with every loop of the octave.
double amplitude = pow(p,a);//This decreases the amplitude with every loop of the octave.
total = total + InterpolateNoise(seed, x * frequency / zoom, y / zoom * frequency) * amplitude;
}
if (colored == 1)
{
bool water = false;
int height = (int)((total*128.0)+128.0);//Convert to 0-256 values.
if (height<=0)
{
height=0;
water = true;
r = 0;
g = 150;
b = 195;
}
if (height>=50)
{
water = true;
r = 0;
g = 155;
b = 200;
}
if (height>=145)
{
r = 232;
g = 223;
b = 230;
}
if (height>=150)
{
r = 114;
g = 193;
b = 101;
}
if (height>=200)
{
r = 201;
g = 193;
b = 101;
}
if (height>=250)
{
r = 217;
g = 227;
b = 237;
}
if (height>=255)
{
height=255;
r = 227;
g = 237;
b = 247;
}
double random = DNoise(int(rand()));
if (random >= .25)
{
//if (water == false)
//{
int smooth = (int)((random)*2+total);
r = r + smooth;
g = g + smooth;
b = b + smooth;
//}
}
if (random >= .50)
{
//if (water == false)
//{
int smooth = (int)((random)*5+total);
r = r + smooth;
g = g + smooth;
b = b + smooth;
//}
}
NoiseMap->
setPixel(x,y,SColor(255,(int)r,(int)g,(int)b),false);
}
else
{
int height = (int)((total*128.0)+128.0);//Convert to 0-256 values.
if(height>255)
height=255;
if(height<0)
height=0;
NoiseMap->
setPixel(x,y,SColor(255,(int)height,(int)height,(int)height),false);
}
}
}
if (NoiseMap)
{
cout << "Image created.\n";
}
else
{
cout << "Image failed.\n";
}
bool i =
driver->writeImageToFile(NoiseMap,"NoiseMaps/noise.bmp",0);
//NoiseMap->drop();
//Tex->drop();
if (i)
{
cout << "Image exported.\n";
ITexture* File =
driver->getTexture("NoiseMaps/noise.bmp");
}
else
{
cout << "Image failed to export.\n";
}
return File;
};
Code: Select all
#include "Noise.h"
using namespace std;
using namespace irr;
using namespace core;
using namespace io;
using namespace video;
using namespace scene;
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
//------------------------------------------------------------------------------------------------
// Default device settings
//------------------------------------------------------------------------------------------------
E_DRIVER_TYPE driverType = EDT_DIRECT3D9;
int deviceWidth = 512;
int deviceHeight = deviceWidth;
int bits = 32;
int AA = 0; // AntiAliasing off default
bool AnisotropicFilter = false;
bool StencilBuffer = false; // Shadows
bool windowMode = false; // false = windowed
bool vsync = false;
SIrrlichtCreationParameters Parameters;
int main()
{
int NoiseSize = 512;
int NoiseZoom = 40;
int Octaves = 5;
double Persistance = .60;
bool Colored = 0;
int SeedNumber = 60493;
cout << "Seed Number: ";
cin >> SeedNumber;
Parameters.AntiAlias = AA;
Parameters.DriverType = driverType;
Parameters.Bits = bits;
Parameters.Vsync = vsync;
Parameters.Fullscreen = windowMode;
Parameters.WindowSize.Width = deviceWidth;
Parameters.WindowSize.Height = deviceHeight;
IrrlichtDevice* device =
createDeviceEx(Parameters);
if (device == 0)
return 1;
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
driver->setTextureCreationFlag(ETCF_OPTIMIZED_FOR_QUALITY, true);
driver->setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false);
Noise::Render_Clouds(SeedNumber,Colored,NoiseSize,NoiseSize,NoiseZoom,Octaves,Persistance, 0, 0, 0,driver);
ITexture* Map =
driver->getTexture("NoiseMaps/noise.bmp");
int lastFPS = -1;
while(device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, SColor(255,200,150,150));
smgr->drawAll();
driver->draw2DImage(Map,vector2d<s32>(0,0)); // display noise image
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
stringw str = L"Endless Engine [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
device->drop();
return 0;
}