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: 8–128 px
Blend Strength: 0–100%
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 150–300 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.