Examples · AR/VR & Game Developer
Icons and textures for your game
A set of inventory icons in one style, with a transparent background, ready for Unity. Then a stone texture that repeats, and how to find its seams.
Intermediate · 45 min
The idea
Placeholder art for a prototype, or ideas to show an artist. One sentence of style, shared by every icon, makes them look like a set.
What you need
A key and the openai library, as in Your first API call in Python, and Pillow, the Python library for pictures:
pip install pillow
The icons
Save it as icons.py:
import base64
import io
import os
from pathlib import Path
from openai import OpenAI
from PIL import Image, ImageDraw
client = OpenAI(
base_url="https://api.ai.itsincom.org/v1",
api_key=os.environ["API_KEY"],
)
STYLE = ("flat vector game art, thick dark outline, bright colours, "
"a single object in the centre, isolated on a plain white background")
ITEMS = {
"sword": "one short iron sword pointing up, with a leather grip",
"shield": "a round wooden shield with an iron rim",
"potion": "a round glass bottle of red potion with a cork",
"coins": "a small leather bag full of gold coins",
}
out = Path("icons")
out.mkdir(exist_ok=True)
for name, item in ITEMS.items():
result = client.images.generate(model="z-image-turbo", prompt=f"{item}, {STYLE}", extra_body={"seed": 7})
icon = Image.open(io.BytesIO(base64.b64decode(result.data[0].b64_json))).convert("RGBA")
icon = icon.resize((256, 256), Image.LANCZOS)
# The white around the object becomes transparent: fill it from the four corners
for corner in [(0, 0), (255, 0), (0, 255), (255, 255)]:
ImageDraw.floodfill(icon, corner, (255, 255, 255, 0), thresh=60)
icon.save(out / f"{name}.png")
print(out / f"{name}.png")
Run it with python3 icons.py: four icons take less than a minute.
What you should see
Four files in the icons folder, 256 by 256 pixels: a sword, a shield, a red potion and a bag of gold coins, all with the same thick outline and the same colours, on a transparent background. Run the program again and you get the same four: the seed fixes them. Change the seed for another set.
A texture that repeats
A floor or a wall is one small picture repeated many times, so its right edge must continue into its left edge, and its top into its bottom. Save it as texture.py:
import base64
import io
import os
from openai import OpenAI
from PIL import Image
client = OpenAI(
base_url="https://api.ai.itsincom.org/v1",
api_key=os.environ["API_KEY"],
)
result = client.images.generate(
model="z-image-turbo",
prompt="seamless tileable texture of grey cobblestones, seen from straight above, flat even lighting",
)
tile = Image.open(io.BytesIO(base64.b64decode(result.data[0].b64_json)))
tile.save("cobblestones.png")
# Four copies, two by two: where the texture does not repeat well, a line crosses the middle
check = Image.new("RGB", (tile.width * 2, tile.height * 2))
for x in (0, tile.width):
for y in (0, tile.height):
check.paste(tile, (x, y))
check.save("cobblestones-2x2.png")
print("Look at the middle of cobblestones-2x2.png")
Run it with python3 texture.py, then open cobblestones-2x2.png and look at the middle, where the four copies meet.
Cobblestones hide a seam well: when we tried it, from a distance the four copies looked like one floor. Up close, though, the row of stones on the line between the copies was cut in half: that is a seam. On a floor far from the camera nobody sees it; close to the camera everyone does. Wooden planks are harder: in our tests the boards did not continue across the edge, and the seam was plain to see.
To fix a seam, try another description, or smooth the edges in an image editor: GIMP has Filters → Map → Tile Seamless.
In Unity
- Icons: put the PNGs in
Assets, select them and, in the Inspector, set Texture Type to Sprite (2D and UI), then Apply. Drag a sprite into the Source Image of a UI Image: the background stays transparent. - Texture: put
cobblestones.pnginAssets, create a Material, drag the texture into its Base Map (Albedo in the Built-in render pipeline) and raise the Tiling, for example to 4 and 4. Put the material on a plane, then move the camera close to the floor and look for the seam.
Good to know
- No transparent pictures from the API: OpenAI's
backgroundfield is refused. Ask for a plain white background and remove it afterwards, asicons.pydoes. - Closed white areas stay white. The fill starts from the corners, so it cannot reach a white area closed in by the outline: when we made a key, the hole in it stayed white. Fill it in an image editor, or add a point inside the hole to the list of corners.
- One style, one set: keep the
STYLEsentence and theseed, and change only the object. Write “one sword”: with “a sword” we once got two, crossed. - Avoid the word “icon” in the description: with it, we got an app-style frame around the object.
- What is not drawn: famous characters and brands, real people, nudity, blood and hate. Fantasy objects, monsters and stylised fights are fine.
- The AI mark: every PNG from the API says in its metadata that it was made by AI, but Pillow does not copy the metadata when it saves. Say in your game's credits that the icons and textures were generated with AI.
Exercise
- Add five more items to
ITEMS: a bow, an apple, a scroll, a torch, a gem. Do they look like the same set? - Change only
STYLE: “pixel art, 16-bit”, or “hand-painted, soft shading”. Which suits your game? - Make the floor of your level: grass, sand, or wooden planks. Check each one with the 2×2 test.
- Make a key with a hole, and add a point inside the hole to the list of corners so that it becomes transparent.
- Concept art for a level: a landscape picture (
size="1536x1024") of the place, to show your team before anyone builds it.
