CommunityImagegithub.com

threejs-procedural-textures

Procedurally generate photorealistic material maps in three.js without using any image files – including seamless noise, millimeter-scale height-to-normal maps, roughness & AO packing, Canvas2D-to-texture conversion, and average albedo (for light baking).

What is threejs-procedural-textures?

This skill provides a comprehensive library for generating physically plausible material maps at runtime in three.js, entirely procedurally. It is ideal for developers who want to avoid external texture downloads, ensure deterministic results, and create surfaces that respond realistically to lighting. The library includes a wide range of materials: painted chip wallpaper with large-scale plaster and paint variation, lacquer orange peel, smudged roughness, dust accumulation, oak flooring (with staggered joints, per-plank variation, knots, and micro-bevels), generic wood grain, matched oak veneer, woven fabrics (plain weave, waffle, terry, rib, knit, felt, rope), and wear-and-tear maps (dust, grease, fingerprints, crumbs, lint, hair, cup rings, fine scratches – all baked into both color and roughness). It also supports specialized features like speckled glaze, powder-coated scratch textures, book cover atlases with corresponding geometry, book edge textures, topographic posters, photographs, and fake text. The skill handles common user requests such as "procedural texture", "normal map generation", "wood floor / wood grain texture", "fabric materials", "wear and tear marks", "roughness map", and "seamless tiling". It works with three.js and can be adapted for Godot and Unreal Engine, as documented in the references.

Works with✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/ammosu/claude-threejs-photoreal/tree/HEAD/skills/threejs-procedural-textures

Installed? Explore more Image skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

Procedural Material Textures

Source: room-at-dawn (MIT), from src/core/tex.js, rng.js, src/scene/materials.js, and the material functions under parts/. The original project's bedroom does not use a single image file; all textures are generated procedurally at load time.

Core ideas:

  1. Design in physical units. Heights are in millimeters; each tile is clearly defined in meters, and UVs are also in meters. This way repeat = 1 / tileMeters, and changing resolution does not alter the appearance.
  2. Most realism comes from roughness, not color. Fingerprints, wipe marks, and dust are nearly invisible in the color channel; they only show up when highlights scan across the surface.
  3. All textures are seamless and reproducible. Noise functions have integer periods; randomness always uses RNG(seed) so the same seed always produces identical results (essential for light baking and screenshot regression testing).

Files

PathContents
scripts/tex.jsFoundations: RNG, pnoise/pfbm (independent period per axis), worley, vn (lookup-table fast noise), field, normalBytes (in millimeters), dataTex/canvasTex/packTex/colorTex, avgColor, once (caching), rep (share images, only change repeat), seamScore, texData
scripts/surfaces.jswallNormal + wallPatch (chip wallpaper with 3.2m-scale plaster & paint variation), lacquerNormal, smudgeRough, dustRough, floorMaps, woodMaps, oakVeneer
scripts/textiles.jsweaveNormal, waffleNormal, terryNormal, ribNormal, knitNormal, feltNormal, ropeNormal, fabricMaterial (sheen with backlight translucency)
scripts/wear.jswornMaps (a whole used surface: both color and roughness), speckleTexture, scuffTexture, and basic brushes softBlob, strand, fingerprint, noiseTile, overlay
scripts/print.jsword/phrase (fake words from syllables), PAL, packer, fitText, paperGrain, makeBook + bookAtlas + bookGeometry, pagesTexture, topoPoster, photoPrints
example/A room corner, each surface uses a material from the library. ?cam= (room, desk, glint, fabric, floor, wall, books); ?flat=1 switches to solid colors for comparison
example/preview.jpgExample screenshot
references/recipes.mdRecipes for each material: dimensions, parameters, and how to add new ones
references/verify-engines.mdVerification methods, known issues, performance, and porting to Godot/Unreal

Running the Example

cd <skill folder> && python3 -m http.server 5422 --bind 127.0.0.1
# Open http://127.0.0.1:5422/example/   (window.__tex shows generation time, seam score, and average albedo for each texture)

(<skill folder> is the Base directory shown when loading this skill; when installed as a plugin, it is located under ~/.claude/plugins/cache/)

Usage

import { rep } from './scripts/tex.js';
import { floorMaps, wallNormal, wallPatch, lacquerNormal } from './scripts/surfaces.js';
import { knitNormal, fabricMaterial } from './scripts/textiles.js';
import { wornMaps } from './scripts/wear.js';

const fl = floorMaps();                                   // UV in meters; repeat is already set
floor.material = new THREE.MeshStandardMaterial({ map: fl.map, normalMap: fl.normalMap, roughnessMap: fl.roughnessMap, roughness: 1 });
wall.material = wallPatch(new THREE.MeshStandardMaterial({ color: 0xebebe6, roughness: 0.93, normalMap: wallNormal() }));
door.material = new THREE.MeshStandardMaterial({ color: 0xdddddd, roughness: 0.6, normalMap: rep(lacquerNormal(), 9), normalScale: new THREE.Vector2(0.18, 0.18) });
sweater.material = fabricMaterial(0x6f7f6a, { normal: knitNormal(), tileM: 0.1 });
const w = wornMaps({ sizeM: [1.2, 0.6], hands: [[0.55, 0.5]], rings: [[0.9, 0.4, 0.032, 0.6]], prints: 6 });
deskTop.material = new THREE.MeshStandardMaterial({ map: w.map, roughnessMap: w.roughnessMap, roughness: 1 });
  • For materials that have a roughnessMap, set roughness to 1. three.js multiplies the two together.
  • packTex and wornMaps store roughness in the G channel; grayscale canvases can also be used directly.
  • Every material function returns avg (the linear average color) for use as the albedo in threejs-baked-gi.

Must Follow

  1. Do not use Math.random(). Every texture must have a fixed seed.
  2. Noise periods must be integers and aligned with the tile grid (e.g., pfbm(u*6, v*6, oct, seed, 6)). Misalignment causes seams. Use seamScore to check.
  3. Heights are in millimeters; use normalBytes(H, w, h, mmPerTile). Changing resolution does not change the bump strength; some textures have non-square tiles (e.g., floor 1.1 × 1.9 mm), so supply the two axes separately.
  4. Draw roughness together with color. Each stroke in wornMaps is painted on both canvases using the same new RNG(i), so the shapes align.
  5. Dark surfaces should have fewer specks and highlights (e.g., the dark desktop reduces 9000 to 2500), otherwise they look like granite.
  6. All text and patterns drawn on canvases must be self-composed (word(), geometric shapes); do not use real book titles, brands, or trademarks.
  7. The largest textures (2048²) take 0.1–0.35 seconds to generate; cache them with once and share via rep(). Do not generate one per object.

Benchmarks (RTX 4090, Chrome headless, total scene 1.1s)

TextureSizeTimeSeam Score (x/y)
floorMaps2048² × 3 maps0.32 scolor 0.96 / 1.10, normal 1.00 / 1.02, roughness 0.89 / 1.05
woodMaps1024² × 30.20–0.23 scolor 0.93 / 1.12, normal 1.30 / 1.06
wornMaps (1.2 × 0.6 m, 3400 px/m)4080×2040 + half-size roughness0.13 snon-repeating
oakVeneer1024² × 30.10 s0.98–1.06
wallNormal1024²0.04 s1.00 / 1.07
lacquerNormal, smudgeRough512²0.02–0.04 s0.98–1.04
7 fabric types128²–512²1–19 ms0.94–1.10 (rope y is 2.03, intentional groove; see verify-engines.md)
bookAtlas (12 books)2048×15360.05–0.08 s—

A seam score close to 1 means seams are invisible; over 2 requires inspection. The calculation adds 1 color step to both numerator and denominator to avoid large ratios from sub-1-step noise in near-flat directions (e.g., grain-following wood).

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

threejs-photoreal-interior

用 three.js 從零做一個照片級的室內場景,完全用程式生成、不需要模型檔、貼圖或 HDRI 的總綱與起手式。內容包括:整體流程(尺寸與座標 → 外殼與窗 → 主角物件 → 材質 → 小物 → 烘焙光照 → 後製 → 驗證 → 電影輸出)、各步驟該用哪個 skill、跨 skill 整合的規則(決定性、細分、材質要經過 GI 補丁且保留原本的 shader 補丁、反照率、太陽直射與烘焙分工、陰影漏光)、一個指令就能建立可執行的新專案(房間、窗、木地板、牆面、桌椅、掛在椅背的毛巾、書架、杯子、水壺、現場烘焙、後製),以及驗收清單和實測數字。當使用者說「做一個寫實的房間/室內」「three.js 照片級場景」「程式生成整個場景」「不用模型做室內」「room-at-dawn 那種」「從哪裡開始做寫實 3D 場景」「開一個新的寫實場景專案」「把這些 skill 串起來」「寫實室內場景流程」時使用;做其中單一環節時,直接用對應的子 skill。

threejs-procedural-cloth

用程式「設計」出照片級的靜態布料(不做物理模擬):沒鋪好的棉被、毯子、桌巾、垂下床緣或桌緣的布、翻起一角的被子、布上放東西,以及掛在桿子上的窗簾(吊環夾出的折、往下鬆開與散開、綁起下擺、車線與雙層縫邊、亞麻平織)。方法是平面高度場(團塊+有方向的長折+削峰+逐條畫上的皺褶)→ 包到支撐物上 → 高的折往一側倒 → 翻角 → 依 3D 曲面攤平 UV → 細皺紋 normal map+凹處變暗,含可重用程式庫、分階段範例、驗證數據,以及搬到 Godot/Unreal 的做法。當使用者說「程式生成布料」「棉被/床單/毯子/桌巾建模」「布料皺褶」「布垂下床邊」「被子翻一角」「布料不要用模擬」「cloth without simulation」「procedural cloth」「布上的花紋被拉長」「布料看起來像塑膠/像山」「窗簾建模」「程式生成窗簾」「窗簾皺褶」「curtain」「布簾」時使用。

threejs-sky-backdrop

在 three.js 用程式做天空與窗外遠景,不需要 HDRI 或圖檔。天空的同一份參數同時用在三個地方:烘焙光照用的解析式天空、看得到的天空球(雲層、高空薄雲、地平線霧帶、太陽),以及不烘焙時用的太陽光、半球光與環境貼圖。內含四種預設(清晨、白天、陰天、黃昏)和一個量測工具,確認看到的天空和照亮場景的天空亮度一致。遠景部分包括:只建從室內窗戶看得到的東西(窗洞可見性與 LOD)、隨距離變淡的大氣霧化、遠處逐漸變粗的草地網格、碎石小路、樹籬、鄰居房子(陶瓦屋頂、窗戶、煙囪、天窗)、封住地平線的遠方樹牆,並可以搭配 threejs-procedural-vegetation 種樹。當使用者說「天空」「sky shader」「雲」「程式生成天空」「不用 HDRI」「窗外景色」「遠景」「背景房子」「地平線」「大氣透視」「霧化」「窗外的樹」「天空和光照對不上」「清晨/黃昏/陰天的天空」「只建看得到的東西」時使用。

Related Skills