载入中...
搜索中...
未找到
CaveLithology.cpp
浏览该文件的文档.
2
3#include <algorithm>
4#include <cmath>
5
6namespace eve::procgen {
7namespace {
8
9float smoothstep(float lo, float hi, float value) {
10 const float t = std::clamp((value - lo) / std::max(hi - lo, 1e-6f), 0.f, 1.f);
11 return t * t * (3.f - 2.f * t);
12}
13
14uint32_t hash(uint32_t value) {
15 value ^= value >> 16u;
16 value *= 0x7feb352du;
17 value ^= value >> 15u;
18 value *= 0x846ca68bu;
19 return value ^ (value >> 16u);
20}
21
22float unitHash(uint32_t value) { return float(hash(value) & 0xffffu) / 65535.f; }
23
24uint32_t signedBedKey(int bedIndex) { return bedIndex >= 0 ? uint32_t(bedIndex) * 2u : uint32_t(-bedIndex) * 2u - 1u; }
25
26} // namespace
27
30 if (input.heterogeneity <= 0.f) return result;
31
32 const float seedPhase = float(input.seed % 4093u) * 0.001534326f;
33 // A long-wavelength warp keeps contacts stratigraphically coherent without
34 // turning them into perfectly planar, synthetic slices.
35 const float warp = std::sin(input.x * 2.1f + input.z * 1.7f + seedPhase) * 0.035f +
36 std::sin(input.x * 4.7f - input.z * 3.2f + seedPhase * 1.61f) * 0.012f;
37 const float bedCoordinate = (input.y + warp) * 7.25f;
38 result.bedIndex = int(std::floor(bedCoordinate + 0.5f));
39 const float contactDistance = std::fabs(bedCoordinate - float(result.bedIndex));
40 const uint32_t bedKey = signedBedKey(result.bedIndex) ^ input.seed;
41
42 // Intrinsic dissolution contrast is correlated by bed, not white noise per voxel.
43 const float bedReactivity = unitHash(bedKey ^ 0x9e3779b9u);
44 result.bedResistance = 1.35f - bedReactivity * 0.70f * input.heterogeneity;
45 const float weakBed = smoothstep(0.44f, 0.78f, bedReactivity);
46 const float bedInterior =
47 smoothstep(0.05f, 0.36f, contactDistance) * (1.f - smoothstep(0.36f, 0.49f, contactDistance));
48 result.interbedMask = weakBed * bedInterior;
49
50 // Only some contacts carry stylolite clusters. Lateral modulation produces
51 // connected patches rather than an implausible groove around every wall.
52 const float stylolitePropensity = unitHash(bedKey ^ 0x85ebca6bu);
53 const float activeContact = smoothstep(0.48f, 0.68f, stylolitePropensity);
54 const float thinContact = 1.f - smoothstep(0.035f, 0.16f, contactDistance);
55 const float lateralCluster = smoothstep(
56 -0.28f, 0.35f, std::sin(input.along * 2.4f + input.z * 3.1f + seedPhase + float(result.bedIndex) * 1.37f));
57 result.styloliteMask = activeContact * thinContact * lateralCluster;
58
59 // Preferentially flushed contacts receive fresh undersaturated water, while
60 // stagnant beds retain a weak background response.
61 const float hydraulicAccess = std::clamp(0.18f + 0.82f * input.hydraulicIntensity, 0.18f, 1.35f);
62 const float selectiveDissolution =
63 result.styloliteMask * 0.72f + result.interbedMask * (1.15f - result.bedResistance) * 0.65f;
64 result.retreat = std::clamp(selectiveDissolution * hydraulicAccess * input.heterogeneity, 0.f, 1.f);
65 return result;
66}
67
68} // namespace eve::procgen
double value
std::array< std::uint8_t, 32 > hash
Definition Evpack.cpp:172
EvpackChunkInput input
Definition Evpack.cpp:170
float warp
float t
CaveLithologySample sampleCaveLithology(const CaveLithologyInput &input)
Sample flow-accessible dissolution caused by contrasting beds and clustered stylolites.
Inputs for lithology-selective bedding and stylolite dissolution.
Local bed resistance, stylolite exposure, and selective retreat.