Last active
February 13, 2017 16:28
-
-
Save 9prady9/0a3167f5c57ea3ad83e6cad00d4a7bde to your computer and use it in GitHub Desktop.
C++ Program using ArrayFire that show cases Perlin Noise Generation using GPU.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/******************************************************* | |
* Copyright (c) 2017, ArrayFire | |
* All rights reserved. | |
* | |
* This file is distributed under 3-clause BSD license. | |
* The complete license agreement can be obtained at: | |
* http://arrayfire.com/licenses/BSD-3-Clause | |
********************************************************/ | |
#include <arrayfire.h> | |
#include <cstdio> | |
#include <cstdlib> | |
using namespace af; | |
array perlin(int w, int h) | |
{ | |
const float PERSISTENCE = 0.5f; | |
array base = randu(w, h); | |
array perlin = constant(0.0f, w, h); | |
float amp = 1.0f; | |
float samp = 0.0f; | |
for (int octave=6; octave>=0; --octave) { | |
float period = float(1 << octave); | |
float freq = 1.0f/period; | |
array x = iota(dim4(w, 1)); // Coloumn Vector | |
array y = iota(dim4(1, h)); // Row Vector | |
// Generate horizontal indices to sample data | |
// for interpolation w.r.t current period | |
array si0 = (x / period).as(s32) * period; | |
array si1 = (si0 + period).as(s32) % w; | |
array hblend = (x - si0) * freq; | |
hblend = tile(hblend, dim4(1, h)); // tile data along second dimension to enable use in equations that expect matrices | |
// Generate horizontal indices to sample data | |
// for interpolation w.r.t current period | |
array sj0 = (y / period).as(s32) * period; | |
array sj1 = (sj0 + period).as(s32) % h; | |
array vblend = (y - sj0) * freq; | |
vblend = tile(vblend, dim4(w, 1)); // tile data along first dimension to enable use in equations that expect matrices | |
array top = base(si0, sj0)*(1.0f-hblend) + hblend*base(si1, sj0); // base(array, array) | |
array bot = base(si0, sj1)*(1.0f-hblend) + hblend*base(si1, sj1); // use indices generated to sample base noise | |
array blend = top*(1.0f-vblend) + vblend*bot; //interpolate all values | |
perlin += (amp*blend); //scale by amplitude and add to perlin noise accumulator | |
samp += amp; | |
amp *= PERSISTENCE; | |
} | |
return perlin/samp; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
try { | |
int device = argc > 1 ? atoi(argv[1]) : 0; | |
af::setDevice(device); | |
af::info(); | |
af::Window w(640, 640); | |
while(!w.close()) | |
w.image(perlin(256, 256)); | |
} catch (af::exception& e) { | |
fprintf(stderr, "%s\n", e.what()); | |
throw; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@9prady9
.as(s32)
forsi0
,si1
,sj0
,sj1