Download CommonLua/Classes/PerlinNoise.lua from sirnii/myspace: direct link, hf CLI and curl.
- Browser
- Download file 7.68 kB
-
https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/Classes/PerlinNoise.lua
- Command line
-
hf download hf://spaces/sirnii/myspace/CommonLua/Classes/PerlinNoise.lua
-
curl -L -o PerlinNoise.lua https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/Classes/PerlinNoise.lua
7.68 kB
| local max_octaves = 20 | |
| local octave_scale = 1024 | |
| local noise_scale = 1024 | |
| local ratio_scale = 1000 | |
| DefineClass.PerlinNoiseBase = | |
| { | |
| __parents = { "PropertyObject" }, | |
| properties = { | |
| { category = "Noise", id = "Frequency", name = "Frequency (%)", editor = "number", default = false, min = 0, max = 100, slider = true, help = "A tool for changing the main noise frequency. Depends on the number of octaves and the chosen persistence" }, | |
| { category = "Noise", id = "Persistence", name = "Persistence", editor = "number", default = 50, min = 1, max = 99, slider = true, help = "Defines the behavior of the noise octaves when changing the noise frequency" }, | |
| { category = "Noise", id = "Octaves", name = "Octaves Count", editor = "number", default = 9, min = 1, max = max_octaves, help = "Number of octaves to use" }, | |
| { category = "Noise", id = "OctavesList", name = "Octaves", editor = "text", default = "", dont_save = true, help = "Used to copy or paste a set octaves" }, | |
| { category = "Noise", id = "BestSize", name = "Best Size", editor = "number", default = 0, read_only = true, dont_save = true, help = "Recomended noise grid size" }, | |
| }, | |
| octave_ids = {}, | |
| } | |
| function ExpandPerlinParams(count, persistence, main, amp) | |
| count = count or -1 | |
| persistence = persistence or 50 | |
| main = main or 1 | |
| if count == 0 then return "" end | |
| local octaves = {} | |
| amp = amp or octave_scale | |
| octaves[main] = amp | |
| local i = 0 | |
| while i ~= count do | |
| i = i + 1 | |
| local new_amp = amp * persistence / 100 | |
| if new_amp == amp and count <= 0 then | |
| break | |
| end | |
| amp = new_amp | |
| local left = main - i | |
| local right = main + i | |
| if count > 0 and left < 1 and right > count then | |
| break | |
| end | |
| if left >= 1 then | |
| octaves[left] = amp | |
| end | |
| if count < 0 or right <= count then | |
| octaves[right] = amp | |
| end | |
| end | |
| return octaves | |
| end | |
| do | |
| local params = ExpandPerlinParams(max_octaves, 50) | |
| local octave_ids = PerlinNoiseBase.octave_ids | |
| for i=1,max_octaves do | |
| local id = "Octave_"..i | |
| octave_ids[i] = id | |
| octave_ids[id] = i | |
| table.insert(PerlinNoiseBase.properties, { | |
| id = id, | |
| name = "Octave "..i, | |
| editor = "number", | |
| default = params[i] or 0, | |
| category = "Noise", | |
| min = 0, max = octave_scale, slider = true, | |
| no_edit = function(self) return self.Octaves < i end, | |
| }) | |
| end | |
| end | |
| function PerlinNoiseBase:GetOctavesList() | |
| return table.concat(self:ExportOctaves(), ', ') | |
| end | |
| function PerlinNoiseBase:SetOctavesList(list) | |
| local octaves = dostring("return {" .. list .. "}") | |
| if octaves then | |
| return self:ImportOctaves(octaves) | |
| end | |
| end | |
| function PerlinNoiseBase:GetBestSize() | |
| return 2 ^ self.Octaves | |
| end | |
| function PerlinNoiseBase:OnEditorSetProperty(prop_id, old_value, ged) | |
| if prop_id == "Frequency" or prop_id == "Persistence" or prop_id == "Octaves" then | |
| if self.Frequency then | |
| local mo = 1 + MulDivRound(self.Octaves - 1, self.Frequency, 100) | |
| self:SetMainOctave(mo) | |
| end | |
| elseif self.octave_ids[prop_id] then | |
| self.Frequency = nil | |
| end | |
| end | |
| function PerlinNoiseBase:SetMainOctave(mo) | |
| if not mo then | |
| return | |
| end | |
| local params = ExpandPerlinParams(self.Octaves, self.Persistence, mo) | |
| self:ImportOctaves(params) | |
| end | |
| function PerlinNoiseBase:ExportOctaves() | |
| local octaves = {} | |
| local octave_ids = self.octave_ids | |
| for i=1,self.Octaves do | |
| octaves[#octaves + 1] = self[octave_ids[i]] | |
| end | |
| for i=self.Octaves,1,-1 do | |
| if octaves[i] ~= 0 then | |
| break | |
| end | |
| octaves[i] = nil | |
| end | |
| return octaves | |
| end | |
| function PerlinNoiseBase:ImportOctaves(octaves) | |
| self.Octaves = #octaves | |
| local params = {} | |
| local octave_ids = self.octave_ids | |
| for i=1,max_octaves do | |
| self[octave_ids[i]] = octaves[i] | |
| end | |
| end | |
| function PerlinNoiseBase:GetNoiseRaw(rand_seed, g, ...) | |
| rand_seed = self.Seed + (rand_seed or 0) | |
| GridPerlin(rand_seed, self:ExportOctaves(), g, ...) | |
| return g, ... | |
| end | |
| ---- | |
| DefineClass.PerlinNoise = | |
| { | |
| __parents = { "PerlinNoiseBase" }, | |
| properties = { | |
| { id = "Seed", name = "Random Seed", editor = "number", default = 0, category = "Noise", buttons = {{name = "Rand", func = "ActionRand"}}, help = "Fixed randomization seed"}, | |
| { id = "Size", name = "Grid Size", editor = "number", default = 256, category = "Noise", min = 2, max = 2048, help = "Size of the noise grid" }, | |
| { id = "Min", name = "Min Value", editor = "number", default = 0, category = "Noise", }, | |
| { id = "Max", name = "Max Value", editor = "number", default = noise_scale, category = "Noise", }, | |
| { id = "Preview", editor = "grid", default = false, category = "Noise", dont_save = true, interpolation = "nearest", frame = 1, min = 128, max = 512, read_only = true, no_validate = true }, | |
| { id = "Clamp", name = "Clamp Range (%)", editor = "range", default = range(0, 100), category = "Post Process", min = 0, max = 100, slider = true, help = "Clamp the noise in that range and re-normalize afterwards" }, | |
| { id = "Sin", name = "Sin Unity (%)", editor = "number", default = 0, category = "Post Process", min = 0, max = 100, slider = true, help = "Applies sinusoidal easing. Useful to smooth noise after clamping" }, | |
| { id = "Mask", name = "Mask Area (%)", editor = "number", default = 0, category = "Post Process", min = 0, max = 100, slider = true, help = "Creates a mask with that percentage of area" }, | |
| }, | |
| } | |
| function PerlinNoise:OnNoiseChanged() | |
| end | |
| function PerlinNoise:GetPreview() | |
| return self:GetNoise() | |
| end | |
| function GetNoisePreview(noise_name) | |
| local noise_preset = NoisePresets[noise_name] | |
| return noise_preset and noise_preset:GetPreview() | |
| end | |
| function PerlinNoise:GetNoise(rand_seed, g, ...) | |
| g = g or NewComputeGrid(self.Size, self.Size, "F") | |
| return self:PostProcess(self:GetNoiseRaw(rand_seed, g, ...)) | |
| end | |
| function PerlinNoise:PostProcess(g, ...) | |
| if not g then | |
| return | |
| end | |
| local min, max = self.Min, self.Max | |
| local smin, smax = min * ratio_scale, max * ratio_scale | |
| local function pct(v) | |
| return smin + MulDivRound(smax - smin, v, 100) | |
| end | |
| GridNormalize(g, min, max) | |
| if self.Clamp.from > 0 or self.Clamp.to < 100 then | |
| local from = pct(self.Clamp.from) | |
| local to = pct(self.Clamp.to) | |
| GridClamp(g, from, to, ratio_scale) | |
| GridRemap(g, from, to, smin, smax, ratio_scale) | |
| end | |
| if self.Sin ~= 0 then | |
| local unity = pct(self.Sin) | |
| if unity > smin then | |
| GridSin(g, smin, unity, ratio_scale) | |
| GridRemap(g, -1, 1, min, max) | |
| end | |
| end | |
| if self.Mask ~= 0 then | |
| local level = GridLevel(g, self.Mask, 100, ratio_scale) | |
| GridMask(g, 0, level, ratio_scale) | |
| GridRemap(g, 0, 1, min, max) | |
| end | |
| --NetUpdateHash("PerlinNoise", g) | |
| return g, self:PostProcess(...) | |
| end | |
| function PerlinNoise:ActionRand(root, prop_id, ged) | |
| self.Seed = AsyncRand() | |
| ObjModified(self) | |
| end | |
| function NoisePresetsCombo() | |
| local items = table.values(NoisePresets) | |
| items = table.map(items, "id") | |
| table.sort(items) | |
| table.insert(items, 1, "") | |
| return items | |
| end | |
| DefineClass.WangPerlinNoise = { | |
| __parents = {"PerlinNoise"}, | |
| properties = { | |
| {id = "unique_edges", editor = "number", default = 2,}, | |
| {id = "tiles", editor = "point", default = point(4,4), read_only = true,}, | |
| {id = "cells_per_tile", editor = "point", default = point(4,4), }, | |
| } | |
| } | |
| function WangPerlinNoise:Gettiles() | |
| local size = self.unique_edges ^ 2 | |
| return point(size, size) | |
| end | |
| function WangPerlinNoise:GetNoiseRaw(rand_seed, g, ...) | |
| rand_seed = self.Seed + (rand_seed or 0) | |
| local n = GetPreciseTicks() | |
| GridWang(rand_seed, {octaves = self:ExportOctaves(), tiles = self:Gettiles(), cells_per_tile = self.cells_per_tile}, g) | |
| --print("WangNoise Took", GetPreciseTicks() - n) | |
| return g, ... | |
| end | |