v4k-git-backup/demos/art/shadertoys/XtGGzG.fs

95 lines
4.0 KiB
GLSL

// Viridis approximation, Jerome Liard, August 2016
// https://www.shadertoy.com/view/XtGGzG
// Applied polynomial regression to viridis color palettes so I could easily use them in shaders.
// Degree 5 seems to be a good fit (doesn't capture all details but...)
//
// Some credits/reference links about viridis palettes and why they are good, and some use examples:
//
// https://bids.github.io/colormap/ (says license is CC0)
// https://github.com/sjmgarnier/viridis#references @sjmgarnier
// https://cran.r-project.org/web/packages/viridis/vignettes/intro-to-viridis.html
//
// I learned about the existence of this palette via via https://www.mrao.cam.ac.uk/~dag/CUBEHELIX/ via @kenpex
//#define PLOT_CURVES
#define BLACK_BANDS
float saturate( float x ) { return clamp( x, 0.0, 1.0 ); }
vec3 viridis_quintic( float x )
{
x = saturate( x );
vec4 x1 = vec4( 1.0, x, x * x, x * x * x ); // 1 x x2 x3
vec4 x2 = x1 * x1.w * x; // x4 x5 x6 x7
return vec3(
dot( x1.xyzw, vec4( +0.280268003, -0.143510503, +2.225793877, -14.815088879 ) ) + dot( x2.xy, vec2( +25.212752309, -11.772589584 ) ),
dot( x1.xyzw, vec4( -0.002117546, +1.617109353, -1.909305070, +2.701152864 ) ) + dot( x2.xy, vec2( -1.685288385, +0.178738871 ) ),
dot( x1.xyzw, vec4( +0.300805501, +2.614650302, -12.019139090, +28.933559110 ) ) + dot( x2.xy, vec2( -33.491294770, +13.762053843 ) ) );
}
vec3 inferno_quintic( float x )
{
x = saturate( x );
vec4 x1 = vec4( 1.0, x, x * x, x * x * x ); // 1 x x2 x3
vec4 x2 = x1 * x1.w * x; // x4 x5 x6 x7
return vec3(
dot( x1.xyzw, vec4( -0.027780558, +1.228188385, +0.278906882, +3.892783760 ) ) + dot( x2.xy, vec2( -8.490712758, +4.069046086 ) ),
dot( x1.xyzw, vec4( +0.014065206, +0.015360518, +1.605395918, -4.821108251 ) ) + dot( x2.xy, vec2( +8.389314011, -4.193858954 ) ),
dot( x1.xyzw, vec4( -0.019628385, +3.122510347, -5.893222355, +2.798380308 ) ) + dot( x2.xy, vec2( -3.608884658, +4.324996022 ) ) );
}
vec3 magma_quintic( float x )
{
x = saturate( x );
vec4 x1 = vec4( 1.0, x, x * x, x * x * x ); // 1 x x2 x3
vec4 x2 = x1 * x1.w * x; // x4 x5 x6 x7
return vec3(
dot( x1.xyzw, vec4( -0.023226960, +1.087154378, -0.109964741, +6.333665763 ) ) + dot( x2.xy, vec2( -11.640596589, +5.337625354 ) ),
dot( x1.xyzw, vec4( +0.010680993, +0.176613780, +1.638227448, -6.743522237 ) ) + dot( x2.xy, vec2( +11.426396979, -5.523236379 ) ),
dot( x1.xyzw, vec4( -0.008260782, +2.244286052, +3.005587601, -24.279769818 ) ) + dot( x2.xy, vec2( +32.484310068, -12.688259703 ) ) );
}
vec3 plasma_quintic( float x )
{
x = saturate( x );
vec4 x1 = vec4( 1.0, x, x * x, x * x * x ); // 1 x x2 x3
vec4 x2 = x1 * x1.w * x; // x4 x5 x6 x7
return vec3(
dot( x1.xyzw, vec4( +0.063861086, +1.992659096, -1.023901152, -0.490832805 ) ) + dot( x2.xy, vec2( +1.308442123, -0.914547012 ) ),
dot( x1.xyzw, vec4( +0.049718590, -0.791144343, +2.892305078, +0.811726816 ) ) + dot( x2.xy, vec2( -4.686502417, +2.717794514 ) ),
dot( x1.xyzw, vec4( +0.513275779, +1.580255060, -5.164414457, +4.559573646 ) ) + dot( x2.xy, vec2( -1.916810682, +0.570638854 ) ) );
}
float tri( float x ) { return 1.0 - abs( fract( x * 0.5 ) - 0.5 ) * 2.0; }
vec3 smoothstep_unchecked( vec3 x ) { return ( x * x ) * ( 3.0 - x * 2.0 ); }
vec3 smoothbump( vec3 a, vec3 r, vec3 x ) { return 1.0 - smoothstep_unchecked( min( abs( x - a ), r ) / r ); }
#ifdef SHADERTOY_STANDALONE
void main()
#else
void mainImage( out vec4 fragColor, in vec2 fragCoord )
#endif
{
fragColor.a = 1.0;
vec2 uv = fragCoord.xy / iResolution.xy;
if ( uv.y > 0.75 ) fragColor.xyz = viridis_quintic( uv.x );
else if ( uv.y > 0.5 ) fragColor.xyz = inferno_quintic( uv.x );
else if ( uv.y > 0.25 ) fragColor.xyz = magma_quintic( uv.x );
else if ( uv.y > 0.0 ) fragColor.xyz = plasma_quintic( uv.x );
#ifdef BLACK_BANDS
float r = 32.0 / iResolution.y;
fragColor.xyz *= step( r, tri( uv.y / 0.125 ) );
#endif
#ifdef PLOT_CURVES
float y = fract( uv.y / 0.25 );
float r = 6.0 / iResolution.y;
fragColor.xyz += smoothbump( vec3( 0.0 ), vec3( r ), vec3( y ) - fragColor.xyz );
#endif
}