Selectable Noise Implementation in Ruby Processing

@CodeMasterX, @jb4x @cfloutier @hamoid AFAIK the “Perlin Noise” in processing is a value noise which bears no resemblance to the original Perlin noise, which is a gradient noise that uses a table of permutations. Ken Perlin went on to create an improved gradient noise implementation he called simplex noise, for which he obtained a patent, that was due to expire in January 2021. Anyway currently the “Perlin noise” is part of PApplet which is a behemoth. There is currently a pull request to use the delegate pattern to move the meat of the code out of PApplet. I have used this delegate pattern to extract the noise code in propane (a simplified version of ruby-processing), but I have also introduced a version of simplex noise, and thus created a choice of noise implementations. Here is a code example:-

#!/usr/bin/env jruby
require 'propane'

# Alternative to using array or string as key
Key = Struct.new(:x, :y) do
  def eql?(key)
    return false unless key.y == y
    key.x == x
  end
end
# The propane sketch press mouse to use SimpleNoise
class Terrain < Propane::App
  WIDTH = 1400
  HEIGHT = 1100
  SCL = 30
  attr_reader :terrain, :rows, :columns, :mover

  def settings
    size 800, 800, P3D
  end

  def setup
    sketch_title 'Terrain'
    @columns = WIDTH / SCL
    @rows = HEIGHT / SCL
    @terrain = {}
    @mover = 0
  end

  def draw
    background 0
    @mover -= 0.1
    yoff = mover
    (0..rows).each do |y|
      xoff = 0
      (0..columns).each do |x|
        terrain[Key.new(x, y)] = Vec3D.new(x * SCL, y * SCL, map1d(noise(xoff, yoff), 0..1.0, -65..65))
        xoff += 0.2
      end
      yoff += 0.2
    end
    no_fill
    stroke 235, 69, 129
    translate width / 2, height / 2
    rotate_x PI / 3
    translate(-WIDTH / 2, -HEIGHT / 2)
    (0...rows).each do |y|
      begin_shape(TRIANGLE_STRIP)
      (0..columns).each do |x|
        terrain[Key.new(x, y)].to_vertex(renderer)
        terrain[Key.new(x, y.succ)].to_vertex(renderer)
      end
      end_shape
    end
  end

  def mouse_pressed
    mode = Propane::SIMPLEX
    noise_mode mode
    sketch_title "#{mode}"
  end

  def mouse_released
    mode = Propane::VALUE
    noise_mode(mode)
    sketch_title "#{mode}"
  end

  private

  def renderer
    @renderer ||= GfxRender.new(self.g)
  end
end

Terrain.new

Install propane as follows

jgem install propane # requires JRuby and jdk11+

See project on github here.

2 Likes