bool ProceduralTexture::Load(const char* fileName, class AssetCache* cache) { mWidth = 600; mHeight = 450; channels = 3; int octaves = 8; image = new unsigned char[mWidth*mHeight*channels]; PerlinNoise pnoise; int kk = 0; for (int y=0; y < mHeight; y++) { for (int x=0; x < mWidth; x++) { double pn = 0.0f; double x_f = double(x) / mWidth; double y_f = double(y) / mHeight; for (int o=0; o < octaves; ++o) { float add = pnoise.Noise(4*x_f * (1 << o), 4*y_f * (1 << o), 0.8 * ( 1 << o)); if ( add > 0) { add = -1*add + 1.0f; } else { add += 1.0f; } pn += ( add / (1 << o)); } unsigned char color = (unsigned char) (floor(255 * pn)); for (int c=0; c < channels; c++) { image[kk++] = color; } } } int mode = GL_RGB; // Generate a GL texture glGenTextures(1, &mTextureID); glBindTexture(GL_TEXTURE_2D, mTextureID); glTexImage2D(GL_TEXTURE_2D, 0, mode, mWidth, mHeight, 0, mode, GL_UNSIGNED_BYTE, image); // Use linear filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Generate mip maps, just in case glGenerateMipmap(GL_TEXTURE_2D); return true; }
void generatePerlinNoise(glm::vec3 perlinMatrix[IslandWidth][IslandHeight], double elevation[IslandWidth][IslandHeight]) { PerlinNoise pn; // int x,y; // double n, i, j; // for(x = 0; x < IslandWidth; x++){ // for(y = 0; y < IslandHeight; y++){ // i = (double) x / IslandWidth; // j = (double) y / IslandHeight; // n = 20 * pn.noise((double) i, (double) j, 0.0); // n = n - floor(n); // if(elevation[x][y] == 0){ // elevation[x][y] += ((int) floor(n) % 2) ? n : -n; // } // } // } int i = 0, j = 0, xtemp; double n; int n_int; while(j < IslandHeight) { while(i < IslandWidth) { n = 2.0 * pn.noise((double) i, (double) j, elevation[i][j]); perlinMatrix[i][j].x = 0; perlinMatrix[i][j].y = 0; perlinMatrix[i][j].z = n; i++; } i = 0; j++; } }
void TerrainProceduralDialog::makePertrub(float frequency, float distance) { setWorking(true); PerlinNoise perlin; perlin.setSeed(1); perlin.initGradients(); int u, v; float * temp = new float[m_mapWidth*m_mapDepth]; for (int i = 0; i < m_mapWidth; ++i) for (int j = 0; j < m_mapDepth; ++j) { u = i + (int)(perlin.noise(frequency * i / (float)m_mapWidth, frequency * j / (float)m_mapDepth, 0) * distance); v = j + (int)(perlin.noise(frequency * i / (float)m_mapWidth, frequency * j / (float)m_mapDepth, 1) * distance); if (u < 0) u = 0; if (u >= m_mapWidth) u = m_mapWidth - 1; if (v < 0) v = 0; if (v >= m_mapDepth) v = m_mapDepth - 1; temp[i*m_mapWidth+j] = data[u*m_mapWidth+v]; } for(int i=0;i<m_mapWidth*m_mapDepth;i++) data[i]=temp[i]; delete temp; updateImage(); setWorking(false); }
bool cScene::Init(FILE* fd) { maxHeight = 0; minHeight = SCENE_HEIGHT; int randomseed = 0; int amplitude = SCENE_HEIGHT/2; PerlinNoise noise = PerlinNoise(0.1,1,amplitude,8,randomseed); for(int z=0;z<SCENE_DEPTH;z++){ for(int x=0;x<SCENE_WIDTH;x++){ int alt = amplitude + (int)noise.GetHeight(x,z); int y; for (y = 0; y < alt; y++){ mapa[y][x][z] = 1; nCubes[y]++; } minHeight = min(y,minHeight); maxHeight = max(y,maxHeight); heightMap[x][z] = y; for(;y<SCENE_HEIGHT;y++){ mapa[y][x][z] = 0; } } } //fprintf(fd,"min-->%d\nmax-->%d\n",minHeight,maxHeight); initVBO(); initNormals(); unsigned long len = 0; if(shader.loadShader("vertexShader.vert", &len, VERTEX_SHADER) != OK) return false; if(shader.loadShader("fragmentShader.frag", &len, FRAGMENT_SHADER) != OK) return false; if(shader.compileShader(VERTEX_SHADER) != OK) { GLchar *log = shader.getCompilationLog(VERTEX_SHADER); return false; } if(shader.compileShader(FRAGMENT_SHADER) != OK) { GLchar *log = shader.getCompilationLog(FRAGMENT_SHADER); return false; } if(shader.linkShader(VERTEX_SHADER) != OK) { GLchar *log = shader.getLinkingLog(VERTEX_SHADER); return false; } if(shader.linkShader(FRAGMENT_SHADER) != OK) { GLchar *log = shader.getLinkingLog(FRAGMENT_SHADER); return false; } if(shader.useShader(VERTEX_SHADER) != OK) return false; //if(shader.useShader(FRAGMENT_SHADER) != OK) return false; return true; }
Image CreateSkyImage() { PerlinNoise noise; Image image(640, 960); for (auto p : step(image.size)) image[p.y][p.x] = HSV(220, 0.9 * noise.octaveNoise0_1(p.x / 160.0, Abs(p.y / 120.0 - 4.0), 8), 0.8); return image; }
void GeneratePerlinNoiseProcess::run() { PerlinNoise pn; Image* pOutImage = 0; if ( mUseNormalization ) { pOutImage = pn.GenerateNormalized( mPersistence, mNrOctaves, mWidth, mHeight, mRed, mGreen, mBlue, mSeed, mZoom ); } else { pOutImage = pn.Generate( mPersistence, mNrOctaves, mWidth, mHeight, mRed, mGreen, mBlue, mSeed, mZoom ); } std::string imageName = std::string("PerlinClouds"); pOutImage->SetImageName( imageName ); AddResult( pOutImage ); // ownership of this image is transfered through GetImage() to ImageDataList }
void TerrainProceduralDialog::makePerlinNoise(float seed, float frequency) { setWorking(true); PerlinNoise perlin; perlin.setSeed(seed); perlin.initGradients(); for(int i=0; i<m_mapWidth;i++) for(int j=0; j<m_mapDepth;j++) { float value=perlin.noise(frequency * i / (float)m_mapWidth, frequency * j / (float)m_mapDepth, 0); data[i*m_mapWidth+j]=value; } updateImage(); setWorking(false); }
void RaytracingWindow::CreatePic() { #define XX RAYTRACING_DISPLAY_WIDTH #define YY RAYTRACING_DISPLAY_HEIGHT mPic.Init(XX, YY); RGBAPixel* Pixels = mPic.GetPixels(); // FractalBrownianMotion FBM(0.5f, 1.5f, 4.0f); // RidgedFractal FBM(0.5f, 1.5f, 4.0f, 1.0f, 1.0f); PerlinNoise FBM; Point Vector(1.0f, 0.0f, 100.0f); static float z = 0.0f; z+=0.01f; Vector.z = z; float Coeff = 0.005f; for(udword y=0;y<YY;y++) { for(udword x=0;x<XX;x++) { Vector.x = float(x)*Coeff; Vector.y = float(y)*Coeff; float fR = 128.0f + 128.0f * FBM.Compute(Vector); float fG = 128.0f + 128.0f * FBM.Compute(Vector+Point(0.0f, 0.0f, -1.0f)); float fB = 128.0f + 128.0f * FBM.Compute(Vector+Point(0.0f, 0.0f, 1.0f)); Pixels->R = ubyte(fR); Pixels->G = ubyte(fG); Pixels->B = ubyte(fB); Pixels->A = 255; Pixels++; /* udword fR = (udword)(200.0f - FBM.Turbulence(Vector, 32.0f) * 250.0f); udword fG = (udword)(200.0f - FBM.Turbulence(Vector+Point(0.0f, 0.0f, -1.0f), 32.0f) * 250.0f); udword fB = (udword)(200.0f - FBM.Turbulence(Vector+Point(0.0f, 0.0f, 1.0f), 32.0f) * 250.0f); Pixels->R = ubyte(fR); Pixels->G = ubyte(fG); Pixels->B = ubyte(fB); Pixels->A = 255; Pixels++;*/ } } }
GridSystem::GridSystem(int w, int h, PerlinNoise p, float gridsize) { this->selectedi = -1; this->selectedj = -1; this->w = w; this->h = h; this->offset = gridsize; this->p = p; float persistance = 0.2f; float amplitude = 1.0f; float octave = 7.0f; //initialize grids for (float i = 0.0f; i < w + (offset/2); i += offset) //float correction that's why we add (offset/2) { vector<Grid*> gridRow; for (float j = 0.0; j < h + (offset/2); j += offset) { Grid* g = new Grid(i, 0.0f, j); float val = p.Noise(i, 0.0f, j, persistance, amplitude, octave) * 3; g->assignNoise(val); /*if (i == 0.0f || (i + (2 * offset))>w || j == offset || (j + (2 * offset))>h) { g.assignNoise(p.octave_noise(i, 0.0f, j, persistance, amplitude, octave)); } else { g.assignNoise(p.octave_noise(i, 0.0f, j, persistance, amplitude, octave) * 3); }*/ gridRow.push_back(g); } grids.push_back(gridRow); } for (int i = 0; i < grids.size(); i++) { for (int j = 0; j < grids[0].size(); j++) { Grid* n_up = (i > 0) ? grids[i - 1][j] : grids[i][j]; Grid* n_down = (i < grids.size()-1) ? grids[i + 1][j] : grids[i][j]; Grid* n_right = (j < grids[0].size() - 1) ? grids[i][j + 1] : grids[i][j]; Grid* n_left = (j > 0) ? grids[i][j - 1] : grids[i][j]; grids[i][j]->setNeighboringGrid(n_up, n_right, n_down, n_left); } } /*for (int a = 0; a < grids.size()*grids[0].size()*5; a++){ int i = rand() % grids.size(); int j = rand() % grids[0].size(); grids[i][j].naturalizeGrid(); }*/ }
T noise(T x, T y, T z) { T sum = 0; T frequency = (T)1; T amplitude = (T)1; T max = (T)0; for (int32_t i = 0; i < (int32_t)octaves; i++) { sum += perlinNoise.noise(x * frequency, y * frequency, z * frequency) * amplitude; max += amplitude; amplitude *= persistence; frequency *= (T)2; } sum = sum / max; return (sum + (T)1.0) / (T)2.0; }
// Called when the game starts or when spawned void APDemo::BeginPlay() { Super::BeginPlay(); FString GameDir = FPaths::GameDir(); FString CompleteFilePath = GameDir + "map_settings.txt"; FString FileData = ""; FFileHelper::LoadFileToString(FileData, *CompleteFilePath); int map_hash = FCString::Atoi(*FileData); //UE_LOG(LogTemp, Warning, TEXT("map_hash is %i and the path is %s"), map_hash, *CompleteFilePath); pn = PerlinNoise(map_hash); // Create an empty PPM image ppm image(width, height); unsigned int kk = 0; // Visit every pixel of the image and assign a color generated with Perlin noise for (unsigned int i = 0; i < height; ++i) { // y for (unsigned int j = 0; j < width; ++j) { // x double x = (double)j / ((double)width); double y = (double)i / ((double)height); // Typical Perlin noise double n = pn.noise(10 * x, 10 * y, 0.8); // Wood like structure //n = 20 * pn.noise(x, y, 0.8); //n = n - floor(n); n = n < noise_threshold ? 0 : n;//used to create a clear distinction between space and land // Map the values to the [0, 255] interval, for simplicity we use // tones of grey image.r[kk] = floor(255 * n); image.g[kk] = floor(255 * n); image.b[kk] = floor(255 * n); kk++; } } // Save the image in a binary PPM file int result = image.write("figure_8_R.ppm"); }
bool GenerateSyntheticImagesTest() { bool allSuccess = true; int width = 256; int height = 256; double sigma1 = 3.0; double sigma2 = 15.0; double rho = -0.9; double sigma = 7.0; ArrayGrid<double>* pGrid = GridGenerator::GenerateHorizontalGradient(512, 128); ImageIO::WritePGM(pGrid, string("HorizontalGradient.pgm"), ImageIO::NULL_OUT); delete pGrid; ArrayGrid<double>* pInvZone = GridGenerator::GenerateInverseZonePlate ( ); ImageIO::WritePGM(pInvZone, string("InvZonePlate.pgm"), ImageIO::NULL_OUT ); delete pInvZone; ArrayGrid<double>* pZone = GridGenerator::GenerateZonePlate ( ); ImageIO::WritePGM(pZone, string("ZonePlate.pgm"), ImageIO::NULL_OUT ); delete pZone; ArrayGrid<double>* pSheppLogan = GridGenerator::GenerateSheppLogan ( ); ImageIO::WritePGM(pSheppLogan, string("SheppLogan.pgm"), ImageIO::NORMAL_OUT ); delete pSheppLogan; ArrayGrid<double>* pLogFrequencyContrast = GridGenerator::GenerateLogFrequencyContrastChart( ); ImageIO::WritePGM( pLogFrequencyContrast, string("LogFrequencyContrast.pgm"), ImageIO::NORMAL_OUT ); delete pLogFrequencyContrast; int nrPeriods = 85; ArrayGrid<double>* pStarChart = GridGenerator::GenerateStarChart( width, nrPeriods ); ImageIO::WritePGM( pStarChart, string("StarChart.pgm"), ImageIO::NORMAL_OUT ); delete pStarChart; double length = 13.0; double angle = 0.4; ArrayGrid<double>* pLine = GridGenerator::GenerateLine( width, height, length, angle ); ImageIO::WritePGM( pLine, string("PSFLine.pgm"), ImageIO::NORMAL_OUT ); delete pLine; ArrayGrid<double>* pSquare = GridGenerator::GenerateSquare( width, height, sigma); ImageIO::WritePGM(pSquare, string("PSFSquare.pgm"), ImageIO::NORMAL_OUT ); delete pSquare; ArrayGrid<double>* pDisk = GridGenerator::GenerateDisk( width, height, sigma); ImageIO::WritePGM(pDisk, string("PSFDisk.pgm"), ImageIO::NORMAL_OUT ); delete pDisk; ArrayGrid<double>* pAiry = GridGenerator::GenerateAiry( width, height, sigma); ImageIO::WritePGM(pAiry, string("Airy.pgm"), ImageIO::NORMAL_OUT ); delete pAiry; ArrayGrid<double>* pGauss = GridGenerator::GenerateGaussian( width, height, sigma1, sigma2, rho); ImageIO::WritePGM( pGauss, string("Gauss.pgm"), ImageIO::NORMAL_OUT ); delete pGauss; ArrayGrid<double>* pGx = GridGenerator::GenerateGaussianFirstDerivativeX( width, height, sigma1, sigma2 ); ImageIO::WritePGM( pGx, string("Gx.pgm"), ImageIO::GRADIENT_OUT ); ImageIO::WriteTXT( pGx, string("Gx.txt") ); delete pGx; ArrayGrid<double>* pGy = GridGenerator::GenerateGaussianFirstDerivativeY( width, height, sigma1, sigma2 ); ImageIO::WritePGM( pGy, string("Gy.pgm"), ImageIO::GRADIENT_OUT ); ImageIO::WriteTXT( pGy, string("Gy.txt") ); delete pGy; ArrayGrid<double>* pGxx = GridGenerator::GenerateGaussianSecondDerivativeX ( width, height, sigma1, sigma2 ); ImageIO::WritePGM( pGxx, string("Gxx.pgm"), ImageIO::NORMAL_OUT ); ImageIO::WriteTXT( pGxx, string("Gxx.txt") ); delete pGxx; ArrayGrid<double>* pGyy = GridGenerator::GenerateGaussianSecondDerivativeY ( width, height, sigma1, sigma2 ); ImageIO::WritePGM( pGyy, string("Gyy.pgm"), ImageIO::NORMAL_OUT ); ImageIO::WriteTXT( pGyy, string("Gyy.txt") ); delete pGyy; ArrayGrid<double>* pGxy = GridGenerator::GenerateGaussianMixedDerivativesXY ( width, height, sigma1, sigma2 ); ImageIO::WritePGM(pGxy, string("Gxy.pgm"), ImageIO::NORMAL_OUT ); delete pGxy; ArrayGrid<double>* pBars = GridGenerator::GenerateBars( width, height, 20 ); ImageIO::WritePGM( pBars, string("Bars.pgm"), ImageIO::NORMAL_OUT ); delete pBars; float persistence = 0.8; int octaves = 7; float red = 1.5; float green = 1.0; float blue = 2.0; int seed = 0; float zoom = 75; PerlinNoise pn; Image* pData = pn.Generate( persistence, octaves, width, height, red, green, blue, seed, zoom ); ImageIO::Write( pData, std::string("PerlinColor.ppm") ); delete pData; //ArrayGrid<int>* pIsing = GridGenerator::GenerateIsingTexture( ); //ImageIO::WritePGM(pGx, string("Ising.pgm"), ImageIO::GRADIENT_OUT ); //delete pIsing; return allSuccess; }
double * adjustVoronoi(int ** voronoiPositions, double ** voronoiColors, double elevation[IslandWidth][IslandHeight], glm::vec3 landColor[IslandWidth][IslandHeight], int idx){ int x = 0, y = 0, i = 0; double currHeight; double * resVorPos; *voronoiColors = (double *) calloc( idx, sizeof(double) ); resVorPos = (double *) calloc( idx, sizeof(double) ); double maxElev = 0; double elevThresh = 0.4; PerlinNoise pn; double n; int maxrad = 1000, rad ; glm::vec2 center; glm::vec2 loc; center.x = IslandWidth / 2; center.y = IslandHeight / 2; double distanceFromCtr; while(i < idx){ x = (*voronoiPositions)[i]; y = (*voronoiPositions)[i + 1]; loc.x = x; loc.y = y; if( (x >= 0 && x < IslandWidth) && (y >= 0 && y < IslandHeight) ){ distanceFromCtr = (double) glm::length(loc - center); n = pn.noise( (double) x / IslandWidth, (double) y / IslandHeight, 0.0); rad = maxrad * (n - floor(n)); //n = sin(x + y); n *= 1800; resVorPos[i] = normalize(x, IslandWidth); resVorPos[i + 1] = normalize(y, IslandHeight); //z-value currHeight = elevation[x][y]; if(maxElev < currHeight){ maxElev = currHeight ; } // (*voronoiPositions)[i + 2] = -currHeight; // resVorPos[i + 2] = (distanceFromCtr < (IslandRadius + n)) ? -currHeight:0.0f; resVorPos[i + 2] = -currHeight; if(resVorPos[i + 2] > elevThresh){ resVorPos[i + 2] = elevThresh; } // printf("Voronoi pos: (%d, %d) E: %f\n", x, y, resVorPos[i + 2]); // *voronoiColors = (double *) realloc((*voronoiColors), (i+ 3) * sizeof(double) ); // r (*voronoiColors)[i] = landColor[x][y].r; // (*voronoiColors)[i] *= 1.3; // g (*voronoiColors)[i + 1] = landColor[x][y].g; // (*voronoiColors)[i + 1] *= 1.3; // b (*voronoiColors)[i + 2] = landColor[x][y].b; // (*voronoiColors)[i + 2] *= 0.4; // } } else{ if(x < 0){ resVorPos[i] = -1; } if(x >= IslandWidth){ resVorPos[i] = 1; } if(y < 0){ resVorPos[i + 1] = -1; } if(y >= IslandHeight){ resVorPos[i + 1] = 1; } resVorPos[i + 2] = 0; } i += 3; } printf("Max voronoi height: %f", maxElev); return resVorPos; }
void doIdle() { char s[20]="picxxxx.ppm"; int i; // save screen to file s[3] = 48 + (sprite / 1000); s[4] = 48 + (sprite % 1000) / 100; s[5] = 48 + (sprite % 100 ) / 10; s[6] = 48 + sprite % 10; if (saveScreenToFile==1) { saveScreenshot(windowWidth, windowHeight, s); //saveScreenToFile=0; // save only once, change this if you want continuos image generation (i.e. animation) sprite++; } if (sprite >= 300) // allow only 300 snapshots { exit(0); } if (pause == 0) { // insert code which appropriately performs one step of the cube simulation: if (Integration[0] == 'E') { Euler(&jello); }else if (Integration[0] == 'R') { RK4(&jello); }else { exit(0); } } if (Fx == 1) { jello.Force.x += 1; Fx = 0; } if (Fx == -1) { jello.Force.x -= 1; Fx = 0; } if (Fy == 1) { jello.Force.y += 1; Fy = 0; } if (Fy == -1) { jello.Force.y -= 1; Fy = 0; } if (Fa == 1) { alpha += 1; Fa = 0; } if (Fa == -1) { if (alpha != 0) { alpha -= 1; Fa = 0; } } if (Fb == 1) { beta += 0.1; Fb = 0; } if (Fb == -1) { beta -= 0.1; Fb = 0; } if (PNoise == -1) { jello.Force.x = 0; jello.Force.y = -1; PNoise = 0; for (int i=0; i<particleNum; i++) { jello.v[i].x = 0; jello.v[i].y = 0; jello.v[i].z = 0; jello.a[i].x = 0; jello.a[i].y = 0; jello.a[i].z = 0; } } if (PNoise == 1) { srand(time(NULL)); PerlinNoise P; if (alpha == 0) { jello.Force.x = P.PerlinNoise1D(rand()%100, particleNum , 0.3); jello.Force.y = P.PerlinNoise1D(rand()%100, particleNum , 0.3); }else { jello.Force.x = P.PerlinNoise1D(rand()%100, particleNum , 0.3) * 20; jello.Force.y = P.PerlinNoise1D(rand()%100, particleNum , 0.3) * 20; } } //reset everything if (Fx == -5) { for (int i=0; i<particleNum; i++) { jello.v[i].x = 0; jello.v[i].y = 0; jello.v[i].z = 0; jello.a[i].x = 0; jello.a[i].y = 0; jello.a[i].z = 0; } jello.Force.x = 0; jello.Force.y = -1; alpha = 0; beta = 0; PNoise = 0; Fx = 0; } glutPostRedisplay(); }
//-------------------------------------------------------------------------------- VolumeActor::VolumeActor() { // Create the texture that we will be using as the volume. PerlinNoise noise; noise.initialize(); const int DIM = 32; float* fData = new float[DIM*DIM*DIM]; for ( int z = 0; z < DIM; z++ ) { for ( int y = 0; y < DIM; y++ ) { for ( int x = 0; x < DIM; x++ ) { fData[z*DIM*DIM+y*DIM+x] = noise.noise3( (float)x * 0.25f, (float)y * 0.25f, (float)z * 0.25f ); } } } D3D11_SUBRESOURCE_DATA data; data.pSysMem = fData; data.SysMemPitch = sizeof( float ) * DIM; data.SysMemSlicePitch = sizeof( float ) * DIM * DIM; Texture3dConfigDX11 config; config.SetFormat( DXGI_FORMAT_R32_FLOAT ); config.SetBindFlags( D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS ); config.SetWidth( DIM ); config.SetHeight( DIM ); config.SetDepth( DIM ); m_VolumeTexture = RendererDX11::Get()->CreateTexture3D( &config, &data ); delete [] fData; // Generate the volume geometry to display what is in the volume texture. m_pGeometry = VolumeGeometryPtr( new DrawIndexedExecutorDX11<VolumeTextureVertexDX11::Vertex>() ); m_pGeometry->SetPrimitiveType( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); m_pGeometry->SetLayoutElements( VolumeTextureVertexDX11::GetElementCount(), VolumeTextureVertexDX11::Elements ); VolumeTextureVertexDX11::Vertex v; // [-X,+Y,-Z] Offset 0 v.position = Vector3f( -1.0f, 1.0f, -1.0f ); v.texcoords = Vector3f( 0.0f, 0.0f, 0.0f ); m_pGeometry->AddVertex( v ); // [+X,+Y,-Z] Offset 1 v.position = Vector3f( 1.0f, 1.0f, -1.0f ); v.texcoords = Vector3f( 1.0f, 0.0f, 0.0f ); m_pGeometry->AddVertex( v ); // [+X,-Y,-Z] Offset 2 v.position = Vector3f( 1.0f, -1.0f, -1.0f ); v.texcoords = Vector3f( 1.0f, 1.0f, 0.0f ); m_pGeometry->AddVertex( v ); // [-X,-Y,-Z] Offset 3 v.position = Vector3f( -1.0f, -1.0f, -1.0f ); v.texcoords = Vector3f( 0.0f, 1.0f, 0.0f ); m_pGeometry->AddVertex( v ); // [-X,+Y,-Z] Offset 4 v.position = Vector3f( -1.0f, 1.0f, 1.0f ); v.texcoords = Vector3f( 0.0f, 0.0f, 1.0f ); m_pGeometry->AddVertex( v ); // [+X,+Y,-Z] Offset 5 v.position = Vector3f( 1.0f, 1.0f, 1.0f ); v.texcoords = Vector3f( 1.0f, 0.0f, 1.0f ); m_pGeometry->AddVertex( v ); // [+X,-Y,-Z] Offset 6 v.position = Vector3f( 1.0f, -1.0f, 1.0f ); v.texcoords = Vector3f( 1.0f, 1.0f, 1.0f ); m_pGeometry->AddVertex( v ); // [-X,-Y,-Z] Offset 7 v.position = Vector3f( -1.0f, -1.0f, 1.0f ); v.texcoords = Vector3f( 0.0f, 1.0f, 1.0f ); m_pGeometry->AddVertex( v ); // -Z Face m_pGeometry->AddIndices( 0, 1, 2 ); m_pGeometry->AddIndices( 0, 2, 3 ); // +Z Face m_pGeometry->AddIndices( 5, 4, 7 ); m_pGeometry->AddIndices( 5, 7, 6 ); // -X Face m_pGeometry->AddIndices( 4, 0, 3 ); m_pGeometry->AddIndices( 4, 3, 7 ); // +X Face m_pGeometry->AddIndices( 1, 5, 6 ); m_pGeometry->AddIndices( 1, 6, 2 ); // -Y Face m_pGeometry->AddIndices( 3, 2, 6 ); m_pGeometry->AddIndices( 3, 6, 7 ); // +Y Face m_pGeometry->AddIndices( 5, 1, 0 ); m_pGeometry->AddIndices( 5, 0, 4 ); GetBody()->Visual.SetGeometry( m_pGeometry ); GetBody()->Visual.SetMaterial( MaterialGeneratorDX11::GenerateVolumeGeometryMaterial( *RendererDX11::Get() ) ); GetBody()->Parameters.SetShaderResourceParameter( L"VolumeTexture", m_VolumeTexture ); Matrix4f ObjectToTextureSpaceMatrix = Matrix4f::TranslationMatrix( 1.0f, -1.0f, 1.0f ) * Matrix4f::ScaleMatrixXYZ( 0.5f, -0.5f, 0.5f ); TextureSpaceCameraPositionWriter* pCameraTSPositionWriter = new TextureSpaceCameraPositionWriter(); pCameraTSPositionWriter->SetObjectToTextureSpaceXform( ObjectToTextureSpaceMatrix ); GetBody()->Parameters.AddRenderParameter( pCameraTSPositionWriter ); TextureSpaceLightPositionWriter* pLightTSPositionWriter = new TextureSpaceLightPositionWriter(); pLightTSPositionWriter->SetObjectToTextureSpaceXform( ObjectToTextureSpaceMatrix ); GetBody()->Parameters.AddRenderParameter( pLightTSPositionWriter ); }
// Thoughout the function we delete all in-world coordinates by 200. // This is to make a cube in the real world be equal to a pixel from the map image. void APDemo::Tick( float DeltaTime ) { Super::Tick( DeltaTime ); UWorld* World = GetWorld(); APlayerCameraManager* PlayerCameraManager = World->GetFirstPlayerController()->PlayerCameraManager; FVector cam_position = PlayerCameraManager->GetCameraLocation(); if (br != 0){ //go through brick_to... and remove the marked ones from bricks for (unsigned int i = 0; i < br; ++i){ ABrick* Brick = bricks[bricks_to_be_removed[i]]; bricks.erase(bricks_to_be_removed[i]); Brick->Destroy(); bricks_to_be_removed[i] = ""; } br = 0; } //now go through bricks and mark the new bricks to be removed next frame for (auto it = bricks.begin(); it != bricks.end(); ++it){ FVector brick_loc = it->second->GetActorLocation(); float distance = ( (brick_loc - cam_position).Size() )/200; if (distance >= despawn_dist){ bricks_to_be_removed[br] = it->first; ++br; } } //int spawn_height_sector = (int)floor(cam_position.Z / 200) / 80; //spawn_height = 160 * spawn_height_sector; //this magic tho int spawn_height_sector = (int)floor(cam_position.Z / 200); int sector_offset = spawn_height_sector == 0 ? 0 : (spawn_height_sector / abs(spawn_height_sector)) * 80; spawn_height_sector += sector_offset; spawn_height_sector = spawn_height_sector / 160; spawn_height = 160 * spawn_height_sector; int distance_fwd = 60; int distance_left = 60; int start_i = (int)floor(cam_position.X / 200); int start_j = (int)floor(cam_position.Y / 200); for (int i = start_i - distance_fwd; i < start_i + distance_fwd; ++i) { // y for (int j = start_j - distance_left; j < start_j + distance_left; ++j) { // x double x = (double)(abs(j) % width) / ((double)width);// we use % to make sure we never go out of the defined map double y = (double)(abs(i) % height) / ((double)height); double n = pn.noise(10 * x, 10 * y, 0.8); n = n < noise_threshold ? 0 : n;//used to create a clear distinction between space and land FVector brick_position = FVector(i * 200, j * 200, spawn_height * 200); float distance = ((brick_position - cam_position).Size()) / 200; if (distance < despawn_dist){ string key = to_string(i) + to_string(j); if (n > 0 && !bricks[key]){ float brick_height = n; ABrick* Brick = World->SpawnActor<ABrick>(ABrick::StaticClass()); Brick->SetPositionAndHeight(brick_position, brick_height, noise_threshold); bricks[key] = Brick; } } } } }
/* Computes acceleration to every control point of the chain, which is in state given by 'chain'. Returns result in array 'a'. */ void computeAcceleration(struct chain * chain, struct point a[]) { for(int i=1; i<=chain->number; i++) { chain->f[i].x = 0; chain->f[i].y = 0; } if(isRandomforce) for(int i=1; i<=chain->number; i++) { chain->f[i].x = PN.PerlinNoise1D(tempCount++, 1000, 0.7) * 500; chain->f[i].y = PN.PerlinNoise1D(tempCount, 1000, 0.7) * 500; } //Gravity Force if(isGravity) for(int i=1; i<=chain->number; i++) chain->f[i].y = -GRAVITY; //Damping Force if(isDamping) for(int i=1; i<=chain->number; i++) { chain->f[i].x += - (chain->v[i].x * DAMPINGCOEF); chain->f[i].y += - (chain->v[i].y * DAMPINGCOEF); } //User Force for(int i=1; i<=chain->number; i++) chain->f[i].x += g_vDiffPos[0] * 0.5; for(int i=1; i<=chain->number; i++) chain->f[i].y += g_vDiffPos[1] * 0.5; if(pushUp) for(int i=1; i<=chain->number; i++) chain->f[i].y += USERFORCE; if(pushDown) for(int i=1; i<=chain->number; i++) chain->f[i].y -= USERFORCE; if(pushLeft) for(int i=1; i<=chain->number; i++) chain->f[i].x -= USERFORCE; if(pushRight) for(int i=1; i<=chain->number; i++) chain->f[i].x += USERFORCE; //Plane Collision if(isPlane) for(int i=1; i<=chain->number; i++) if(chain->p[i].y > 0) { chain->f[i].y += -1.0 * chain->p[i].y * KCOLLISION; } computePhysics(chain, a); }
//....................................................................................... unsigned char *TextureGenerator::GenPerlinNoise(GLenum *_type, int *_w, int *_h, int *_d) { (*_w) = m_x; (*_h) = m_y; (*_d) = m_z; Logw("TextureGenerator::GenPerlinNoise(): Generating noise (%dx%dx%d px)\n", (*_w), (*_h), (*_d)); int offset = 0; __int64 t0 = StartCounter(); PerlinNoise *pn = NULL; // seed engine for new permutation? if (m_iPerlinSeed) pn = new PerlinNoise(m_iPerlinSeed); // use standard permutation vector G else pn = new PerlinNoise(); unsigned char *textureData = NULL; double *noiseData = NULL; double dmin = 0.0, dmax = 0.0; // GL_TEXTURE_1D|2D|3D ? switch (*_type) { case GL_TEXTURE_1D: textureData = new unsigned char[m_x * m_iBPP]; #pragma omp parallel for for (int x = 0; x < m_x; x++) { int offset = m_x * m_iBPP; double xp = (double)x / (double)m_x; double noise = pn->Noise(m_iPerlinAmp * xp, 0, 0); int c = floor(xp * 256); textureData[offset + 0] = c; textureData[offset + 1] = c; textureData[offset + 2] = c; } break; case GL_TEXTURE_2D: textureData = new unsigned char[m_x * m_y * m_iBPP]; noiseData = new double[m_x * m_y]; switch (m_ePerlinType) { case PerlinNoiseType::Simple: #pragma omp parallel for for (int y = 0; y < m_y; y++) { for (int x = 0; x < m_x; x++) { double xp = (double)x / (double)m_x; double yp = (double)y / (double)m_y; double noise = pn->Noise(m_iPerlinAmp * xp, m_iPerlinAmp * yp, 0.0); dmin = MIN(dmin, noise); dmax = MAX(dmax, noise); int offset = (y * m_x + x); noiseData[offset] = noise; } } break; case PerlinNoiseType::FractalSum: #pragma omp parallel for for (int y = 0; y < m_y; y++) { for (int x = 0; x < m_x; x++) { double xp = (double)x / (double)m_x; double yp = (double)y / (double)m_y; double noise = 0.0; for (int n = 1; n < (1 << m_nPerlinOctaves); n *= 2) noise += (1.0 / (double)n) * pn->Noise(m_iPerlinAmp * n * xp, m_iPerlinAmp * n * yp, 0.0); dmin = MIN(dmin, noise); dmax = MAX(dmax, noise); int offset = (y * m_x + x); noiseData[offset] = noise; } } break; case PerlinNoiseType::Wood: #pragma omp parallel for for (int y = 0; y < m_y; y++) { for (int x = 0; x < m_x; x++) { double xp = (double)x / (double)m_x; double yp = (double)y / (double)m_y; double noise = m_iPerlinThickness * pn->Noise(m_iPerlinAmp * xp, m_iPerlinAmp * yp, 0.0); noise -= floor(noise); dmin = MIN(dmin, noise); dmax = MAX(dmax, noise); int offset = (y * m_x + x); noiseData[offset] = noise; } } break; } // end switch PerlinNoiseType #pragma omp parallel for for (int y = 0; y < m_y; y++) { for (int x = 0; x < m_x; x++) { int offset = y * m_x + x; int offset_bpp = offset * m_iBPP; int color = (int)(((noiseData[offset] - dmin) / (dmax - dmin)) * 255.0); textureData[offset_bpp + 0] = color; textureData[offset_bpp + 1] = color; textureData[offset_bpp + 2] = color; } } break; // end GL_TEXTURE_2D case GL_TEXTURE_3D: break; } // release temp noise data if (noiseData) delete noiseData; // release pn class if (pn) delete pn; // done return (textureData); }
// Generate randomized noise and upload it to the 3D texture using staging void updateNoiseTexture() { const uint32_t texMemSize = texture.width * texture.height * texture.depth; uint8_t *data = new uint8_t[texMemSize]; memset(data, 0, texMemSize); // Generate perlin based noise std::cout << "Generating " << texture.width << " x " << texture.height << " x " << texture.depth << " noise texture..." << std::endl; auto tStart = std::chrono::high_resolution_clock::now(); PerlinNoise<float> perlinNoise; FractalNoise<float> fractalNoise(perlinNoise); std::default_random_engine rndEngine(std::random_device{}()); const int32_t noiseType = rand() % 2; const float noiseScale = static_cast<float>(rand() % 10) + 4.0f; #pragma omp parallel for for (int32_t z = 0; z < (int32_t)texture.depth; z++) { for (int32_t y = 0; y < (int32_t)texture.height; y++) { for (int32_t x = 0; x < (int32_t)texture.width; x++) { float nx = (float)x / (float)texture.width; float ny = (float)y / (float)texture.height; float nz = (float)z / (float)texture.depth; #define FRACTAL #ifdef FRACTAL float n = fractalNoise.noise(nx * noiseScale, ny * noiseScale, nz * noiseScale); #else float n = 20.0 * perlinNoise.noise(nx, ny, nz); #endif n = n - floor(n); data[x + y * texture.width + z * texture.width * texture.height] = static_cast<uint8_t>(floor(n * 255)); } } } auto tEnd = std::chrono::high_resolution_clock::now(); auto tDiff = std::chrono::duration<double, std::milli>(tEnd - tStart).count(); std::cout << "Done in " << tDiff << "ms" << std::endl; // Create a host-visible staging buffer that contains the raw image data VkBuffer stagingBuffer; VkDeviceMemory stagingMemory; // Buffer object VkBufferCreateInfo bufferCreateInfo = vkTools::initializers::bufferCreateInfo(); bufferCreateInfo.size = texMemSize; bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; bufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; VK_CHECK_RESULT(vkCreateBuffer(device, &bufferCreateInfo, nullptr, &stagingBuffer)); // Allocate host visible memory for data upload VkMemoryAllocateInfo memAllocInfo = vkTools::initializers::memoryAllocateInfo(); VkMemoryRequirements memReqs = {}; vkGetBufferMemoryRequirements(device, stagingBuffer, &memReqs); memAllocInfo.allocationSize = memReqs.size; memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &stagingMemory)); VK_CHECK_RESULT(vkBindBufferMemory(device, stagingBuffer, stagingMemory, 0)); // Copy texture data into staging buffer uint8_t *mapped; VK_CHECK_RESULT(vkMapMemory(device, stagingMemory, 0, memReqs.size, 0, (void **)&mapped)); memcpy(mapped, data, texMemSize); vkUnmapMemory(device, stagingMemory); VkCommandBuffer copyCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); // Image barrier for optimal image // The sub resource range describes the regions of the image we will be transition VkImageSubresourceRange subresourceRange = {}; subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; subresourceRange.baseMipLevel = 0; subresourceRange.levelCount = 1; subresourceRange.layerCount = 1; // Optimal image will be used as destination for the copy, so we must transfer from our // initial undefined image layout to the transfer destination layout vkTools::setImageLayout( copyCmd, texture.image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresourceRange); // Copy 3D noise data to texture // Setup buffer copy regions VkBufferImageCopy bufferCopyRegion{}; bufferCopyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; bufferCopyRegion.imageSubresource.mipLevel = 0; bufferCopyRegion.imageSubresource.baseArrayLayer = 0; bufferCopyRegion.imageSubresource.layerCount = 1; bufferCopyRegion.imageExtent.width = texture.width; bufferCopyRegion.imageExtent.height = texture.height; bufferCopyRegion.imageExtent.depth = texture.depth; vkCmdCopyBufferToImage( copyCmd, stagingBuffer, texture.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferCopyRegion); // Change texture image layout to shader read after all mip levels have been copied texture.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; vkTools::setImageLayout( copyCmd, texture.image, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, texture.imageLayout, subresourceRange); VulkanExampleBase::flushCommandBuffer(copyCmd, queue, true); // Clean up staging resources delete[] data; vkFreeMemory(device, stagingMemory, nullptr); vkDestroyBuffer(device, stagingBuffer, nullptr); regenerateNoise = false; }
/* Procedural texture function */ int ptex_fun(float u, float v, GzColor color) { static PerlinNoise newnoise; static bool initialized = false; if( !initialized ) { newnoise.setParams(4, 4, 1, 94); initialized = true; } // note: in order to make the texture continuous, we need the edges of the texture to all be the same color float U_modified, V_modified; if( SYMMETRICAL_STONE ) { U_modified = ( u < 0.5 ) ? u : 1 - u; V_modified = ( v < 0.5 ) ? v : 1 - v; } else { if( u < .005 || u > .995 || v < .005 || v > .995 ) { color[RED] = color[BLUE] = color[GREEN] = 0; return GZ_SUCCESS; } U_modified = u; V_modified = v; } float * F = new float[2]; float (*delta)[3] = new float[2][3]; unsigned long * ID = new unsigned long[2]; float * at = new float[3]; // just use texture coordinates for the "at" point at[0] = U_modified * 3; at[1] = V_modified * 3; at[2] = U_modified * V_modified; // use Worley noise function to create our texture WorleyNoise::noise3D( at, 2, F, delta, ID ); float distance = F[1] - F[0]; float colorID = ID[0]; // clean up allocated memory delete [] F; F = NULL; delete [] delta; delta = NULL; delete [] ID; ID = NULL; delete [] at; at = NULL; // use diffuse lighting (if distance <= threshold, leave it black) if( distance > STONE_THRESHOLD ) { switch( stoneType ) { case COLORFUL: color[RED] = max( 0.0f, (1 + sin(colorID))/2 ); color[BLUE] = max( 0.0f, (1 + cos(colorID))/2 ); color[GREEN] = max( 0.0f, ( color[RED] + color[BLUE] ) / 2 ); break; case REALISTIC: float perlinNoise; perlinNoise = (1 + newnoise.Get( U_modified * 3, V_modified * 3 )) / 2; // make each stone the same color with some grainy noise variation color[RED] = color[BLUE] = color[GREEN] = perlinNoise * 0.5f; break; } } else { // leave color black; this is a dividing line between stones color[RED] = color[GREEN] = color[BLUE] = 0; } return GZ_SUCCESS; }