@genex-ai/cli-demo 0.53.0-dev.118 → 0.53.0-dev.120

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genex-ai/cli-demo",
3
- "version": "0.53.0-dev.118",
3
+ "version": "0.53.0-dev.120",
4
4
  "description": "Set up your ~/.claude workspace, authorize, create a game project, generate AI assets, and publish (genex CLI).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -24,19 +24,24 @@ npx genex texture "<prompt>"
24
24
  npx genex texture "lush green grass" --terrain # seamless tiling for ground/terrain
25
25
  ```
26
26
 
27
- Blocks until ready, then prints its public URL:
27
+ Blocks until ready, then prints a URL per map it produced:
28
28
 
29
29
  ```
30
- https://assets.genex.technology/generations/<id>/texture-basecolor
30
+ basecolor: https://assets.genex.technology/generations/<id>/texture-basecolor
31
+ normal: https://assets.genex.technology/generations/<id>/texture-normal
32
+ roughness: https://assets.genex.technology/generations/<id>/texture-roughness
33
+ metalness: https://assets.genex.technology/generations/<id>/texture-metalness
31
34
  ```
32
35
 
33
- The image lives in Genex storage (R2) and loads straight from that URL — you don't
34
- download it and nothing is committed to your repo. The URL is permanent (local dev,
35
- published game, and remixes alike).
36
+ Each lives in Genex storage (R2) and loads straight from its URL — you don't
37
+ download anything and nothing is committed to your repo. The URLs are permanent
38
+ (local dev, published game, and remixes alike).
36
39
 
37
- > **Scope:** v1 generates the **base-color (albedo)** map only. Normal / roughness
38
- > / AO are a planned follow-up for now set sensible `roughness`/`metalness`
39
- > constants on the material.
40
+ > **Wire only the roles it actually printed.** Most deployments still run the
41
+ > base-color-only route and print `texture-basecolor` alone; the PBR maps above
42
+ > appear only where the platform is configured for them. A `normalMap` pointed at
43
+ > a URL that was never printed is a 404, not a bump — and a 404 inside a
44
+ > `Promise.all` costs you the whole material, base colour included.
40
45
 
41
46
  ## Apply it (tiling material)
42
47
 
@@ -47,21 +52,63 @@ judgement call.
47
52
  ```ts
48
53
  import * as THREE from "three";
49
54
 
50
- // the URL `npx genex texture` printed (R2 sends CORS headers, so cross-origin works):
51
- const TEXTURE_URL = "https://assets.genex.technology/generations/<id>/texture-basecolor";
52
- const map = await new THREE.TextureLoader().loadAsync(TEXTURE_URL);
53
- map.colorSpace = THREE.SRGBColorSpace;
54
- map.wrapS = map.wrapT = THREE.RepeatWrapping;
55
- map.anisotropy = renderer.capabilities.getMaxAnisotropy();
56
- // NOTE: no map.repeat here, on purpose — worldUV puts the scale in the UVs.
55
+ const BASE = "https://assets.genex.technology/generations/<id>"; // the id it printed
56
+ const load = async (role: string, srgb = false) => {
57
+ const t = await new THREE.TextureLoader().loadAsync(`${BASE}/${role}`);
58
+ // ONLY base color is colour data. A normal/roughness/metalness map holds
59
+ // NUMBERS decode them as sRGB and the lighting is quietly wrong everywhere.
60
+ t.colorSpace = srgb ? THREE.SRGBColorSpace : THREE.NoColorSpace;
61
+ t.wrapS = t.wrapT = THREE.RepeatWrapping;
62
+ t.anisotropy = renderer.capabilities.getMaxAnisotropy();
63
+ // NOTE: no t.repeat here, on purpose — worldUV puts the scale in the UVs.
64
+ return t;
65
+ };
66
+
67
+ // Load ONLY the roles the CLI printed. Asking for one it didn't print is a 404,
68
+ // and inside a Promise.all a single 404 rejects the whole thing — you get no
69
+ // material at all, not a base-colour one.
70
+ const map = await load("texture-basecolor", true);
57
71
 
58
72
  const TILE_M = 4; // one tile covers 4×4 metres — choose ONCE per material
59
73
  const geo = worldUV(new THREE.PlaneGeometry(200, 200), TILE_M);
60
- const ground = new THREE.Mesh(geo, new THREE.MeshStandardMaterial({ map, roughness: 0.9 }));
74
+ const ground = new THREE.Mesh(
75
+ geo,
76
+ new THREE.MeshStandardMaterial({ map, roughness: 0.9, metalness: 0 }),
77
+ );
61
78
  ground.rotation.x = -Math.PI / 2;
62
79
  scene.add(ground);
63
80
  ```
64
81
 
82
+ ### When it printed the PBR maps too
83
+
84
+ If the run also printed `texture-normal` / `texture-roughness` / `texture-metalness`,
85
+ load them and drop the hand-picked constants — the maps carry roughness and
86
+ metalness per texel, so rust reads matte and the rivets read metallic out of one
87
+ material:
88
+
89
+ ```ts
90
+ const [map, normalMap, roughnessMap, metalnessMap] = await Promise.all([
91
+ load("texture-basecolor", true),
92
+ load("texture-normal"),
93
+ load("texture-roughness"),
94
+ load("texture-metalness"),
95
+ ]);
96
+
97
+ const mat = new THREE.MeshStandardMaterial({
98
+ map,
99
+ normalMap,
100
+ roughnessMap,
101
+ metalnessMap,
102
+ // NOT optional. Three.js MULTIPLIES each map by its scalar
103
+ // (`metalnessFactor *= texelMetalness.b` in the shader), and metalness
104
+ // defaults to **0** — so a metalnessMap on a default material contributes
105
+ // exactly nothing and the rivets stay plastic. roughness defaults to 1, which
106
+ // is why roughnessMap appears to "just work" and metalnessMap silently doesn't.
107
+ metalness: 1,
108
+ roughness: 1,
109
+ });
110
+ ```
111
+
65
112
  Same two lines for a wall, a kerb, a platform, a crate — any shape, any size:
66
113
 
67
114
  ```ts