Topic: Perlin Noise + Canvas (Page 1 of 1) Pages that link to <a href="http://ozoneasylum.com/backlink?for=30982" 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>\

 
iron_wallaby
Nervous Wreck (II) Inmate

From:
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.

code:
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.width,
                                                 offscreen.height),
      offscreen_pixels = offscreen_id.data

  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
}

poi
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.

racerX
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.
http://h1.ripway.com/stirfry/perlin/RGBcolorPickerWithPerlinNoise.html
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.

iron_wallaby
Nervous Wreck (II) Inmate

From:
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...)

racerX
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.

racerX
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?

code:
<!DOCTYPE html>
<html lang="en">
  <head>
    <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';
elem.width=img.width
elem.height=img.height
  // 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) {
      netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
       var imgd = context.getImageData(x, y, img.width, img.height);
    }
  } catch (e) {
    throw new Error("unable to access image data: " + e);
  }
   
    var pix = imgd.data;

    // 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 );
}
*/
</script>
  </head>
  <body onload="runcolors(1)">
    <canvas id="myCanvas" width="150" height="150" onmouseover="runcolors(.75)"></canvas>

  </body>
</html>

iron_wallaby
Nervous Wreck (II) Inmate

From:
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: http://lonelypinkelephants.com/random/perlin.html

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)

racerX
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.

killbot_7
Neurotic (0) Inmate
Newly admitted

From:
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

http://proceduralgraphics.blogspot.com/2010/05/cloudy-blue-perlin-sky.html

Petskull
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++?

q455923354
Obsessive-Compulsive (I) Inmate

From:
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)

iron_wallaby
Nervous Wreck (II) Inmate

From:
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: http://freespace.virgin.net/hugo.elias/models/m_clouds.htm

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 Pouet.net)--they've taken the technique much, much further than I have.

coach
Nervous Wreck (II) Inmate

From:
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:
Loading...
Options: Show Signature
Enable Slimies
Enable Linkwords

« BackwardsOnwards »

Show Forum Drop Down Menu