Generator to generate mountain views. Edit some settings click  "Generate" and generate away! Depending on the strength of your machine, you might not see anything happening for a bit, just let it crunch and something should come out.

This was an attempt of mine to see if I could procedurally generate some waterpaint kinda look. Also an experiment for me into p5js and vector fields. If there is some interest I might add  a feature for automatically generating colors.

Submission for Procjam 2020. 

Github: https://github.com/Deep-Fold/Starscapes

StatusReleased
CategoryTool
PlatformsHTML5
Rating
Rated 4.9 out of 5 stars
(32 total ratings)
AuthorDeep-Fold
Tags2D, Generator, landscape, Painting, Procedural Generation, PROCJAM, watercolor

Comments

Log in with itch.io to leave a comment.

(+1)

wow! you should make a downloadable version

Ah, this is just html and javascript, so not much point to a downloadable version. I think you can just ctrl + s the page.

(+1)

aah, that makes sense

(3 edits) (+1)

Hey! Nice tool! I used images made using this in a jam game (free) hope that's alright! (there is credit given) :

Here's the link if you wanted to see it (it's fine if you don't) https://complexdragon.itch.io/poisonkid

(+1)

Thanks for the credits, glad it was useful to you!

Just played your game, really funny, nice job!

(+1)

No problem!  :)   And thanks! 

(+2)

could you add a button that randomizes the colors?

(+1)

That would be cool. I'm not really working on this project right now, but I could maybe add that at some point. Thanks for the suggestion!

(+1)

This is so pretty! Can I use what I create with this as a background in a game I'm making(with a mention + link to here in the credits)?

Yes, go ahead! Interested in seeing what you can make with it!

(+1)

Thanks, here's a lil preview with the beautiful background. It's my first game btw & still workin on it. It'll be a multiplayer drawing/dating profile creation game :) Anyways thanks again, I'll update here when it's up! Might be a while lol

Oh that sounds interesting! Good luck with your game.

An artist may call it abstract, but a developer will call it procedural generation. This tool creates some of the most fascinating watercolor art

Yes I tried quite hard on this one to get a watercolor effect, pretty happy with it. Glad you like em!

Just commented on your other generation tool, but I used this tool as well. Such a time saver and it looks fantastic. Thanks a lot! And here is the link:


https://barelyevengames.itch.io/demon-dance

I love this so much, I just wish there was an option to remove the mountains

(+1)

Glad you like it, Not sure how comfortable you are with some code, but if you download the source from github, you could edit "sketch.js" and remove line 7 to 11 ( all the ones with  "drawMountain" in them). Then when you open index.html in your browser it wont draw any mountains.
Let me know if that works for you. Sorry for a bit late reply btw.

Thanks, I probably won't mess with the code but I'll let you know if I do.

(+1)

Hello forthebundle,

I messed with the code and it works the way DF said!

Thanks DF for your hard work and creative talents.

If you want I can send it to you vial email if you want.

A_R

Here is the changed script, just copy and paste into notepad, save as 'sketch.js' and write over a copy of the sketch.js file in the directory. Then just run the index.html file like normal:

let drawSteps = [
  function() { background(255)},
  doSkyStep,
  doStarStep,
  drawStars,
  ]

let drawIndex = drawSteps.length;

function setup() {
  let cvs = createCanvas(resolutionX, resolutionY);
  cvs.parent("container")

  skyColor = color(57, 120, 168);
  skyColor2 = color(57, 49, 75);
  skyAccentColor = color(205, 96, 147);
  skyAccentColor2 = color(142, 71, 140);
  mountainColor =  color(57, 123, 68);
  mountainColor2 = color(182, 213, 60);
  starColor = color(244, 180, 27);
  starColor2 = color(138, 235, 241);
  cloudColor = color(223, 246, 245);

  document.getElementById("skyColor1").value = skyColor.toString('#rrggbb');
  document.getElementById("skyColor2").value = skyColor2.toString('#rrggbb');
  document.getElementById("skyAccentColor1").value = skyAccentColor.toString('#rrggbb');
  document.getElementById("skyAccentColor2").value = skyAccentColor2.toString('#rrggbb');
  document.getElementById("mountainColor1").value = mountainColor.toString('#rrggbb');
  document.getElementById("mountainColor2").value = mountainColor2.toString('#rrggbb');
  document.getElementById("starColor1").value = starColor.toString('#rrggbb');
  document.getElementById("starColor2").value = starColor2.toString('#rrggbb');
  document.getElementById("cloudColor1").value = cloudColor.toString('#rrggbb');

  cols = floor(width / particleScl);
  rows = floor(height / particleScl);
}

function drawFromSeed() {
  resizeCanvas(resolutionX, resolutionY);
  cols = floor(width / particleScl);
  rows = floor(height / particleScl);

    drawIndex = 0;
}

function doCloudStep() {
  let clouds = makeCloudCircles();
  drawCloudCircles(clouds);
  let cloudParticles = [];

  for (cloud of clouds) {
      let p = new StarParticle();
      p.position = createVector(cloud.x, cloud.y )
      p.previousPosition = p.position.copy()
      p.targetColor = lerpColor(skyColor, skyColor2, random(0,1));

      p.spread = 10;
      cloudParticles.push(p);
  }

  let cloudField = makeCloudField();
  drawField(cloudField, cloudParticles, 20)
}

function doSkyStep() {
  drawBackground();

  let skyField = makeSkyField();
  let skyParticles = [];

  for (var x = -40; x < width; x += particleScl) {
    for (var y = -40; y < height; y += particleScl) {

      let p = new Particle();
      p.pos = createVector(x, y)
      p.previousPosition = createVector(x, y)
      skyParticles.push(p);
    }
  }

 drawField(skyField, skyParticles, 40);
}

function doStarStep() {
  let circles = makeStarCircles();
  let starParticles = [];

  for (c of circles) {
    let rScl = c.r* 0.5;
        for(let j = 0; j < floor(c.r * 0.35);j++) {
            let p = new StarParticle();
            p.position = createVector(random(c.x - rScl, c.x + rScl), random(c.y - rScl, c.y + rScl))
      p.previousPosition = p.position.copy();
      p.targetColor = lerpColor(starColor, starColor2, random(0,1));
            starParticles.push(p);  
        }
  }

  let starField = makeStarField(circles);
  drawField(starField, starParticles, 20)
}

function draw() {
  if (drawIndex < drawSteps.length) {
    drawSteps[drawIndex]();
    drawIndex ++;
  }
}

function drawStars() {
  for(let i = 0; i < 500; i++) {
    strokeWeight(random(0.3, 5.0));
    stroke(255, 255, 255, random(0, 255));
    var h = random(0, 30) * random(4, 30);
    point(random(0, width), h);
  }
}

function drawCloudCircles(clouds) {
  noStroke();
  for (cloud of clouds) {
    let c = lerpColor(cloud.c, skyColor, random(0.0, 1.0))
    fill(c)
    circle(cloud.x, cloud.y, cloud.r)
  }
}

function drawBackground() {
  strokeWeight(mountainDetail*1.5);
  for(let y = 0; y < height; y+= mountainDetail) {
    stroke(lerpColor(skyColor2, skyColor, y/height * random(0.7, 1.3)));
    line(0, y, width, y)
  }
  noStroke();
  for(let y = 0; y < height; y+= 5) {
    if (random(0, 100) > 95) {
      let c = lerpColor(skyColor, skyAccentColor, random(0, 1))
      fill(c)
      circle(random(0, width), y, random(100, 200))
    }

    if (random(0, 100) > 95) {
      let c = lerpColor(skyColor, skyAccentColor2, random(0, 1))
      fill(c)
      circle(random(0, width), y, random(100, 200))
    }
  }
}

function drawMountain(distance) {
  let mountainHeight = height - mountainStart;
  let particles = [];
  let renderer = createGraphics(width, height);
  let iters = 30 - distance * 2 - random(0, 10);
  let lRenderers = [];

  for(let x = 0; x < width + mountainDetail; x+=mountainDetail) {
    let n = noise(x*0.001 * (distance/.7), distance*50);
    let heighestPoint = (mountainHeight * 0.85) + (distance/10.0)*mountainHeight + mountainStart;
    let altitude = n*(mountainHeight * 0.85) + (distance/10.0)*mountainHeight + mountainStart ;

    renderer.strokeWeight(mountainDetail*2);
    for (let y = altitude; y < height + mountainDetail; y+=mountainDetail) {

      let c = lerpColor(mountainColor, mountainColor2, pow(y/(heighestPoint-150), 7));
      c = lerpColor(skyColor, c, pow(distance/5.0, 2.0))

      renderer.stroke(c);
      renderer.point(x,y);
    }

    if (random(0, 100) > 20 * (5 - mountainDetail)) {
      let yy = random(0, 50)
      noStroke();
      fill(red(cloudColor), green(cloudColor), blue(cloudColor), random(50, 150));
      circle(x, altitude + yy, random(10, 40));
        let p = new StarParticle();
      p.position = createVector(x, altitude + yy)
      p.previousPosition = p.position.copy();
      p.maxSteps = iters + floor(random(-10, 5));
      p.targetColor = skyColor2;
      p.spread = 9.0;
      p.colorMerge = 0.98;
      particles.push(p);
    }
  }

 
  let cloudField = makeCloudField();
    drawField(cloudField, particles, iters + 5, skyColor)
  image(renderer, 0, 0);

  for (l of lRenderers) {
    image(l, 0, 0);
  }
}

I'd love to use this, but the bottom of the tool is cut off in my browser! (Chrome, Windows 8.1)

(1 edit)

Oh that's unfortunate, I think when the size of embed exceeds the size I set for the viewport in itch it gets cutoff. As a workaround you could download the source and just open index.html in your browser.

Edit: I'm stupid, forgot to enable scrollbars in itch, should work now.

Thanks! Now I can see the whole panel. I wasn't missing anything critical, but then I didn't know that!

Woah, incredible! The most beautiful procgen I've seen come out of this jam so far.

These look really cool, I'm actually going to use one of these for my phone background!

Nice, glad you like it!

That's really cool. I like it! :)

Incredible.