实测 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>
45 lines
1.7 KiB
Python
45 lines
1.7 KiB
Python
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 编码,再编码一次会双重 gamma(well10k 变亮 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()
|