The generators handed back noise spanning about one channel however many the latent had, and travel_mode walk worked around it by remixing 64 renders after the fact. The plan was to fix shaders/base.py::expand_channels. That alone would have changed nothing for SD 1.5 or SDXL: the collapse had three sources, and the one that mattered at four channels was somewhere else. - domain_warp copied one field four times with repeat(1, 4, 1, 1), so expand_channels returned early at four channels and never ran. - temporal_coherent broadcast one field to every channel with .expand(): rank 1.00 at any channel count, and it is the shader the video preset picks. - curl_noise padded its colour path with copies of one magnitude field. BaseNoiseGenerator.fill_channels replaces expand_channels. Every channel up to CHANNEL_BASIS (64) is its own render at seed + 6151*c; channels past that are QR-orthogonalised mixtures of those renders. Channel 0 stays the generator's own draw, so a one-channel request is unchanged -- and jump, which is built from one-channel draws, is byte-identical to before for all four generators. The extra renders run inside a forked RNG. 6151 has no collisions among the first 64 channels under the mod-10000 seed hashing curl_noise does internally. Effective rank for domain_warp at 4 / 24 / 128 channels goes from 1.00 / 2.13 / 2.43 to 3.91 / 22.72 / 69.56. The travel-mode guard had to become direction-aware. Only a basis of 1 skipped it, so once the generators were wide, drift (basis 4) would have been treated as a remix that could not help and silently returned walk's noise. It already did that for tensor_field and curl_noise. A basis below the widest now narrows unconditionally. Widening is skipped once a draw exceeds 0.65 of its target, just above the best a random remix reached (0.52-0.64, measured across all four generators at 16, 24 and 128 channels), so walk passes the generator's noise through instead of rendering 64 more draws and discarding them. The old 0.9 threshold would still have paid for that on 16-channel models. Seven of the eleven goldens moved, not the one the handoff predicted; the four that should not move held byte-identical. The suite is now pinned to the standard pipeline, re-captured, with every standard-only input set explicitly in NODE_DEFAULTS. The old legacy output is at the pre-collapse-fix tag. test_legacy_golden.py becomes test_golden.py. test_blend_calibration_is_current no longer compares difference on an absolute tolerance: its whole curve sits below the tolerance, and after this change it passed by 0.002. Every other mode stays within 0.049 of the table. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
102 lines
2.2 KiB
Python
102 lines
2.2 KiB
Python
"""
|
|
Constants and magic numbers for shader noise generation.
|
|
|
|
This module centralizes all constants used across the codebase to
|
|
ensure consistency and make values easy to tune.
|
|
"""
|
|
|
|
# Hash constant used in simplex noise and pseudo-random functions
|
|
HASH_CONSTANT = 43758.5453
|
|
|
|
# Default number of channels for latent space
|
|
DEFAULT_CHANNELS = 4
|
|
|
|
# Independent renders a generator draws to fill a latent's channel axis. Channels
|
|
# past this are mixtures of those renders, so a very wide latent does not cost one
|
|
# render per channel. 64 is the basis travel_mode's walk was measured at on
|
|
# MiniMax H3 (7661d7c), and it covers every latent ComfyUI ships short of LTXV's 128.
|
|
CHANNEL_BASIS = 64
|
|
|
|
# Maximum octaves for FBM noise to prevent DoS
|
|
MAX_OCTAVES = 20
|
|
|
|
# Minimum and maximum scale values
|
|
MIN_SCALE = 0.001
|
|
MAX_SCALE = 100.0
|
|
|
|
# Default parameter values
|
|
DEFAULT_SCALE = 1.0
|
|
DEFAULT_OCTAVES = 3.0
|
|
DEFAULT_WARP_STRENGTH = 0.5
|
|
DEFAULT_PHASE_SHIFT = 0.5
|
|
DEFAULT_SHAPE_STRENGTH = 1.0
|
|
DEFAULT_COLOR_INTENSITY = 0.8
|
|
DEFAULT_SHADER_STRENGTH = 0.3
|
|
DEFAULT_TIME = 0.0
|
|
|
|
# Supported blend modes for combining shader noise with base noise
|
|
SUPPORTED_BLEND_MODES = [
|
|
"normal",
|
|
"add",
|
|
"multiply",
|
|
"screen",
|
|
"overlay",
|
|
"soft_light",
|
|
"hard_light",
|
|
"difference",
|
|
]
|
|
|
|
# Supported noise transforms
|
|
SUPPORTED_TRANSFORMS = [
|
|
"none",
|
|
"reverse",
|
|
"inverse",
|
|
"absolute",
|
|
"square",
|
|
"sqrt",
|
|
"log",
|
|
"sin",
|
|
"cos",
|
|
]
|
|
|
|
# Supported shader types
|
|
SUPPORTED_SHADER_TYPES = [
|
|
"domain_warp",
|
|
"tensor_field",
|
|
"curl_noise",
|
|
"temporal_coherent",
|
|
"fbm_noise",
|
|
"perlin",
|
|
"waves",
|
|
"gaussian",
|
|
"heterogeneous_fbm",
|
|
"interference",
|
|
"spectral",
|
|
"projection_3d",
|
|
]
|
|
|
|
# Supported stage distributions for multi-stage sampling
|
|
SUPPORTED_DISTRIBUTIONS = [
|
|
"uniform",
|
|
"linear_decrease",
|
|
"linear_increase",
|
|
"gaussian",
|
|
"first_stronger",
|
|
"last_stronger",
|
|
]
|
|
|
|
# High channel threshold for fast mode
|
|
HIGH_CHANNEL_THRESHOLD = 16
|
|
|
|
# Visualization types
|
|
VISUALIZATION_TYPES = {
|
|
0: "arrows",
|
|
1: "lines",
|
|
2: "dots",
|
|
3: "ellipses",
|
|
4: "streamlines",
|
|
}
|
|
|
|
# Default visualization type
|
|
DEFAULT_VISUALIZATION_TYPE = 3 # ellipses
|