Files
2026-05-15 01:09:14 -07:00

461 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Tileset Generator — Design Document
1. Overview
Tileset Generator is a simple browser-based image tool that lets a user upload an image and convert it into a tileable texture. The tool hides obvious seams by offsetting the image, blending or healing the exposed center seams, and exporting the result as a resized .webp texture suitable for games, web backgrounds, 3D materials, and UI art.
The tool should run fully client-side in the browser. No server upload is required.
2. Core User Flow
User opens the Tileset Generator page.
User uploads or drags in an image.
The app displays:
Original preview
Tileable preview
Repeated texture preview
The app shifts the image by 50% horizontally and vertically.
The app hides the newly exposed seams using a selected seam-repair method.
User adjusts settings:
Output size
Seam blend width
Repair strength
Export quality
Crop or fit behavior
User exports the result as a .webp file.
3. Primary Features
Image Upload
Supported formats:
.png
.jpg
.jpeg
.webp
Input methods:
File picker
Drag and drop
Optional paste from clipboard
The image should be processed locally using browser APIs.
Seam Offset
The standard tile-generation operation is a 50% offset:
Original image:
[A B]
[C D]
After 50% offset:
[D C]
[B A]
This moves the original outer edges into the center of the image, making seams visible and easier to hide.
User-facing option:
Offset Mode:
- Auto 50% offset
- Horizontal only
- Vertical only
- Custom offset
For V1, Auto 50% offset is enough.
Seam Hiding
The exposed seam appears as a vertical and horizontal cross through the center of the offset image.
V1 should use a simple but effective blend-based repair approach.
V1 Seam Repair Method
Use a soft blur/blend region around the center seams:
Define a seam band around the vertical center.
Define a seam band around the horizontal center.
Sample pixels from both sides of the seam.
Blend across the seam using a smooth falloff.
Optionally add subtle noise preservation to avoid overly blurry lines.
User controls:
Seam Width: 8128 px
Blend Strength: 0100%
Detail Preservation: Low / Medium / High
Default:
Seam Width: 32 px
Blend Strength: 70%
Detail Preservation: Medium
Repeated Preview
The app should show the generated texture repeated in a grid so the user can visually inspect tiling quality.
Preview modes:
Single Tile
2x2 Repeat
3x3 Repeat
4x4 Repeat
Default:
3x3 Repeat
This is critical because a texture can look good alone but fail when repeated.
Resize and Export
The user can export the final image as .webp.
Output size options:
Original Size
512 x 512
1024 x 1024
2048 x 2048
Custom Width / Height
Resize behavior:
Crop to Square
Fit Within Size
Stretch to Size
Keep Aspect Ratio
Default:
1024 x 1024
Crop to Square
WebP Quality: 90
Export filename pattern:
tileset-generator-[width]x[height].webp
Example:
tileset-generator-1024x1024.webp
4. Interface Layout
Suggested Layout
+------------------------------------------------------+
| Tileset Generator |
| Upload image → Generate tileable WebP texture |
+------------------------------------------------------+
+----------------------+-------------------------------+
| Controls | Preview |
| | |
| Upload Image | [ Single / Repeated Preview ] |
| Output Size | |
| Seam Width | |
| Blend Strength | |
| Export Quality | |
| | |
| [Generate] [Export] | |
+----------------------+-------------------------------+
Control Panel
Controls should appear in this order:
Upload image
Output size
Resize behavior
Seam width
Blend strength
Preview repeat count
WebP quality
Export button
5. Recommended Tech Stack
For a lightweight browser tool:
Vite + React + TypeScript
Canvas 2D API
browser-image-compression optional
FileSaver optional
Recommended stack:
React for UI
TypeScript for safer image-processing code
Canvas 2D API for pixel manipulation
OffscreenCanvas / Web Worker optional for larger images
WebP export via canvas.toBlob()
No backend required.
6. Image Processing Pipeline
Step 1 — Load Image
File → Object URL → ImageBitmap → Canvas
Use createImageBitmap() when available.
Step 2 — Normalize Image
Depending on the selected resize behavior:
Crop to square
Fit within output bounds
Stretch
Preserve aspect ratio
For texture generation, square textures are strongly preferred.
Recommended internal working size:
1024 x 1024 by default
Step 3 — Offset Image
Draw the source image into a new canvas in four wrapped quadrants.
Pseudo-code:
function offsetCanvas(source, offsetX, offsetY) {
draw source shifted by offsetX / offsetY
wrap overflowing regions to opposite edges
}
For 50% offset:
offsetX = width / 2
offsetY = height / 2
Step 4 — Repair Seam
Repair the vertical seam centered at:
x = width / 2
Repair the horizontal seam centered at:
y = height / 2
For each pixel inside the seam band:
distanceFromSeam = abs(pixelPosition - seamCenter)
blendAmount = 1 - smoothstep(0, seamWidth, distanceFromSeam)
Blend nearby pixels from both sides of the seam.
A simple practical V1 approach:
For each seam pixel:
- Sample left/right or top/bottom neighbor pixels
- Average them based on distance from seam center
- Mix the averaged color with the original pixel
This gives a soft seam-hiding effect without needing AI/inpainting.
Step 5 — Preview Repetition
Create a preview canvas or CSS background using the generated image.
For repeated preview:
background-image: url(generated-texture.webp);
background-repeat: repeat;
background-size: tileSize tileSize;
Canvas-based repeated preview is also fine.
Step 6 — Export WebP
Use:
canvas.toBlob(
blob => saveBlob(blob, filename),
"image/webp",
quality
);
Where quality is:
quality = userQuality / 100;
7. V1 Scope
Include in V1
Local image upload
Canvas-based 50% offset
Basic seam blending
Output resize options
Repeated texture preview
WebP export
Quality slider
Drag-and-drop support
Exclude from V1
AI inpainting
Multi-texture PBR export
Normal map generation
Roughness/metalness map generation
Batch processing
Account system
Server-side processing
8. Nice-to-Have Features
Good V2 additions:
Brush-based manual seam repair
Clone-stamp tool
Random patch sampling
Content-aware seam healing
Generate normal map
Generate roughness map
Batch export
Presets:
Pixel art
Stone
Fabric
Terrain
Sci-fi panel
Organic texture
Export as:
.webp
.png
.jpg
Save/load project settings
Before/after comparison slider
9. Data Model
type ResizeMode =
| "crop-square"
| "fit"
| "stretch"
| "keep-aspect";
type PreviewMode =
| "single"
| "repeat-2"
| "repeat-3"
| "repeat-4";
type TilesetSettings = {
outputWidth: number;
outputHeight: number;
resizeMode: ResizeMode;
seamWidth: number;
blendStrength: number;
detailPreservation: "low" | "medium" | "high";
webpQuality: number;
previewMode: PreviewMode;
};
Default settings:
const defaultSettings: TilesetSettings = {
outputWidth: 1024,
outputHeight: 1024,
resizeMode: "crop-square",
seamWidth: 32,
blendStrength: 70,
detailPreservation: "medium",
webpQuality: 90,
previewMode: "repeat-3",
};
10. Main Components
App
├── UploadPanel
├── SettingsPanel
├── PreviewPanel
│ ├── OriginalPreview
│ ├── TilePreview
│ └── RepeatedPreview
├── ExportPanel
└── ProcessingWorker optional
11. Performance Considerations
For V1, Canvas 2D is enough.
Recommended limits:
Max input image size: 4096 x 4096
Default working size: 1024 x 1024
Warning above: 2048 x 2048
For large files:
Downscale before seam repair.
Use createImageBitmap() for efficient decoding.
Consider Web Worker processing later.
Avoid repeatedly processing on every slider movement.
Debounce setting changes by 150300 ms.
12. Error Handling
Show user-friendly errors for:
Unsupported file type
Image failed to load
Image too large
Browser does not support WebP export
Canvas export failed
Example messages:
This file type is not supported. Please upload a PNG, JPG, or WebP image.
This image is very large. The tool will resize it before processing.
13. Export Behavior
Export button should be disabled until:
An image is uploaded
Processing is complete
A valid output size exists
Export metadata:
Format: WebP
Quality: user-selected
Dimensions: user-selected
Color space: browser default / sRGB
Transparency: preserve if source supports alpha
14. Practical V1 Algorithm
1. Load uploaded image.
2. Resize/crop to target working canvas.
3. Offset image by 50% width and 50% height.
4. Blend center vertical seam.
5. Blend center horizontal seam.
6. Display single and repeated previews.
7. Export final canvas as WebP.
Pseudo-code:
async function generateTileableTexture(file: File, settings: TilesetSettings) {
const bitmap = await createImageBitmap(file);
const normalizedCanvas = normalizeImage(bitmap, settings);
const offsetCanvas = applyWrappedOffset(
normalizedCanvas,
settings.outputWidth / 2,
settings.outputHeight / 2
);
const repairedCanvas = repairCenterSeams(offsetCanvas, {
seamWidth: settings.seamWidth,
blendStrength: settings.blendStrength,
detailPreservation: settings.detailPreservation,
});
return repairedCanvas;
}
15. Success Criteria
The tool is successful when:
A user can upload an image and export a tileable .webp in under a minute.
The exported texture repeats without obvious hard seams.
The UI is understandable without instructions.
The tool runs fully in-browser.
The output is usable in game engines, websites, and 3D material workflows.
16. Suggested MVP Build Order
Build image upload and preview.
Add canvas normalization/resizing.
Implement 50% wrapped offset.
Add basic vertical/horizontal seam blend.
Add repeated preview.
Add WebP export.
Add settings controls.
Add drag-and-drop polish.
Add error handling.
Test with photos, fabric, stone, clouds, sci-fi panels, and terrain textures.