Worley/Cellular Noise Demo

Showcase your libraries, tools and other projects that help your fellow love users.
Post Reply
User avatar
substitute541
Party member
Posts: 484
Joined: Fri Aug 24, 2012 9:04 am
Location: Southern Leyte, Visayas, Philippines
Contact:

Worley/Cellular Noise Demo

Post by substitute541 »

Went ahead and implemented Cellular noise for my noise library. Uses LuaJIT's FFI and BitOps libraries.

Worley Noise tutorial.
demo.png
demo.png (165.81 KiB) Viewed 4749 times
worleynoise.love
(1.9 KiB) Downloaded 270 times
worley.lua

Code: Select all


local floor = math.floor
local sqrt = math.sqrt

local bit = require "bit"
local bxor = bit.bxor

local ffi = require "ffi"
ffi.cdef[[
    typedef struct {float x, y, z;} vector3;
]]

-- linear congruential generator
local function lcgRandom(lastValue)
    return floor((110351245 * lastValue + 12345) % 0x100000000)
end

local OFFSET_BASIS = 2166136261
local FNV_PRIME = 16777619

-- FNV hash
local function hash(i, j, k)
    return ( bxor(
                bxor(
                  bxor(OFFSET_BASIS, i)*FNV_PRIME, j
                ) * FNV_PRIME
             , k) * FNV_PRIME )
end

-- possion distribution
local function probLookup(value)
    if value < 393325350 then return 1 end
    if value < 1022645910 then return 2 end
    if value < 1861739990 then return 3 end
    if value < 2700834071 then return 4 end
    if value < 3372109335 then return 5 end
    if value < 3819626178 then return 6 end
    if value < 4075350088 then return 7 end
    if value < 4203212043 then return 8 end
    return 9
end

-- insertion sort
local function insert(arr, value)
    local temp, l = 0, #arr
    for i=l, 1, -1 do
        if value > arr[i] then break end
        temp = arr[i]
        arr[i] = value
        if (i+1 < l) then arr[i+1] = temp end
    end
end

-- distance function
local function distfunc(a, b)
    local dx, dy, dz = b.x-a.x, b.y-a.y, b.z-a.z
    return (dx*dx+dy*dy+dz*dz)
end

-- clamp
local max, min = math.max, math.min
local function clamp(v)
    return max(min(v, 1), 0)
end


local function worleyNoise(x, y, z, arraylen)
    local x = x or 0
    local y = y or 0
    local z = z or 0

    local input = ffi.new("vector3", x, y, z)

    local lastRandom, numPoints = 0, 0
    local randomDiff, featurePoint = ffi.new("vector3"), ffi.new("vector3")
    local cubeX, cubeY, cubeZ = 0, 0, 0

    distArray = {}
    for i=1, arraylen or 1 do
        distArray[i] = 6666
    end

    local evalCubeX = floor(x)
    local evalCubeY = floor(y)
    local evalCubeZ = floor(z)

    for i=-1, 1 do
        for j=-1, 1 do
            for k=-1, 1 do
                cubeX = evalCubeX + i
                cubeY = evalCubeY + j
                cubeZ = evalCubeZ + k

                lastRandom = lcgRandom(hash(cubeX, cubeY, cubeZ))
                numPoints = probLookup(lastRandom)
                for l=1, numPoints do
                    lastRandom = lcgRandom(lastRandom)
                    randomDiff.x = lastRandom / 0x100000000

                    lastRandom = lcgRandom(lastRandom)
                    randomDiff.y = lastRandom / 0x100000000

                    lastRandom = lcgRandom(lastRandom)
                    randomDiff.z = lastRandom / 0x100000000

                    featurePoint.x = randomDiff.x+cubeX
                    featurePoint.y = randomDiff.y+cubeY
                    featurePoint.z = randomDiff.z+cubeZ

                    insert(distArray, clamp(distfunc(featurePoint, input)*2))
                end
            end
        end
    end

    return distArray
end

return worleyNoise
Currently designing themes for WordPress.

Sometimes lurks around the forum.
digdugluv
Prole
Posts: 8
Joined: Mon Jul 07, 2014 10:40 pm

Re: Worley/Cellular Noise Demo

Post by digdugluv »

This is so beautiful!

Code: Select all

local ffi = require "ffi"
ffi.cdef[[
    typedef struct {float x, y, z;} vector3;
    double _lcgRandom(double lastValue);
]]
local clib = ffi.load('./libclib.so')
and in clib.c

Code: Select all

/*

# gcc -shared -o libclib.so clib.c 

local function lcgRandom(lastValue)
    return floor((110351245 * lastValue + 12345) % 0x100000000)
end

*/

#include <math.h>
#include <stdio.h>

void debug(void) {
    printf("sizeof long long %lu\n", sizeof(long long));
}

double _lcgRandom(double lastValue) {
    unsigned long long intermediate = 110351245L * (long) lastValue + 12345L;
    unsigned long _mod = intermediate % 0x100000000L;
    return (double) _mod;
}
It speeds it up about 15%, nothing stellar but kinda fun.
gestaltist
Prole
Posts: 49
Joined: Thu May 29, 2014 10:56 am

Re: Worley/Cellular Noise Demo

Post by gestaltist »

It looks kind of similar to a Voronoi diagram. How do the two relate?

I am still looking for a decent Voronoi implementation for Lua.
WetDesertRock
Citizen
Posts: 67
Joined: Fri Mar 07, 2014 8:16 pm

Re: Worley/Cellular Noise Demo

Post by WetDesertRock »

Voronoi is different in the fact that it uses points given by the user, and then uses a mathematical process to work with them.


Here is a Delaunay library https://github.com/Yonaba/delaunay in which I use as the basis for this file: https://gist.github.com/WetDesertRock/7 ... 5b286a4ca6

Delaunay achieves much of the same effect.
digdugluv
Prole
Posts: 8
Joined: Mon Jul 07, 2014 10:40 pm

Re: Worley/Cellular Noise Demo

Post by digdugluv »



I attached the love for others to enjoy.
Attachments
delaunay.love
(6.47 KiB) Downloaded 188 times
gestaltist
Prole
Posts: 49
Joined: Thu May 29, 2014 10:56 am

Re: Worley/Cellular Noise Demo

Post by gestaltist »

Thanks! I will test it out.
Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests