@needle-tools/gltf-build-pipeline 2.8.0-alpha.0 → 2.8.0-alpha.2

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/CHANGELOG.md CHANGED
@@ -4,6 +4,10 @@ All notable changes to this package will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [2.8.0-alpha.2] - 2024-03-04
8
+ - change: use webp compression for textures smaller than 32x32
9
+ - fix: webp compression for small textures (64x64)
10
+
7
11
  ## [2.8.0-alpha.0] - 2024-02-27
8
12
  - change: `product` usecase now uses webp compression for 'normalTexture' and 'metallicRoughnessTexture' textures
9
13
 
@@ -954,7 +954,7 @@ class MeshIndexResolver extends PointerResolver {
954
954
  if (parent instanceof Node) {
955
955
  obj = parent.getMesh();
956
956
  if (obj) {
957
- console.log(`INFO: resolved mesh \"${this.inputObject.getName()}\" from parent node \"${parent.getName()}\"`);
957
+ this.document.getLogger().info(`INFO: resolved mesh \"${this.inputObject.getName()}\" from parent node \"${parent.getName()}\"`);
958
958
  break;
959
959
  }
960
960
  }
@@ -97,8 +97,11 @@ async function processTexture(texture, index, document, logger, context) {
97
97
  const compressionSettings = ext?.model;
98
98
  // is a user has configured a texture explictly to NOT be compressed
99
99
  // we should respect that
100
- if (ext?.model?.mode === "none")
100
+ if (ext?.model?.mode === "none") {
101
+ logger.info(`→ Skipping texture compression for ${texture.getName()} [${index}] as configured in the texture extension`);
101
102
  return;
103
+ }
104
+ // generate the cache key from the file data and settings
102
105
  const key = context.useCache ? (getKey(texture) + getHash(context.config)) : undefined;
103
106
  let cached = context.useCache && key ? tryGetFromCache(key) : undefined;
104
107
  if (cached) {
@@ -143,13 +146,11 @@ async function processTexture(texture, index, document, logger, context) {
143
146
  }
144
147
  else {
145
148
  let mimeType = "image/ktx2";
149
+ let ktx2Format = undefined;
150
+ let webpOptions = {};
146
151
  const slots = listTextureSlots(texture);
147
- // if (slots.includes("metallicRoughnessTexture"))
148
- // mimeType = "image/webp";
152
+ const size = texture.getSize();
149
153
  const isVRM = context.file?.toLowerCase().endsWith(".vrm");
150
- if (slots.includes("lightmapTexture") || isLightmap(texture)) {
151
- mimeType = "image/webp";
152
- }
153
154
  // TODO: need to make this into a function
154
155
  // const webpThreshold = 256; // this is the default threshold in progressive textures (needle_progressive.ts)
155
156
  // console.log(context.file, isVRM);
@@ -161,9 +162,17 @@ async function processTexture(texture, index, document, logger, context) {
161
162
  // mimetype = "image/webp";
162
163
  // }
163
164
  // }
165
+ if (slots.includes("lightmapTexture") || isLightmap(texture)) {
166
+ mimeType = "image/webp";
167
+ }
168
+ // for https://linear.app/needle/issue/NE-6464
169
+ else if (size[0] <= 32 || size[1] <= 32) {
170
+ // can not use UASTC because it's ALSO shitty, see issue above
171
+ mimeType = "image/webp";
172
+ }
164
173
  // For product compression we automatically select webP if the texture is used in a PBR material
165
174
  // https://linear.app/needle/issue/NE-6458
166
- if (context.config.usecase === "product") {
175
+ else if (context.config.usecase === "product") {
167
176
  const shouldUseWebp = slots.includes("normalTexture") || slots.includes("metallicRoughnessTexture");
168
177
  if (shouldUseWebp) {
169
178
  mimeType = "image/webp";
@@ -178,6 +187,7 @@ async function processTexture(texture, index, document, logger, context) {
178
187
  await resizeTextureIfNecessary(texture);
179
188
  if (mimeType === "image/webp") {
180
189
  successFullyProcessed = await context.webPContext.process(index, texture, {
190
+ ...webpOptions,
181
191
  quality: .9,
182
192
  }, context);
183
193
  }
@@ -186,8 +196,8 @@ async function processTexture(texture, index, document, logger, context) {
186
196
  // if we ever change what is used for default compression we need to teach the cache to save the mime type
187
197
  // For VRMs we use ETC1S always
188
198
  let options = null;
189
- if (isVRM) {
190
- options = { mode: "ETC1S" };
199
+ if (ktx2Format || isVRM) {
200
+ options = { mode: ktx2Format || "ETC1S" };
191
201
  }
192
202
  successFullyProcessed = await context.toktxContext.process(index, texture, options, context);
193
203
  }
@@ -1,6 +1,7 @@
1
1
  import { Document, ILogger, Texture } from '@gltf-transform/core';
2
2
  import { NEEDLE_compression_texture_schema } from '../extensions/index.js';
3
3
  import { INeedleTextureTransformContext, NeedleTransformContext } from './needle_common.js';
4
+ import sharp from 'sharp';
4
5
  export interface NeedleWebPOptions {
5
6
  }
6
7
  export declare class NeedleWebPContext implements INeedleTextureTransformContext {
@@ -9,6 +10,6 @@ export declare class NeedleWebPContext implements INeedleTextureTransformContext
9
10
  private compressed;
10
11
  constructor(options: NeedleWebPOptions);
11
12
  prepare(document: Document): Promise<void>;
12
- process(index: number, texture: Texture, settings: Pick<NEEDLE_compression_texture_schema, "quality">, context: NeedleTransformContext): Promise<boolean>;
13
+ process(index: number, texture: Texture, settings: Pick<NEEDLE_compression_texture_schema, "quality"> & Partial<sharp.WebpOptions>, context: NeedleTransformContext): Promise<boolean>;
13
14
  finalize(document: Document): Promise<void>;
14
15
  }
@@ -13,7 +13,15 @@ export class NeedleWebPContext {
13
13
  this.logger = document.getLogger();
14
14
  }
15
15
  async process(index, texture, settings, context) {
16
+ const size = texture.getSize();
17
+ // if the texture is too small we will use lossless compression
18
+ let lossless = false;
19
+ if (size[0] < 64 || size[1] < 64) {
20
+ lossless = true;
21
+ }
16
22
  const options = {
23
+ lossless,
24
+ ...settings,
17
25
  quality: settings.quality,
18
26
  // effort: remap(options.effort, 100, 6),
19
27
  // lossless: options.lossless,
@@ -1 +1 @@
1
- export declare const version = "2.8.0-alpha.0";
1
+ export declare const version = "2.8.0-alpha.2";
@@ -1 +1 @@
1
- export const version = "2.8.0-alpha.0";
1
+ export const version = "2.8.0-alpha.2";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@needle-tools/gltf-build-pipeline",
3
- "version": "2.8.0-alpha.0",
3
+ "version": "2.8.0-alpha.2",
4
4
  "description": "Pipeline and tools for optimizing gltf files using gltf-transform and compression settings within glTF extensions",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",