Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit95280a384c

README.md

pbr_gen (service)

PBR material generation. Each run lands a .material whose base colour, normal, roughness and metalness maps are stored inside it and bound to the pbr shader, ready to put on a surface.

local pbr = asset.resolve("pbr_gen", "service")
pbr:operations()   -- the operations below, with their inputs and credit cost

Operations

OperationInputWhat it makes
generate (default)prompt, seamless?A tiling material from a written description.
from_imageimage or image_urlThe maps of an image you already have, one set for the picture as it stands. Costs 3 credits.
from_image_seamlessprompt, and image or image_urlA tiling material built from an image. prompt names the surface to take from it. Costs 8 credits.

image is a VFS path to a .texture asset (an image_gen result, for example) or an image file; image_url is a public URL.

Maps

from_image and from_image_seamless return five maps: base colour, normal, roughness, metalness and height. Roughness and metalness are gathered into one surface raster at the glTF layout (green roughness, blue metallic) that fills both slots reading it. height is written into the material's folder beside the other maps; the pbr shader has no height slot, so the finished run lists it among its unboundMaps.

from_image reads the maps off the image, so they line up with it pixel for pixel. from_image_seamless re-synthesises the surface so that it tiles, so its result resembles the image's surface without matching it pixel for pixel.

Usage

-- Watch a run until it settles; a completed row's `asset` is the finished asset.
local function settle(id: string): any
    local row = tools.use("services", "status", { id = id })
    while row ~= nil and row.status ~= "completed" and row.status ~= "failed" do
        task.wait(1)
        row = tools.use("services", "status", { id = id })
    end
    return row
end

-- An image, then the maps that make it light correctly.
local image = asset.resolve("image_gen", "service")
local made = image:invoke({
    prompt = "seamless top-down mossy cobblestone pavement, flat even lighting, no shadows",
})
local picture = settle(made.id)

local pbr = asset.resolve("pbr_gen", "service")
print(pbr:cost(), pbr:balance())          -- budget before spending
local run = pbr:invoke({ operation = "from_image", image = picture.asset })
local row = settle(run.id)
print(row.status, row.asset)              -- row.asset is the .material

Metering (no secret in this code)

API calls go through the origozero/pbr_gen offering: ZeroMind resolves each logical endpoint (generate, from_image, from_image_seamless, poll, result) to its provider target, injects the provider's secret server-side, debits the caller's credits and forwards. The provider URL and the secret never appear in this module. Check credits with pbr:balance().