fal-ai/patina/material

Generate complete seamlessly tiling PBR materials including normal, roughness, basecolor, height and metalness maps up to 8K
Inference
Commercial use

Input

Additional Settings

Customize your input with more control.

Result

Idle

What would you like to do next?

Your request will cost $0.01 plus $0.02 per megapixel plus $0.01 per megapixel per map type. When using 2x upscaling, an additional $0.004 per (pre-upscaling) megapixel per map will be charged, and when using 4x upscaling, an additional $0.016 per (pre-upscaling) megapixel per map will be charged. For example, A 1024x1024 material with all 5 maps and no upscaling (1K) will cost $0.08, and a 2048x2048 material with all 5 maps and 4x upscaling (8K) will cost $0.61.

Logs

PATINA Material - Text to PBR Material

Endpoint: fal-ai/patina/material

Category: Text-to-image (also supports image-to-image)

Pricing: $0.01 base + $0.02 per megapixel + $0.01 per megapixel per map. Upscaling adds $0.004 (2x) or $0.016 (4x) per megapixel per map.

Generate complete, seamlessly tiling PBR materials from text prompts - up to 8K resolution with built-in upscaling. Also supports image-to-image for creating variations of existing textures.


When to use this

Use this endpoint to generate new PBR materials from scratch using a text description, or to create variations of an existing texture via image-to-image.

Good for:

  • Creating new materials from a text prompt ("weathered copper patina", "rough hewn limestone")
  • Generating seamlessly tiling textures at up to 2048px (8K with upscaling)
  • Creating variations on an existing texture using image_url (pure image-to-image, not an edit)
  • Inpainting regions of a texture using image_url + mask_image_url

Use a different endpoint if:

  • You already have a finished texture and just want PBR maps from it - use /patina
  • You have a photo of a scene and want to extract a specific material from it - use /patina/material/extract

Quick start

Text to material
javascript
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/patina/material", {
  input: {
    prompt: "weathered copper patina with verdigris"
  }
});

// result.data.images - generated texture + PBR maps
Image-to-image (create variations)
javascript
const result = await fal.subscribe("fal-ai/patina/material", {
  input: {
    prompt: "mossy stone wall",
    image_url: "https://example.com/stone-texture.jpg",
    strength: 0.75
  }
});

Input

ParameterTypeRequiredDefaultDescription
promptstringYes-Text description of the material to generate
image_sizestring or objectNosquare_hdA named size, or an object like {"width": 1024, "height": 2048}
num_inference_stepsintegerNo8Number of denoising steps (1-8)
seedintegerNoRandomSeed for reproducible generation
num_imagesintegerNo1Number of texture images to generate (1-4)
enable_prompt_expansionbooleanNotrueExpand prompt with an LLM for richer detail. Adds ~$0.0025.
enable_safety_checkerbooleanNotrueEnable safety filtering on outputs
tiling_modestringNo"both"Tiling direction: both, horizontal, or vertical
tile_sizeintegerNo128Tile size in latent space (64 = 512px, 128 = 1024px). Range: 32-256
tile_strideintegerNo64Tile stride in latent space. Range: 16-128
image_urlstringNo-Input image URL for image-to-image. Without mask_image_url, creates variations. With it, performs inpainting.
mask_urlstringNo-Mask image for inpainting. White regions are regenerated, black regions are preserved. Requires image_url.
strengthfloatNo0.75How much to transform the input image. Only used with image_url.
mapsstring[]NoAll fiveWhich PBR maps to predict: basecolor, normal, roughness, metalness, height. Deselect all to skip PBR estimation.
upscale_factorintegerNo0Upscale via SeedVR seamless: 0 (none), 2 (2x), or 4 (4x)
output_formatstringNo"png"Output format: jpeg, png, or webp
Example request (text only)
json
{
  "prompt": "mossy stone wall",
  "image_size": "square_hd",
  "maps": ["basecolor", "normal", "roughness", "metalness", "height"]
}
Example request (image-to-image)
json
{
  "prompt": "mossy stone wall",
  "image_url": "https://example.com/stone-texture.jpg",
  "strength": 0.75,
  "maps": ["basecolor", "normal", "roughness", "metalness", "height"]
}

Output

FieldTypeDescription
images(ImageFile | MapImageFile)[]The generated texture (no map_type) followed by PBR maps (each with map_type).
seedintegerSeed used for generation
promptstringThe prompt used (may differ from input if prompt expansion was enabled)
timingsobjectTiming breakdown in seconds
Example response
json
{
  "images": [
    { "url": "https://fal.media/files/..." },
    { "url": "https://fal.media/files/...", "map_type": "basecolor" },
    { "url": "https://fal.media/files/...", "map_type": "height" },
    { "url": "https://fal.media/files/...", "map_type": "normal" },
    { "url": "https://fal.media/files/...", "map_type": "roughness" },
    { "url": "https://fal.media/files/...", "map_type": "metalness" }
  ],
  "seed": 42,
  "prompt": "mossy stone wall"
}

The first image (without map_type) is the generated texture itself. The rest are the PBR maps.


Output maps explained

MapWhat it represents
Base ColorThe surface color (albedo). What the material looks like without lighting effects.
NormalPer-pixel surface orientation. Adds fine detail and bumps without changing geometry.
RoughnessHow rough or smooth each point is. Controls reflection sharpness.
MetalnessWhether each point is metallic or dielectric. Affects how light reflects and refracts.
HeightElevation data. Can be used for parallax mapping or actual mesh displacement.

Code examples

JavaScript
javascript
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/patina/material", {
  input: {
    prompt: "mossy stone wall"
  },
  logs: true,
  onQueueUpdate: (update) => {
    if (update.status === "IN_PROGRESS") {
      update.logs.map((log) => log.message).forEach(console.log);
    }
  },
});
console.log(result.data);
Python
python
import fal_client

result = fal_client.subscribe(
    "fal-ai/patina/material",
    arguments={
        "prompt": "mossy stone wall"
    },
    with_logs=True,
)
print(result)
cURL
bash
curl -X POST https://fal.run/fal-ai/patina/material \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "mossy stone wall"}'