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

10 KiB
Raw Permalink Blame History

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.

  1. 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.
  2. 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.

  1. 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.