* feat: transform texture nodes into a complete v3 PBR toolkit * fix(ci): validate metadata on Python 3.10
57 lines
1.9 KiB
Python
57 lines
1.9 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
|
|
import numpy as np
|
|
import torch
|
|
|
|
import texture_nodes as nodes
|
|
|
|
|
|
def gradient(batch=1, height=24, width=32):
|
|
x = torch.linspace(0, 1, width).view(1, 1, width, 1)
|
|
return x.repeat(batch, height, 1, 3)
|
|
|
|
|
|
def test_normal_from_height_is_unit_length_and_finite():
|
|
output, = nodes.TextureNormalFromHeight().generate(
|
|
gradient(), 3.0, 1, "OpenGL (+Y)", True
|
|
)
|
|
vectors = output.numpy() * 2.0 - 1.0
|
|
assert output.shape == (1, 24, 32, 3)
|
|
assert np.isfinite(vectors).all()
|
|
assert np.allclose(np.linalg.norm(vectors, axis=-1), 1.0, atol=1e-5)
|
|
|
|
|
|
def test_ao_and_channel_pack_contracts():
|
|
ao, = nodes.TextureAOFromHeight().generate(gradient(), 2.0, 4, "8", True)
|
|
packed, manifest = nodes.TextureChannelPack().pack(
|
|
"ORM (glTF)", 1.0, 1.0, 0.0, 1.0,
|
|
red_or_ao=ao,
|
|
green_or_roughness=gradient(),
|
|
)
|
|
assert packed.shape == (1, 24, 32, 4)
|
|
assert packed.min() >= 0 and packed.max() <= 1
|
|
assert json.loads(manifest)["channels"]["G"] == "roughness"
|
|
channel, mask = nodes.TextureChannelExtract().extract(packed, "green")
|
|
assert channel.shape[-1] == 3
|
|
assert mask.shape == packed.shape[:3]
|
|
|
|
|
|
def test_tileable_emits_larger_visual_proof_and_low_edge_error():
|
|
image = torch.rand((2, 20, 30, 3), generator=torch.Generator().manual_seed(4))
|
|
tileable, proof, report = nodes.TextureMakeTileable().make(
|
|
image, "Offset + feather", 0.2
|
|
)
|
|
data = json.loads(report)
|
|
assert tileable.shape == image.shape
|
|
assert proof.shape == (2, 40, 60, 3)
|
|
assert data["edge_mae_horizontal"] < 0.02
|
|
assert data["edge_mae_vertical"] < 0.02
|
|
|
|
|
|
def test_pbr_analyzer_highlights_clipped_pixels():
|
|
report, diagnostic = nodes.TexturePBRAnalyze().analyze(torch.zeros((1, 8, 8, 3)), "albedo")
|
|
assert json.loads(report)["clipped_pixel_fraction"] == 1.0
|
|
assert diagnostic.shape == (1, 8, 8, 3)
|