主题
Project Custom Terrain Textures
Use the Editor's project texture generator and the existing discrete-terrain asset contract. Do not ask users to decode or copy TNND-wrapped files from the Editor Update directory, and do not invent a runtime registration API, shader format, or client capability version for ordinary project textures.
Read the complete custom terrain texture guide before creating or changing project assets.
Preferred workflow
For a user-provided color image:
- Open the target discrete-terrain scene.
- Select an existing surface texture as the fallback for missing normal/mix channels.
- Keep an engine-ready
*_mixor standard-suffix normal/roughness/metallic files beside the color image when overriding template channels. Choose UV旋转 and normal-green handling. - Use 添加项目纹理 and select the color image.
- Wait for the Editor to generate the project source Material, full catalog override, 96-layer arrays, and nine final terrain Materials.
- Select 项目自定义地表, paint a small area, then verify Undo/Redo, save/reload, and runtime rendering.
The selected existing surface is a template only. The Editor extracts its layer from the published combined MixColor array and Material buffers, writes a project-owned *_mix.png, and generates a source Material with the new diffuse plus the restored TileScale and ColorRoughnessFactor. Do not assume the downloaded standalone Material exists.
UV rotation is the final absolute angle; never add the template material's hidden rotation. It must transform both BaseColor and packed normal/mix. For MCP import, pass uv_rotation_degrees as 0, 90, 180, or 270; it defaults to 90 and is included in the Preview hash.
Import priority is explicit packed mix, auto-discovered *_mix, individual component maps, then template fallback. Packed mix is used without channel repacking or green flipping. Auto-discovery recognizes _normal/_norm/_n, _roughness/_rough, and _metallic/_metal; it strips _basecolor/_albedo/_diffuse from the color stem. Never infer _m. Multiple candidates for one role require an explicit path.
Use 生成/更新资源 after manually changing an existing project TextureStyle or source Material. This rebuilds the arrays and final Materials but does not add a new slot. The button appears only after the first project texture has been added; the built-in 82-layer catalog has no project outputs to rebuild.
To remove a selected project texture, use 删除选中纹理 in the Editor surface panel only after warning the user that the action has no Undo and reusing the slot can change old maps that still reference it. Deletion hides the texture and frees its slot immediately; the next import replaces that slot without moving the remaining textures. Do not promise preservation of scenes that used the removed texture. The MCP import/generate tools do not provide deletion.
For a manual source Material edit, TileScale is (scaleX, scaleY, turns, 0): 0.25 is +90 degrees, -0.25 is -90 degrees, and 0.5 is 180 degrees. Rebuild after changing it so all final Material buffers receive the new transform.
For MCP automation, use the same Preview/Apply boundary. Review the returned surface_inputs; file hashes, discovery results, green handling, and UV rotation are part of the one-use Preview:
text
terrain_list_surface_styles
-> terrain_list_surface_textures
-> terrain_preview_project_surface_import
-> terrain_apply_project_surface_import
-> terrain_project_surface_waitFor an existing complete project catalog, use terrain_preview_project_surface_generate followed by terrain_apply_project_surface_generate. Before the first import, generate Preview must return terrain_project_surface_not_configured; use the import workflow instead. Never skip Preview, reuse a consumed token, expose internal Material paths, or treat a queued operation as completion. Import Apply revalidates the project, image SHA256, template IDs, UV rotation, catalog slots, and terrain document revision.
Required contract
- Scope the work to discrete tile terrain; Landscape uses a different pipeline.
- Treat generated project
res/tiles/tile_config/config_v1.jsonas a complete override. Let the Editor construct its built-in prefix through ResourceCache; downloaded config and Material files may be TNND-wrapped. - Preserve the existing
Dota2prefix exactly and append project styles only. - Set project entries to
SurfaceOnly: trueand reuse an existing TileSetName. - Keep at most 16 styles and 16 dense
Itemsslots per style. Slot 0 remains the hidden cliff placeholder. - Keep the published catalog at exactly 96 Material layers. Fill unused project slots with valid hidden entries using
DisableDisplay: true. - Never reorder existing styles or slots. The Editor's explicitly confirmed delete action is a destructive exception: it permits reusing a project texture slot without checking whether existing scenes reference it. Explain the risk and recommend backing up the project.
- Keep TextureStyle item order, source Materials, both texture-array XML inputs, combined arrays, and all nine terrain Materials in the same
Dota2 -> Itemsorder. - Treat project
*_mix.pngas linear RGBA data: R=normal X, G=normal Y, B=roughness, A=metallic; normal Z is reconstructed. Preserve alpha, do not apply sRGB conversion, and never substitute an ordinary RGB normal map. - Require the platform's 96-layer shader overlay before treating blue terrain as a Material/configuration bug.
Advanced review workflow
- Confirm the scene uses discrete tile terrain.
- Inspect the complete project override and all referenced TextureStyle JSON files.
- Inspect every source Material and its
diffuseandnormalresources. - Count the two
<textureArray inputs="...">lists and verify their layer order. - Verify all nine
*_Terrain.materialfiles useNumMaterials=96and matching Buffer order. - Confirm
editor/terrain/.surface_resource_stage_*does not remain after a successful generation. If it remains after failure, preserve it for diagnosis until the old formal files are confirmed intact. - Reopen the project, then verify list visibility, paint, Undo/Redo, save/reload, and runtime rendering.
- For a compatibility claim, test the oldest supported real client on each required platform twice: first with an existing project to detect overlay regressions, then with a scene containing project textures to verify the new layer and project-resource path. Current Editor success alone is insufficient.
When diagnosing a project-switch issue, first confirm the list follows the current project: a project with one custom style should show one more entry than the same Editor session's project without it. A custom style from the previous project must not remain selectable.
Boundaries
The importer directly accepts packed mix or composes discovered/explicit normal, roughness, and metallic over the selected template. Missing component channels stay from the template. The Editor has a separate destructive delete action for project texture slots; it does not compact slots, hot-reload arbitrary file edits, or add custom cliffs, roads, and decorations.
For a manual neutral mix texture, use approximately RGBA (128,128,255,0) for flat normal, full roughness, and non-metal. Normal sources may require a green-channel flip; do not guess or silently flip it.
Built-in mixed styles are public surface choices. Show only their first three paint slots; the fourth entry is an internal extend texture. Preserve texture_group.json order because its 1-based index is encoded in terrain weights.
Changing the 16x16 encoding, blend channel count, vertex encoding, shader inputs, or runtime array construction requires a new client capability and is outside this workflow.