Skip to content

Commit

Permalink
Added octave noise method
Browse files Browse the repository at this point in the history
  • Loading branch information
clexmond committed Oct 3, 2022
1 parent d05d717 commit 6c55a8b
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 9 deletions.
35 changes: 31 additions & 4 deletions contracts/cairo_rand_64x61/simplex.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ from cairo_math_64x61.vec64x61 import Vec64x61

namespace Simplex {
// Primary method to calculate Simplex 3D noise at a 3D point
// @param v A 64.61 fixed point 3d vector
func noise3{range_check_ptr}(v: (felt, felt, felt)) -> felt {
alloc_locals;

Expand Down Expand Up @@ -251,9 +252,21 @@ namespace Simplex {
return Math64x61.mul(res_sum, 42 * Math64x61.ONE);
}

// Returns the average noise value given a percentile (from 0 to 1) for a single
// octave of simplex noise scaled to a range from 0 to 1
// Arg and return are both in 64.61
// Returns multiple octaves of noise with a persistence dropoff
// @param v A 64.61 fixed point 3d vector
// @param octaves A simple felt indicating the number of iterations to add together
// @param persistence A 64.61 fixed point value used to decrease (or increase) the impact of each iteration
func noise3_octaves{range_check_ptr}(v: (felt, felt, felt), octaves: felt, persistence: felt) -> felt {
let noise = _noise3_octaves_loop{persistence = persistence, v = v}(
noise = 0, octaves = octaves, scale = Math64x61.ONE
);

return noise;
}

// Returns the average noise value given a percentile for a single octave of simplex noise scaled
// to a range from 0 to 1
// @param percentile A 64.61 fixed point value indicating the percentile (between 0 and 1)
func noise3_at_percentile{range_check_ptr}(percentile: felt) -> felt {
alloc_locals;
let upper_half = is_le(1152921504606846976, percentile); // 0.5
Expand All @@ -274,6 +287,20 @@ namespace Simplex {

return whole_noise_val + partial_noise_val;
}

func _noise3_octaves_loop{range_check_ptr, persistence: felt, v: (felt, felt, felt)}(
noise: felt, octaves: felt, scale: felt
) -> felt {
if (octaves == 0) {
return noise;
}

let resized_point = Vec64x61.div(v, scale);
let current_noise = noise3(resized_point);
let scaled_noise = Math64x61.mul(current_noise, scale);
let new_scale = Math64x61.mul(scale, persistence);
return _noise3_octaves_loop(noise = noise + scaled_noise, octaves = octaves - 1, scale = new_scale);
}
}

// Calculate x mod 289
Expand Down Expand Up @@ -392,4 +419,4 @@ func _simplex_dist_data() -> (data: felt*) {
dw 1124809191307870208;
dw 1137757040236560384;
dw 1152921504606846976;
}
}
6 changes: 6 additions & 0 deletions contracts/cairo_rand_64x61/simplex_mock.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ func noise3_at_percentile_test{range_check_ptr}(percentile: felt) -> (res: felt)
let res = Simplex.noise3_at_percentile(percentile);
return (res = res);
}

@view
func noise3_octaves_test{range_check_ptr}(v: (felt, felt, felt), octaves: felt, persistence: felt) -> (res: felt) {
let res = Simplex.noise3_octaves(v, octaves, persistence);
return (res = res);
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"name": "@infuenceth/cairo-rand",
"version": "2.1.0",
"version": "2.2.0",
"description": "Pseudorandom and procedural generation library using 64.61 fixed point",
"repository": {
"type": "git",
"url": "git+https://github.com/influenceth/cairo-rand-64x61.git"
},
"scripts": {
"compile": "npx hardhat starknet-compile ./contracts/cairo_rand_64x61/*.cairo",
"release": "python3.9 -m twine upload dist/*",
"build": "python3.9 -m build",
"postinstall": "pip install -r requirements.txt",
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "cairo_rand_64x61"
version = "2.1.0"
version = "2.2.0"
authors = [
{ name="Unstoppable Games, Inc.", email="info@unstoppablegames.io" },
]
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
build==0.8.0
cairo-lang==0.10.0
cairo-math-64x61==2.0.0
cairo-math-64x61==2.1.0
starknet-devnet==0.3.1
twine==4.0.1
45 changes: 45 additions & 0 deletions test/simplex.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,49 @@ describe('simplex', function () {
expect(Number(from64x61(res).toFixed(5))).to.equal(expected[i]);
}
});

it('should return octave noise with one octave matching ', async () => {
const argsList = [
[ 0.0, 0.0, 0.0 ],
[ 0.5, -1.23, 1.63 ],
[ -1.94, -1.25, -1.63 ],
[ -9.99, 8.25, 6.98 ],
[ -0.005, 12.578, -2.87 ]
];

const expected = [ -0.4122, 0.6335, 0.21512, -0.72603, -0.50797 ];

for (const [ i, args ] of argsList.entries()) {
const v = args.map((a) => to64x61(a));
const { res } = await contract.call('noise3_octaves_test', { v, octaves: 1, persistence: to64x61(1) });
expect(Number(from64x61(res).toFixed(5))).to.equal(expected[i]);
}
});

it('should return octave noise with multiple octaves', async () => {
const argsList = [
{ v: [ 0.5, -1.23, 1.63 ], octaves: 3, persistence: 0.5 },
{ v: [ -1.94, -1.25, -1.63 ], octaves: 2, persistence: 0.33 },
{ v: [ -9.99, 8.25, 6.98 ], octaves: 4, persistence: 0.25 }
];

for (const [ i, args ] of argsList.entries()) {
let expectedNoise = 0;

for (let i = 0; i < args.octaves; i++) {
const v = args.v.map((a) => to64x61(a / Math.pow(args.persistence, i)));
const { res } = await contract.call('noise3_test', { v });
const currentNoise = from64x61(res) * Math.pow(args.persistence, i);
expectedNoise += currentNoise;
}

const { res } = await contract.call('noise3_octaves_test', {
v: args.v.map((a) => to64x61(a)),
octaves: args.octaves,
persistence: to64x61(args.persistence)
});

expect(Number(from64x61(res).toFixed(5))).to.equal(Number(expectedNoise.toFixed(5)));
}
});
});

0 comments on commit 6c55a8b

Please sign in to comment.