Files
shaders/test_ice.py
T
emil28092005 27d238cbe6 Ice slab with layered plasma, two-pass refraction
Pass 1 renders eight plasma sheets into an atlas with linear depth in alpha;
pass 2 marches the refracted ray to each sheet and absorbs it by real path
length, so near and far layers separate under pointer parallax. Plasma cycle
repeats exactly every 30 s; - / = change speed.
2026-10-30 19:56:16 +03:00

47 lines
2.1 KiB
Python

#!/usr/bin/env python3
"""Render regression checks. Requires Firefox and Pillow; the page itself needs neither."""
import subprocess
import tempfile
import unittest
from pathlib import Path
from PIL import Image, ImageChops, ImageStat
HERE = Path(__file__).resolve().parent
class IceRenderTest(unittest.TestCase):
def test_loop_mouse_and_visible_plasma(self):
subprocess.run(['python3', str(HERE / 'build_plasma.py')], check=True)
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
profile = root / 'profile'
profile.mkdir()
def render(name, parameters):
output = root / (name + '.png')
url = (HERE / 'ice_plasma.html').as_uri() + '#shot&' + parameters
subprocess.run(['firefox', '--headless', '--new-instance', '--profile', str(profile),
'--window-size=320,240', '--screenshot=' + str(output), url],
check=True, timeout=120, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Exclude the on-screen instructions.
with Image.open(output) as image:
return image.convert('RGB').crop((0, 0, 320, 180))
start = render('start', 't=0&mx=0.5&my=0.5')
loop = render('loop', 't=30&mx=0.5&my=0.5')
moved = render('moved', 't=0&mx=0.9&my=0.5')
halfway = render('halfway', 't=15&mx=0.5&my=0.5')
difference = lambda a, b: sum(ImageStat.Stat(ImageChops.difference(a, b)).mean) / 3
self.assertLess(difference(start, loop), 1.0)
self.assertGreater(difference(start, moved), 3.0)
self.assertGreater(difference(start, halfway), 3.0)
self.assertGreater(ImageStat.Stat(start).stddev[2], 10.0)
luminance = start.convert('L').histogram()
pixels = sum(luminance)
self.assertLess(sum(luminance[:20]) / pixels, 0.10) # No vast black voids.
self.assertGreater(sum(luminance[:35]) / pixels, 0.08) # The depth stays dark.
if __name__ == '__main__':
unittest.main()