-
Creator 版本: 3.8.2
-
目标平台: mac creator编辑器
项目配置了多张图片压缩纹理,小游戏平台统一配置为ASTC8x8 medium和PNG,构建微信小游戏时查看构建日志,total time显示只有0.0125s,但是都要间隔4s以上日志才会显示压缩下一张图,导致图片多时构建极慢,这个是哪里配置有问题吗?有办法优化吗?
Creator 版本: 3.8.2
目标平台: mac creator编辑器
项目配置了多张图片压缩纹理,小游戏平台统一配置为ASTC8x8 medium和PNG,构建微信小游戏时查看构建日志,total time显示只有0.0125s,但是都要间隔4s以上日志才会显示压缩下一张图,导致图片多时构建极慢,这个是哪里配置有问题吗?有办法优化吗?
首次久,下次就快了又缓存
算快了,etc2, 10 分钟一图我都见过,我们项目不使用缓存,完整压一遍要 1 天多 
给我的感觉是压缩任务没有做并行处理而是一个个依次压缩,这样挺影响开发效率的 
那确实是,理论上并行压缩很容易做的
压缩器线程本身并行了。你看Compressor thread count 是16,如果再多开几个进程就要挤兑cpu了。
每次开启压缩器进程本身就要耗费一定时间。要压的快,看看有没有批量传文件列表到压缩器的方式,省去每个文件开关进程的部分时间。
可以把文件列表(src -> dest)放在一个json里面,然后修改压缩器,使其支持从配置文件里面读取文件列表批量操作就行了。
是需要修改astcenc吗?门槛有点高呀 
看日志的话压缩时只有一个task在进程里
astc_8x89d90b3b266.astc
2024-10-24 11:23:08 - debug: astc compressed command: astcenc -cl /Users/admin/Documents/xx/Project/library/0b/0b6b0e5e-6317-4678-8811-859d90b3b266.jpg /Users/admin/Documents/xx/Project/temp/builder/CompressTexture/0b/0b6b0e5e-6317-4678-8811-859d90b3b266.astc 8x8 -medium
Source: /Users/admin/Documents/xx/Project/library/0b/0b6b0e5 Coding rate: 10.4116 MT/s ids
2024-10-24 11:23:11 - debug: [compress astc]Child process exit width code 0
2024-10-24 11:23:11 - log: Compress astc success {link(/Users/admin/Documents/xx/Project/temp/builder/CompressTexture/0b/0b6b0e5e-6317-4678-8811-859d90b3b266.astc)}
2024-10-24 11:23:11 - debug: execute compress task 828/1608, 1 in progress}, progress: 28%
2024-10-24 11:23:11 - debug: [compress astc]Child process exit width code 0
我这边用child_process试了是可以并行压缩的,压缩276个文件只要1.72s,creator一个个压的话就要十多分钟。
import { spawn } from “child_process”;
import { readdir } from “fs/promises”;
import path from “path”;
async function compressImages() {
const directoryPath = "/Users/admin/Downloads/test/astccompress/Box"; // 替换为你的图片目录
const files = await readdir(directoryPath);
const iStartTime = performance.now();
const tPromises = files
.filter((file) => file.endsWith(".png")) // 只处理 .png 文件
.map((file) => {
const inputPath = path.join(directoryPath, file);
const outputPath = path.join(directoryPath, `${path.parse(file).name}.astc`);
return new Promise<void>((resolve, reject) => {
const astcProcess = spawn("/Applications/Cocos/Creator/3.8.2/CocosCreator.app/Contents/Resources/tools/astc-encoder/astcenc", [
"-cl",
inputPath,
outputPath,
"8x8",
"-medium",
]);
astcProcess.stdout.on("data", (data) => {
console.log(`Output: ${data}`);
});
astcProcess.stderr.on("data", (data) => {
console.error(`Error: ${data}`);
});
astcProcess.on("close", (code) => {
if (code === 0) {
console.log(`Compressed: ${file}`);
resolve();
} else {
reject(`Compression failed for ${file} with code ${code}`);
}
});
});
});
await Promise.all(tPromises);
console.log("All images compressed.");
const iEndTime = performance.now();
console.log(`总耗时:${(iEndTime - iStartTime) / 1000} s. 转换文件数:${tPromises.length}`);
}
compressImages().catch(console.error);
那挺好的啊,就让引擎组加入进去吧。
如果引擎组不改编辑器的话,也可以在纹理压缩那里做个假的纹理压缩器,用来记录参数到json里面,build后用外部脚本来批量压缩到temp目录里面并且拷贝到工程。
记录一下最后的解决方法,后面有碰到的小伙伴可以参考一下。
在自定义构建扩展的钩子函数compressTextures里记录所有astc压缩的task的路径,保存到json里,再额外执行js脚本,脚本里读取json,内容跟上面代码差不多就是并行压缩。没有直接在compressTextures里执行是因为直接执行会跟原来一样慢,估计是有资源竞争,放在脚本执行就很快了,800个文件耗时18s。压缩的时候资源占满导致电脑卡顿,不过总比等半天好。