Tangent Disc Generator (16-bit RGB)
What this does (in one line): Generates a 16-bit RGB image where R/G encode a unit tangent direction field and B encodes a radial falloff (often used as an anisotropy “level”/mask), with robust saving via OpenCV / TIFF / PyPNG.
Why you might care
Physically meaningful channels
R = 0.5·(tx+1), G = 0.5·(ty+1) where (tx, ty) is the normalized tangent around a disc.
B = radial falloff ([0, 1]), controllable via radius_ratio and falloff_gamma.
True 16-bit pipeline for high-precision shading workflows (Unity/Unreal/ DCC tools).
Zero-fuss saving: tries OpenCV (PNG/TIFF) → tifffile (TIFF) → PyPNG (PNG).
git clone https://github.com//tangent-disc-generator.git cd tangent-disc-generator
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -U numpy
Any one of the writers below is enough (OpenCV preferred):
pip install -U opencv-python # preferred
or
pip install -U tifffile
or
pip install -U pypng
python tangent_disc.py
outputs: tangent_disc_16bit.png (or .tif depending on backend)
File name in your repo can be tangent_disc.py (or keep yours). The script writes the image next to the file you run.
Import and call the function generate_tangent_disc() from tangent_disc.py, or run the script directly:
python tangent_disc.py
Default parameters:
size=2048
radius_ratio=0.48
falloff_gamma=0.6
out_path="tangent_disc_16bit.png"
generate_tangent_disc(
size=1024,
radius_ratio=0.5,
falloff_gamma=0.8,
out_path="tangent_disc_16bit.tif" # extension may be changed by writer
)
| Parameter | Type | Description |
|---|---|---|
size |
int | Output is size × size |
radius_ratio |
float | Disc radius = size × radius_ratio. Outside the disc, B=0 |
falloff_gamma |
float | Gamma applied to radial falloff. Lower → softer falloff; higher → sharper edge |
center |
tuple | None | (cx, cy) in pixel coordinates; default is image center |
out_path |
str | Desired base name; actual extension may change depending on backend |
Output format & channel semantics
Data type: uint16 (0–65535 per channel).
R: 0.5·(tx + 1) mapped to [0, 1] → [0, 65535]
G: 0.5·(ty + 1) mapped to [0, 1] → [0, 65535]
B: max(1 - r/radius, 0) ** falloff_gamma where r is distance to center
Writers (priority): OpenCV (PNG/TIFF) → tifffile (TIFF) → PyPNG (PNG) If your out_path extension is unsupported by the active writer, the code switches to .png or .tif.
Anisotropic shading: use R/G as tangent directions, B as anisotropy/strength mask.
Flow maps / vector fields: normalized tangent vectors encoded in two channels.
Procedural texturing: stable, high-bit-depth masks and direction guides.