Topic: Perlin Noise + Canvas (Page 1 of 1) Pages that link to <a href="" title="Pages that link to Topic: Perlin Noise + Canvas (Page 1 of 1)" rel="nofollow" >Topic: Perlin Noise + Canvas <span class="small">(Page 1 of 1)</span>\

Nervous Wreck (II) Inmate

Insane since: Dec 2007

IP logged posted posted 05-01-2009 19:48 Edit Quote

Here's a little function that fills a canvas with Perlin noise. It's not rocket science, but maybe someone will find it useful in their tinkering.

(The "canvas_ctx.globalAlpha = 4 / size" is totally tweakable, and will adjust how much smoothness vs. noise you'll get. It just seemed to produce decent results for what I was doing (terrain generation).)

As usual, best results in Opera and FF3. Webkit (and Chrome?) look terrible.

function perlin_noise (canvas) {
  var canvas_ctx = canvas.getContext ("2d"),
      offscreen = document.createElement ("canvas"),
      offscreen_ctx = offscreen.getContext ("2d"),
      saved_alpha = canvas_ctx.globalAlpha

  /* Fill the offscreen buffer with random noise. */
  offscreen.width = canvas.width
  offscreen.height = canvas.height

  var offscreen_id = offscreen_ctx.getImageData (0, 0,
      offscreen_pixels =

  for (var i = 0; i < offscreen_pixels.length; i += 4) {
    offscreen_pixels[i    ] =
    offscreen_pixels[i + 1] =
    offscreen_pixels[i + 2] = Math.floor (Math.random () * 256)
    offscreen_pixels[i + 3] = 255

  offscreen_ctx.putImageData (offscreen_id, 0, 0)

  /* Scale random iterations onto the canvas to generate Perlin noise. */
  for (var size = 4; size <= offscreen.width; size *= 2) {
    var x = Math.floor (Math.random () * (offscreen.width - size)),
        y = Math.floor (Math.random () * (offscreen.height - size))

    canvas_ctx.globalAlpha = 4 / size
    canvas_ctx.drawImage (offscreen, x, y, size, size,
                                     0, 0, canvas.width, canvas.height)

  canvas_ctx.globalAlpha = saved_alpha

Paranoid (IV) Inmate

From: Norway
Insane since: Jun 2002

IP logged posted posted 05-02-2009 14:32 Edit Quote

I like the slightly recursive approach : much more Canvas-like and efficient.

No surprise it looks like poo in Webkit browsers as it suck at things globalAlpha, globalCompositieOperation and color interpolation in general.

Nervous Wreck (II) Inmate

From: Portland Oregon
Insane since: Jun 2006

IP logged posted posted 05-09-2009 15:17 Edit Quote

that's awesome. I had to play with it.
I wonder how to make oranges and yellows dominant? is there anywhere I learn about mixing the colors.
it redraws every mousemove and the colors can be picked by clicking in the little bars
here's a sample pick.

Thanks for sharing this script, iron_wallaby. I'm going to use this to style elements with todataURL. i wonder how cool it would look to make marble tiles for your ray caster floor script. You could make it scale down little squares to another canvas and then save that canvas as the tile floor like the checker board floor. i'll have to try it.

Nervous Wreck (II) Inmate

Insane since: Dec 2007

IP logged posted posted 05-12-2009 04:39 Edit Quote

Bear in mind that all (canvas-based) images have 3 color channels: red, green, and blue. If you modify each of these color channels separately (like in that app you cite), you can get different color ratios. Bright Red + Bright Green = Bright Yellow, Dark Green + Bright Blue = Aqua, etc.

Actually making my code above do that is a little trickier... I'd do it by creating three noise maps, one for each color channel, and then copy all of them onto the result canvas one at a time.

Does that make sense? Would you like some example code? (From personal experience, it's generally much better to play around and figure out why you get the results you do, rather than seeing somebody else write the code, but sometimes you need a nudge in the right direction...)

Nervous Wreck (II) Inmate

From: Portland Oregon
Insane since: Jun 2006

IP logged posted posted 05-12-2009 04:50 Edit Quote

You read my mind. I've thinking about how to do that. I was trying to follow the pixastic script with the histograms, but I just get confused with jQuery stuff and I had to give up. I would love to see how to do it.

Nervous Wreck (II) Inmate

From: Portland Oregon
Insane since: Jun 2006

IP logged posted posted 05-12-2009 06:17 Edit Quote

I saved this script from somewhere and I found a way to make it work on a local machine so it doesn't throw a security error.
Is there anyway to avoid it?

<!DOCTYPE html>
<html lang="en">
    <meta charset="utf-8">
    <title>Canvas Primer - Example: ImageData colour inversion filter</title>
    <script type="text/javascript">

function runcolors(colorNum) { var elem = document.getElementById('myCanvas');

  // Get the canvas 2d context.
  var context = elem.getContext('2d');

  // Create a new image.
  var img = new Image();
img.src = 'logoBig.jpg';
  // Once it's loaded draw the image on canvas and invert the colors.
  img.addEventListener('load', function () {
    var x = 0, y = 0;

    // Draw the image on canvas.

    context.drawImage(this, x, y,this.width,this.height,x,y,this.width,this.height);

    // Get the pixels.

  try {
    try {
        var imgd = context.getImageData(x, y, img.width, img.height);
    } catch (e) {"UniversalBrowserRead");
       var imgd = context.getImageData(x, y, img.width, img.height);
  } catch (e) {
    throw new Error("unable to access image data: " + e);
    var pix =;

    // Loop over each pixel and invert the color.
    for (var i = 0, n = pix.length; i < n; i += 4) {
      pix[i  ] = 255 - pix[i  ]; // red
      pix[i+1] = 255 - pix[i+1]*colorNum; // green
      pix[i+2] = 255 - pix[i+2]; // blue
      // i+3 is alpha (the fourth element)

    // Draw the ImageData object.
    context.putImageData(imgd, x, y);
  }, false);

/*todo: make this function work.
function rgb2lum( r, g, b ) {
  return( (0.299/255.0)*r + (0.587/255.0)*g + (0.114/255.0)*b );
  <body onload="runcolors(1)">
    <canvas id="myCanvas" width="150" height="150" onmouseover="runcolors(.75)"></canvas>


Nervous Wreck (II) Inmate

Insane since: Dec 2007

IP logged posted posted 05-15-2009 23:17 Edit Quote

Hey, sorry for the delay. Don't have all that much time in my life these days. I don't generally bother with jQuery or any of the other frameworks (I've been doing JS so long that it feels easier, if wordier, to do the scripts by hand--besides, I'm a total hacker anyways), so I'm afraid I can't help you much there.

Anyway, I've uploaded an example at:

Hopefully it's pretty self-explanatory. Basically, all I do is independently randomize each of the three color channels in the noise() function. Since each color channel is independent, you get fun, pretty-colored plasmas.

I also made this version totally unreliant on get/putImageData, so it's more compatible, but slower. Expect a little wait if you click the link.

(Edited by iron_wallaby on 05-15-2009 23:50)

Nervous Wreck (II) Inmate

From: Portland Oregon
Insane since: Jun 2006

IP logged posted posted 05-16-2009 05:38 Edit Quote

Very nice. Thanks for the examples. I'll be studying them. I really appreciate your help.

Neurotic (0) Inmate
Newly admitted

Insane since: May 2010

IP logged posted posted 05-21-2010 12:29 Edit Quote

Hi Iron Wallaby, I took your code and used it to make a cloudy sky

Maniac (V) Mad Scientist

From: 127 Halcyon Road, Marenia, Atlantis
Insane since: Aug 2000

IP logged posted posted 05-21-2010 13:24 Edit Quote

Procedural texture generation?! iron_wallaby, we need to talk! Do you know any C++?

Obsessive-Compulsive (I) Inmate

Insane since: Jul 2010

IP logged posted posted 07-30-2010 10:08 Edit Quote

TP: Spam removed

(Edited by Tyberius Prime on 07-30-2010 12:15)

Nervous Wreck (II) Inmate

Insane since: Dec 2007

IP logged posted posted 09-10-2010 02:00 Edit Quote

Wow, long time since I've been here...

killbot, glad you found it fun to experiment with, the cloudy sky looks great! For future improvements, I suggest checking out:

Petskull, any programmer worth their salt knows at least several dozen languages, so yes, I know C++. That said, Perlin noise isn't anything particularly complicated. You should read Perlin's papers, or look into Farbrauch's demos (I'd try Google or've taken the technique much, much further than I have.

Nervous Wreck (II) Inmate

Insane since: May 2011

IP logged posted posted 05-31-2011 11:00 Edit Quote
Edit TP: spam removed

Post Reply
Your User Name:
Your Password:
Login Options: Remember Me On This Computer
Your Text:
Options: Show Signature
Enable Slimies
Enable Linkwords

« BackwardsOnwards »

Show Forum Drop Down Menu