react-native-webrtc-kaleidoscope 2.6.1 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/simiancraft/kaleidoscope/gpu/ShadersGenerated.kt +205 -31
- package/catalog/composites/nebula/nebula.thumb.webp +0 -0
- package/catalog/shaders/data-mesh/data-mesh.form.tsx +53 -0
- package/catalog/shaders/data-mesh/data-mesh.frag +205 -0
- package/catalog/shaders/data-mesh/data-mesh.ts +225 -0
- package/catalog/shaders/index.ts +4 -0
- package/catalog/shaders/nebula/nebula.frag +11 -3
- package/catalog/shaders/outrun-grid/outrun-grid.frag +40 -36
- package/catalog/shaders/outrun-grid/outrun-grid.ts +2 -2
- package/dist/catalog/composites/nebula/nebula.thumb.webp +0 -0
- package/dist/catalog/shaders/data-mesh/data-mesh.d.ts +50 -0
- package/dist/catalog/shaders/data-mesh/data-mesh.d.ts.map +1 -0
- package/dist/catalog/shaders/data-mesh/data-mesh.form.d.ts +3 -0
- package/dist/catalog/shaders/data-mesh/data-mesh.form.d.ts.map +1 -0
- package/dist/catalog/shaders/data-mesh/data-mesh.form.js +15 -0
- package/dist/catalog/shaders/data-mesh/data-mesh.form.js.map +1 -0
- package/dist/catalog/shaders/data-mesh/data-mesh.js +179 -0
- package/dist/catalog/shaders/data-mesh/data-mesh.js.map +1 -0
- package/dist/catalog/shaders/index.d.ts +4 -0
- package/dist/catalog/shaders/index.d.ts.map +1 -1
- package/dist/catalog/shaders/index.js +3 -1
- package/dist/catalog/shaders/index.js.map +1 -1
- package/dist/catalog/shaders/outrun-grid/outrun-grid.js +2 -2
- package/dist/catalog/shaders/outrun-grid/outrun-grid.js.map +1 -1
- package/dist/web-driver/shaders.generated.d.ts +3 -2
- package/dist/web-driver/shaders.generated.d.ts.map +1 -1
- package/dist/web-driver/shaders.generated.js +205 -32
- package/dist/web-driver/shaders.generated.js.map +1 -1
- package/ios/KaleidoscopeModule/shaders/GENERATIVE.txt +1 -0
- package/ios/KaleidoscopeModule/shaders/SHADERS.txt +1 -0
- package/ios/KaleidoscopeModule/shaders/data-mesh.metalsrc +99 -0
- package/ios/KaleidoscopeModule/shaders/nebula.metalsrc +56 -51
- package/ios/KaleidoscopeModule/shaders/outrun-grid.metalsrc +12 -14
- package/package.json +8 -1
|
@@ -565,34 +565,38 @@ void main() {
|
|
|
565
565
|
|
|
566
566
|
col = mix(col, sunCol, sunBody);
|
|
567
567
|
} else {
|
|
568
|
-
// --- FLOOR --- perspective grid
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
//
|
|
573
|
-
//
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
//
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
//
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
568
|
+
// --- FLOOR --- perspective grid, a faithful port of a known-good community
|
|
569
|
+
// outrun grid (prior versions read as a too-dense, flickering sheet). Work in
|
|
570
|
+
// the reference's centered frame: cx is full-width centered x, dy is the
|
|
571
|
+
// centered distance BELOW the horizon. The additive offset caps the depth at
|
|
572
|
+
// the horizon, and putting big cells in the near field (low min depth) is what
|
|
573
|
+
// keeps the line spacing above a pixel, so it neither sheets nor shimmers.
|
|
574
|
+
float cx = 2.0 * fx; // = (2*vUv.x - 1) * aspect
|
|
575
|
+
float dy = 2.0 * (h - fy); // centered distance below the horizon (> 0)
|
|
576
|
+
|
|
577
|
+
// Cell count: uGridDensity 4 -> numerator 1.0 (sparse, big near cells). x
|
|
578
|
+
// widens with depth (the 0.7 factor); scroll is a slow drift toward the viewer.
|
|
579
|
+
float num = uGridDensity * 0.25;
|
|
580
|
+
float depth = num / (dy + 0.05);
|
|
581
|
+
vec2 g = vec2(cx * depth * 0.7, depth);
|
|
582
|
+
g.y += uTime * uSpeed * 0.3;
|
|
583
|
+
vec2 e = abs(fract(g) - 0.5);
|
|
584
|
+
|
|
585
|
+
// PIXEL-CALIBRATED line width: each line core is a fixed ~px wide in SCREEN
|
|
586
|
+
// PIXELS (via uResolution), the same at every depth and every resolution. The
|
|
587
|
+
// old depth^2*const width was constant in theory but landed sub-pixel, so
|
|
588
|
+
// discrete sampling rendered some rungs thick and others thin -> the uneven
|
|
589
|
+
// rungs that read as flicker. Solving sz so screen thickness == px: the rungs
|
|
590
|
+
// (g.y, compression ~depth^2/num) need sz.y = depth^2 * pf / num; the verticals
|
|
591
|
+
// (g.x) need sz.x = depth * 0.7 * pf. uGridGlow sets px (0.5 -> 2 px).
|
|
592
|
+
float pf = (uGridGlow * 4.0) / uResolution.y;
|
|
593
|
+
vec2 sz = vec2(depth * 0.7 * pf, depth * depth * pf / num);
|
|
594
|
+
vec2 lines = 1.0 - smoothstep(vec2(0.0), sz, e);
|
|
595
|
+
lines += (1.0 - smoothstep(vec2(0.0), sz * 4.0, e)) * 0.5;
|
|
596
|
+
float gridVal = clamp(lines.x + lines.y, 0.0, 1.0);
|
|
597
|
+
|
|
598
|
+
vec3 floorBase = uSkyHorizon * 0.06;
|
|
599
|
+
col = mix(floorBase, uGridColor, gridVal * calm);
|
|
596
600
|
}
|
|
597
601
|
|
|
598
602
|
// Glowing horizon seam where floor meets sky.
|
|
@@ -740,9 +744,11 @@ const float MIN_DIVIDE = 64.0;
|
|
|
740
744
|
const float MAX_DIVIDE = 0.01;
|
|
741
745
|
// Number of stacked starfield layers. Compile-time constant so the layer
|
|
742
746
|
// loop has a fixed integer bound (cross-compile-safe; no float loop counter).
|
|
743
|
-
//
|
|
744
|
-
//
|
|
745
|
-
|
|
747
|
+
// 7 (was 8 #74, was 12 #39) for cost; the work is linear in the count and
|
|
748
|
+
// dimByDensity rebalances per-star brightness automatically. 7 keeps the dense
|
|
749
|
+
// look essentially intact (6 was visibly sparser at some animation phases);
|
|
750
|
+
// paired with the empty-cell early-out below it lands ~34% under the old 8.
|
|
751
|
+
const int STARFIELD_LAYERS_COUNT = 7;
|
|
746
752
|
|
|
747
753
|
mat2 Rotate(float angle) {
|
|
748
754
|
float s = sin(angle);
|
|
@@ -810,6 +816,12 @@ vec3 StarFieldLayer(vec2 uv, float rotAngle) {
|
|
|
810
816
|
float size = fract(randomN * 1356.33);
|
|
811
817
|
float flareSwitch = smoothstep(0.9, 1.0, size);
|
|
812
818
|
float star = Star(randomPosition, flareSwitch, rotAngle, randomN);
|
|
819
|
+
// The per-cell color below is multiplied by `star` at the end, so for any
|
|
820
|
+
// cell whose star is 0 (Star() returns exactly 0 for d >= 1.0, i.e. the
|
|
821
|
+
// empty-sky majority of the 8x9 = 72 cells/pixel) the whole term is 0.
|
|
822
|
+
// Skipping the sin(vec3) color work for those cells is output-identical and
|
|
823
|
+
// is the bulk of the win (issue #74).
|
|
824
|
+
if (star <= 0.0) continue;
|
|
813
825
|
|
|
814
826
|
// fract trick: random colors
|
|
815
827
|
float randomStarColorSeed = fract(randomN * 2150.0) * (3.0 * PI) * deltaTimeTwinkle;
|
|
@@ -1678,6 +1690,167 @@ void main() {
|
|
|
1678
1690
|
// Premultiplied output; tint grades the (premultiplied) color, not alpha.
|
|
1679
1691
|
oColor = vec4(blobCol * uColor, blobAlpha);
|
|
1680
1692
|
}
|
|
1693
|
+
"""
|
|
1694
|
+
|
|
1695
|
+
const val DATA_MESH_FRAG = """#version 300 es
|
|
1696
|
+
precision highp float;
|
|
1697
|
+
|
|
1698
|
+
uniform float uTime; // seconds, monotonically increasing; range [0, inf)
|
|
1699
|
+
uniform vec2 uResolution; // framebuffer size in pixels; both components > 0
|
|
1700
|
+
uniform vec3 uBgTop; // background gradient color at the top of frame
|
|
1701
|
+
uniform vec3 uBgBottom; // background gradient color at the bottom of frame
|
|
1702
|
+
uniform vec3 uLineColor; // mid wireframe-line tint (the trough/body color)
|
|
1703
|
+
uniform vec3 uCrestColor; // crest highlight color (brightest along the peaks)
|
|
1704
|
+
uniform vec3 uHazeColor; // atmospheric haze tint on the far rows
|
|
1705
|
+
uniform vec3 uAccentColor; // the one restrained accent (e.g. enterprise red)
|
|
1706
|
+
uniform float uWaveScale; // wave-field spatial frequency; lower = looser, broader hills
|
|
1707
|
+
uniform float uWaveAmp; // vertical wave displacement amount (near rows)
|
|
1708
|
+
uniform float uWaveSpeed; // animation rate; 0 freezes the surface
|
|
1709
|
+
uniform float uGridX; // column-grid density across the surface; keep loose
|
|
1710
|
+
uniform float uHorizon; // horizon height in uv.y units (rows converge toward it)
|
|
1711
|
+
uniform float uFarScale; // perspective scale of the farthest row, 0.05..0.5 (>0)
|
|
1712
|
+
uniform float uSlant; // diagonal tilt; raises the right side for corner composition
|
|
1713
|
+
uniform float uLineWidth; // wireframe line half-width (smaller = finer, sharper)
|
|
1714
|
+
uniform float uNodeMix; // 0..1 emphasis of glowing intersection nodes (dot reading)
|
|
1715
|
+
uniform float uStrutMix; // 0..1 emphasis of vertical struts (wireframe reading)
|
|
1716
|
+
uniform float uGlow; // overall additive mesh-glow / bloom strength
|
|
1717
|
+
uniform float uHaze; // atmospheric far-haze strength
|
|
1718
|
+
uniform float uParticles; // floating-particle intensity; 0 disables the field
|
|
1719
|
+
uniform float uAccent; // lone accent-mote intensity; 0 disables it
|
|
1720
|
+
uniform float uCalm; // 0..1 eases the additive glow at frame center (face zone)
|
|
1721
|
+
|
|
1722
|
+
in highp vec2 vUv;
|
|
1723
|
+
out vec4 oColor;
|
|
1724
|
+
|
|
1725
|
+
// ROWS / PARTICLES must stay compile-time constants (GLSL ES loop bounds). ROWS is
|
|
1726
|
+
// kept modest on purpose (loose mesh); perspective bunching toward the horizon
|
|
1727
|
+
// makes it read as far more lines than it costs.
|
|
1728
|
+
#define ROWS 18
|
|
1729
|
+
#define PARTICLES 10
|
|
1730
|
+
#define WAVE_DEPTH_SPAN 4.5 // world-depth the eased row range maps across
|
|
1731
|
+
#define COL_SHARP 48.0 // column-stripe sharpness in cell-phase units
|
|
1732
|
+
#define Y_NEAR (-0.62) // nearest row baseline (just below the bottom edge)
|
|
1733
|
+
|
|
1734
|
+
// Cheap stable hash for the particle field (highp; the 43758.5453 multiplier
|
|
1735
|
+
// bands under mediump, same note as clouds/nebula).
|
|
1736
|
+
float hash11(float n) {
|
|
1737
|
+
return fract(sin(n * 12.9898) * 43758.5453123);
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
// The shared surface. x is perspective world-x, z is eased world-depth, t is time.
|
|
1741
|
+
// A small sum of sines whose x/z cross terms produce the hills, valleys, and
|
|
1742
|
+
// saddles; bounded to roughly [-1.6, 1.6].
|
|
1743
|
+
float waveField(float x, float z, float t) {
|
|
1744
|
+
float h = 0.0;
|
|
1745
|
+
h += sin(x * 1.00 + z * 0.55 + t) * 0.60;
|
|
1746
|
+
h += sin(x * 0.55 - z * 0.95 - t * 0.70) * 0.45;
|
|
1747
|
+
h += sin((x + z) * 0.45 + t * 0.40 + 1.7) * 0.40; // diagonal ridges -> saddles
|
|
1748
|
+
h += sin(x * 1.70 - z * 0.30 + t * 1.20) * 0.16; // fine ripple
|
|
1749
|
+
return h;
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
void main() {
|
|
1753
|
+
vec2 fragCoord = vUv * uResolution;
|
|
1754
|
+
vec2 uv = (fragCoord - 0.5 * uResolution) / uResolution.y; // centered, aspect-correct
|
|
1755
|
+
|
|
1756
|
+
// Background: smooth vertical gradient, no texture. g = 0 bottom .. 1 top.
|
|
1757
|
+
float g = clamp(uv.y + 0.5, 0.0, 1.0);
|
|
1758
|
+
vec3 col = mix(uBgBottom, uBgTop, g);
|
|
1759
|
+
|
|
1760
|
+
// Ease additive glow near the frame center (the subject's face sits there).
|
|
1761
|
+
float calm = 1.0 - uCalm * (1.0 - smoothstep(0.18, 0.62, length(uv)));
|
|
1762
|
+
|
|
1763
|
+
float t = uTime * uWaveSpeed;
|
|
1764
|
+
float horizon = clamp(uHorizon, -0.2, 0.45);
|
|
1765
|
+
|
|
1766
|
+
// Line-glow widths from the half-width. The core line keeps the one exp() (its
|
|
1767
|
+
// sharp gaussian is the wireframe signature); the bloom halo and the vertical
|
|
1768
|
+
// strut use rational falloffs (1/(1+k·dy^2)) instead of more exp() calls, which
|
|
1769
|
+
// are ~8x-weighted transcendentals on the hot per-row path. The node reuses the
|
|
1770
|
+
// core exp directly. Net: 2 exp/row (core + column), down from 5.
|
|
1771
|
+
float coreSharp = 1.0 / max(uLineWidth * uLineWidth, 1e-5);
|
|
1772
|
+
float haloK = coreSharp * 0.14; // rational-bloom width (matches the old halo half-width)
|
|
1773
|
+
float strutK = coreSharp * 0.14; // rational vertical-bridge width
|
|
1774
|
+
|
|
1775
|
+
vec3 mesh = vec3(0.0);
|
|
1776
|
+
vec3 haze = vec3(0.0);
|
|
1777
|
+
|
|
1778
|
+
for (int i = 0; i < ROWS; i++) {
|
|
1779
|
+
float rowT = float(i) / float(ROWS - 1); // 0 near .. 1 far
|
|
1780
|
+
float om = 1.0 - rowT;
|
|
1781
|
+
float f = 1.0 - om * om; // eased depth: rows bunch toward horizon
|
|
1782
|
+
float persp = mix(1.0, uFarScale, f);
|
|
1783
|
+
persp = max(persp, uFarScale); // guard the divide (uFarScale > 0)
|
|
1784
|
+
|
|
1785
|
+
// Row baseline in screen-y, with a diagonal tilt for corner composition.
|
|
1786
|
+
float baseY = mix(Y_NEAR, horizon, f) + uv.x * uSlant * persp;
|
|
1787
|
+
|
|
1788
|
+
// Early-out: skip the sines for any row that cannot reach this pixel. Margin
|
|
1789
|
+
// covers the max wave displacement plus the strut's vertical bridge.
|
|
1790
|
+
float reach = persp * uWaveAmp * 1.7 + uLineWidth * 3.0 + 0.06;
|
|
1791
|
+
if (abs(uv.y - baseY) > reach) continue;
|
|
1792
|
+
|
|
1793
|
+
float worldX = uv.x / persp;
|
|
1794
|
+
float h = waveField(worldX * uWaveScale, f * WAVE_DEPTH_SPAN, t);
|
|
1795
|
+
float surfY = baseY + persp * uWaveAmp * h;
|
|
1796
|
+
float dy = uv.y - surfY;
|
|
1797
|
+
|
|
1798
|
+
// Crest factor: peaks of the field glow white, troughs stay the line tint.
|
|
1799
|
+
float crest = smoothstep(0.2, 1.4, h);
|
|
1800
|
+
|
|
1801
|
+
// Horizontal ribbon: sharp gaussian core (the line) + rational bloom halo.
|
|
1802
|
+
float dy2 = dy * dy;
|
|
1803
|
+
float core = exp(-dy2 * coreSharp);
|
|
1804
|
+
float ribbon = core + 0.22 / (1.0 + dy2 * haloK);
|
|
1805
|
+
|
|
1806
|
+
// Column grid: one bright stripe per cell of worldX. cph = 0 at the stripe.
|
|
1807
|
+
float cph = fract(worldX * uGridX) - 0.5;
|
|
1808
|
+
float colLine = exp(-cph * cph * COL_SHARP);
|
|
1809
|
+
|
|
1810
|
+
// Vertical strut (rational falloff in y so it bridges toward neighbors, gated
|
|
1811
|
+
// by the column) and the intersection node (core line x column -> a glowing
|
|
1812
|
+
// dot; reuses the core exp, no extra transcendental).
|
|
1813
|
+
float strut = colLine / (1.0 + dy2 * strutK);
|
|
1814
|
+
float node = core * colLine;
|
|
1815
|
+
|
|
1816
|
+
// Atmospheric fade: far rows dim and tint toward the haze color.
|
|
1817
|
+
float fade = om * om; // 1 near .. 0 far
|
|
1818
|
+
float lit = ribbon + uStrutMix * strut + uNodeMix * node * 2.0;
|
|
1819
|
+
vec3 lineCol = mix(uLineColor, uCrestColor, crest);
|
|
1820
|
+
|
|
1821
|
+
// Crest-dominant brightness: troughs stay dim, peaks carry the illumination.
|
|
1822
|
+
mesh += lineCol * lit * fade * (0.35 + 1.0 * crest);
|
|
1823
|
+
haze += uHazeColor * ribbon * (1.0 - fade) * crest;
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
col += mesh * uGlow * calm;
|
|
1827
|
+
col += haze * uHaze * calm;
|
|
1828
|
+
|
|
1829
|
+
// Sparse floating particles; index 0 is the lone accent mote (independent of
|
|
1830
|
+
// uParticles so an accent can show with the particle field off).
|
|
1831
|
+
if (uParticles > 0.0 || uAccent > 0.0) {
|
|
1832
|
+
vec3 motes = vec3(0.0);
|
|
1833
|
+
for (int p = 0; p < PARTICLES; p++) {
|
|
1834
|
+
float fp = float(p);
|
|
1835
|
+
vec2 seed = vec2(hash11(fp * 1.7 + 0.3), hash11(fp * 3.1 + 1.9));
|
|
1836
|
+
vec2 ppos = (seed * 2.0 - 1.0) * vec2(0.92, 0.46);
|
|
1837
|
+
ppos.x += sin(uTime * 0.07 + fp * 2.3) * 0.03;
|
|
1838
|
+
ppos.y += cos(uTime * 0.05 + fp * 1.7) * 0.03;
|
|
1839
|
+
float twinkle = 0.5 + 0.5 * sin(uTime * (0.6 + hash11(fp * 5.0)) + fp * 4.0);
|
|
1840
|
+
float pd = length(uv - ppos);
|
|
1841
|
+
float glint = exp(-pd * pd * 2300.0) * twinkle;
|
|
1842
|
+
vec3 pcol = (p == 0) ? uAccentColor * uAccent : uCrestColor * uParticles;
|
|
1843
|
+
motes += pcol * glint;
|
|
1844
|
+
}
|
|
1845
|
+
col += motes * calm;
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
// Soft highlight rolloff: fold the additive foreground pile-up into clean white
|
|
1849
|
+
// crests instead of a clipped slab; leaves the dark gradient essentially intact.
|
|
1850
|
+
col = vec3(1.0) - exp(-col);
|
|
1851
|
+
|
|
1852
|
+
oColor = vec4(col, 1.0);
|
|
1853
|
+
}
|
|
1681
1854
|
"""
|
|
1682
1855
|
|
|
1683
1856
|
// Generative background shaders, by name. The generic shader processor and
|
|
@@ -1698,5 +1871,6 @@ void main() {
|
|
|
1698
1871
|
"anamorphic-lensflare" to ANAMORPHIC_LENSFLARE_FRAG,
|
|
1699
1872
|
"light-beams-and-motes" to LIGHT_BEAMS_AND_MOTES_FRAG,
|
|
1700
1873
|
"corporate-blobs" to CORPORATE_BLOBS_FRAG,
|
|
1874
|
+
"data-mesh" to DATA_MESH_FRAG,
|
|
1701
1875
|
)
|
|
1702
1876
|
}
|
|
Binary file
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Data-mesh's editor form: the shader OWNS its control layout. One
|
|
2
|
+
// <Control uniform="…"/> per uniform; grouped into palette / surface / glow
|
|
3
|
+
// sections so the big color levers, the structural dials, and the additive extras
|
|
4
|
+
// read as three clusters. A new primitive flows in through <Control> without
|
|
5
|
+
// touching this file. Conventional layer id: "mesh".
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
Control,
|
|
9
|
+
ControlForm,
|
|
10
|
+
ControlSection,
|
|
11
|
+
type KaleidoscopeControls,
|
|
12
|
+
} from '../../../src/components/preset-control-panel';
|
|
13
|
+
import { DATA_MESH_CONTROLS } from './data-mesh';
|
|
14
|
+
|
|
15
|
+
export function DataMeshForm({ uniforms, onPatch, disabled }: KaleidoscopeControls) {
|
|
16
|
+
return (
|
|
17
|
+
<ControlForm
|
|
18
|
+
id="mesh"
|
|
19
|
+
uniforms={uniforms.mesh ?? {}}
|
|
20
|
+
onPatch={onPatch}
|
|
21
|
+
disabled={disabled}
|
|
22
|
+
controls={DATA_MESH_CONTROLS}
|
|
23
|
+
>
|
|
24
|
+
<ControlSection title="palette">
|
|
25
|
+
<Control uniform="uBgTop" />
|
|
26
|
+
<Control uniform="uBgBottom" />
|
|
27
|
+
<Control uniform="uLineColor" />
|
|
28
|
+
<Control uniform="uCrestColor" />
|
|
29
|
+
<Control uniform="uHazeColor" />
|
|
30
|
+
<Control uniform="uAccentColor" />
|
|
31
|
+
</ControlSection>
|
|
32
|
+
<ControlSection title="surface">
|
|
33
|
+
<Control uniform="uWaveScale" />
|
|
34
|
+
<Control uniform="uWaveAmp" />
|
|
35
|
+
<Control uniform="uWaveSpeed" />
|
|
36
|
+
<Control uniform="uGridX" />
|
|
37
|
+
<Control uniform="uHorizon" />
|
|
38
|
+
<Control uniform="uFarScale" />
|
|
39
|
+
<Control uniform="uSlant" />
|
|
40
|
+
<Control uniform="uLineWidth" />
|
|
41
|
+
<Control uniform="uNodeMix" />
|
|
42
|
+
<Control uniform="uStrutMix" />
|
|
43
|
+
</ControlSection>
|
|
44
|
+
<ControlSection title="glow">
|
|
45
|
+
<Control uniform="uGlow" />
|
|
46
|
+
<Control uniform="uHaze" />
|
|
47
|
+
<Control uniform="uParticles" />
|
|
48
|
+
<Control uniform="uAccent" />
|
|
49
|
+
<Control uniform="uCalm" />
|
|
50
|
+
</ControlSection>
|
|
51
|
+
</ControlForm>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// Data-mesh: a mid-2000s corporate digital-futurism background. A large smooth
|
|
2
|
+
// three-dimensional wave surface drawn as a fine wireframe of perspective rows,
|
|
3
|
+
// with glowing nodes at the grid intersections, bent into broad hills, valleys,
|
|
4
|
+
// and saddle curves and receding into deep virtual space. Electric crest glow,
|
|
5
|
+
// soft turquoise bloom, faint atmospheric haze on the far rows, and a sparse
|
|
6
|
+
// drift of particles (one of which is the lone accent mote). Enterprise box-art
|
|
7
|
+
// and OEM-wallpaper idiom (Microsoft / Dell / SQL Server / Alienware era), clean
|
|
8
|
+
// negative space for a logo. An opaque BACKGROUND layer; the masked subject
|
|
9
|
+
// composites over it downstream.
|
|
10
|
+
//
|
|
11
|
+
// Technique (performance-first): NO raymarch, NO fbm, NO variable-exponent pow.
|
|
12
|
+
// The surface is a stack of ROWS perspective-spaced ridgelines. Every row samples
|
|
13
|
+
// ONE shared 2D wave field H(worldX, depth, time), so adjacent rows are continuous
|
|
14
|
+
// and read as a single coherent surface rather than independent lines. A row's
|
|
15
|
+
// screen height is its perspective baseline plus H scaled by that row's
|
|
16
|
+
// perspective factor. Per pixel the bounded ROWS loop accumulates an analytic
|
|
17
|
+
// ribbon + strut + node glow; an early-out skips any row whose baseline is outside
|
|
18
|
+
// this pixel's vertical reach BEFORE the sines run, so most rows cost a compare.
|
|
19
|
+
// Keep the mesh loose: ROWS and uGridX are deliberately modest, not hi-def.
|
|
20
|
+
//
|
|
21
|
+
// Overdrive surface: the color set is the mood (uBgTop/uBgBottom gradient,
|
|
22
|
+
// uLineColor mid tint, uCrestColor peak highlight, uHazeColor far atmosphere,
|
|
23
|
+
// uAccentColor the one restrained accent). Structural dials (uWaveScale/Amp/Speed,
|
|
24
|
+
// uGridX, uHorizon, uFarScale, uSlant) set composition and motion; uNodeMix /
|
|
25
|
+
// uStrutMix grade the lines-vs-dots reading; uGlow / uHaze / uParticles / uAccent
|
|
26
|
+
// set the additive extras. uCalm eases the additive glow near frame center, where
|
|
27
|
+
// the masked subject's face sits.
|
|
28
|
+
//
|
|
29
|
+
// UV convention: matches passthrough.vert. vUv = (0, 0) bottom-left, (1, 1)
|
|
30
|
+
// top-right; fragCoord is reconstructed as vUv * uResolution and the centered,
|
|
31
|
+
// aspect-correct uv divides by height. Fully procedural: no input texture, no
|
|
32
|
+
// gl_FragCoord, so net texture flips are zero on every runtime (web/Android/Metal
|
|
33
|
+
// alike).
|
|
34
|
+
//
|
|
35
|
+
// Cross-target correctness: the only divide is worldX = uv.x / persp, and persp is
|
|
36
|
+
// clamped to max(persp, uFarScale) with uFarScale >= 0.05, so it never approaches
|
|
37
|
+
// zero (no Inf/NaN, no highp-vs-mediump divergence at a vanishing line). No fwidth
|
|
38
|
+
// or derivatives (depth fade and haze are analytic, not screen-space). No
|
|
39
|
+
// variable-exponent pow, no atan, no gl_FragCoord, no arrays, no extensions. ROWS
|
|
40
|
+
// and PARTICLES stay compile-time constants (GLSL ES loop bounds); the dynamic
|
|
41
|
+
// continue/break inside are uniform-flow and survive the SPIR-V -> MSL step.
|
|
42
|
+
//
|
|
43
|
+
// Precision: highp float throughout. worldX grows up to ~0.9 / uFarScale and feeds
|
|
44
|
+
// fract() for the column grid, so the field needs the range and the front-to-far
|
|
45
|
+
// dynamic range; mediump would band the gradient and alias the far columns.
|
|
46
|
+
|
|
47
|
+
#version 300 es
|
|
48
|
+
precision highp float;
|
|
49
|
+
|
|
50
|
+
uniform float uTime; // seconds, monotonically increasing; range [0, inf)
|
|
51
|
+
uniform vec2 uResolution; // framebuffer size in pixels; both components > 0
|
|
52
|
+
uniform vec3 uBgTop; // background gradient color at the top of frame
|
|
53
|
+
uniform vec3 uBgBottom; // background gradient color at the bottom of frame
|
|
54
|
+
uniform vec3 uLineColor; // mid wireframe-line tint (the trough/body color)
|
|
55
|
+
uniform vec3 uCrestColor; // crest highlight color (brightest along the peaks)
|
|
56
|
+
uniform vec3 uHazeColor; // atmospheric haze tint on the far rows
|
|
57
|
+
uniform vec3 uAccentColor; // the one restrained accent (e.g. enterprise red)
|
|
58
|
+
uniform float uWaveScale; // wave-field spatial frequency; lower = looser, broader hills
|
|
59
|
+
uniform float uWaveAmp; // vertical wave displacement amount (near rows)
|
|
60
|
+
uniform float uWaveSpeed; // animation rate; 0 freezes the surface
|
|
61
|
+
uniform float uGridX; // column-grid density across the surface; keep loose
|
|
62
|
+
uniform float uHorizon; // horizon height in uv.y units (rows converge toward it)
|
|
63
|
+
uniform float uFarScale; // perspective scale of the farthest row, 0.05..0.5 (>0)
|
|
64
|
+
uniform float uSlant; // diagonal tilt; raises the right side for corner composition
|
|
65
|
+
uniform float uLineWidth; // wireframe line half-width (smaller = finer, sharper)
|
|
66
|
+
uniform float uNodeMix; // 0..1 emphasis of glowing intersection nodes (dot reading)
|
|
67
|
+
uniform float uStrutMix; // 0..1 emphasis of vertical struts (wireframe reading)
|
|
68
|
+
uniform float uGlow; // overall additive mesh-glow / bloom strength
|
|
69
|
+
uniform float uHaze; // atmospheric far-haze strength
|
|
70
|
+
uniform float uParticles; // floating-particle intensity; 0 disables the field
|
|
71
|
+
uniform float uAccent; // lone accent-mote intensity; 0 disables it
|
|
72
|
+
uniform float uCalm; // 0..1 eases the additive glow at frame center (face zone)
|
|
73
|
+
|
|
74
|
+
in highp vec2 vUv;
|
|
75
|
+
out vec4 oColor;
|
|
76
|
+
|
|
77
|
+
// ROWS / PARTICLES must stay compile-time constants (GLSL ES loop bounds). ROWS is
|
|
78
|
+
// kept modest on purpose (loose mesh); perspective bunching toward the horizon
|
|
79
|
+
// makes it read as far more lines than it costs.
|
|
80
|
+
#define ROWS 18
|
|
81
|
+
#define PARTICLES 10
|
|
82
|
+
#define WAVE_DEPTH_SPAN 4.5 // world-depth the eased row range maps across
|
|
83
|
+
#define COL_SHARP 48.0 // column-stripe sharpness in cell-phase units
|
|
84
|
+
#define Y_NEAR (-0.62) // nearest row baseline (just below the bottom edge)
|
|
85
|
+
|
|
86
|
+
// Cheap stable hash for the particle field (highp; the 43758.5453 multiplier
|
|
87
|
+
// bands under mediump, same note as clouds/nebula).
|
|
88
|
+
float hash11(float n) {
|
|
89
|
+
return fract(sin(n * 12.9898) * 43758.5453123);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// The shared surface. x is perspective world-x, z is eased world-depth, t is time.
|
|
93
|
+
// A small sum of sines whose x/z cross terms produce the hills, valleys, and
|
|
94
|
+
// saddles; bounded to roughly [-1.6, 1.6].
|
|
95
|
+
float waveField(float x, float z, float t) {
|
|
96
|
+
float h = 0.0;
|
|
97
|
+
h += sin(x * 1.00 + z * 0.55 + t) * 0.60;
|
|
98
|
+
h += sin(x * 0.55 - z * 0.95 - t * 0.70) * 0.45;
|
|
99
|
+
h += sin((x + z) * 0.45 + t * 0.40 + 1.7) * 0.40; // diagonal ridges -> saddles
|
|
100
|
+
h += sin(x * 1.70 - z * 0.30 + t * 1.20) * 0.16; // fine ripple
|
|
101
|
+
return h;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
void main() {
|
|
105
|
+
vec2 fragCoord = vUv * uResolution;
|
|
106
|
+
vec2 uv = (fragCoord - 0.5 * uResolution) / uResolution.y; // centered, aspect-correct
|
|
107
|
+
|
|
108
|
+
// Background: smooth vertical gradient, no texture. g = 0 bottom .. 1 top.
|
|
109
|
+
float g = clamp(uv.y + 0.5, 0.0, 1.0);
|
|
110
|
+
vec3 col = mix(uBgBottom, uBgTop, g);
|
|
111
|
+
|
|
112
|
+
// Ease additive glow near the frame center (the subject's face sits there).
|
|
113
|
+
float calm = 1.0 - uCalm * (1.0 - smoothstep(0.18, 0.62, length(uv)));
|
|
114
|
+
|
|
115
|
+
float t = uTime * uWaveSpeed;
|
|
116
|
+
float horizon = clamp(uHorizon, -0.2, 0.45);
|
|
117
|
+
|
|
118
|
+
// Line-glow widths from the half-width. The core line keeps the one exp() (its
|
|
119
|
+
// sharp gaussian is the wireframe signature); the bloom halo and the vertical
|
|
120
|
+
// strut use rational falloffs (1/(1+k·dy^2)) instead of more exp() calls, which
|
|
121
|
+
// are ~8x-weighted transcendentals on the hot per-row path. The node reuses the
|
|
122
|
+
// core exp directly. Net: 2 exp/row (core + column), down from 5.
|
|
123
|
+
float coreSharp = 1.0 / max(uLineWidth * uLineWidth, 1e-5);
|
|
124
|
+
float haloK = coreSharp * 0.14; // rational-bloom width (matches the old halo half-width)
|
|
125
|
+
float strutK = coreSharp * 0.14; // rational vertical-bridge width
|
|
126
|
+
|
|
127
|
+
vec3 mesh = vec3(0.0);
|
|
128
|
+
vec3 haze = vec3(0.0);
|
|
129
|
+
|
|
130
|
+
for (int i = 0; i < ROWS; i++) {
|
|
131
|
+
float rowT = float(i) / float(ROWS - 1); // 0 near .. 1 far
|
|
132
|
+
float om = 1.0 - rowT;
|
|
133
|
+
float f = 1.0 - om * om; // eased depth: rows bunch toward horizon
|
|
134
|
+
float persp = mix(1.0, uFarScale, f);
|
|
135
|
+
persp = max(persp, uFarScale); // guard the divide (uFarScale > 0)
|
|
136
|
+
|
|
137
|
+
// Row baseline in screen-y, with a diagonal tilt for corner composition.
|
|
138
|
+
float baseY = mix(Y_NEAR, horizon, f) + uv.x * uSlant * persp;
|
|
139
|
+
|
|
140
|
+
// Early-out: skip the sines for any row that cannot reach this pixel. Margin
|
|
141
|
+
// covers the max wave displacement plus the strut's vertical bridge.
|
|
142
|
+
float reach = persp * uWaveAmp * 1.7 + uLineWidth * 3.0 + 0.06;
|
|
143
|
+
if (abs(uv.y - baseY) > reach) continue;
|
|
144
|
+
|
|
145
|
+
float worldX = uv.x / persp;
|
|
146
|
+
float h = waveField(worldX * uWaveScale, f * WAVE_DEPTH_SPAN, t);
|
|
147
|
+
float surfY = baseY + persp * uWaveAmp * h;
|
|
148
|
+
float dy = uv.y - surfY;
|
|
149
|
+
|
|
150
|
+
// Crest factor: peaks of the field glow white, troughs stay the line tint.
|
|
151
|
+
float crest = smoothstep(0.2, 1.4, h);
|
|
152
|
+
|
|
153
|
+
// Horizontal ribbon: sharp gaussian core (the line) + rational bloom halo.
|
|
154
|
+
float dy2 = dy * dy;
|
|
155
|
+
float core = exp(-dy2 * coreSharp);
|
|
156
|
+
float ribbon = core + 0.22 / (1.0 + dy2 * haloK);
|
|
157
|
+
|
|
158
|
+
// Column grid: one bright stripe per cell of worldX. cph = 0 at the stripe.
|
|
159
|
+
float cph = fract(worldX * uGridX) - 0.5;
|
|
160
|
+
float colLine = exp(-cph * cph * COL_SHARP);
|
|
161
|
+
|
|
162
|
+
// Vertical strut (rational falloff in y so it bridges toward neighbors, gated
|
|
163
|
+
// by the column) and the intersection node (core line x column -> a glowing
|
|
164
|
+
// dot; reuses the core exp, no extra transcendental).
|
|
165
|
+
float strut = colLine / (1.0 + dy2 * strutK);
|
|
166
|
+
float node = core * colLine;
|
|
167
|
+
|
|
168
|
+
// Atmospheric fade: far rows dim and tint toward the haze color.
|
|
169
|
+
float fade = om * om; // 1 near .. 0 far
|
|
170
|
+
float lit = ribbon + uStrutMix * strut + uNodeMix * node * 2.0;
|
|
171
|
+
vec3 lineCol = mix(uLineColor, uCrestColor, crest);
|
|
172
|
+
|
|
173
|
+
// Crest-dominant brightness: troughs stay dim, peaks carry the illumination.
|
|
174
|
+
mesh += lineCol * lit * fade * (0.35 + 1.0 * crest);
|
|
175
|
+
haze += uHazeColor * ribbon * (1.0 - fade) * crest;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
col += mesh * uGlow * calm;
|
|
179
|
+
col += haze * uHaze * calm;
|
|
180
|
+
|
|
181
|
+
// Sparse floating particles; index 0 is the lone accent mote (independent of
|
|
182
|
+
// uParticles so an accent can show with the particle field off).
|
|
183
|
+
if (uParticles > 0.0 || uAccent > 0.0) {
|
|
184
|
+
vec3 motes = vec3(0.0);
|
|
185
|
+
for (int p = 0; p < PARTICLES; p++) {
|
|
186
|
+
float fp = float(p);
|
|
187
|
+
vec2 seed = vec2(hash11(fp * 1.7 + 0.3), hash11(fp * 3.1 + 1.9));
|
|
188
|
+
vec2 ppos = (seed * 2.0 - 1.0) * vec2(0.92, 0.46);
|
|
189
|
+
ppos.x += sin(uTime * 0.07 + fp * 2.3) * 0.03;
|
|
190
|
+
ppos.y += cos(uTime * 0.05 + fp * 1.7) * 0.03;
|
|
191
|
+
float twinkle = 0.5 + 0.5 * sin(uTime * (0.6 + hash11(fp * 5.0)) + fp * 4.0);
|
|
192
|
+
float pd = length(uv - ppos);
|
|
193
|
+
float glint = exp(-pd * pd * 2300.0) * twinkle;
|
|
194
|
+
vec3 pcol = (p == 0) ? uAccentColor * uAccent : uCrestColor * uParticles;
|
|
195
|
+
motes += pcol * glint;
|
|
196
|
+
}
|
|
197
|
+
col += motes * calm;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Soft highlight rolloff: fold the additive foreground pile-up into clean white
|
|
201
|
+
// crests instead of a clipped slab; leaves the dark gradient essentially intact.
|
|
202
|
+
col = vec3(1.0) - exp(-col);
|
|
203
|
+
|
|
204
|
+
oColor = vec4(col, 1.0);
|
|
205
|
+
}
|