c# - artefacts during heightmap generation using plasma style fractal -
i've spent few hours today researching how random terrain generation tends done , after reading plasma fractal (midpoint displacement , diamond square algo's) decided seek , have go @ implementing one. result not terriable, have these horrible square/line/grid type artefacts can not seem rid of!
when rendered grayness scale image height map looks like:
obviously there fair amount of code involved in seek post relevant. i've not not posted code turns texture example, not worry have tried filling height array smooth gradient , texture comes out fine :)
i begin setting 4 corners of map random values between 0 , 1 , start recursive displacement algo:
public void generateterrainlayer() { //set 4 corners of map have random values terraindata[0, 0] = (float)randomgenerator.nextdouble(); terraindata[gensize, 0] = (float)randomgenerator.nextdouble(); terraindata[0, gensize] = (float)randomgenerator.nextdouble(); terraindata[gensize, gensize] = (float)randomgenerator.nextdouble(); //begin midpoint displacement algorithm... midpointdisplace(new vector2_i(0, 0), new vector2_i(gensize, 0), new vector2_i(0, gensize), new vector2_i(gensize, gensize)); }
terraindata 2d array of floats*. vector2_i own integer vector class. lastly 4 functions midpointdisplace recursive function, calculateterrainpointdata averages 2 info values , adds noise, calculateterrainpointdata2 averages 4 info values , adds noise , has higher scale value (its used center points) , noise function atm random noise , not real noise perlin etc. this:
private void midpointdisplace(vector2_i topleft, vector2_i topright, vector2_i bottomleft, vector2_i bottomright) { //check size of square working on.. if shorter amount stop algo, we've done plenty if (topright.x - topleft.x < displacementmaxlod) { return; } //calculate positions of middle points square has been passed function vector2_i midleft, midright, midtop, midbottom, center; midleft.x = topleft.x; midleft.y = topleft.y + ((bottomleft.y - topleft.y) / 2); midright.x = topright.x; midright.y = topright.y + ((bottomright.y - topright.y) / 2); midtop.x = topleft.x + ((topright.x - topleft.x) / 2); midtop.y = topleft.y; midbottom.x = bottomleft.x + ((bottomright.x - bottomleft.x) / 2); midbottom.y = bottomleft.y; center.x = midtop.x; center.y = midleft.y; //collect existing info corners of area passed algo float topleftdat, toprightdat, bottomleftdat, bottomrightdat; topleftdat = getterraindata(topleft.x, topleft.y); toprightdat = getterraindata(topright.x, topright.y); bottomleftdat = getterraindata(bottomleft.x, bottomleft.y); bottomrightdat = getterraindata(bottomright.x, bottomright.y); //and center //adverage info , insert midpoints.. setterraindata(midleft.x, midleft.y, calculateterrainpointdata(topleftdat, bottomleftdat, midleft.x, midleft.y)); setterraindata(midright.x, midright.y, calculateterrainpointdata(toprightdat, bottomrightdat, midright.x, midright.y)); setterraindata(midtop.x, midtop.y, calculateterrainpointdata(topleftdat, toprightdat, midtop.x, midtop.y)); setterraindata(midbottom.x, midbottom.y, calculateterrainpointdata(bottomleftdat, bottomrightdat, midbottom.x, midbottom.y)); setterraindata(center.x, center.y, calculateterrainpointdata2(topleftdat, toprightdat, bottomleftdat, bottomrightdat, center.x, center.y)); debug_displacement_iterations++; //and recursively fire off new calls function smaller squares rectangle newtopleft = new rectangle(topleft.x, topleft.y, center.x - topleft.x, center.y - topleft.y); rectangle newtopright = new rectangle(center.x, topright.y, topright.x - center.x, center.y - topright.y); rectangle newbottomleft = new rectangle(bottomleft.x, center.y, center.x - bottomleft.x, bottomleft.y - center.y); rectangle newbottomright = new rectangle(center.x , center.y, bottomright.x - center.x, bottomright.y - center.y); midpointdisplace(new vector2_i(newtopleft.left, newtopleft.top), new vector2_i(newtopleft.right, newtopleft.top), new vector2_i(newtopleft.left, newtopleft.bottom), new vector2_i(newtopleft.right, newtopleft.bottom)); midpointdisplace(new vector2_i(newtopright.left, newtopright.top), new vector2_i(newtopright.right, newtopright.top), new vector2_i(newtopright.left, newtopright.bottom), new vector2_i(newtopright.right, newtopright.bottom)); midpointdisplace(new vector2_i(newbottomleft.left, newbottomleft.top), new vector2_i(newbottomleft.right, newbottomleft.top), new vector2_i(newbottomleft.left, newbottomleft.bottom), new vector2_i(newbottomleft.right, newbottomleft.bottom)); midpointdisplace(new vector2_i(newbottomright.left, newbottomright.top), new vector2_i(newbottomright.right, newbottomright.top), new vector2_i(newbottomright.left, newbottomright.bottom), new vector2_i(newbottomright.right, newbottomright.bottom)); } //helper function homecoming info value adveraged 2 inputs, noise value added randomness , result clamped ensure value private float calculateterrainpointdata(float dataa, float datab, int noisex, int noisey) { homecoming mathhelper.clamp(((dataa + datab) / 2.0f) + noisefunction(noisex, noisey), 0.0f, 1.0f) * 1.0f; } //helper function homecoming info value adveraged 4 inputs, noise value added randomness , result clamped ensure value private float calculateterrainpointdata2(float dataa, float datab, float datac, float datad, int noisex, int noisey) { homecoming mathhelper.clamp(((dataa + datab + datac + datad) / 4.0f) + noisefunction(noisex, noisey), 0.0f, 1.0f) * 1.5f; } private float noisefunction(int x, int y) { homecoming (float)(randomgenerator.nextdouble() - 0.5) * 0.5f; }
ok taking time - knows grid-like pattern appearing :)
*edit - accidently wrote ints, corrected floats
i see problem in calculateterrainpointdata
implementation: you're not scaling downwards result of noisefunction
each iteration.
see this description of midpoint displacement algorithm:
start single horizontal line segment. repeat sufficiently big number of times: repeat on each line segment in scene: find midpoint of line segment. displace midpoint in y random amount. reduce range random numbers.a fast way in code without changing much adding scale
parameter midpointdisplace
(with default set 1.0f) , calculateterrainpointdata
; utilize in calculateterrainpointdata
multiply result of noisefunction
; , cut down each recursive phone call midpointdisplace(..., 0.5f * scale)
.
not sure though if cause image looking wrong or there other problems.
c# terrain fractals procedural-generation heightmap
No comments:
Post a Comment