Files
ud18010andClaude Opus 4.8 c682ab4ebe ModelTranslator: 修复 base 贴图双重 sRGB 编码变亮(well10k 内嵌贴图案例)
实测 blender 5.0:Image.pixels 对 8-bit 图返回原始字节值(不做色彩变换),
sRGB PNG 读出已是编码值,再 linear->sRGB 就双重 gamma(均值 0.33->0.60)。
现仅对线性来源编码:float 图(EXR)与 Principled 常量色。
端到端验证:well10k 重转后 base 与源贴图平均差 0.0013。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 20:54:21 +08:00

45 lines
1.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import sys
import unittest
import numpy as np
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import bl_convert as bc
class TestBaseTextureEncoding(unittest.TestCase):
# Blender Image.pixels 对 8-bit 图返回原始字节值(不做色彩变换,实测 blender 5.0
# 字节 32/128/192 -> 0.1255/0.502/0.7529),即 sRGB PNG 读出来已是 sRGB 编码值。
# 仅线性来源(float 图 / Principled 常量色)需要 linear->sRGB。
def test_linear_source_rgb_is_encoded_as_srgb_and_alpha_is_preserved(self):
rgba = np.array([[[0.0, 0.18, 0.5, 0.37]]], dtype=np.float32)
encoded = bc.encode_base_texture_for_png(rgba, rgb_is_linear=True)
expected_rgb = np.array([0.0, 0.461356, 0.735357], dtype=np.float32)
np.testing.assert_allclose(encoded[0, 0, :3], expected_rgb, rtol=0, atol=1e-5)
self.assertAlmostEqual(float(encoded[0, 0, 3]), 0.37, places=6)
def test_byte_source_rgb_passes_through_unchanged(self):
# 8-bit 贴图像素已是 sRGB 编码,再编码一次会双重 gammawell10k 变亮 bug
rgba = np.array([[[0.1255, 0.502, 0.7529, 0.37]]], dtype=np.float32)
encoded = bc.encode_base_texture_for_png(rgba, rgb_is_linear=False)
np.testing.assert_allclose(encoded[0, 0], rgba[0, 0], rtol=0, atol=1e-6)
def test_out_of_range_values_are_clipped(self):
rgba = np.array([[[-0.1, 1.2, 0.5, 1.5]]], dtype=np.float32)
encoded = bc.encode_base_texture_for_png(rgba, rgb_is_linear=False)
self.assertEqual(float(encoded[0, 0, 0]), 0.0)
self.assertEqual(float(encoded[0, 0, 1]), 1.0)
self.assertEqual(float(encoded[0, 0, 3]), 1.0)
if __name__ == "__main__":
unittest.main()