载入中...
搜索中...
未找到
CaveMicrostructure.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <cmath>
5
6namespace eve::procgen {
7namespace {
8
9uint32_t microHash(uint32_t value) {
10 value ^= value >> 16u;
11 value *= 0x7feb352du;
12 value ^= value >> 15u;
13 value *= 0x846ca68bu;
14 return value ^ (value >> 16u);
15}
16
17float noise(float x, float y, float z, uint32_t seed) {
18 const int ix = int(std::floor(x)), iy = int(std::floor(y)), iz = int(std::floor(z));
19 const float fx = x - float(ix), fy = y - float(iy), fz = z - float(iz);
20 auto smooth = [](float t) { return t * t * (3.f - 2.f * t); };
21 auto sample = [seed](int sx, int sy, int sz) {
22 const uint32_t h =
23 microHash(uint32_t(sx) * 73856093u ^ uint32_t(sy) * 19349663u ^ uint32_t(sz) * 83492791u ^ seed);
24 return float(h & 0xffffu) / 32767.5f - 1.f;
25 };
26 auto lerp = [](float a, float b, float t) { return a + (b - a) * t; };
27 const float ux = smooth(fx), uy = smooth(fy), uz = smooth(fz);
28 const float x00 = lerp(sample(ix, iy, iz), sample(ix + 1, iy, iz), ux);
29 const float x10 = lerp(sample(ix, iy + 1, iz), sample(ix + 1, iy + 1, iz), ux);
30 const float x01 = lerp(sample(ix, iy, iz + 1), sample(ix + 1, iy, iz + 1), ux);
31 const float x11 = lerp(sample(ix, iy + 1, iz + 1), sample(ix + 1, iy + 1, iz + 1), ux);
32 return lerp(lerp(x00, x10, uy), lerp(x01, x11, uy), uz);
33}
34
35float smoothstep(float edge0, float edge1, float value) {
36 const float t = std::clamp((value - edge0) / (edge1 - edge0), 0.f, 1.f);
37 return t * t * (3.f - 2.f * t);
38}
39
40} // namespace
41
42CaveMicrostructureSample sampleCaveMicrostructure(float x, float y, float z, uint32_t seed, float heterogeneity,
43 float microporosityAccess, float permeabilityContrast) {
44 if (heterogeneity <= 0.f) return {};
45
46 // A coarse connected field represents intergranular macropores; a finer field
47 // represents intragranular surface that can be reached without becoming a conduit.
48 const float coarse = 0.68f * noise(x * 3.1f, y * 2.2f, z * 3.1f, seed ^ 0x93c467e3u) +
49 0.32f * noise(x * 7.3f, y * 4.6f, z * 7.3f, seed ^ 0x6d2b79f5u);
50 const float fine = noise(x * 13.7f, y * 9.1f, z * 13.7f, seed ^ 0xa511e9b3u);
51 const float connectedPore = smoothstep(-0.42f, 0.58f, coarse);
52 const float accessibleSurface = smoothstep(-0.55f, 0.48f, 0.65f * fine + 0.35f * coarse);
53
54 const float localized = 0.22f + 1.58f * std::pow(connectedPore, 1.f + 5.f * permeabilityContrast);
55 const float distributed = 0.72f + 0.48f * accessibleSurface;
56 const float reactionPattern = microporosityAccess * distributed + (1.f - microporosityAccess) * localized;
57 const float permeabilityPattern = 0.42f + 1.28f * std::pow(connectedPore, 1.f + 3.f * permeabilityContrast);
58
60 result.reactiveSurface = std::clamp(1.f + heterogeneity * (reactionPattern - 1.f), 0.2f, 1.8f);
61 result.permeability =
62 std::clamp(1.f + heterogeneity * permeabilityContrast * (permeabilityPattern - 1.f), 0.35f, 1.7f);
63 return result;
64}
65
66} // namespace eve::procgen
double value
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
int h
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
std::uint32_t seed
Definition PointSet.cpp:807
float t
constexpr HexVec3 lerp(HexVec3 a, HexVec3 b, float t) noexcept
Linear interpolation between two positions.
Definition HexMetrics.h:51
double sample(const Heightmap &map, double u, double v)
Sample.
CaveMicrostructureSample sampleCaveMicrostructure(float x, float y, float z, uint32_t seed, float heterogeneity, float microporosityAccess, float permeabilityContrast)
Sample cave microstructure.
CaveMicrostructureSample public API.