@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 +4 -0
- package/dist/extensions/NEEDLE_opaque/NEEDLE_opaque.js +1 -1
- package/dist/transforms/needle_texture_transform.js +19 -9
- package/dist/transforms/needle_webp.d.ts +2 -1
- package/dist/transforms/needle_webp.js +8 -0
- package/dist/utils/version.gen.d.ts +1 -1
- package/dist/utils/version.gen.js +1 -1
- package/package.json +1 -1
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
|
-
|
|
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
|
-
|
|
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.
|
|
1
|
+
export declare const version = "2.8.0-alpha.2";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = "2.8.0-alpha.
|
|
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.
|
|
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",
|