ModelTranslator: dedupe sanitized material names, set alphaIsTransparency for alpha-test textures
This commit is contained in:
@@ -132,7 +132,7 @@ def _channel(pixels, ch):
|
||||
return pixels[..., ch if ch is not None else 0]
|
||||
|
||||
|
||||
def _save_png(path, rgba, srgb_view=False):
|
||||
def _save_png(path, rgba):
|
||||
"""float32 (h,w,4) -> PNG。写原始值(Non-Color,避免色彩管理改写数据)。"""
|
||||
import bpy
|
||||
h, w = rgba.shape[:2]
|
||||
@@ -146,7 +146,7 @@ def _save_png(path, rgba, srgb_view=False):
|
||||
bpy.data.images.remove(img)
|
||||
|
||||
|
||||
def _convert_material(mat, model_name, outdir, max_size):
|
||||
def _convert_material(mat, model_name, outdir, max_size, used_snames):
|
||||
warnings = []
|
||||
maps, consts = _material_maps(mat, warnings)
|
||||
tw, th = _target_size(maps, max_size)
|
||||
@@ -192,7 +192,15 @@ def _convert_material(mat, model_name, outdir, max_size):
|
||||
else:
|
||||
mix[..., 3] = consts["roughness"]
|
||||
|
||||
sname = safe_name(mat.name)
|
||||
# 中文等非 ASCII 材质名会同样退化(如都变 "mat"),加序号防止互相覆盖
|
||||
sname = base_sname = safe_name(mat.name)
|
||||
n = 1
|
||||
while sname in used_snames:
|
||||
n += 1
|
||||
sname = "%s_%d" % (base_sname, n)
|
||||
used_snames.add(sname)
|
||||
if sname != base_sname:
|
||||
warnings.append("材质名 %s 清洗后与其它材质重名,输出改用 %s" % (mat.name, sname))
|
||||
base_png = os.path.abspath(os.path.join(outdir, "%s_%s_base.png" % (model_name, sname)))
|
||||
mix_png = os.path.abspath(os.path.join(outdir, "%s_%s_mix.png" % (model_name, sname)))
|
||||
_save_png(base_png, base)
|
||||
@@ -242,7 +250,9 @@ def main():
|
||||
if slot.material and slot.material not in used_mats:
|
||||
used_mats.append(slot.material)
|
||||
|
||||
results = [_convert_material(m, model_name, outdir, max_size) for m in used_mats]
|
||||
used_snames = set()
|
||||
results = [_convert_material(m, model_name, outdir, max_size, used_snames)
|
||||
for m in used_mats]
|
||||
|
||||
_strip_textures()
|
||||
fbx_out = os.path.join(outdir, model_name + ".fbx")
|
||||
@@ -253,5 +263,5 @@ def main():
|
||||
ensure_ascii=False))
|
||||
|
||||
|
||||
if __name__ == "__main__" and "--" in __import__("sys").argv:
|
||||
if __name__ == "__main__" and "--" in sys.argv:
|
||||
main()
|
||||
|
||||
@@ -44,15 +44,16 @@ def write_unity_assets(outdir, summary, max_size):
|
||||
mix_png = os.path.join(outdir, m["mix_png"])
|
||||
base_guid = ua.guid_for(base_png)
|
||||
mix_guid = ua.guid_for(mix_png)
|
||||
alpha_test = m["alpha_mode"] == "transparency"
|
||||
with open(base_png + ".meta", "w", encoding="utf-8", newline="\n") as f:
|
||||
f.write(ua.texture_meta(base_guid, srgb=True, max_size=max_size))
|
||||
f.write(ua.texture_meta(base_guid, srgb=True, max_size=max_size,
|
||||
alpha_is_transparency=alpha_test))
|
||||
with open(mix_png + ".meta", "w", encoding="utf-8", newline="\n") as f:
|
||||
f.write(ua.texture_meta(mix_guid, srgb=False, max_size=max_size))
|
||||
|
||||
mat_name = "%s_%s" % (summary["model"], m["safe_name"])
|
||||
mat_path = os.path.join(outdir, mat_name + ".mat")
|
||||
mat_guid = ua.guid_for(mat_path)
|
||||
alpha_test = m["alpha_mode"] == "transparency"
|
||||
with open(mat_path, "w", encoding="utf-8", newline="\n") as f:
|
||||
f.write(ua.material_yaml(mat_name, ua.XPBR_SHADER_GUID,
|
||||
base_guid, mix_guid, alpha_test))
|
||||
|
||||
@@ -35,6 +35,13 @@ class TestTemplates(unittest.TestCase):
|
||||
self.assertIn("maxTextureSize: 2048", on)
|
||||
self.assertIn("guid: " + "a" * 32, on)
|
||||
|
||||
def test_texture_meta_alpha_is_transparency(self):
|
||||
default = ua.texture_meta("a" * 32, srgb=True, max_size=2048)
|
||||
ait = ua.texture_meta("a" * 32, srgb=True, max_size=2048,
|
||||
alpha_is_transparency=True)
|
||||
self.assertIn("alphaIsTransparency: 0", default)
|
||||
self.assertIn("alphaIsTransparency: 1", ait)
|
||||
|
||||
def test_material_yaml_refs_and_keyword(self):
|
||||
y = ua.material_yaml("tong_wood", "s" * 32, "c" * 32, "d" * 32, alpha_test=True)
|
||||
self.assertIn("m_Name: tong_wood", y)
|
||||
|
||||
@@ -33,7 +33,7 @@ def safe_name(name):
|
||||
return re.sub(r"[^0-9A-Za-z_\-]", "_", name).strip("_") or "mat"
|
||||
|
||||
|
||||
def texture_meta(guid, srgb, max_size):
|
||||
def texture_meta(guid, srgb, max_size, alpha_is_transparency=False):
|
||||
return """fileFormatVersion: 2
|
||||
guid: {guid}
|
||||
TextureImporter:
|
||||
@@ -88,7 +88,7 @@ TextureImporter:
|
||||
spriteBorder: {{x: 0, y: 0, z: 0, w: 0}}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
alphaIsTransparency: {ait}
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
@@ -135,7 +135,8 @@ TextureImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
""".format(guid=guid, srgb=1 if srgb else 0, max_size=max_size)
|
||||
""".format(guid=guid, srgb=1 if srgb else 0, max_size=max_size,
|
||||
ait=1 if alpha_is_transparency else 0)
|
||||
|
||||
|
||||
def material_yaml(name, shader_guid, base_tex_guid, mix_tex_guid, alpha_test):
|
||||
|
||||
Reference in New Issue
Block a user