-
Notifications
You must be signed in to change notification settings - Fork 511
/
Copy pathgltfbasis.py
77 lines (64 loc) · 2.79 KB
/
gltfbasis.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/python3
import argparse
import concurrent.futures
import matplotlib.pyplot as plt
import os
import os.path
import re
import subprocess
argp = argparse.ArgumentParser()
argp.add_argument('--basisu', type=str, required=True)
argp.add_argument('--graph', type=str, default="basisu.png")
argp.add_argument('--etcbase', action='store_true')
argp.add_argument('files', type=str, nargs='+')
args = argp.parse_args()
def compress(path, flags):
temp_path = "/dev/null" if os.name == "posix" else "NUL"
output = subprocess.check_output([args.basisu, "-file", path, "-output_file", temp_path, "-stats", "-ktx2"] + flags)
for line in output.splitlines():
if m := re.match(r".*source image.*?(\d+)x(\d+)", line.decode()):
pixels = int(m.group(1)) * int(m.group(2))
elif m := re.match(r".*Compression succeeded.*size (\d+) bytes", line.decode()):
bytes = int(m.group(1))
elif m := re.match(r"\.basis RGB Avg:.*RMS: (\d+\.\d+) PSNR: (\d+\.\d+)", line.decode()):
rms = float(m.group(1))
psnr = float(m.group(2))
return {'path': path, 'bpp': bytes * 8 / pixels, 'rms': rms, 'psnr': psnr}
def stats(path):
with concurrent.futures.ThreadPoolExecutor(16) as executor:
futures = []
for i in range(0, 26):
rdo_l = i / 5
flags = ["-uastc", "-uastc_level", "1", "-uastc_rdo_l", str(rdo_l), "-uastc_rdo_d", "1024"]
futures.append((executor.submit(compress, path, flags), rdo_l))
concurrent.futures.wait([f for (f, r) in futures])
results = []
bppbase = 0
for future, rdo_l in futures:
res = future.result()
if rdo_l == 0:
bppbase = res['bpp']
res['rdo_l'] = rdo_l
res['ratio'] = res['bpp'] / bppbase
results.append(res)
return results
fields = ['bpp', 'rms', 'psnr', 'ratio']
fig, axs = plt.subplots(1, len(fields) + 1, layout='constrained')
fig.set_figwidth(5 * (len(fields) + 1))
lines = []
for path in args.files:
print('Processing', path)
results = stats(path)
etcbase = compress(path, ["-q", "192"]) if args.etcbase else None
for idx, field in enumerate(fields):
line, = axs[idx].plot([r['rdo_l'] for r in results], [r[field] for r in results])
if etcbase and field in etcbase:
axs[idx].axhline(etcbase[field], color=line.get_color(), linestyle='dotted')
if idx == 0:
lines.append(line)
axs[len(fields)].scatter([r['ratio'] for r in results], [r['psnr'] for r in results], color=line.get_color())
for idx, field in enumerate(fields):
axs[idx].set_title(field)
axs[len(fields)].set_title('psnr vs ratio')
fig.legend(lines, [os.path.basename(path) for path in args.files], loc='outside right upper')
plt.savefig(args.graph)