So, over the past several days, I've been working on an HTML page that uses Javascript to procedurally generate perlin noise, and draw it in a canvas element. With help from chatGPT, I was able to figure out how to write and implement the perlin noise function, how to seed the function by using a seedable PRNG, how to draw stuff on the canvas isometrically, and also how to handle UI things like dragging the terrain around with the cursor.

Try the generator out here!
https://michael2-3b.github.io/Procedural-Perlin-Terrain/


And star the repository:
https://github.com/Michael2-3B/Procedural-Perlin-Terrain





I initially started this project by programming a rather simplistic interdependent terrain generation system (which is what my Isometric Minecraft program for the CE currently uses), where cell heights are generated based on their neighbors; no two neighbors can have a height difference greater than 1. Obviously, this is not a very good system to use, as it generates a lot of bias, and does not allow for procedural generation. I then looked into other algorithms like diamond-square, but ultimately decided I need to learn how to do perlin noise.

With some guidance from the chatGPT bot by openAI, I was able to create a custom perlin noise function, with dot products, linear interpolation, etc. and it uses variables like persistence, wavelength, octaves (the amount of detail), and more. It also uses offset variables for what portion of the noise map it should generate, and because it's procedural, the world size is virtually infinite. From there, all I had to do was interpret the noise values as values between 0 and 255 (because this works great for color values), add a world light value, draw the points on the canvas, and also add input elements to the html page for controlling the different variables.

One thing to note is that as of right now, I'm only representing the terrain based on elevation. In the near future I'm hoping/planning to implement more noise maps that control things like biomes, moisture, tree placements and more.

Overall I've learned a good bit already in the past few days, and I'm excited to continue working on this! Let me know what you all think!
I think there will be some days when I spend nearly an hour messing around with the settings of this terrain generator. Nice job Smile

Gossamer ASM-code-injected version for monochrome calcs when?
Thanks DJ! I am working on it a lot right now, so it can only get even more fun from here!

I've made a few significant changes in the past couple hours, these being:
-Added zoom in/out capability to the isometric renderer
-Added customizable world light variable, from pitch black to normal daylight
-Fixed the isometric drawing code so it draws proper tiles
-Added a customizable isoHeight variable which stretches the isometric map render vertically
-Added a colorLookup function and tweaked some of the color values
-Organized and improved the look of the UI, including stylistic changes to the sliders, a faint grey background to the inputs div, and reset buttons for the variables.



Again, the terrain colors are simply based on elevation alone, but I'll be changing that soon hopefully Smile

If anyone creates a really unique generation you'd like to share, feel free to do so! There's lots of different variables to change, so there are lots of different ways the world can look.

EDIT:
Just added an input randomization button for the terrain generation variables.
Also tweaked some terrain colors and input variable ranges.
So today I've added two significant features:

- The terrain can now be rendered as cubes!
- I added a draggable light position variable, which simulates a light source that changes the shade of the cubes side faces depending on where the light position is from left to right.

Check it out:



Something that I need to figure out now is how to program the occlusion culling, so that it renders faster. I also am thinking about how to apply the light position feature to the polygon rendering code, instead of just the cubes. I think I could do it based on the polygon slope directions...

Anyway, hope you all like it!
Michael2_3B wrote:
- The terrain can now be rendered as cubes!


So are you recreating Minecraft now I guess?

yaya minecraft yayayy
I downloaded it to "my" device (since github.io is blocked on our school's network) and ran it. I got some nice, pretty terrain that I like, but it is blurry and pretty low-resolution. Can you make a resolution slider?
clevor wrote:
but it is blurry and pretty low-resolution

Yeah, so the reason it was blurry is because I had a 100x100 canvas, that I was scaling up, instead of creating a bigger canvas and scaling the drawing itself. I've now updated the code to take care of this, and made a few other great changes.

List of Changes:
- Terrain is no longer blurry; removed canvas scaling, and instead am scaling the drawing
- Zooming now works in both top-down view and isometric view
- Zooming input is now a vertical slider next to the canvas
- World Coordinates are displayed for the point your mouse is hovering over, but only in top-down view

Stylistic changes:
- Added favicon
- Added a drop shadow to the canvas when you are in top-down viewing mode
- Added a light grey page background so the terrain is easier to see, and separated from the background. This is especially helpful when it comes to seeing the snow capped mountains in isometric mode.

Enjoy!





Itís worth noting that Iím using Firefox on Mac, and for me it runs significantly faster on Firefox than both chrome and safari. Nonetheless there are some big optimizations I still need to make, the main one being to add occlusion culling so the isometric rendering is faster. The cube drawing mode is especially slow.
Wow ok so it's been a little while since I last updated this! (2.5 weeks to be exact)

I've just pushed a major update to the GitHub, in which I've made several changes, which include the following:

- Added terrain and water borders on the sides of the isometric drawing, so it looks like its filled in
- Fixed the terrain customization functionality so that it actually changes the shape of the terrain, instead of just the colors
- Removed the block rendering option, as it is slow and not my main focus for the project right now.
- Added dynamic shading, so tiles get a certain amount of light subtracted from their color based on their slope / slope direction and based on the lightPosition and lightHeight variables. lightPosition is a value from 0-360 and lightHeight is a value between -90 and 90.
- Added ability to draw/outline where the coastline is

And of course, some changes to the site itself:

- Added stepper buttons for range inputs
- Added dark mode, which changes the sites background color to a shade of black
- Added dynamic mode, which changes the sites background color based on the current value of lightHeight.

Overall this update makes the site much prettier to look at, and should keep you folks entertained for a good while!

Be sure to try it out here.

Looks great, congrats!
This looks awesome! Smile
A bit of a smaller update this time:

- I've now introduced ridged noise, so the terrain should look a little more natural than before. I will probably make some tweaks though
- Checkboxes now save their state in localStorage, so whenever you revisit the site, the page settings (such as dark mode) will be restored to what you've previously set.
- Adriweb made a small but great suggestion/commit, which is that you can now click anywhere on a checkboxes associated text to toggle it.

Here's some ridged noise:

Great work on this! I messed around with it for quite a while when you released one of the first previews for it, and it's looking even more impressive now. I especially like being able to click and drag to pan around and the new slider to adjust the zoom, which both make the demo a lot more enjoyable to work with.

A few suggestions:
- The "Randomize" button for the terrain customization is pretty neat, so I'd like to see the same for the noise map and lighting values as well.
- To add to Adriweb's suggestion, you should add the no-select or whatever it's called property to the checkboxes' associated text, as that improves usability somewhat.
- I'd like to be able to zoom out a bit further--is this is a technical limitation?
- When you're zoomed in very far, a small mini-map in the top left corner showing what area of the map is currently shown could be useful.
- Zooming in/out on the page should zoom in/out the map rather than the page (maybe only when it's hovered over).

Looking forward to some more updates!
Nice. It looks weird when water has a slope though Smile
epsilon5 wrote:
The "Randomize" button for the terrain customization is pretty neat, so I'd like to see the same for the noise map and lighting values as well.

To me, the randomize button seems like it's best suited only for the terrain customization values. I could add a randomize button for both the noise map and lighting values, but I feel like those are better off being manually adjusted...

epsilon5 wrote:
To add to Adriweb's suggestion, you should add the no-select or whatever it's called property to the checkboxes' associated text, as that improves usability somewhat.

Added.

epsilon5 wrote:
I'd like to be able to zoom out a bit further--is this is a technical limitation?

Not a technical limitation. Chunk size is currently 100 by 100. It'll just inevitably make the program slower the larger I make it; so I think 100 is a good number for now. It's also important to note that if you decrease the wavelength, you will see more, although this is not the same as zooming out.

epsilon5 wrote:
When you're zoomed in very far, a small mini-map in the top left corner showing what area of the map is currently shown could be useful.

Perhaps, I will think about it

epsilon5 wrote:
Zooming in/out on the page should zoom in/out the map rather than the page (maybe only when it's hovered over).

I may or may not attempt to do something like that... we will see.


MateoConLechuga wrote:
Nice. It looks weird when water has a slope though Smile

I assume you are talking about the front corner of the terrain in the last screenshot. Water is not sloped- I leveled out the surface, and the sides of the terrain/water are filled in when it's at the border. It probably looks sloped in the screenshot only because the water depth is fairly small and the side color of the water is not much different than the top.


In other news, I've tweaked the noise generator slightly so ridged noise is less pronounced / looks a little more natural. Eventually I'm planning to get it to only apply to the higher mountain peaks. I'm also going to look into tree placement soon, and eventually I also want to add spline points and some other noise maps to hopefully vary the types of terrain you see.

I've also corrected how the program uses the persistence value, and I've added an amplitude slider. My latest commit is published, so be sure to try it out.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement