]> git.nega.tv - josh/narcissus/commitdiff
shark-shaders: Add color_map module
authorJoshua Simmons <josh@nega.tv>
Sun, 19 Oct 2025 14:29:07 +0000 (16:29 +0200)
committerJoshua Simmons <josh@nega.tv>
Sun, 19 Oct 2025 14:46:22 +0000 (16:46 +0200)
title/shark-shaders/shaders/color_map.slang [new file with mode: 0644]
title/shark-shaders/shaders/draw_2d.slang

diff --git a/title/shark-shaders/shaders/color_map.slang b/title/shark-shaders/shaders/color_map.slang
new file mode 100644 (file)
index 0000000..63a367a
--- /dev/null
@@ -0,0 +1,79 @@
+module color_map;
+
+// Polynomial approximations of popular color maps for data science.
+//
+// Created by mattz
+// https://www.shadertoy.com/view/WlfXRN
+// https://www.shadertoy.com/view/4fScWt
+namespace color_map {
+
+public float3 viridis(float t) {
+    let t = clamp(t, 0.0, 1.0);
+    let c0 = float3(0.2777273272234177, 0.005407344544966578, 0.3340998053353061);
+    let c1 = float3(0.1050930431085774, 1.404613529898575, 1.384590162594685);
+    let c2 = float3(-0.3308618287255563, 0.214847559468213, 0.09509516302823659);
+    let c3 = float3(-4.634230498983486, -5.799100973351585, -19.33244095627987);
+    let c4 = float3(6.228269936347081, 14.17993336680509, 56.69055260068105);
+    let c5 = float3(4.776384997670288, -13.74514537774601, -65.35303263337234);
+    let c6 = float3(-5.435455855934631, 4.645852612178535, 26.3124352495832);
+    return c0 + t * (c1 + t * (c2 + t * (c3 + t * (c4 + t * (c5 + t * c6)))));
+}
+
+public float3 plasma(float t) {
+    let t = clamp(t, 0.0, 1.0);
+    let c0 = float3(0.05873234392399702, 0.02333670892565664, 0.5433401826748754);
+    let c1 = float3(2.176514634195958, 0.2383834171260182, 0.7539604599784036);
+    let c2 = float3(-2.689460476458034, -7.455851135738909, 3.110799939717086);
+    let c3 = float3(6.130348345893603, 42.3461881477227, -28.51885465332158);
+    let c4 = float3(-11.10743619062271, -82.66631109428045, 60.13984767418263);
+    let c5 = float3(10.02306557647065, 71.41361770095349, -54.07218655560067);
+    let c6 = float3(-3.658713842777788, -22.93153465461149, 18.19190778539828);
+    return c0 + t * (c1 + t * (c2 + t * (c3 + t * (c4 + t * (c5 + t * c6)))));
+}
+
+public float3 magma(float t) {
+    let t = clamp(t, 0.0, 1.0);
+    let c0 = float3(-0.002136485053939582, -0.000749655052795221, -0.005386127855323933);
+    let c1 = float3(0.2516605407371642, 0.6775232436837668, 2.494026599312351);
+    let c2 = float3(8.353717279216625, -3.577719514958484, 0.3144679030132573);
+    let c3 = float3(-27.66873308576866, 14.26473078096533, -13.64921318813922);
+    let c4 = float3(52.17613981234068, -27.94360607168351, 12.94416944238394);
+    let c5 = float3(-50.76852536473588, 29.04658282127291, 4.23415299384598);
+    let c6 = float3(18.65570506591883, -11.48977351997711, -5.601961508734096);
+    return c0 + t * (c1 + t * (c2 + t * (c3 + t * (c4 + t * (c5 + t * c6)))));
+}
+
+public float3 inferno(float t) {
+    let t = clamp(t, 0.0, 1.0);
+    let c0 = float3(0.0002189403691192265, 0.001651004631001012, -0.01948089843709184);
+    let c1 = float3(0.1065134194856116, 0.5639564367884091, 3.932712388889277);
+    let c2 = float3(11.60249308247187, -3.972853965665698, -15.9423941062914);
+    let c3 = float3(-41.70399613139459, 17.43639888205313, 44.35414519872813);
+    let c4 = float3(77.162935699427, -33.40235894210092, -81.80730925738993);
+    let c5 = float3(-71.31942824499214, 32.62606426397723, 73.20951985803202);
+    let c6 = float3(25.13112622477341, -12.24266895238567, -23.07032500287172);
+    return c0 + t * (c1 + t * (c2 + t * (c3 + t * (c4 + t * (c5 + t * c6)))));
+}
+
+public float3 twilight(float t) {
+    t *= 6.283185307179586;
+    let cs1 = float2(cos(t), sin(t));
+    let cs2 = float2(cs1.x * cs1.x - cs1.y * cs1.y, 2.0 * cs1.x * cs1.y);
+    var n = float3(0.604241906517949, 0.4211209742387994, 0.5654329623884283);
+    n += float3(0.3786081652411069, 0.4231873615015874, 0.3006285459149778) * cs1.x;
+    n += float3(-0.3806740645833865, -0.2192933437505726, 0.297215004243999) * cs1.y;
+    n += float3(-0.1225310774589317, 0.05262481606068274, -0.1299696350001923) * cs2.x;
+    n += float3(-0.209793460377647, -0.08229299637364859, 0.2043188473156559) * cs2.y;
+    var d = float3(1.0);
+    d += float3(0.2411111517951086, 0.1090036451124381, 0.1358630678955726) * cs1.x;
+    d += float3(-0.3611005116375753, -0.7206085364851942, 0.09738419152461333) * cs1.y;
+    d += float3(-0.2459830263163363, -0.04512164179268539, -0.2825334376412894) * cs2.x;
+    d += float3(-0.2362425339299566, 0.1115700597048391, 0.3416930715651435) * cs2.y;
+    return n / d;
+}
+
+public float3 twilight_shifted(float t) {
+    return twilight(fract(0.5 - t));
+}
+
+}
index 67509de1458b9ec2ea20e42ff3f8f6db29902610..709271bd7af7bdd2373078e242202d30f07df988 100644 (file)
@@ -2,6 +2,7 @@
 import bindings_samplers;
 import bindings_compute;
 
+import color_map;
 import sdf;
 
 namespace Draw2d {
@@ -502,16 +503,6 @@ struct RasterizeConstants {
 
 #define DEBUG_SHOW_TILES 0
 
-float3 plasma_quintic(float x) {
-    let x = clamp(x, 0.0, 1.0);
-    let x1 = float4(1.0, x, x * x, x * x * x); // 1 x x2 x3
-    let x2 = x1 * x1.w * x;                    // x4 x5 x6 x7
-    return float3(
-        dot(x1.xyzw, float4(+0.063861086, +1.992659096, -1.023901152, -0.490832805)) + dot(x2.xy, float2(+1.308442123, -0.914547012)),
-        dot(x1.xyzw, float4(+0.049718590, -0.791144343, +2.892305078, +0.811726816)) + dot(x2.xy, float2(-4.686502417, +2.717794514)),
-        dot(x1.xyzw, float4(+0.513275779, +1.580255060, -5.164414457, +4.559573646)) + dot(x2.xy, float2(-1.916810682, +0.570638854)));
-}
-
 [shader("compute")]
 [numthreads(8, 8, 1)]
 void rasterize(uniform RasterizeConstants constants, uint3 thread_id: SV_DispatchThreadID, uint3 thread_id_in_group: SV_GroupThreadID) {
@@ -527,7 +518,7 @@ void rasterize(uniform RasterizeConstants constants, uint3 thread_id: SV_Dispatc
 #if DEBUG_SHOW_TILES == 1
 
     let count = hi - lo;
-    let color = count > 1 ? plasma_quintic(float(count) / 16.0) : float3(0.0);
+    let color = count > 1 ? color_map::viridis(float(count) / 16.0) : float3(0.0);
     ui_layer.Store(position, float4(color, 1.0));
 
 #elif DEBUG_SHOW_TILES == 2
@@ -536,7 +527,7 @@ void rasterize(uniform RasterizeConstants constants, uint3 thread_id: SV_Dispatc
     for (uint i = lo; i < hi; i++) {
         count += countbits(constants.fine_buffer[i]);
     }
-    let color = count == 1 ? float3(0.0) : plasma_quintic(float(count) / 300.0);
+    let color = count > 1 ? color_map::viridis(float(count) / 300.0) : float3(0.0);
     ui_layer.Store(position, float4(color, 1.0));
 
 #else