noise/hash.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /// @file | ||
| 2 | /// @brief Stateless PCG hashes for the CPU and GPU backends (`portable.h`). | ||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include "terraingen/util/portable.h" | ||
| 6 | |||
| 7 | namespace terraingen { | ||
| 8 | |||
| 9 | /// Three 32-bit words. | ||
| 10 | struct UVec3 { | ||
| 11 | 9 | uint32_t x = 0; ///< First word. | |
| 12 | 8 | uint32_t y = 0; ///< Second word. | |
| 13 | 7 | uint32_t z = 0; ///< Third word. | |
| 14 | |||
| 15 | #ifndef __SLANG__ | ||
| 16 | 9 | bool operator==(const UVec3&) const = default; | |
| 17 | #endif | ||
| 18 | }; | ||
| 19 | |||
| 20 | /// PCG hash (PCG-RXS-M-XS over one LCG step) of one 32-bit word; bit-identical everywhere. | ||
| 21 | 464330570 | constexpr uint32_t PcgHash(uint32_t v) { | |
| 22 | 464330570 | const uint32_t state = v * 747796405u + 2891336453u; | |
| 23 | 464330570 | const uint32_t word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u; | |
| 24 | 464330570 | return (word >> 22u) ^ word; | |
| 25 | } | ||
| 26 | |||
| 27 | /// The `pcg3d` hash of three 32-bit words to three well-mixed words. | ||
| 28 | 3976324006 | constexpr UVec3 Pcg3dHash(UVec3 v) { | |
| 29 | 3976324006 | v.x = v.x * 1664525u + 1013904223u; | |
| 30 | 3976324006 | v.y = v.y * 1664525u + 1013904223u; | |
| 31 | 3976324006 | v.z = v.z * 1664525u + 1013904223u; | |
| 32 | |||
| 33 | 3976324006 | v.x += v.y * v.z; | |
| 34 | 3976324006 | v.y += v.z * v.x; | |
| 35 | 3976324006 | v.z += v.x * v.y; | |
| 36 | |||
| 37 | 3976324006 | v.x ^= v.x >> 16u; | |
| 38 | 3976324006 | v.y ^= v.y >> 16u; | |
| 39 | 3976324006 | v.z ^= v.z >> 16u; | |
| 40 | |||
| 41 | 3976324006 | v.x += v.y * v.z; | |
| 42 | 3976324006 | v.y += v.z * v.x; | |
| 43 | 3976324006 | v.z += v.x * v.y; | |
| 44 | 3976324006 | return v; | |
| 45 | } | ||
| 46 | |||
| 47 | /// Maps a hash to a float in [0, 1) from its top 24 bits, which a `float` represents exactly. | ||
| 48 | 1583093841 | constexpr float HashToUnitFloat(uint32_t hash) { | |
| 49 | 1583093841 | return float(hash >> 8u) * 0x1p-24f; | |
| 50 | } | ||
| 51 | |||
| 52 | } // namespace terraingen | ||
| 53 |