@aethervtt/shard-texture 0.0.1 → 0.2.0

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.
@@ -0,0 +1,9 @@
1
+ import type { Image } from './image.js';
2
+ import { Texture } from './texture.js';
3
+ /**
4
+ * Packs separate roughness and metalness images into one `metallicRoughnessTexture` (0066): G is
5
+ * roughness, B is metalness, as glTF has it. Each input's red channel is its value (grayscale
6
+ * maps). A missing map packs as 1, so the material's own roughness and metallic factors apply
7
+ * unchanged. Maps of different sizes are resized to the larger one.
8
+ */
9
+ export declare function packMetallicRoughness(roughness?: Image, metalness?: Image): Texture;
@@ -0,0 +1,40 @@
1
+ import { ShardError } from "@aethervtt/shard-core";
2
+ import { resizeImage } from "./array.js";
3
+ import { Texture } from "./texture.js";
4
+ function packMetallicRoughness(roughness, metalness) {
5
+ if (!roughness && !metalness) {
6
+ throw new ShardError(
7
+ "texture/nothing-to-pack",
8
+ "packMetallicRoughness needs a roughness or a metalness map",
9
+ {
10
+ hint: "Without either, leave metallicRoughnessTexture empty: the scalar factors apply."
11
+ }
12
+ );
13
+ }
14
+ for (const image of [roughness, metalness]) {
15
+ if (image && image.kind !== "u8") {
16
+ throw new ShardError(
17
+ "texture/wrong-kind",
18
+ "Roughness and metalness maps must be 8-bit images",
19
+ {
20
+ hint: 'Decode them as RGBA8 (kind "u8").'
21
+ }
22
+ );
23
+ }
24
+ }
25
+ const width = Math.max(roughness?.width ?? 0, metalness?.width ?? 0);
26
+ const height = Math.max(roughness?.height ?? 0, metalness?.height ?? 0);
27
+ const r = roughness ? resizeImage(roughness, width, height).data : void 0;
28
+ const m = metalness ? resizeImage(metalness, width, height).data : void 0;
29
+ const out = new Uint8Array(width * height * 4);
30
+ for (let i = 0; i < width * height; i++) {
31
+ out[i * 4] = 0;
32
+ out[i * 4 + 1] = r ? r[i * 4] : 255;
33
+ out[i * 4 + 2] = m ? m[i * 4] : 255;
34
+ out[i * 4 + 3] = 255;
35
+ }
36
+ return Texture.create({ width, height, usage: "data", mips: [out], mipmaps: true });
37
+ }
38
+ export {
39
+ packMetallicRoughness
40
+ };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  export { resizeImage, type TextureArrayFile, TextureArrayImporter } from './array.js';
2
2
  export { encodeBasis, type TranscodedTexture, type TranscodeTarget, transcodeBasis } from './basis.js';
3
+ export { packMetallicRoughness } from './channels.js';
3
4
  export { decodeHdr, decodeImage, decodeJpeg, decodePngImage, decodeWebp, type ImageFormat, sniffImage, } from './decode/index.js';
4
5
  export type { Image } from './image.js';
5
6
  export { flipGreen, importImageBytes, TextureImporter, TextureImportSettings, type TextureSettings, usageFromName, } from './importer.js';
6
7
  export { type Ktx2Data, readKtx2, tagKtx2, writeKtx2 } from './ktx2.js';
7
8
  export { buildMips, type MipChain, type MipOptions, type TextureUsage, toHalf } from './mips.js';
8
9
  export { type PackItem, type PackResult, packRects, SkylinePacker } from './pack.js';
9
- export { FORMAT_INFO, setTextureCapabilities, Texture, TextureAssetType, type TextureCapabilities, type TextureFormat, type TextureInit, Textures, textureCapabilities, textureFromKtx2, transcodeTarget, } from './texture.js';
10
+ export { FORMAT_INFO, fallbackTexture, setTextureCapabilities, Texture, TextureAssetType, type TextureCapabilities, type TextureFormat, type TextureInit, Textures, textureCapabilities, textureFromKtx2, transcodeTarget, } from './texture.js';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { resizeImage, TextureArrayImporter } from "./array.js";
2
2
  import { encodeBasis, transcodeBasis } from "./basis.js";
3
+ import { packMetallicRoughness } from "./channels.js";
3
4
  import {
4
5
  decodeHdr,
5
6
  decodeImage,
@@ -20,6 +21,7 @@ import { buildMips, toHalf } from "./mips.js";
20
21
  import { packRects, SkylinePacker } from "./pack.js";
21
22
  import {
22
23
  FORMAT_INFO,
24
+ fallbackTexture,
23
25
  setTextureCapabilities,
24
26
  Texture,
25
27
  TextureAssetType,
@@ -44,8 +46,10 @@ export {
44
46
  decodePngImage,
45
47
  decodeWebp,
46
48
  encodeBasis,
49
+ fallbackTexture,
47
50
  flipGreen,
48
51
  importImageBytes,
52
+ packMetallicRoughness,
49
53
  packRects,
50
54
  readKtx2,
51
55
  resizeImage,
package/dist/texture.d.ts CHANGED
@@ -95,3 +95,8 @@ export declare function textureFromKtx2(bytes: Uint8Array, options?: {
95
95
  cpu?: boolean;
96
96
  }): Promise<Texture>;
97
97
  export declare const TextureAssetType: import("@aethervtt/shard-assets").AssetTypeDef<Texture>;
98
+ /**
99
+ * What a texture that failed to load shows (0061): 50% gray, or in a dev build a magenta and gray
100
+ * checker that can't be mistaken for art. RGBA8, so it binds in any color or data slot.
101
+ */
102
+ export declare function fallbackTexture(dev: boolean): Texture;
package/dist/texture.js CHANGED
@@ -204,13 +204,31 @@ const TextureAssetType = defineAssetType("Texture", {
204
204
  existing.layers = next.layers;
205
205
  existing.premultiplied = next.premultiplied;
206
206
  existing.version++;
207
- }
207
+ },
208
+ fallback: ({ dev }) => fallbackTexture(dev),
209
+ cost: (texture) => ({ textures: 1, bytes: texture.byteSize })
208
210
  });
211
+ function fallbackTexture(dev) {
212
+ const size = dev ? 8 : 1;
213
+ const pixels = new Uint8Array(size * size * 4);
214
+ for (let y = 0; y < size; y++) {
215
+ for (let x = 0; x < size; x++) {
216
+ const o = (y * size + x) * 4;
217
+ const checker = dev && ((x >> 1) + (y >> 1)) % 2 === 0;
218
+ pixels[o] = checker ? 255 : 128;
219
+ pixels[o + 1] = checker ? 0 : 128;
220
+ pixels[o + 2] = checker ? 255 : 128;
221
+ pixels[o + 3] = 255;
222
+ }
223
+ }
224
+ return Texture.create({ width: size, height: size, mips: [pixels], usage: "color", cpu: true });
225
+ }
209
226
  export {
210
227
  FORMAT_INFO,
211
228
  Texture,
212
229
  TextureAssetType,
213
230
  Textures,
231
+ fallbackTexture,
214
232
  setTextureCapabilities,
215
233
  textureCapabilities,
216
234
  textureFromKtx2,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aethervtt/shard-texture",
3
- "version": "0.0.1",
3
+ "version": "0.2.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -18,8 +18,8 @@
18
18
  ],
19
19
  "dependencies": {
20
20
  "@jsquash/webp": "^1.5.0",
21
- "@aethervtt/shard-assets": "0.0.1",
22
- "@aethervtt/shard-core": "0.0.1",
21
+ "@aethervtt/shard-assets": "0.2.0",
22
+ "@aethervtt/shard-core": "0.2.0",
23
23
  "fzstd": "^0.1.1",
24
24
  "jpeg-js": "^0.4.4",
25
25
  "ktx-parse": "^2.0.0"
@@ -34,6 +34,6 @@
34
34
  "provenance": true
35
35
  },
36
36
  "shard": {
37
- "buildSha": "d6c5c6aef4675575c878b02cf2c8f738b4190229"
37
+ "buildSha": "32c22a3944ed23f5d1baa90bf7cc9fae724f5fd8"
38
38
  }
39
39
  }