Skip to content

Updated zig port to be compatible with 0.15.#173

Open
Schroedingers-Hat wants to merge 1 commit into
Auburn:masterfrom
Schroedingers-Hat:master
Open

Updated zig port to be compatible with 0.15.#173
Schroedingers-Hat wants to merge 1 commit into
Auburn:masterfrom
Schroedingers-Hat:master

Conversation

@Schroedingers-Hat

@Schroedingers-Hat Schroedingers-Hat commented Feb 20, 2026

Copy link
Copy Markdown

In addition to type errors from zig-.14 -> 0.15 There were a few instances where it was producing out of range values or values that disagreed with the Cpp version, notably the calculation for some of the fractal types differed until I changed the for loop to match the Cpp version more closely.

After making them match, some values were no longer clamped to [-1.0,1.0] so clamping has been added in places that resulted in that test failing (possibly more than is needed, but it didn't seem to impact performance notably).

Additionally, all implementations of fastRound and fastFloor going back to perlin's original java code do not perform the operation commonly known as round or floor.

fastFloor maps negative integers to the next integer below (as well as some numbers that are integer + frac mapping to integer - 1 or integer + 1 if frac is very close to 0 or 1). Eg fastFloor(-1) == -2 and fastFloor(4.9999998) == 5. These also get a bit worse out around 2^16 where people would expect f32 values to still work with precision of better than 1%.

fastRound maps some numbers very close to half-integers to the second nearest integer instead of the nearest.

I am surprised this does not cause visible artifacts near the 0 value of any given axis or near the middle of coordinate grid squares for things like domain warp or cellular noise.

I have seen people point out ragged edges in the discord for cellular noise, which could potentially be explained by fastRound if it was not user error. Especially if they are dividing an grid into a power of two fractional parts -- could be worth investigating.

The perlin-derived versions also harm performance very marginally (fastfloor is about 2-3x slower than std.floor in java for example, but it's only single digit % for fastnoiselite as it mostly isn't doing floor) on modern hardware compared to stdlib versions of floor or round in most languages. This includes modern java and many recent compiled languages based on llvm.

The version of fastfloor included in this commit is still marginally slower than the builtin for zig by three instructions on sse4 (as well as arm and a few others) hardware, but it matches or beats the ternary version on variations of x86 i386, arm etc. It may be an option if the very small performance penalty on pre-sse4 hardware from library implementations is unacceptable.

The fractal domain warp implementation of fastnoise.zig still disagrees with the Cpp for a few values in a million. I can't seem to spot the bug, but it appears to be independent of the fastFloor/fastRound issue stated above and did go away when the function was altered slightly to make it compatible with @Vector types instead of f32/f64 (which used @floor) so is likely a typo or similar I can't spot and accidentally fixed on the other branch. I couldn't seem to spot visual artifacts on a brief look, but didn't investigate thoroughly.

There were a few instances where it was producing out of range values or
values that disagreed with the Cpp version, notably the calculation for
some of the fractal types differed.

After making them match, some values were no longer clamped to [-1.0,1.0]
so clamping has been added in places that resulted in that test failing.

Additionally, all implementations of fastRound and fastFloor going back to
perlin's original java code do not perform the operation commonly known as
round or floor. Notably, they are incorrect at negative integers and numbers
very close to half-integers. I am surprised this does not cause visible
artifacts near the 0 value of any given axis.

The perlin derived versionas also harm performance very marginally on modern
hardware compared to stdlib versions of floor or round in most languages.
This includes modern java and many recent compiled languages based on llvm.

The domain warp implementation of fastnoise.zig still disagrees with the
Cpp for a few values in a million. I can't seem to spot the bug, but it
appears to be independent of the fastFloor/fastRound issue stated above
and did go away when the function was altered slightly to make it compatible
with @vector types instead of f32/f64.
@Schroedingers-Hat

Schroedingers-Hat commented Feb 20, 2026

Copy link
Copy Markdown
Author

A better example of the fastFloor mapping might be f32 fastFloor(-250000.9933) == -250002 compiled with clang++ -O0 -g

So various assumptions about x - floor(x) being in [0,1) get violated starting at a couple hundred km from the origin if someone is representing 1m as 1.0. One would expect to only see farlands starting at on the order of 4 million metres ordinarily.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant