@call-me-sensei/toonlab 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ATTRIBUTION.md +40 -0
- package/LICENSE +21 -0
- package/README.md +125 -0
- package/package.json +97 -0
- package/src/character/characterRig.js +353 -0
- package/src/character/freestyleSwimClip.js +541 -0
- package/src/character/index.js +4 -0
- package/src/character/modelLoader.js +433 -0
- package/src/core/materialRoles.js +438 -0
- package/src/core/presetDocuments.js +110 -0
- package/src/core/shaderBackend.js +24 -0
- package/src/debrisgen/debrisFields.js +544 -0
- package/src/debrisgen/debrisGenerator.js +1929 -0
- package/src/debrisgen/debrisPalettes.js +71 -0
- package/src/debrisgen/debrisPhysics.js +198 -0
- package/src/debrisgen/debrisPresets.js +155 -0
- package/src/debrisgen/debrisSettings.js +333 -0
- package/src/debrisgen/debrisTextures.js +380 -0
- package/src/debrisgen/index.js +5 -0
- package/src/debug/fieldValues.js +95 -0
- package/src/debug/index.js +7 -0
- package/src/debug/settingsPanel.js +170 -0
- package/src/environment/environmentAmbientProbe.js +160 -0
- package/src/environment/environmentMaterialAdapter.js +336 -0
- package/src/environment/environmentMaterialClassifier.js +178 -0
- package/src/environment/environmentPlanarReflection.js +201 -0
- package/src/environment/environmentPresets.js +443 -0
- package/src/environment/environmentRigs.js +684 -0
- package/src/environment/environmentSettings.js +504 -0
- package/src/environment/environmentShaderMaterials.js +318 -0
- package/src/environment/environmentSunShadowPass.js +268 -0
- package/src/environment/environmentTextureResolver.js +161 -0
- package/src/environment/environmentTimeOfDay.js +167 -0
- package/src/environment/environmentVertexAo.js +188 -0
- package/src/environment/index.js +8 -0
- package/src/environment/scanAssetStylize.js +103 -0
- package/src/index.js +21 -0
- package/src/loaders/index.js +1 -0
- package/src/post/index.js +2 -0
- package/src/post/postProcessing.js +1087 -0
- package/src/rockgen/export/glbExport.js +177 -0
- package/src/rockgen/heightfield/heightfieldErosion.js +7 -0
- package/src/rockgen/heightfield/heightfieldPatch.js +183 -0
- package/src/rockgen/heightfield/stylizedErosionSim.js +356 -0
- package/src/rockgen/index.js +14 -0
- package/src/rockgen/mesh/meshAttributes.js +374 -0
- package/src/rockgen/mesh/meshDocument.js +158 -0
- package/src/rockgen/mesh/surfaceNets.js +329 -0
- package/src/rockgen/noise/cellularNoise3.js +92 -0
- package/src/rockgen/noise/prng.js +62 -0
- package/src/rockgen/noise/simplexNoise3.js +89 -0
- package/src/rockgen/noise/valueNoise3.js +87 -0
- package/src/rockgen/rockDocument.js +255 -0
- package/src/rockgen/rockHelpers.js +8 -0
- package/src/rockgen/rockgenPresets.js +559 -0
- package/src/rockgen/rockgenSettings.js +756 -0
- package/src/rockgen/sdf/fieldCompiler.js +544 -0
- package/src/rockgen/sdf/sculptEdits.js +66 -0
- package/src/rockgen/sdf/sdfModifiers.js +45 -0
- package/src/rockgen/sdf/sdfOps.js +37 -0
- package/src/rockgen/sdf/sdfPrimitives.js +88 -0
- package/src/shaders-tsl/anime.js +963 -0
- package/src/shaders-tsl/chunks/character-color.js +64 -0
- package/src/shaders-tsl/chunks/character-highlights.js +174 -0
- package/src/shaders-tsl/chunks/character-lighting.js +309 -0
- package/src/shaders-tsl/chunks/character-material-maps.js +146 -0
- package/src/shaders-tsl/chunks/character-roles.js +52 -0
- package/src/shaders-tsl/chunks/character-scene-lights.js +270 -0
- package/src/shaders-tsl/chunks/character-shadow-color.js +61 -0
- package/src/shaders-tsl/chunks/character-skinning.js +140 -0
- package/src/shaders-tsl/chunks/environment-color.js +47 -0
- package/src/shaders-tsl/chunks/environment-debug.js +79 -0
- package/src/shaders-tsl/chunks/environment-lighting.js +260 -0
- package/src/shaders-tsl/chunks/environment-sun-shadow.js +87 -0
- package/src/shaders-tsl/chunks/foliage-fog.js +60 -0
- package/src/shaders-tsl/chunks/pass-depth-color.js +89 -0
- package/src/shaders-tsl/chunks/stylized-cloud-shadow.js +70 -0
- package/src/shaders-tsl/chunks/water-color.js +190 -0
- package/src/shaders-tsl/chunks/water-common.js +124 -0
- package/src/shaders-tsl/chunks/water-foam.js +93 -0
- package/src/shaders-tsl/chunks/water-lighting.js +116 -0
- package/src/shaders-tsl/chunks/water-ripple.js +64 -0
- package/src/shaders-tsl/chunks/water-waves.js +100 -0
- package/src/shaders-tsl/environment-ao-overlay.js +60 -0
- package/src/shaders-tsl/environment.js +680 -0
- package/src/shaders-tsl/flower.js +267 -0
- package/src/shaders-tsl/grass.js +193 -0
- package/src/shaders-tsl/post-composite.js +461 -0
- package/src/shaders-tsl/sky.js +175 -0
- package/src/shaders-tsl/tree-leaf.js +264 -0
- package/src/shaders-tsl/water-breaker.js +423 -0
- package/src/shaders-tsl/water-kelp.js +171 -0
- package/src/shaders-tsl/water-rain.js +107 -0
- package/src/shaders-tsl/water-simulation.js +140 -0
- package/src/shaders-tsl/water-splash.js +298 -0
- package/src/shaders-tsl/water.js +509 -0
- package/src/sky/index.js +2 -0
- package/src/sky/stylizedSky.js +341 -0
- package/src/toon/characterRenderPasses.js +646 -0
- package/src/toon/index.js +4 -0
- package/src/toon/settings/alphaSettings.js +170 -0
- package/src/toon/settings/averageShadowSettings.js +181 -0
- package/src/toon/settings/baseTextureSettings.js +133 -0
- package/src/toon/settings/celShadeSettings.js +96 -0
- package/src/toon/settings/contactShadowSettings.js +114 -0
- package/src/toon/settings/eyeHighlightSettings.js +187 -0
- package/src/toon/settings/faceLightingSettings.js +135 -0
- package/src/toon/settings/furSettings.js +112 -0
- package/src/toon/settings/glitterSettings.js +102 -0
- package/src/toon/settings/hairHighlightSettings.js +325 -0
- package/src/toon/settings/indirectLightSettings.js +244 -0
- package/src/toon/settings/localLightSettings.js +176 -0
- package/src/toon/settings/materialMapSettings.js +299 -0
- package/src/toon/settings/outlineSettings.js +263 -0
- package/src/toon/settings/perspectiveRemovalSettings.js +60 -0
- package/src/toon/settings/rimLightSettings.js +268 -0
- package/src/toon/settings/sceneShadowSettings.js +147 -0
- package/src/toon/settings/selfShadowSettings.js +221 -0
- package/src/toon/settings/shadowColorSettings.js +238 -0
- package/src/toon/settings/skinToneSettings.js +150 -0
- package/src/toon/settings/specularSettings.js +314 -0
- package/src/toon/settings/stickerSettings.js +102 -0
- package/src/toon/toonMaterialAdapter.js +2235 -0
- package/src/toon/toonSettings.js +860 -0
- package/src/vegetation/flowerSpecies.js +260 -0
- package/src/vegetation/index.js +10 -0
- package/src/vegetation/stylizedBush.js +136 -0
- package/src/vegetation/stylizedFlower.js +213 -0
- package/src/vegetation/stylizedFlowers.js +297 -0
- package/src/vegetation/stylizedGrass.js +491 -0
- package/src/vegetation/stylizedTree.js +2449 -0
- package/src/vegetation/stylizedTreeFoliage.js +691 -0
- package/src/vegetation/treeExport.js +300 -0
- package/src/vegetation/treeRecipe.js +647 -0
- package/src/water/index.js +2 -0
- package/src/water/water.js +20 -0
- package/src/water/waterBreakerSystem.js +591 -0
- package/src/water/waterInteraction.js +193 -0
- package/src/water/waterMaterial.js +263 -0
- package/src/water/waterRain.js +136 -0
- package/src/water/waterRippleSimulation.js +227 -0
- package/src/water/waterScenePasses.js +415 -0
- package/src/water/waterSettings.js +1138 -0
- package/src/water/waterSplashSystem.js +251 -0
- package/src/water/waterSurface.js +475 -0
- package/src/water/waterVegetation.js +83 -0
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
// Named rockgen presets: one string selects a coherent rock look (piece
|
|
2
|
+
// settings partials, plus optional document-level surface/meshing
|
|
3
|
+
// overrides). Registry mirrors environmentPresets.js. Phase B adds the
|
|
4
|
+
// cliff/mountain presets; Phase C adds multi-piece `kind: 'document'`
|
|
5
|
+
// presets (mountain ranges, scree clusters).
|
|
6
|
+
|
|
7
|
+
/** Document type tag for shareable rockgen preset JSON documents. */
|
|
8
|
+
export const ROCKGEN_PRESET_DOCUMENT_TYPE = 'toonlab/rockgen-preset';
|
|
9
|
+
|
|
10
|
+
/** Current schema version for rockgen preset documents. */
|
|
11
|
+
export const ROCKGEN_PRESET_SCHEMA_VERSION = 1;
|
|
12
|
+
|
|
13
|
+
const ROCKGEN_PRESETS = new Map();
|
|
14
|
+
|
|
15
|
+
export function registerRockgenPreset(name, preset, { overwrite = false } = {}) {
|
|
16
|
+
const key = String(name ?? '').trim();
|
|
17
|
+
if (!key) throw new Error('Rockgen preset name is required.');
|
|
18
|
+
if (!overwrite && ROCKGEN_PRESETS.has(key)) {
|
|
19
|
+
throw new Error(`Rockgen preset "${key}" is already registered.`);
|
|
20
|
+
}
|
|
21
|
+
ROCKGEN_PRESETS.set(key, {
|
|
22
|
+
kind: 'piece', // 'document' presets carry a `pieces` array instead
|
|
23
|
+
label: key,
|
|
24
|
+
meshing: null,
|
|
25
|
+
piece: {},
|
|
26
|
+
pieces: null,
|
|
27
|
+
surface: null,
|
|
28
|
+
...preset,
|
|
29
|
+
});
|
|
30
|
+
return key;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function normalizeRockgenPresetName(name) {
|
|
34
|
+
const key = String(name ?? 'boulder').trim();
|
|
35
|
+
return ROCKGEN_PRESETS.has(key) ? key : 'boulder';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function getRockgenPresetOptions(kind = null) {
|
|
39
|
+
return Array.from(ROCKGEN_PRESETS.entries())
|
|
40
|
+
.filter(([, preset]) => kind === null || preset.kind === kind)
|
|
41
|
+
.map(([value, preset]) => ({ label: preset.label, value }));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Returns a deep copy of the preset (`{ kind, label, piece, surface,
|
|
46
|
+
* meshing }`) safe to mutate; unknown names fall back to 'boulder'.
|
|
47
|
+
*/
|
|
48
|
+
export function resolveRockgenPreset(name) {
|
|
49
|
+
return structuredClone(ROCKGEN_PRESETS.get(normalizeRockgenPresetName(name)));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Preset doctrine (learned the hard way): rocks are flat or round with
|
|
53
|
+
// some jagged sides. Jaggedness comes from planar cuts; facet grooves and
|
|
54
|
+
// domain warp past ~0.15 read as melted organic tissue, and gradient
|
|
55
|
+
// normals on blobby geometry amplify it. Round presets stay smooth and
|
|
56
|
+
// QUIET (river stones); everything else gets flat normals + cuts.
|
|
57
|
+
|
|
58
|
+
registerRockgenPreset('boulder', {
|
|
59
|
+
label: 'Boulder',
|
|
60
|
+
meshing: { normalsMode: 'flat' },
|
|
61
|
+
piece: {
|
|
62
|
+
cuts: {
|
|
63
|
+
bevel: 0.03, count: 7, depth: 0.24, enabled: true, verticalBias: 0.3,
|
|
64
|
+
},
|
|
65
|
+
falloff: { bottomFlatten: 0.4 },
|
|
66
|
+
name: 'Boulder',
|
|
67
|
+
noise: { amplitude: 0.07, frequency: 1.1, octaves: 3 },
|
|
68
|
+
shape: { sizeX: 1.15, sizeY: 0.8, sizeZ: 1.0 },
|
|
69
|
+
warp: { frequency: 0.7, strength: 0.08 },
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
registerRockgenPreset('river-boulder', {
|
|
74
|
+
label: 'River Boulder',
|
|
75
|
+
piece: {
|
|
76
|
+
falloff: { bottomFlatten: 0.2 },
|
|
77
|
+
name: 'River Boulder',
|
|
78
|
+
// Water-worn = genuinely smooth: one gentle noise octave pair, a
|
|
79
|
+
// whisper of warp, gradient normals. The one preset meant to be round.
|
|
80
|
+
noise: { amplitude: 0.05, frequency: 0.8, octaves: 2 },
|
|
81
|
+
shape: { sizeX: 1.1, sizeY: 0.7, sizeZ: 0.9 },
|
|
82
|
+
warp: { frequency: 0.6, strength: 0.12 },
|
|
83
|
+
},
|
|
84
|
+
surface: {
|
|
85
|
+
baseColor: [0.58, 0.57, 0.55],
|
|
86
|
+
cavityColor: [0.4, 0.38, 0.35],
|
|
87
|
+
topColor: [0.82, 0.84, 0.85],
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
registerRockgenPreset('karst-spire', {
|
|
92
|
+
label: 'Karst Spire',
|
|
93
|
+
meshing: { normalsMode: 'flat' },
|
|
94
|
+
piece: {
|
|
95
|
+
cuts: {
|
|
96
|
+
bevel: 0.02, count: 8, depth: 0.3, enabled: true, verticalBias: 0.6,
|
|
97
|
+
},
|
|
98
|
+
falloff: { bottomFlatten: 0.35, topTaper: 0.5 },
|
|
99
|
+
name: 'Karst Spire',
|
|
100
|
+
noise: {
|
|
101
|
+
amplitude: 0.07, frequency: 2.0, octaves: 4, ridged: true,
|
|
102
|
+
},
|
|
103
|
+
shape: { capsuleLength: 3.4, sizeX: 0.75, type: 'capsule' },
|
|
104
|
+
strata: {
|
|
105
|
+
enabled: true, frequency: 2.2, sharpness: 0.6, strength: 0.07, tiltDegrees: 4,
|
|
106
|
+
},
|
|
107
|
+
warp: { enabled: false, frequency: 0.55, strength: 0.1 },
|
|
108
|
+
},
|
|
109
|
+
surface: {
|
|
110
|
+
baseColor: [0.6, 0.58, 0.52],
|
|
111
|
+
cavityColor: [0.35, 0.32, 0.27],
|
|
112
|
+
topColor: [0.78, 0.82, 0.8],
|
|
113
|
+
topSlopeStart: 0.75,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
registerRockgenPreset('sea-stack', {
|
|
118
|
+
label: 'Sea Stack',
|
|
119
|
+
meshing: { normalsMode: 'flat' },
|
|
120
|
+
piece: {
|
|
121
|
+
cuts: {
|
|
122
|
+
bevel: 0.025, count: 8, depth: 0.3, enabled: true, verticalBias: 0.75,
|
|
123
|
+
},
|
|
124
|
+
falloff: { bottomFlatten: 0.5, radialPinch: 0.25 },
|
|
125
|
+
name: 'Sea Stack',
|
|
126
|
+
noise: { amplitude: 0.06, frequency: 1.4, octaves: 3 },
|
|
127
|
+
shape: { capsuleLength: 2.4, sizeX: 0.95, type: 'capsule' },
|
|
128
|
+
strata: {
|
|
129
|
+
enabled: true, frequency: 3.6, sharpness: 0.7, strength: 0.1, tiltDegrees: 6,
|
|
130
|
+
},
|
|
131
|
+
warp: { enabled: false, frequency: 0.6, strength: 0.1 },
|
|
132
|
+
},
|
|
133
|
+
surface: {
|
|
134
|
+
baseColor: [0.45, 0.44, 0.42],
|
|
135
|
+
cavityColor: [0.26, 0.25, 0.23],
|
|
136
|
+
topColor: [0.75, 0.78, 0.76],
|
|
137
|
+
topHeightStart: 0.65,
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// --- Showcase presets: tuned looks meant to sell the generator ------------
|
|
142
|
+
// Flat normals + strong Voronoi faceting is the signature stylized-rock
|
|
143
|
+
// recipe: surface nets' even topology turns into clean angular planes that
|
|
144
|
+
// cel-shade beautifully.
|
|
145
|
+
|
|
146
|
+
registerRockgenPreset('granite-boulder', {
|
|
147
|
+
label: 'Granite Block (Angular)',
|
|
148
|
+
meshing: { normalsMode: 'flat' },
|
|
149
|
+
piece: {
|
|
150
|
+
// Angular granite = many all-direction planar cuts on a squat
|
|
151
|
+
// ellipsoid. (The old facet-groove version read as a brain.)
|
|
152
|
+
cracks: {
|
|
153
|
+
coverage: 0.45, depth: 0.06, enabled: true, scale: 1.1, width: 0.07,
|
|
154
|
+
},
|
|
155
|
+
cuts: {
|
|
156
|
+
bevel: 0.02, count: 11, depth: 0.3, enabled: true, verticalBias: 0.2,
|
|
157
|
+
},
|
|
158
|
+
falloff: { bottomFlatten: 0.45 },
|
|
159
|
+
name: 'Granite Block',
|
|
160
|
+
noise: {
|
|
161
|
+
amplitude: 0.05, frequency: 1.3, octaves: 3,
|
|
162
|
+
},
|
|
163
|
+
shape: { sizeX: 1.15, sizeY: 0.85, sizeZ: 1.0 },
|
|
164
|
+
warp: { frequency: 0.7, strength: 0.06 },
|
|
165
|
+
},
|
|
166
|
+
surface: {
|
|
167
|
+
baseColor: [0.55, 0.54, 0.53],
|
|
168
|
+
cavityColor: [0.3, 0.29, 0.3],
|
|
169
|
+
colorNoise: 0.04,
|
|
170
|
+
topColor: [0.78, 0.79, 0.77],
|
|
171
|
+
topHeightStart: 0.45,
|
|
172
|
+
topSlopeStart: 0.6,
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Columnar basalt cliff (Liyue / Giant's Causeway): vertical prismatic
|
|
177
|
+
// columns with stepped tops and offset horizontal joints. The columns
|
|
178
|
+
// stage defines the structure; strata adds the per-column break lines.
|
|
179
|
+
registerRockgenPreset('basalt-columns', {
|
|
180
|
+
label: 'Basalt Columns',
|
|
181
|
+
meshing: { exportResolution: 256, normalsMode: 'flat', previewResolution: 96 },
|
|
182
|
+
piece: {
|
|
183
|
+
columns: {
|
|
184
|
+
enabled: true, grooveDepth: 0.17, grooveWidth: 0.13, heightVariation: 1.2, scale: 1.7,
|
|
185
|
+
},
|
|
186
|
+
falloff: { bottomFlatten: 0.35 },
|
|
187
|
+
name: 'Basalt Columns',
|
|
188
|
+
noise: { amplitude: 0.035, frequency: 2.4, octaves: 3 },
|
|
189
|
+
shape: {
|
|
190
|
+
cornerRadius: 0.2, sizeX: 1.6, sizeY: 2.4, sizeZ: 1.1, type: 'box',
|
|
191
|
+
},
|
|
192
|
+
strata: {
|
|
193
|
+
enabled: true, frequency: 2.0, sharpness: 0.9, strength: 0.04, tiltDegrees: 0, warpAmount: 0.05,
|
|
194
|
+
},
|
|
195
|
+
warp: { frequency: 0.4, strength: 0.08 },
|
|
196
|
+
},
|
|
197
|
+
surface: {
|
|
198
|
+
baseColor: [0.68, 0.58, 0.48],
|
|
199
|
+
cavityColor: [0.4, 0.31, 0.24],
|
|
200
|
+
colorNoise: 0.05,
|
|
201
|
+
topColor: [0.8, 0.73, 0.62],
|
|
202
|
+
topHeightStart: 0.3,
|
|
203
|
+
topSlopeStart: 0.6,
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// A single sheer cliff wall: near-raw box silhouette, planar cuts with a
|
|
208
|
+
// strong vertical bias for stepped rock faces, whisper-quiet noise so the
|
|
209
|
+
// faces stay planar, subtle strata joints. Warp stays OFF — it would bow
|
|
210
|
+
// the wall back into a blob.
|
|
211
|
+
registerRockgenPreset('cliff-wall', {
|
|
212
|
+
label: 'Cliff Wall (Flat)',
|
|
213
|
+
meshing: { exportResolution: 288, normalsMode: 'flat', previewResolution: 96 },
|
|
214
|
+
piece: {
|
|
215
|
+
// Columns give the stepped skyline and vertical joints; cuts stagger
|
|
216
|
+
// the wall plane itself so the face isn't one flat sheet.
|
|
217
|
+
columns: {
|
|
218
|
+
enabled: true, grooveDepth: 0.1, grooveWidth: 0.14, heightVariation: 0.9, scale: 1.2,
|
|
219
|
+
},
|
|
220
|
+
cuts: {
|
|
221
|
+
bevel: 0.02, count: 10, depth: 0.32, enabled: true, verticalBias: 0.85,
|
|
222
|
+
},
|
|
223
|
+
falloff: { bottomFlatten: 0.45 },
|
|
224
|
+
name: 'Cliff Wall',
|
|
225
|
+
noise: { amplitude: 0.03, frequency: 2.2, octaves: 3 },
|
|
226
|
+
shape: {
|
|
227
|
+
cornerRadius: 0.02, sizeX: 2.6, sizeY: 2.4, sizeZ: 1.0, type: 'box',
|
|
228
|
+
},
|
|
229
|
+
strata: {
|
|
230
|
+
enabled: true, frequency: 1.6, sharpness: 0.85, strength: 0.045, tiltDegrees: 2, warpAmount: 0.08,
|
|
231
|
+
},
|
|
232
|
+
warp: { enabled: false, frequency: 0.4, strength: 0.08 },
|
|
233
|
+
},
|
|
234
|
+
surface: {
|
|
235
|
+
baseColor: [0.68, 0.58, 0.48],
|
|
236
|
+
cavityColor: [0.4, 0.31, 0.24],
|
|
237
|
+
colorNoise: 0.05,
|
|
238
|
+
topColor: [0.8, 0.73, 0.62],
|
|
239
|
+
topHeightStart: 0.3,
|
|
240
|
+
topSlopeStart: 0.6,
|
|
241
|
+
},
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// Eroded landforms ('heightfield' shape): stylized drainage gullies + thermal
|
|
245
|
+
// talus — the terrain-tool look at rock-piece scale.
|
|
246
|
+
// Displacement stages stay quiet; the erosion IS the detail.
|
|
247
|
+
registerRockgenPreset('eroded-mesa', {
|
|
248
|
+
label: 'Eroded Mesa',
|
|
249
|
+
meshing: { exportResolution: 288, normalsMode: 'flat', previewResolution: 96 },
|
|
250
|
+
piece: {
|
|
251
|
+
falloff: { bottomFlatten: 0 },
|
|
252
|
+
heightfield: {
|
|
253
|
+
droplets: 0.55, erosion: 0.75, profile: 'mesa', relief: 0.55,
|
|
254
|
+
roughness: 0.45, terrace: 0.5, terraceSteps: 7, thermal: 0.65,
|
|
255
|
+
},
|
|
256
|
+
name: 'Eroded Mesa',
|
|
257
|
+
noise: { amplitude: 0.02, frequency: 2.6, octaves: 2 },
|
|
258
|
+
shape: {
|
|
259
|
+
sizeX: 2.6, sizeY: 1.3, sizeZ: 2.2, type: 'heightfield',
|
|
260
|
+
},
|
|
261
|
+
warp: { enabled: false },
|
|
262
|
+
},
|
|
263
|
+
surface: {
|
|
264
|
+
baseColor: [0.72, 0.5, 0.34],
|
|
265
|
+
cavityColor: [0.44, 0.26, 0.18],
|
|
266
|
+
colorNoise: 0.05,
|
|
267
|
+
topColor: [0.84, 0.7, 0.5],
|
|
268
|
+
topHeightStart: 0.55,
|
|
269
|
+
topSlopeStart: 0.6,
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
registerRockgenPreset('canyon-ridge', {
|
|
274
|
+
label: 'Canyon Ridge',
|
|
275
|
+
meshing: { exportResolution: 288, normalsMode: 'flat', previewResolution: 96 },
|
|
276
|
+
piece: {
|
|
277
|
+
falloff: { bottomFlatten: 0 },
|
|
278
|
+
heightfield: {
|
|
279
|
+
// Relief past ~0.6 with 9 terrace steps out-runs what the droplets
|
|
280
|
+
// can smooth at patch resolution — the ridge shatters into hoodoo
|
|
281
|
+
// needles. Keep the backbone moderate and let erosion carve it.
|
|
282
|
+
droplets: 0.7, erosion: 0.85, profile: 'ridge', relief: 0.52,
|
|
283
|
+
roughness: 0.38, terrace: 0.55, terraceSteps: 7, thermal: 0.7,
|
|
284
|
+
},
|
|
285
|
+
name: 'Canyon Ridge',
|
|
286
|
+
noise: { amplitude: 0.02, frequency: 2.4, octaves: 2 },
|
|
287
|
+
shape: {
|
|
288
|
+
sizeX: 1.6, sizeY: 1.6, sizeZ: 2.8, type: 'heightfield',
|
|
289
|
+
},
|
|
290
|
+
warp: { enabled: false },
|
|
291
|
+
},
|
|
292
|
+
surface: {
|
|
293
|
+
baseColor: [0.68, 0.44, 0.3],
|
|
294
|
+
cavityColor: [0.4, 0.22, 0.16],
|
|
295
|
+
colorNoise: 0.06,
|
|
296
|
+
topColor: [0.82, 0.66, 0.46],
|
|
297
|
+
topHeightStart: 0.5,
|
|
298
|
+
topSlopeStart: 0.55,
|
|
299
|
+
},
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// --- Document presets (multi-piece compositions) ---------------------------
|
|
303
|
+
|
|
304
|
+
const ARCH_COLUMN_PIECE = {
|
|
305
|
+
columns: {
|
|
306
|
+
enabled: true, grooveDepth: 0.17, grooveWidth: 0.13, heightVariation: 1.2, scale: 1.7,
|
|
307
|
+
},
|
|
308
|
+
falloff: { bottomFlatten: 0.35 },
|
|
309
|
+
noise: { amplitude: 0.035, frequency: 2.4, octaves: 3 },
|
|
310
|
+
strata: {
|
|
311
|
+
enabled: true, frequency: 2.0, sharpness: 0.9, strength: 0.04, tiltDegrees: 0, warpAmount: 0.05,
|
|
312
|
+
},
|
|
313
|
+
warp: { frequency: 0.4, strength: 0.08 },
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
// A natural stone arch (Liyue-style): one wide columnar wall with an
|
|
317
|
+
// ellipsoid subtracted through it for the opening, flanked by a second
|
|
318
|
+
// bundle for an asymmetric skyline.
|
|
319
|
+
registerRockgenPreset('column-arch', {
|
|
320
|
+
kind: 'document',
|
|
321
|
+
label: 'Column Arch',
|
|
322
|
+
meshing: { exportResolution: 288, normalsMode: 'flat', previewResolution: 96 },
|
|
323
|
+
pieces: [
|
|
324
|
+
{
|
|
325
|
+
...ARCH_COLUMN_PIECE,
|
|
326
|
+
name: 'Arch Wall',
|
|
327
|
+
shape: {
|
|
328
|
+
cornerRadius: 0.2, sizeX: 3.0, sizeY: 2.6, sizeZ: 1.0, type: 'box',
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
...ARCH_COLUMN_PIECE,
|
|
333
|
+
combine: { blend: 0.5, op: 'smoothUnion' },
|
|
334
|
+
name: 'Flank Bundle',
|
|
335
|
+
seed: 3,
|
|
336
|
+
shape: {
|
|
337
|
+
cornerRadius: 0.25, sizeX: 1.1, sizeY: 1.9, sizeZ: 1.2, type: 'box',
|
|
338
|
+
},
|
|
339
|
+
transform: { position: [-2.9, -0.7, 0.4] },
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
combine: { blend: 0.18, op: 'subtract' },
|
|
343
|
+
name: 'Opening',
|
|
344
|
+
noise: { amplitude: 0.12, frequency: 1.6, octaves: 3 },
|
|
345
|
+
shape: { sizeX: 1.6, sizeY: 2.05, sizeZ: 3.2, type: 'ellipsoid' },
|
|
346
|
+
transform: { position: [0.45, -1.45, 0] },
|
|
347
|
+
warp: { frequency: 0.6, strength: 0.2 },
|
|
348
|
+
},
|
|
349
|
+
],
|
|
350
|
+
surface: {
|
|
351
|
+
baseColor: [0.68, 0.58, 0.48],
|
|
352
|
+
cavityColor: [0.4, 0.31, 0.24],
|
|
353
|
+
colorNoise: 0.05,
|
|
354
|
+
topColor: [0.8, 0.73, 0.62],
|
|
355
|
+
topHeightStart: 0.3,
|
|
356
|
+
topSlopeStart: 0.6,
|
|
357
|
+
},
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// Shared slab recipe for the cliff-face composition below.
|
|
361
|
+
const CLIFF_SLAB_PIECE = {
|
|
362
|
+
cuts: {
|
|
363
|
+
bevel: 0.02, count: 8, depth: 0.3, enabled: true, verticalBias: 0.8,
|
|
364
|
+
},
|
|
365
|
+
noise: { amplitude: 0.03, frequency: 2.2, octaves: 3 },
|
|
366
|
+
strata: {
|
|
367
|
+
enabled: true, frequency: 1.8, sharpness: 0.85, strength: 0.04, tiltDegrees: 2, warpAmount: 0.08,
|
|
368
|
+
},
|
|
369
|
+
warp: { enabled: false, frequency: 0.4, strength: 0.08 },
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
// A stacked cliff face (anime-style): staggered flat-cut slabs joined
|
|
373
|
+
// with HARD unions — smoothUnion would round the seams away; the crisp
|
|
374
|
+
// slab-on-slab joints are the look.
|
|
375
|
+
registerRockgenPreset('cliff-face', {
|
|
376
|
+
kind: 'document',
|
|
377
|
+
label: 'Cliff Face',
|
|
378
|
+
meshing: { exportResolution: 288, normalsMode: 'flat', previewResolution: 96 },
|
|
379
|
+
pieces: [
|
|
380
|
+
{
|
|
381
|
+
...CLIFF_SLAB_PIECE,
|
|
382
|
+
falloff: { bottomFlatten: 0.5 },
|
|
383
|
+
name: 'Lower Wall',
|
|
384
|
+
shape: {
|
|
385
|
+
cornerRadius: 0.02, sizeX: 2.9, sizeY: 1.9, sizeZ: 1.15, type: 'box',
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
...CLIFF_SLAB_PIECE,
|
|
390
|
+
combine: { blend: 0, op: 'union' },
|
|
391
|
+
name: 'Mid Wall',
|
|
392
|
+
seed: 4,
|
|
393
|
+
shape: {
|
|
394
|
+
cornerRadius: 0.02, sizeX: 2.4, sizeY: 1.5, sizeZ: 0.95, type: 'box',
|
|
395
|
+
},
|
|
396
|
+
transform: { position: [0.35, 2.6, -0.3], rotation: [0, 0.12, 0] },
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
...CLIFF_SLAB_PIECE,
|
|
400
|
+
combine: { blend: 0, op: 'union' },
|
|
401
|
+
name: 'Crown Slab',
|
|
402
|
+
seed: 9,
|
|
403
|
+
shape: {
|
|
404
|
+
cornerRadius: 0.03, sizeX: 1.7, sizeY: 1.0, sizeZ: 0.8, type: 'box',
|
|
405
|
+
},
|
|
406
|
+
transform: { position: [-0.5, 4.4, -0.55], rotation: [0, -0.2, 0] },
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
...CLIFF_SLAB_PIECE,
|
|
410
|
+
combine: { blend: 0, op: 'union' },
|
|
411
|
+
falloff: { bottomFlatten: 0.4 },
|
|
412
|
+
name: 'Shoulder Block',
|
|
413
|
+
seed: 13,
|
|
414
|
+
shape: {
|
|
415
|
+
cornerRadius: 0.03, sizeX: 1.1, sizeY: 1.1, sizeZ: 0.9, type: 'box',
|
|
416
|
+
},
|
|
417
|
+
transform: { position: [2.9, -0.8, 0.35], rotation: [0, 0.35, 0] },
|
|
418
|
+
},
|
|
419
|
+
],
|
|
420
|
+
surface: {
|
|
421
|
+
baseColor: [0.68, 0.58, 0.48],
|
|
422
|
+
cavityColor: [0.4, 0.31, 0.24],
|
|
423
|
+
colorNoise: 0.05,
|
|
424
|
+
topColor: [0.8, 0.73, 0.62],
|
|
425
|
+
topHeightStart: 0.3,
|
|
426
|
+
topSlopeStart: 0.6,
|
|
427
|
+
},
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
// A boulder with satellite rubble — demonstrates hard-union clustering.
|
|
431
|
+
const SCREE_ROCK_PIECE = {
|
|
432
|
+
cuts: {
|
|
433
|
+
bevel: 0.025, count: 6, depth: 0.25, enabled: true, verticalBias: 0.3,
|
|
434
|
+
},
|
|
435
|
+
falloff: { bottomFlatten: 0.35 },
|
|
436
|
+
noise: { amplitude: 0.06, frequency: 1.4, octaves: 3 },
|
|
437
|
+
warp: { frequency: 0.7, strength: 0.06 },
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
registerRockgenPreset('scree-cluster', {
|
|
441
|
+
kind: 'document',
|
|
442
|
+
label: 'Scree Cluster',
|
|
443
|
+
meshing: { normalsMode: 'flat' },
|
|
444
|
+
pieces: [
|
|
445
|
+
{
|
|
446
|
+
...SCREE_ROCK_PIECE,
|
|
447
|
+
falloff: { bottomFlatten: 0.4 },
|
|
448
|
+
name: 'Main Boulder',
|
|
449
|
+
shape: { sizeX: 1.15, sizeY: 0.8, sizeZ: 1.0 },
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
...SCREE_ROCK_PIECE,
|
|
453
|
+
combine: { blend: 0, op: 'union' },
|
|
454
|
+
name: 'Rubble A',
|
|
455
|
+
seed: 5,
|
|
456
|
+
shape: { sizeX: 0.5, sizeY: 0.35, sizeZ: 0.45 },
|
|
457
|
+
transform: { position: [1.3, -0.5, 0.4], rotation: [0, 0.7, 0] },
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
...SCREE_ROCK_PIECE,
|
|
461
|
+
combine: { blend: 0, op: 'union' },
|
|
462
|
+
name: 'Rubble B',
|
|
463
|
+
seed: 9,
|
|
464
|
+
shape: { sizeX: 0.4, sizeY: 0.3, sizeZ: 0.5 },
|
|
465
|
+
transform: { position: [-1.15, -0.55, -0.5], rotation: [0, -0.4, 0] },
|
|
466
|
+
},
|
|
467
|
+
],
|
|
468
|
+
surface: {
|
|
469
|
+
baseColor: [0.56, 0.53, 0.48],
|
|
470
|
+
cavityColor: [0.36, 0.33, 0.29],
|
|
471
|
+
topColor: [0.75, 0.76, 0.72],
|
|
472
|
+
topHeightStart: 0.5,
|
|
473
|
+
topSlopeStart: 0.6,
|
|
474
|
+
},
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
// The classic low-poly look: the COARSE GRID is the art style. Preview and
|
|
478
|
+
// export mesh at the same resolution so exports are exactly what you see;
|
|
479
|
+
// flat normals turn every surface-nets quad into a readable facet.
|
|
480
|
+
registerRockgenPreset('lowpoly-boulder', {
|
|
481
|
+
label: 'Low-Poly Boulder',
|
|
482
|
+
meshing: { exportResolution: 32, normalsMode: 'flat', previewResolution: 32 },
|
|
483
|
+
piece: {
|
|
484
|
+
falloff: { bottomFlatten: 0.4 },
|
|
485
|
+
name: 'Low-Poly Boulder',
|
|
486
|
+
noise: { amplitude: 0.16, frequency: 1.0, octaves: 3 },
|
|
487
|
+
shape: { sizeX: 1.2, sizeY: 0.85, sizeZ: 1.0 },
|
|
488
|
+
warp: { frequency: 0.7, strength: 0.25 },
|
|
489
|
+
},
|
|
490
|
+
surface: {
|
|
491
|
+
baseColor: [0.56, 0.53, 0.48],
|
|
492
|
+
cavityColor: [0.36, 0.33, 0.29],
|
|
493
|
+
colorNoise: 0.03,
|
|
494
|
+
topColor: [0.75, 0.76, 0.72],
|
|
495
|
+
topHeightStart: 0.5,
|
|
496
|
+
topSlopeStart: 0.6,
|
|
497
|
+
},
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
registerRockgenPreset('mossy-boulder', {
|
|
501
|
+
label: 'Mossy Boulder',
|
|
502
|
+
meshing: { normalsMode: 'flat' },
|
|
503
|
+
piece: {
|
|
504
|
+
cuts: {
|
|
505
|
+
bevel: 0.04, count: 5, depth: 0.2, enabled: true, verticalBias: 0.3,
|
|
506
|
+
},
|
|
507
|
+
falloff: { bottomFlatten: 0.42 },
|
|
508
|
+
name: 'Mossy Boulder',
|
|
509
|
+
noise: { amplitude: 0.06, frequency: 1.2, octaves: 3 },
|
|
510
|
+
shape: { sizeX: 1.1, sizeY: 0.8, sizeZ: 0.95 },
|
|
511
|
+
warp: { frequency: 0.7, strength: 0.08 },
|
|
512
|
+
},
|
|
513
|
+
surface: {
|
|
514
|
+
baseColor: [0.5, 0.47, 0.42],
|
|
515
|
+
cavityColor: [0.28, 0.26, 0.22],
|
|
516
|
+
colorNoise: 0.05,
|
|
517
|
+
lichenCoverage: 0.16,
|
|
518
|
+
mossColor: [0.24, 0.39, 0.18],
|
|
519
|
+
mossCoverage: 0.62,
|
|
520
|
+
textureScale: 1.2,
|
|
521
|
+
textureStrength: 0.18,
|
|
522
|
+
textureStyle: 'granite',
|
|
523
|
+
topColor: [0.55, 0.61, 0.43],
|
|
524
|
+
topHeightStart: 0.4,
|
|
525
|
+
topSlopeStart: 0.5,
|
|
526
|
+
},
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
// ('desert-mesa' retired: the eroded-mesa heightfield preset supersedes the
|
|
530
|
+
// old box-with-strata approximation. normalizeRockgenPresetName falls saved
|
|
531
|
+
// documents back to 'boulder' gracefully.)
|
|
532
|
+
|
|
533
|
+
registerRockgenPreset('shard-monolith', {
|
|
534
|
+
label: 'Shard Monolith (Flat)',
|
|
535
|
+
meshing: { normalsMode: 'flat' },
|
|
536
|
+
piece: {
|
|
537
|
+
// The shard look comes from planar cuts, not facet grooves — cuts leave
|
|
538
|
+
// dead-flat faces and sharp edges; heavy facet strength just shatters
|
|
539
|
+
// the box into rounded blobs.
|
|
540
|
+
cuts: {
|
|
541
|
+
bevel: 0.015, count: 7, depth: 0.4, enabled: true, verticalBias: 0.45,
|
|
542
|
+
},
|
|
543
|
+
falloff: { bottomFlatten: 0.4 },
|
|
544
|
+
name: 'Shard Monolith',
|
|
545
|
+
noise: { amplitude: 0.025, frequency: 1.8, octaves: 3 },
|
|
546
|
+
shape: {
|
|
547
|
+
cornerRadius: 0.04, sizeX: 0.7, sizeY: 2.0, sizeZ: 0.55, type: 'box',
|
|
548
|
+
},
|
|
549
|
+
warp: { frequency: 0.45, strength: 0.05 },
|
|
550
|
+
},
|
|
551
|
+
surface: {
|
|
552
|
+
baseColor: [0.5, 0.54, 0.6],
|
|
553
|
+
cavityColor: [0.26, 0.28, 0.34],
|
|
554
|
+
colorNoise: 0.03,
|
|
555
|
+
topColor: [0.72, 0.77, 0.82],
|
|
556
|
+
topHeightStart: 0.55,
|
|
557
|
+
topSlopeStart: 0.55,
|
|
558
|
+
},
|
|
559
|
+
});
|