From fea62fc8aa5f944bcb4fdb89ece6ad29466516d0 Mon Sep 17 00:00:00 2001 From: "Alexander G. Morano" Date: Sun, 22 Dec 2024 23:39:46 -0500 Subject: [PATCH] updated GLSL programs/libs to match new breakout repository --- res/glsl/.lib/blend.lib | 164 +++++++ res/glsl/.lib/camera.lib | 8 +- res/glsl/.lib/color.lib | 413 +++++++++++++---- res/glsl/.lib/const.lib | 76 +--- res/glsl/.lib/convert.lib | 195 ++++++++ res/glsl/.lib/curve.lib | 49 +- res/glsl/.lib/noise.lib | 626 +++++++++++++++++++------- res/glsl/.lib/physics.lib | 14 + res/glsl/.lib/sdf.lib | 67 +-- res/glsl/.lib/shading.lib | 18 +- res/glsl/.lib/vector.lib | 12 +- res/glsl/adjust/util-invert.frag | 2 +- res/glsl/color/color-convert.frag | 26 +- res/glsl/color/color-hsv.frag | 8 +- res/glsl/filter/filter-posterize.frag | 9 +- 15 files changed, 1282 insertions(+), 405 deletions(-) create mode 100644 res/glsl/.lib/blend.lib create mode 100644 res/glsl/.lib/convert.lib create mode 100644 res/glsl/.lib/physics.lib diff --git a/res/glsl/.lib/blend.lib b/res/glsl/.lib/blend.lib new file mode 100644 index 0000000..2797866 --- /dev/null +++ b/res/glsl/.lib/blend.lib @@ -0,0 +1,164 @@ +//------------------------------------------------------------------------------ +// COLOR +//------------------------------------------------------------------------------ + +#include .lib/const.lib +#include .lib/convert.lib +#include .lib/color.lib + +// ============================================================================= +// PROTOTYPES +// ============================================================================= + +vec3 blend_overlay(vec3 base, vec3 blend); +vec3 blend_softLight(vec3 base, vec3 blend); +vec3 blend_multiply(vec3 base, vec3 blend); +vec3 blend_screen(vec3 base, vec3 blend); +vec3 blend_darken(vec3 base, vec3 blend); +vec3 blend_lighten(vec3 base, vec3 blend); +vec3 blend_colorDodge(vec3 base, vec3 blend); +vec3 blend_colorBurn(vec3 base, vec3 blend); +vec3 blend_hardLight(vec3 base, vec3 blend); +vec3 blend_vividLight(vec3 base, vec3 blend); +vec3 blend_linearLight(vec3 base, vec3 blend); +vec3 blend_pinLight(vec3 base, vec3 blend); +vec3 blend_hardMix(vec3 base, vec3 blend); +vec3 blend_difference(vec3 base, vec3 blend); +vec3 blend_exclusion(vec3 base, vec3 blend); +vec3 blend_subtract(vec3 base, vec3 blend); +vec3 blend_divide(vec3 base, vec3 blend); +vec3 blend_hue(vec3 base, vec3 blend); +vec3 blend_saturation(vec3 base, vec3 blend); +vec3 blend_color(vec3 base, vec3 blend); +vec3 blend_luminosity(vec3 base, vec3 blend); + +//------------------------------------------------------------------------------ +// BLENDING +//------------------------------------------------------------------------------ + +vec3 blend_overlay(vec3 base, vec3 blend) { + return mix( + 2.0 * base * blend, + 1.0 - 2.0 * (1.0 - base) * (1.0 - blend), + step(0.5, base) + ); +} + +vec3 blend_softLight(vec3 base, vec3 blend) { + return mix( + 2.0 * base * blend + base * base * (1.0 - 2.0 * blend), + sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend), + step(0.5, blend) + ); +} + +vec3 blend_multiply(vec3 base, vec3 blend) { + return base * blend; +} + +vec3 blend_screen(vec3 base, vec3 blend) { + return 1.0 - (1.0 - base) * (1.0 - blend); +} + +vec3 blend_darken(vec3 base, vec3 blend) { + return min(base, blend); +} + +vec3 blend_lighten(vec3 base, vec3 blend) { + return max(base, blend); +} + +vec3 blend_colorDodge(vec3 base, vec3 blend) { + vec3 ones = vec3(1.0); + return mix( + ones, + min(ones, base / (ones - blend)), + step(blend, vec3(0.999)) // Handle divide by zero case + ); +} + +vec3 blend_colorBurn(vec3 base, vec3 blend) { + vec3 zeros = vec3(0.0); + vec3 ones = vec3(1.0); + return mix( + zeros, + ones - min(ones, (ones - base) / blend), + step(zeros, blend) + ); +} + +vec3 blend_hardLight(vec3 base, vec3 blend) { + return mix( + 2.0 * base * blend, + 1.0 - 2.0 * (1.0 - base) * (1.0 - blend), + step(0.5, blend) + ); +} + +vec3 blend_vividLight(vec3 base, vec3 blend) { + return mix( + blend_colorBurn(base, 2.0 * blend), + blend_colorDodge(base, 2.0 * (blend - 0.5)), + step(0.5, blend) + ); +} + +vec3 blend_linearLight(vec3 base, vec3 blend) { + return mix( + max(base + 2.0 * blend - 1.0, 0.0), + min(base + 2.0 * (blend - 0.5), 1.0), + step(0.5, blend) + ); +} + +vec3 blend_pinLight(vec3 base, vec3 blend) { + vec3 check = step(0.5, blend); + vec3 darker = min(base, 2.0 * blend); + vec3 lighter = max(base, 2.0 * (blend - 0.5)); + return mix(darker, lighter, check); +} + +vec3 blend_hardMix(vec3 base, vec3 blend) { + return step(1.0, base + blend); +} + +vec3 blend_difference(vec3 base, vec3 blend) { + return abs(base - blend); +} + +vec3 blend_exclusion(vec3 base, vec3 blend) { + return base + blend - 2.0 * base * blend; +} + +vec3 blend_subtract(vec3 base, vec3 blend) { + return max(base - blend, 0.0); +} + +vec3 blend_divide(vec3 base, vec3 blend) { + return base / (blend + M_EPSILON); +} + +vec3 blend_hue(vec3 base, vec3 blend) { + vec3 baseHSV = convert_rgb2hsv(base); + vec3 blendHSV = convert_rgb2hsv(blend); + return convert_hsv2rgb(vec3(blendHSV.x, baseHSV.y, baseHSV.z)); +} + +vec3 blend_saturation(vec3 base, vec3 blend) { + vec3 baseHSV = convert_rgb2hsv(base); + vec3 blendHSV = convert_rgb2hsv(blend); + return convert_hsv2rgb(vec3(baseHSV.x, blendHSV.y, baseHSV.z)); +} + +vec3 blend_color(vec3 base, vec3 blend) { + vec3 baseHSV = convert_rgb2hsv(base); + vec3 blendHSV = convert_rgb2hsv(blend); + return convert_hsv2rgb(vec3(blendHSV.xy, baseHSV.z)); +} + +vec3 blend_luminosity(vec3 base, vec3 blend) { + float baseLum = color_luminance(base); + float blendLum = color_luminance(blend); + float lumDiff = blendLum - baseLum; + return base + lumDiff; +} diff --git a/res/glsl/.lib/camera.lib b/res/glsl/.lib/camera.lib index eb03714..e3e4d64 100644 --- a/res/glsl/.lib/camera.lib +++ b/res/glsl/.lib/camera.lib @@ -8,15 +8,15 @@ // PROTOTYPES // ============================================================================= -vec3 lib_camera_eye(float fov, vec2 size, vec2 pos); -mat3 lib_camera_eye(vec3 pos, vec3 target, float roll); +vec3 camera_eye(float fov, vec2 size, vec2 pos); +mat3 camera_eye(vec3 pos, vec3 target, float roll); //------------------------------------------------------------------------------ // TRANSFORM //------------------------------------------------------------------------------ // Camera direction based on field of view and screen position -vec3 lib_camera_eye(float fov, vec2 size, vec2 pos) { +vec3 camera_eye(float fov, vec2 size, vec2 pos) { vec2 xy = pos - size * 0.5; float cot_half_fov = tan((90.0 - fov * 0.5) * M_DEG2RAD); float z = size.y * 0.5 * cot_half_fov; @@ -24,7 +24,7 @@ vec3 lib_camera_eye(float fov, vec2 size, vec2 pos) { } // Camera view based on eye, target, and roll angle -mat3 lib_camera_eye(vec3 pos, vec3 target, float roll) +mat3 camera_eye(vec3 pos, vec3 target, float roll) { vec3 cw = normalize(target-pos); vec3 cp = vec3(sin(roll), cos(roll),0.0); diff --git a/res/glsl/.lib/color.lib b/res/glsl/.lib/color.lib index 56a25b9..ae146ab 100644 --- a/res/glsl/.lib/color.lib +++ b/res/glsl/.lib/color.lib @@ -2,137 +2,362 @@ // COLOR //------------------------------------------------------------------------------ -#include .lib/const.lib +#include .lib/convert.lib -const vec3 D65 = vec3(95.047, 100.0, 108.883); +#define M_GAMMA 2.2 // Standard gamma correction value +#define M_GAMMA_INV 0.4545 // 1.0 / 2.2 for inverse gamma +#define M_LUMA_R 0.2126 // Rec. 709 luma coefficients for red +#define M_LUMA_G 0.7152 // Rec. 709 luma coefficients for green +#define M_LUMA_B 0.0722 // Rec. 709 luma coefficients for blue // ============================================================================= // PROTOTYPES // ============================================================================= -vec3 rgb2hsv(vec3 rgb); -vec3 rgb2lab(vec3 rgb); -vec3 rgb2xyz(vec3 rgb); -vec3 hsv2rgb(vec3 hsv); -vec3 hsv2lab(vec3 hsv); -vec3 hsv2xyz(vec3 hsv); -vec3 lab2rgb(vec3 lab); -vec3 lab2hsv(vec3 lab); -vec3 lab2xyz(vec3 lab); -vec3 xyz2rgb(vec3 xyz); -vec3 xyz2hsv(vec3 xyz); -vec3 xyz2lab(vec3 xyz); +vec3 color_complementary(vec3 rgb); +vec3[3] color_triadic(vec3 rgb); +vec3[3] color_splitComplementary(vec3 rgb, float angle); +vec3[4] color_tetradic(vec3 rgb, float angle); +vec3[5] color_analogous(vec3 rgb, float angle); + +vec3 color_duotone(vec3 rgb, vec3 dark, vec3 light); +vec3 color_vibrance(vec3 rgb, float amount); +vec3 color_levelAdjust(vec3 rgb, vec3 inBlack, vec3 inWhite, vec3 outBlack, vec3 outWhite); + +float color_perceivedBrightness(vec3 rgb); +float color_colorfulness(vec3 rgb); +bool color_isNeutral(vec3 rgb, float threshold); + +vec3 color_saturate(vec3 rgb, float adjustment); +vec3 color_brighten(vec3 rgb, float adjustment); +vec3 color_rotateHue(vec3 rgb, float angle); +vec3 color_tint(vec3 base, vec3 tintColor, float amount); +float color_luminance(vec3 rgb); +float color_contrastRatio(vec3 rgb1, vec3 rgb2); +float color_deltaE(vec3 lab1, vec3 lab2); + +vec3 color_temperature(float temperature); +float color_estimateTemperature(vec3 rgb); +vec3 color_adjustTemperature(vec3 rgb, float currentTemp, float targetTemp); + +vec3 color_posterize(vec3 rgb, float levels); +vec3 color_colorize(vec3 rgb, vec3 tint, float strength); +vec3 color_gammaAdjust(vec3 rgb, vec3 gamma); + +bool color_isColorBlindSafe(vec3 rgb1, vec3 rgb2); +vec3 color_emphasizeForColorBlind(vec3 rgb); +vec3 color_simulateProtanopia(vec3 rgb); +vec3 color_simulateDeuteranopia(vec3 rgb); + +vec3 color_gradient3(vec3 color1, vec3 color2, vec3 color3, float t); +vec3 color_smoothGradient(vec3 color1, vec3 color2, float t); +vec3 color_radialGradient(vec3 center, vec3 edge, vec2 uv, vec2 center_pos); + +float color_checker(vec2 uv, float scale); +float color_halftone(vec2 uv, float value, float frequency, float angle); + +vec3 color_toneSplit(vec3 rgb, vec3 shadows, vec3 midtones, vec3 highlights); +vec3 color_monochromatic(vec3 rgb, float offset); +vec3 color_weightedPalette(vec3 colors[4], vec4 weights); + +vec3 color_grade(vec3 rgb, vec3 lift, vec3 gamma, vec3 gain); //------------------------------------------------------------------------------ -// RGB +// COLOR HARMONY //------------------------------------------------------------------------------ -vec3 rgb2hsv(vec3 rgb) { - vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); - vec4 p = mix(vec4(rgb.bg, K.wz), vec4(rgb.gb, K.xy), step(rgb.b, rgb.g)); - vec4 q = mix(vec4(p.xyw, rgb.r), vec4(rgb.r, p.yzx), step(p.x, rgb.r)); - float d = q.x - min(q.w, q.y); - return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + M_EPSILON)), d / (q.x + M_EPSILON), q.x); +vec3 color_complementary(vec3 rgb) { + vec3 hsv = convert_rgb2hsv(rgb); + hsv.x = fract(hsv.x + 0.5); // Rotate hue by 180 degrees + return convert_hsv2rgb(hsv); } -vec3 rgb2lab(vec3 rgb) { - vec3 xyz = rgb2xyz(rgb); - return xyz2lab(xyz); +vec3[3] color_triadic(vec3 rgb) { + vec3 hsv = convert_rgb2hsv(rgb); + return vec3[3]( + rgb, + convert_hsv2rgb(vec3(fract(hsv.x + 1.0/3.0), hsv.yz)), + convert_hsv2rgb(vec3(fract(hsv.x + 2.0/3.0), hsv.yz)) + ); } -vec3 rgb2xyz(vec3 rgb) { - vec3 tmp; - tmp.x = (rgb.r > 0.04045) ? pow((rgb.r + 0.055) / 1.055, 2.4) : rgb.r / 12.92; - tmp.y = (rgb.g > 0.04045) ? pow((rgb.g + 0.055) / 1.055, 2.4) : rgb.g / 12.92; - tmp.z = (rgb.b > 0.04045) ? pow((rgb.b + 0.055) / 1.055, 2.4) : rgb.b / 12.92; - return 100.0 * tmp * mat3( - 0.4124, 0.3576, 0.1805, - 0.2126, 0.7152, 0.0722, - 0.0193, 0.1192, 0.9505 +vec3[3] color_splitComplementary(vec3 rgb, float angle) { + vec3 hsv = convert_rgb2hsv(rgb); + return vec3[3]( + rgb, + convert_hsv2rgb(vec3(fract(hsv.x + 0.5 - angle), hsv.yz)), + convert_hsv2rgb(vec3(fract(hsv.x + 0.5 + angle), hsv.yz)) + ); +} + +vec3[4] color_tetradic(vec3 rgb, float angle) { + vec3 hsv = convert_rgb2hsv(rgb); + return vec3[4]( + rgb, + convert_hsv2rgb(vec3(fract(hsv.x + 0.5), hsv.yz)), // Complement + convert_hsv2rgb(vec3(fract(hsv.x + angle), hsv.yz)), // Third color + convert_hsv2rgb(vec3(fract(hsv.x + angle + 0.5), hsv.yz)) // Fourth color + ); +} + +vec3[5] color_analogous(vec3 rgb, float angle) { + vec3 hsv = convert_rgb2hsv(rgb); + return vec3[5]( + convert_hsv2rgb(vec3(fract(hsv.x - angle*2.0), hsv.yz)), + convert_hsv2rgb(vec3(fract(hsv.x - angle), hsv.yz)), + rgb, + convert_hsv2rgb(vec3(fract(hsv.x + angle), hsv.yz)), + convert_hsv2rgb(vec3(fract(hsv.x + angle*2.0), hsv.yz)) ); } //------------------------------------------------------------------------------ -// HSV +// COLOR EFFECTS //------------------------------------------------------------------------------ -vec3 hsv2rgb(vec3 hsv) { - hsv = vec3(hsv.x, clamp(hsv.yz, 0.0, 1.0)); - vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(hsv.xxx + K.xyz) * 6.0 - K.www); - return hsv.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), hsv.y); +vec3 color_duotone(vec3 rgb, vec3 dark, vec3 light) { + float lum = color_luminance(rgb); + return mix(dark, light, lum); } -vec3 hsv2lab(vec3 hsv) { - float H = hsv.x * 360.0; - float S = hsv.y; - float V = hsv.z; - - // Convert to LAB - float L = V * 100.0; - float C = S * L; - - float h = H * M_PI / 180.0; - float a = C * cos(h); - float b = C * sin(h); - - // Normalize LAB - return vec3(L / 100.0, (a + 128.0) / 255.0, (b + 128.0) / 255.0); +vec3 color_vibrance(vec3 rgb, float amount) { + float mx = max(max(rgb.r, rgb.g), rgb.b); + float avg = dot(rgb, vec3(1.0/3.0)); + return mix(rgb, vec3(mx), (mx - avg) * (-amount * 3.0)); } -vec3 hsv2xyz(vec3 hsv) { - vec3 rgb = hsv2rgb(hsv); - return rgb2xyz(rgb); +vec3 color_levelAdjust(vec3 rgb, vec3 inBlack, vec3 inWhite, vec3 outBlack, vec3 outWhite) { + return outBlack + (rgb - inBlack) * (outWhite - outBlack) / (inWhite - inBlack); } //------------------------------------------------------------------------------ -// LAB +// COLOR ANALYSIS //------------------------------------------------------------------------------ -vec3 lab2rgb(vec3 lab) { - vec3 xyz = lab2xyz(lab); - return xyz2rgb(xyz); -} - -vec3 lab2hsv(vec3 lab) { - vec3 rgb = lab2rgb(lab); - return rgb2hsv(rgb); -} - -vec3 lab2xyz(vec3 lab) { - float fy = (lab.x + 16.0) / 116.0; - float fx = lab.y / 500.0 + fy; - float fz = fy - lab.z / 200.0; - return vec3( - 95.047 * ((fx > 0.206897) ? fx * fx * fx : (fx - 16.0 / 116.0) / 7.787), - 100.000 * ((fy > 0.206897) ? fy * fy * fy : (fy - 16.0 / 116.0) / 7.787), - 108.883 * ((fz > 0.206897) ? fz * fz * fz : (fz - 16.0 / 116.0) / 7.787) +float color_perceivedBrightness(vec3 rgb) { + // Uses perceived brightness formula + return sqrt( + rgb.r * rgb.r * 0.299 + + rgb.g * rgb.g * 0.587 + + rgb.b * rgb.b * 0.114 ); } +float color_colorfulness(vec3 rgb) { + vec3 hsv = convert_rgb2hsv(rgb); + return hsv.y * hsv.z; +} + +bool color_isNeutral(vec3 rgb, float threshold) { + vec3 hsv = convert_rgb2hsv(rgb); + return hsv.y < threshold; +} + //------------------------------------------------------------------------------ -// XYZ +// GENERAL PURPOSE //------------------------------------------------------------------------------ -vec3 xyz2rgb(vec3 xyz) { - vec3 v = xyz / D65; - vec3 r; - r.x = ( v.r > 0.0031308 ) ? (( 1.055 * pow( v.r, ( 1.0 / 2.4 ))) - 0.055 ) : 12.92 * v.r; - r.y = ( v.g > 0.0031308 ) ? (( 1.055 * pow( v.g, ( 1.0 / 2.4 ))) - 0.055 ) : 12.92 * v.g; - r.z = ( v.b > 0.0031308 ) ? (( 1.055 * pow( v.b, ( 1.0 / 2.4 ))) - 0.055 ) : 12.92 * v.b; - return r; +vec3 color_saturate(vec3 rgb, float adjustment) { + vec3 hsv = convert_rgb2hsv(rgb); + hsv.y *= adjustment; + return convert_hsv2rgb(hsv); } -vec3 xyz2hsv(vec3 xyz) { - vec3 rgb = xyz2rgb(xyz); - return rgb2hsv(rgb); +vec3 color_brighten(vec3 rgb, float adjustment) { + vec3 hsv = convert_rgb2hsv(rgb); + hsv.z = clamp(hsv.z * adjustment, 0.0, 1.0); + return convert_hsv2rgb(hsv); } -vec3 xyz2lab(vec3 xyz) { - vec3 n = xyz / D65; - vec3 v; - v.x = ( n.x > 0.008856 ) ? pow( n.x, 1.0 / 3.0 ) : ( 7.787 * n.x ) + ( 16.0 / 116.0 ); - v.y = ( n.y > 0.008856 ) ? pow( n.y, 1.0 / 3.0 ) : ( 7.787 * n.y ) + ( 16.0 / 116.0 ); - v.z = ( n.z > 0.008856 ) ? pow( n.z, 1.0 / 3.0 ) : ( 7.787 * n.z ) + ( 16.0 / 116.0 ); - return vec3(( 116.0 * v.y ) - 16.0, 500.0 * ( v.x - v.y ), 200.0 * ( v.y - v.z )); +vec3 color_rotateHue(vec3 rgb, float angle) { + vec3 hsv = convert_rgb2hsv(rgb); + hsv.x = fract(hsv.x + angle); + return convert_hsv2rgb(hsv); } + +// Tints color towards another color by amount (0-1) +vec3 color_tint(vec3 base, vec3 tintColor, float amount) { + return mix(base, tintColor * color_luminance(base), amount); +} + +// Luminance calculation using Rec. 709 coefficients +float color_luminance(vec3 rgb) { + return dot(rgb, vec3(M_LUMA_R, M_LUMA_G, M_LUMA_B)); +} + +// Contrast ratio calculation (WCAG) +float color_contrastRatio(vec3 rgb1, vec3 rgb2) { + float l1 = color_luminance(rgb1); + float l2 = color_luminance(rgb2); + float brightest = max(l1, l2); + float darkest = min(l1, l2); + return (brightest + 0.05) / (darkest + 0.05); +} + +// Perceptual color difference (simple delta E) +float color_deltaE(vec3 lab1, vec3 lab2) { + return length(lab1 - lab2); +} + +// Approximate blackbody radiation (temperature in Kelvin) +vec3 color_temperature(float temperature) { + temperature = clamp(temperature, 1000.0, 40000.0) / 100.0; + + vec3 color = vec3(1.0); + bool under66 = temperature <= 66.0; + + // Red + color.r = under66 ? 1.0 : + 1.29293618606274509804 * pow(temperature - 60.0, -0.1332047592); + + // Green + color.g = under66 ? + 0.39008157876901960784 * log(temperature) - 0.63184144378862745098 : + 1.12989086089529411765 * pow(temperature - 60.0, -0.0755148492); + + // Blue + if(under66) { + if(temperature <= 19.0) + color.b = 0.0; + else + color.b = 0.54320678911019607843 * log(temperature - 10.0) - 1.19625408914; + } + + return clamp(color, 0.0, 1.0); +} + +float color_estimateTemperature(vec3 rgb) { + // Approximate CCT using McCamy's formula + float n = (rgb.x - rgb.z) / (rgb.y - rgb.z); + return 449.0 * pow(n, 3.0) + 3525.0 * pow(n, 2.0) + 6823.3 * n + 5520.33; +} + +vec3 color_adjustTemperature(vec3 rgb, float currentTemp, float targetTemp) { + vec3 current = color_temperature(currentTemp); + vec3 target = color_temperature(targetTemp); + return rgb * (target / current); +} + +vec3 color_posterize(vec3 rgb, float levels) { + float numSteps = clamp(float(levels), 1.0, 255.0); + return floor(rgb * numSteps + 0.0000001) / numSteps; +} + +vec3 color_colorize(vec3 rgb, vec3 tint, float strength) { + float luma = color_luminance(rgb); + vec3 hsvTint = convert_rgb2hsv(tint); + return convert_hsv2rgb(vec3(hsvTint.x, hsvTint.y * strength, luma)); +} + +vec3 color_gammaAdjust(vec3 rgb, vec3 gamma) { + return pow(rgb, 1.0 / gamma); +} + +bool color_isColorBlindSafe(vec3 rgb1, vec3 rgb2) { + // Uses WCAG 2.0 guidelines for color contrast + float contrast = color_contrastRatio(rgb1, rgb2); + return contrast >= 4.5; // Minimum contrast for normal text +} + +vec3 color_emphasizeForColorBlind(vec3 rgb) { + // Enhances differences in color_luminance and saturation + vec3 hsv = convert_rgb2hsv(rgb); + hsv.y = pow(hsv.y, 0.5); // Boost saturation + hsv.z = pow(hsv.z, 0.8); // Adjust value + return convert_hsv2rgb(hsv); +} + +// Simulate color blindness types +vec3 color_simulateProtanopia(vec3 rgb) { + return rgb * mat3( + 0.567, 0.433, 0.000, + 0.558, 0.442, 0.000, + 0.000, 0.242, 0.758 + ); +} + +vec3 color_simulateDeuteranopia(vec3 rgb) { + return rgb * mat3( + 0.625, 0.375, 0.000, + 0.700, 0.300, 0.000, + 0.000, 0.300, 0.700 + ); +} + +vec3 color_gradient3(vec3 color1, vec3 color2, vec3 color3, float t) { + t = clamp(t, 0.0, 1.0); + return t < 0.5 ? + mix(color1, color2, t * 2.0) : + mix(color2, color3, (t - 0.5) * 2.0); +} + +vec3 color_smoothGradient(vec3 color1, vec3 color2, float t) { + t = smoothstep(0.0, 1.0, t); + return mix(color1, color2, t); +} + +//------------------------------------------------------------------------------ +// PATTERNS AND EFFECTS +//------------------------------------------------------------------------------ + +// Creates a gradient in polar coordinates +vec3 color_radialGradient(vec3 center, vec3 edge, vec2 uv, vec2 center_pos) { + float dist = length(uv - center_pos); + return mix(center, edge, smoothstep(0.0, 1.0, dist)); +} + +// Creates a checker pattern +float color_checker(vec2 uv, float scale) { + vec2 pattern = floor(uv * scale); + return mod(pattern.x + pattern.y, 2.0); +} + +// Simulates halftone dot pattern +float color_halftone(vec2 uv, float value, float frequency, float angle) { + vec2 rotated = vec2( + cos(angle) * uv.x - sin(angle) * uv.y, + sin(angle) * uv.x + cos(angle) * uv.y + ); + vec2 nearest = 2.0 * fract(frequency * rotated) - 1.0; + float dist = length(nearest); + return step(dist, 2.0 * value - 1.0); +} + +//------------------------------------------------------------------------------ +// COLOR MODIFICATIONS +//------------------------------------------------------------------------------ + +// Adjust color based on shadows, midtones, and highlights separately +vec3 color_toneSplit(vec3 rgb, vec3 shadows, vec3 midtones, vec3 highlights) { + float lum = color_luminance(rgb); + float shadow = smoothstep(0.0, 0.5, lum); + float highlight = smoothstep(0.5, 1.0, lum); + vec3 mid = mix(shadows, midtones, shadow); + return mix(mid, highlights, highlight); +} + +// Create a monochromatic variation of a color +vec3 color_monochromatic(vec3 rgb, float offset) { + vec3 hsv = convert_rgb2hsv(rgb); + return convert_hsv2rgb(vec3( + hsv.x, + mix(0.0, hsv.y, 0.5 + offset), + mix(0.3, 1.0, offset) + )); +} + +// Create a palette with weighted mix of colors +vec3 color_weightedPalette(vec3 colors[4], vec4 weights) { + weights = weights / (weights.x + weights.y + weights.z + weights.w); + return colors[0] * weights.x + + colors[1] * weights.y + + colors[2] * weights.z + + colors[3] * weights.w; +} + +// Advanced color grading +vec3 color_grade(vec3 rgb, vec3 lift, vec3 gamma, vec3 gain) { + vec3 liftedColor = rgb * (1.0 - lift) + lift; + vec3 gammaCorrected = pow(liftedColor, 1.0 / gamma); + return gammaCorrected * gain; +} \ No newline at end of file diff --git a/res/glsl/.lib/const.lib b/res/glsl/.lib/const.lib index 88e2713..0ab78bd 100644 --- a/res/glsl/.lib/const.lib +++ b/res/glsl/.lib/const.lib @@ -2,63 +2,37 @@ // CONSTANT //------------------------------------------------------------------------------ -#define M_EPSILON 1.0e-10 // zero value for float comparisons +#define M_EPSILON 1.0e-10 // zero value for float comparisons -#define M_DEG2RAD 0.017453292519943 // Degree to radian conversion factor -#define M_RAD2DEG 57.29577951308232 // Radian to degree conversion factor -#define M_TAU 6.283185307179586 // Tau (2 * Pi) -#define M_PI 3.141592653589793 // Pi -#define M_PI_2 1.570796326794896 // Pi divided by 2 (π/2) -#define M_PI_4 0.785398163397448 // Pi divided by 4 (π/4) -#define M_3PI_4 2.356194490192345 // 3 * Pi divided by 4 (3π/4) +#define M_DEG2RAD 0.017453292519943 // Degree to radian conversion factor +#define M_RAD2DEG 57.29577951308232 // Radian to degree conversion factor -#define M_PHI 1.618033988749895 // Golden ratio (φ) -#define M_PHI_INV 0.618033988749895 // Inverse of golden ratio (1/φ) -#define M_PHI_SQ 2.618033988749895 // Square of the golden ratio (φ^2) +#define M_TAU 6.283185307179586 // TAU (2 * π) +#define M_TAU_INV 0.159154943091895 // TAU Inverse (1 / TAU) -#define M_E 2.718281828459045 // Euler's number (base of natural logarithm) -#define M_LOG2E 1.442695040888963 // Log base 2 of e -#define M_LOG10E 0.434294481903252 // Log base 10 of e -#define M_LN2 0.693147180559945 // Natural log of 2 -#define M_LN10 2.302585092994046 // Natural log of 10 +#define M_PI 3.141592653589793 // π +#define M_PI_INV 0.318309886183790 // π Inverse (1 / π) +#define M_PI_2 1.570796326794896 // π divided by 2 (π / 2) +#define M_PI_4 0.785398163397448 // π divided by 4 (π / 4) +#define M_3PI_4 2.356194490192345 // 3 * π divided by 4 (3π / 4) -#define M_SQRT2 1.414213562373095 // Square root of 2 -#define M_SQRT3 1.732050807568877 // Square root of 3 -#define M_SQRT1_2 0.707106781186547 // 1 divided by square root of 2 (1/sqrt(2)) -#define M_SQRT1_3 0.577350269189626 // 1 divided by square root of 3 (1/sqrt(3)) +#define M_PHI 1.618033988749895 // Golden ratio (φ) +#define M_PHI_INV 0.618033988749895 // Inverse of golden ratio (1 / φ) +#define M_PHI_SQ 2.618033988749895 // Square of the golden ratio (φ^2) +#define M_PHI_SQRT5 0.723606797749979 // φ / √5 (useful for fibonacci spherical distribution) +#define M_GOLD_ANG 2.399963229728653 // Golden angle in radians -//------------------------------------------------------------------------------ -// PHYSICS -//------------------------------------------------------------------------------ +#define M_E 2.718281828459045 // Euler's number (base of natural logarithm) +#define M_LOG2E 1.442695040888963 // Log base 2 of e +#define M_LOG10E 0.434294481903252 // Log base 10 of e +#define M_LN2 0.693147180559945 // Natural log of 2 +#define M_LN10 2.302585092994046 // Natural log of 10 -#define M_C 299792458.0 // Speed of light in meters per second (m/s) -#define M_G 9.80665 // Gravitational acceleration on Earth (m/s²) -#define M_PLANCK 6.62607015e-34 // Planck's constant (Js) -#define M_KB 1.380649e-23 // Boltzmann constant (J/K) -#define M_MASS_E 9.10938356e-31 // Mass of electron (kg) -#define M_CHARGE_E 1.602176634e-19 // Elementary charge (C) - -//------------------------------------------------------------------------------ -// EASE -//------------------------------------------------------------------------------ - -#define EASE_IN_OUT_SINE(t) (-0.5 * (cos(M_PI * (t)) - 1.0)) -#define EASE_IN_OUT_CIRC(t) (((t) < 1.0) ? (-0.5 * (sqrt(1.0 - (t) * (t)) - 1.0)) : (0.5 * (sqrt(1.0 - ((t)-2.0) * ((t)-2.0)) + 1.0))) -#define EASE_IN_OUT_QUAD(t) (((t) < 0.5) ? (2.0 * (t) * (t)) : (-2.0 * (t) * (t) + 4.0 * (t) - 1.0)) - -#define DECAY_EXP(t, lambda) exp(-lambda * (t)) -#define INTERP_SS(a, b, t) mix((a), (b), smoothstep(0.0, 1.0, (t))) -#define INTERP_BOUNCE(t) abs(sin(M_TAU * (t) * (1.0 - (t)))) -#define INTERP_BOUNCE_VEC(a, b, t) mix((a), (b), INTERP_BOUNCE(t)) - -#define INTERP_HERMITE_VEC(a, b, tangentA, tangentB, t) \ - ( \ - float h00 = 2.0 * (t) * (t) * (t) - 3.0 * (t) * (t) + 1.0; \ - float h10 = (t) * (t) * (t) - 2.0 * (t) * (t) + (t); \ - float h01 = -2.0 * (t) * (t) * (t) + 3.0 * (t) * (t); \ - float h11 = (t) * (t) * (t) - (t) * (t); \ - (h00 * (a) + h10 * (tangentA) + h01 * (b) + h11 * (tangentB)) \ - ) +#define M_SQRT2 1.414213562373095 // Square root of 2 +#define M_SQRT3 1.732050807568877 // Square root of 3 +#define M_SQRT2_INV 0.707106781186547 // 1 divided by square root of 2 (1 / sqrt(2)) +#define M_SQRT3_INV 0.577350269189626 // 1 divided by square root of 3 (1 / sqrt(3)) +#define M_SQRT5 2.236067977499790 // Square root of 5 //------------------------------------------------------------------------------ // GENERAL diff --git a/res/glsl/.lib/convert.lib b/res/glsl/.lib/convert.lib new file mode 100644 index 0000000..152dbdc --- /dev/null +++ b/res/glsl/.lib/convert.lib @@ -0,0 +1,195 @@ +//------------------------------------------------------------------------------ +// COLOR +//------------------------------------------------------------------------------ + +#include .lib/const.lib + +#define M_SRGB_ALPHA 0.055 +#define M_SRGB_THRESH 0.04045 + +// LAB constants +#define M_LAB_E 0.008856 // LAB epsilon +#define M_LAB_K 903.3 // LAB kappa +#define M_LAB_16_116 0.137931 // 16/116 + +// Additional illuminants +#define M_D50 vec3(96.422, 100.0, 82.521) // D50 reference white +#define M_D65 vec3(95.047, 100.0, 108.883) // D65 reference white +#define M_D75 vec3(94.972, 100.0, 122.638) // D75 reference white + +// ============================================================================= +// PROTOTYPES +// ============================================================================= + +vec3 convert_rgb2hsv(vec3 rgb); +vec3 convert_rgb2lab(vec3 rgb); +vec3 convert_rgb2xyz(vec3 rgb); +vec3 convert_hsv2rgb(vec3 hsv); +vec3 convert_hsv2lab(vec3 hsv); +vec3 convert_hsv2xyz(vec3 hsv); +vec3 convert_lab2rgb(vec3 lab); +vec3 convert_lab2hsv(vec3 lab); +vec3 convert_lab2xyz(vec3 lab); +vec3 convert_xyz2rgb(vec3 xyz); +vec3 convert_xyz2hsv(vec3 xyz); +vec3 convert_xyz2lab(vec3 xyz); +vec3 convert_rgb2oklab(vec3 rgb); +vec3 convert_oklab2rgb(vec3 lab); + +//------------------------------------------------------------------------------ +// RGB +//------------------------------------------------------------------------------ + +vec3 convert_rgb2hsv(vec3 rgb) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(rgb.bg, K.wz), vec4(rgb.gb, K.xy), step(rgb.b, rgb.g)); + vec4 q = mix(vec4(p.xyw, rgb.r), vec4(rgb.r, p.yzx), step(p.x, rgb.r)); + float d = q.x - min(q.w, q.y); + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + M_EPSILON)), d / (q.x + M_EPSILON), q.x); +} + +vec3 convert_rgb2lab(vec3 rgb) { + vec3 xyz = convert_rgb2xyz(rgb); + return convert_xyz2lab(xyz); +} + +vec3 convert_rgb2xyz(vec3 rgb) { + vec3 tmp; + tmp.x = (rgb.r > 0.04045) ? pow((rgb.r + 0.055) / 1.055, 2.4) : rgb.r / 12.92; + tmp.y = (rgb.g > 0.04045) ? pow((rgb.g + 0.055) / 1.055, 2.4) : rgb.g / 12.92; + tmp.z = (rgb.b > 0.04045) ? pow((rgb.b + 0.055) / 1.055, 2.4) : rgb.b / 12.92; + return 100.0 * tmp * mat3( + 0.4124, 0.3576, 0.1805, + 0.2126, 0.7152, 0.0722, + 0.0193, 0.1192, 0.9505 + ); +} + +//------------------------------------------------------------------------------ +// HSV +//------------------------------------------------------------------------------ + +vec3 convert_hsv2rgb(vec3 hsv) { + hsv = vec3(hsv.x, clamp(hsv.yz, 0.0, 1.0)); + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(hsv.xxx + K.xyz) * 6.0 - K.www); + return hsv.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), hsv.y); +} + +vec3 convert_hsv2lab(vec3 hsv) { + float H = hsv.x * 360.0; + float S = hsv.y; + float V = hsv.z; + + // Convert to LAB + float L = V * 100.0; + float C = S * L; + + float h = H * M_PI / 180.0; + float a = C * cos(h); + float b = C * sin(h); + + // Normalize LAB + return vec3(L / 100.0, (a + 128.0) / 255.0, (b + 128.0) / 255.0); +} + +vec3 convert_hsv2xyz(vec3 hsv) { + vec3 rgb = convert_hsv2rgb(hsv); + return convert_rgb2xyz(rgb); +} + +//------------------------------------------------------------------------------ +// LAB +//------------------------------------------------------------------------------ + +vec3 convert_lab2rgb(vec3 lab) { + vec3 xyz = convert_lab2xyz(lab); + return convert_xyz2rgb(xyz); +} + +vec3 convert_lab2hsv(vec3 lab) { + vec3 rgb = convert_lab2rgb(lab); + return convert_rgb2hsv(rgb); +} + +vec3 convert_lab2xyz(vec3 lab) { + float fy = (lab.x + 16.0) / 116.0; + float fx = lab.y / 500.0 + fy; + float fz = fy - lab.z / 200.0; + vec3 f = vec3(fx, fy, fz); + vec3 thresh = step(vec3(0.206897), f); + vec3 xyz = mix( + (f - vec3(16.0/116.0)) / 7.787, + f * f * f, + thresh + ); + return xyz * M_D65; +} + +//------------------------------------------------------------------------------ +// XYZ +//------------------------------------------------------------------------------ + +vec3 convert_xyz2rgb(vec3 xyz) { + vec3 v = xyz / M_D65; + vec3 thresh = step(0.0031308, v); + return mix( + 12.92 * v, + 1.055 * pow(v, vec3(1.0/2.4)) - 0.055, + thresh + ); +} + +vec3 convert_xyz2hsv(vec3 xyz) { + vec3 rgb = convert_xyz2rgb(xyz); + return convert_rgb2hsv(rgb); +} + +vec3 convert_xyz2lab(vec3 xyz) { + vec3 n = xyz / M_D65; + vec3 thresh = step(vec3(0.008856), n); + vec3 v = mix( + 7.787 * n + vec3(16.0/116.0), + pow(n, vec3(1.0/3.0)), + thresh + ); + return vec3( + 116.0 * v.y - 16.0, + 500.0 * (v.x - v.y), + 200.0 * (v.y - v.z) + ); +} + +//------------------------------------------------------------------------------ +// OKLAB +//------------------------------------------------------------------------------ + +// RGB to Oklab (perceptually uniform color space) +vec3 convert_rgb2oklab(vec3 rgb) { + vec3 lms = rgb * mat3( + 0.4122214708, 0.5363325363, 0.0514459929, + 0.2119034982, 0.6806995451, 0.1073969566, + 0.0883024619, 0.2817188376, 0.6299787005 + ); + lms = pow(lms, vec3(1.0/3.0)); + return lms * mat3( + 0.2104542553, 0.7936177850, -0.0040720468, + 1.9779984951, -2.4285922050, 0.4505937099, + 0.0259040371, 0.7827717662, -0.8086757660 + ); +} + +// Oklab to RGB +vec3 convert_oklab2rgb(vec3 lab) { + vec3 lms = lab * mat3( + 1.0000000000, 0.3963377774, 0.2158037573, + 1.0000000000, -0.1055613458, -0.0638541728, + 1.0000000000, -0.0894841775, -1.2914855480 + ); + lms = lms * lms * lms; + return lms * mat3( + 4.0767416621, -3.3077115913, 0.2309699292, + -1.2684380046, 2.6097574011, -0.3413193965, + -0.0041960863, -0.7034186147, 1.7076147010 + ); +} diff --git a/res/glsl/.lib/curve.lib b/res/glsl/.lib/curve.lib index 68e2e15..49cf1bf 100644 --- a/res/glsl/.lib/curve.lib +++ b/res/glsl/.lib/curve.lib @@ -2,29 +2,54 @@ // CURVE //------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// EASE +//------------------------------------------------------------------------------ + +#define EASE_IN_OUT_SINE(t) (-0.5 * (cos(M_PI * (t)) - 1.0)) +#define EASE_IN_OUT_CIRC(t) (((t) < 1.0) ? (-0.5 * (sqrt(1.0 - (t) * (t)) - 1.0)) : (0.5 * (sqrt(1.0 - ((t)-2.0) * ((t)-2.0)) + 1.0))) +#define EASE_IN_OUT_QUAD(t) (((t) < 0.5) ? (2.0 * (t) * (t)) : (-2.0 * (t) * (t) + 4.0 * (t) - 1.0)) +#define EASE_IN_EXPO(t) ((t) == 0.0 ? 0.0 : pow(2.0, 10.0 * (t) - 10.0)) +#define EASE_OUT_EXPO(t) ((t) == 1.0 ? 1.0 : 1.0 - pow(2.0, -10.0 * (t))) +#define EASE_IN_ELASTIC(t) (sin(-13.0 * M_PI_2 * ((t) + 1.0)) * pow(2.0, -10.0 * (t))) + +#define DECAY_EXP(t, lambda) exp(-lambda * (t)) +#define INTERP_SS(a, b, t) mix((a), (b), smoothstep(0.0, 1.0, (t))) +#define INTERP_BOUNCE(t) abs(sin(M_TAU * (t) * (1.0 - (t)))) +#define INTERP_BOUNCE_VEC(a, b, t) mix((a), (b), INTERP_BOUNCE(t)) + +#define INTERP_HERMITE_VEC(a, b, tangentA, tangentB, t) \ + ( \ + float h00 = 2.0 * (t) * (t) * (t) - 3.0 * (t) * (t) + 1.0; \ + float h10 = (t) * (t) * (t) - 2.0 * (t) * (t) + (t); \ + float h01 = -2.0 * (t) * (t) * (t) + 3.0 * (t) * (t); \ + float h11 = (t) * (t) * (t) - (t) * (t); \ + (h00 * (a) + h10 * (tangentA) + h01 * (b) + h11 * (tangentB)) \ + ) + // ============================================================================= // PROTOTYPES // ============================================================================= -vec2 lib_curve_bezierCubic(vec2 p0, vec2 p1, vec2 p2, vec2 p3, float t); -vec3 lib_curve_bezierCubic(vec3 p0, vec3 p1, vec3 p2, vec3 p3, float t); -vec2 lib_curve_bezierQuadratic(vec2 p0, vec2 p1, vec2 p2, float t); -vec3 lib_curve_bezierQuadratic(vec3 p0, vec3 p1, vec3 p2, float t); -vec2 lib_curve_catmullRom(vec2 p0, vec2 p1, vec2 p2, vec2 p3, float t); -vec3 lib_curve_catmullRom(vec3 p0, vec3 p1, vec3 p2, vec3 p3, float t); +vec2 curve_bezierCubic(vec2 p0, vec2 p1, vec2 p2, vec2 p3, float t); +vec3 curve_bezierCubic(vec3 p0, vec3 p1, vec3 p2, vec3 p3, float t); +vec2 curve_bezierQuadratic(vec2 p0, vec2 p1, vec2 p2, float t); +vec3 curve_bezierQuadratic(vec3 p0, vec3 p1, vec3 p2, float t); +vec2 curve_catmullRom(vec2 p0, vec2 p1, vec2 p2, vec2 p3, float t); +vec3 curve_catmullRom(vec3 p0, vec3 p1, vec3 p2, vec3 p3, float t); //------------------------------------------------------------------------------ // CUBIC BEZIER CURVE //------------------------------------------------------------------------------ // Cubic Bezier curve for 2D vectors -vec2 lib_curve_bezierCubic(vec2 p0, vec2 p1, vec2 p2, vec2 p3, float t) { +vec2 curve_bezierCubic(vec2 p0, vec2 p1, vec2 p2, vec2 p3, float t) { float u = 1.0 - t; return u * u * u * p0 + 3.0 * u * u * t * p1 + 3.0 * u * t * t * p2 + t * t * t * p3; } // Cubic Bezier curve between four control points -vec3 lib_curve_bezierCubic(vec3 p0, vec3 p1, vec3 p2, vec3 p3, float t) { +vec3 curve_bezierCubic(vec3 p0, vec3 p1, vec3 p2, vec3 p3, float t) { float u = 1.0 - t; return u * u * u * p0 + 3.0 * u * u * t * p1 + 3.0 * u * t * t * p2 + t * t * t * p3; } @@ -34,13 +59,13 @@ vec3 lib_curve_bezierCubic(vec3 p0, vec3 p1, vec3 p2, vec3 p3, float t) { //------------------------------------------------------------------------------ // Quadratic Bezier curve for 2D vectors -vec2 lib_curve_bezierQuadratic(vec2 p0, vec2 p1, vec2 p2, float t) { +vec2 curve_bezierQuadratic(vec2 p0, vec2 p1, vec2 p2, float t) { float u = 1.0 - t; return u * u * p0 + 2.0 * u * t * p1 + t * t * p2; } // Quadratic Bezier curve between three control points -vec3 lib_curve_bezierQuadratic(vec3 p0, vec3 p1, vec3 p2, float t) { +vec3 curve_bezierQuadratic(vec3 p0, vec3 p1, vec3 p2, float t) { float u = 1.0 - t; return u * u * p0 + 2.0 * u * t * p1 + t * t * p2; } @@ -50,7 +75,7 @@ vec3 lib_curve_bezierQuadratic(vec3 p0, vec3 p1, vec3 p2, float t) { //------------------------------------------------------------------------------ // Catmull-Rom spline for 2D vectors -vec2 lib_curve_catmullRom(vec2 p0, vec2 p1, vec2 p2, vec2 p3, float t) { +vec2 curve_catmullRom(vec2 p0, vec2 p1, vec2 p2, vec2 p3, float t) { vec2 a = 2.0 * p1; vec2 b = p2 - p0; vec2 c = 2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3; @@ -59,7 +84,7 @@ vec2 lib_curve_catmullRom(vec2 p0, vec2 p1, vec2 p2, vec2 p3, float t) { } // Catmull-Rom spline between four points -vec3 lib_curve_catmullRom(vec3 p0, vec3 p1, vec3 p2, vec3 p3, float t) { +vec3 curve_catmullRom(vec3 p0, vec3 p1, vec3 p2, vec3 p3, float t) { vec3 a = 2.0 * p1; vec3 b = p2 - p0; vec3 c = 2.0 * p0 - 5.0 * p1 + 4.0 * p2 - p3; diff --git a/res/glsl/.lib/noise.lib b/res/glsl/.lib/noise.lib index c999cc7..b6cb455 100644 --- a/res/glsl/.lib/noise.lib +++ b/res/glsl/.lib/noise.lib @@ -6,52 +6,82 @@ // PROTOTYPES // ============================================================================= -float lib_noise_dithered(vec2 p); +float noise_hash11(float p); +float noise_hash21(vec2 p); +vec3 noise_hash33(vec3 p); +float noise_blue(vec2 uv); -float lib_noise_rand(vec2 co); -float lib_noise_rand(vec3 co); -float lib_noise_rand(vec4 co); +float dither_noise(vec2 p); +vec3 dither_blueNoise(vec3 color, vec2 uv, float strength); +vec3 dither_quantizedBlueNoise(vec3 color, vec2 uv, float levels); -float lib_noise_gradient(float x); -float lib_noise_gradient(vec2 p); -float lib_noise_gradient(vec3 p); -float lib_noise_gradient(vec4 p); +float noise_rand(vec2 co); +float noise_rand(vec3 co); +float noise_rand(vec4 co); -float lib_noise_fbm(vec2 x, float H, int octaves); -float lib_noise_fbm(vec3 x, float H, int octaves); -float lib_noise_fbm(vec4 x, float H, int octaves); +float noise_gradient(float x); +float noise_gradient(vec2 p); +float noise_gradient(vec3 p); +float noise_gradient(vec4 p); -float lib_noise_value(vec2 p); -float lib_noise_value(vec3 p); -float lib_noise_value(vec3 p); +float noise_fbm(vec2 x, float H, int octaves); +float noise_fbm(vec3 x, float H, int octaves); +float noise_fbm(vec4 x, float H, int octaves); -float lib_noise_simplex(vec2 v); -float lib_noise_simplex(vec3 v); -float lib_noise_simplex(vec4 v); +float noise_value(vec2 p); +float noise_value(vec3 p); +float noise_value(vec3 p); -float lib_noise_perlin(vec2 p); -float lib_noise_perlin(vec3 p); -float lib_noise_perlin(vec4 p); +float noise_simplex(vec2 v); +float noise_simplex(vec3 v); +float noise_simplex(vec4 v); -float lib_noise_fractal(vec2 p, float octaves, float persistence); -float lib_noise_fractal(vec3 p, float octaves, float persistence); -float lib_noise_fractal(vec4 p, float octaves, float persistence); +float noise_perlin(vec2 p); +float noise_perlin(vec3 p); +float noise_perlin(vec4 p); -vec2 lib_noise_voronoi(vec2 p); -vec2 lib_noise_voronoi(vec3 p); -vec2 lib_noise_voronoi(vec4 p); +float noise_fractal(vec2 p, float octaves, float persistence); +float noise_fractal(vec3 p, float octaves, float persistence); +float noise_fractal(vec4 p, float octaves, float persistence); -float lib_noise_worley(vec2 p, int num_cells); -float lib_noise_worley(vec3 p, int num_cells); -float lib_noise_worley(vec4 p, int num_cells); +vec2 noise_voronoi(vec2 p); +vec2 noise_voronoi(vec3 p); +vec2 noise_voronoi(vec4 p); -float lib_noise_turbulence(vec2 p, float size); -float lib_noise_turbulence(vec3 p, float size); -float lib_noise_turbulence(vec3 p, float size); +float noise_worley(vec2 p, int num_cells); +float noise_worley(vec3 p, int num_cells); +float noise_worley(vec4 p, int num_cells); -vec2 lib_noise_smooth(int hash, vec2 p); -vec3 lib_noise_smooth(int hash, vec3 p); -vec4 lib_noise_smooth(int hash, vec4 p); +float noise_turbulence(vec2 p, float size); +float noise_turbulence(vec3 p, float size); +float noise_turbulence(vec3 p, float size); + +vec2 noise_smooth(int hash, vec2 p); +vec3 noise_smooth(int hash, vec3 p); +vec4 noise_smooth(int hash, vec4 p); + +float noise_flow(vec2 p, float time, float strength); +vec2 noise_curl(vec2 p, float epsilon); + +float noise_warp(vec2 p, float strength); +vec3 noise_warp3D(vec3 p, float strength); + +float noise_ridge(vec2 p, float offset); +float noise_ridgeMult(vec2 p, float frequency, float lacunarity, float gain, int octaves); + +float noise_hybrid(vec2 p, float voronoiWeight) +float noise_spiral(vec2 p, float arms, float spin); +float noise_billowed(vec2 p); +float noise_swiss(vec2 p, float scale); + +float noise_terraced(vec2 p, float steps); +float noise_erosion(vec2 p, float roughness); +float noise_river(vec2 p, float width); + +float noise_stars(vec2 p, float density, float size); +float noise_galaxy(vec2 p, float arms, float twist, float chaos); +float noise_nebula(vec2 p, float scale, float detail); +float noise_cosmicWeb(vec2 p, float scale); // // @@ -69,40 +99,90 @@ vec4 grad(vec4 g, vec4 p) { return g * (2.0 * p - 1.0); } +//------------------------------------------------------------------------------ +// HASH NOISE +//------------------------------------------------------------------------------ + +// Hash function for procedural noise +float noise_hash11(float p) { + p = fract(p * .1031); + p *= p + 33.33; + return fract(p * p); +} + +// 2D to 1D hash +float noise_hash21(vec2 p) { + vec3 p3 = fract(vec3(p.xyx) * .1031); + p3 += dot(p3, p3.yzx + 33.33); + return fract((p3.x + p3.y) * p3.z); +} + +// Hash function for blue noise +vec3 noise_hash33(vec3 p) { + p = fract(p * vec3(443.8975, 397.2973, 491.1871)); + p += dot(p.zxy, p.yxz + 19.19); + return fract(vec3(p.x * p.y, p.y * p.z, p.z * p.x)); +} + +//------------------------------------------------------------------------------ +// BLUE NOISE +//------------------------------------------------------------------------------ + +// Generate high-quality blue noise +float noise_blue(vec2 uv) { + vec3 p = vec3(uv, 0.0); + float t = fract(0.0); + vec3 n1 = hash33(floor(p)); + vec3 n2 = hash33(ceil(p)); + return mix(n1.x, n2.x, smoothstep(0.0, 1.0, t)); +} //------------------------------------------------------------------------------ // DITHERED NOISE //------------------------------------------------------------------------------ // Dithered noise -float lib_noise_dithered(vec2 p) { - float base = lib_noise_perlin(p); +float dither_noise(vec2 p) { + float base = noise_perlin(p); float dither = fract(sin(dot(floor(p), vec2(12.9898, 78.233))) * 43758.5453123); return base + dither * 0.5; } +// Improved blue noise dithering +vec3 dither_blueNoise(vec3 color, vec2 uv, float strength) { + float noise = blueNoise(uv); + return color + (noise - 0.5) * strength; +} + +// Quantized dithering with blue noise +vec3 dither_quantizedBlueNoise(vec3 color, vec2 uv, float levels) { + float noise = blueNoise(uv); + vec3 quantized = floor(color * levels + (noise - 0.5)) / levels; + return clamp(quantized, 0.0, 1.0); +} + //------------------------------------------------------------------------------ // RANDOM VALUE //------------------------------------------------------------------------------ // 1D Random Noise function -float lib_noise_rand(float co) { +float noise_rand(float co) { // Compute hash value for the input coordinate return fract(sin(co * 12.9898) * 43758.5453); } // Generate a pseudo-random value based on a 2D coordinate -float lib_noise_rand(vec2 co) { +float noise_rand(vec2 co) { return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453123); } // Generate a pseudo-random value based on a 3D coordinate -float lib_noise_rand(vec3 co) { +float noise_rand(vec3 co) { return fract(sin(dot(co, vec3(12.9898, 78.233, 45.678))) * 43758.5453123); } // Generate a pseudo-random value based on a 4D coordinate -float lib_noise_rand(vec4 co) { +float noise_rand(vec4 co) { return fract(sin(dot(co, vec4(12.9898, 78.233, 45.678, 94.673))) * 43758.5453123); } @@ -110,39 +190,39 @@ float lib_noise_rand(vec4 co) { // NOISE GRADIENT //------------------------------------------------------------------------------ -float lib_noise_gradient(float x) { +float noise_gradient(float x) { float i = floor(x); float f = fract(x); - return mix(lib_noise_rand(i), lib_noise_rand(i + 1.0), smoothstep(0.,1.,f)); + return mix(noise_rand(i), noise_rand(i + 1.0), smoothstep(0.,1.,f)); } // Generate a 2D gradient noise value -float lib_noise_gradient(vec2 p) { +float noise_gradient(vec2 p) { vec2 i = floor(p); vec2 f = fract(p); - float a = lib_noise_rand(i); - float b = lib_noise_rand(i + vec2(1.0, 0.0)); - float c = lib_noise_rand(i + vec2(0.0, 1.0)); - float d = lib_noise_rand(i + vec2(1.0, 1.0)); + float a = noise_rand(i); + float b = noise_rand(i + vec2(1.0, 0.0)); + float c = noise_rand(i + vec2(0.0, 1.0)); + float d = noise_rand(i + vec2(1.0, 1.0)); vec2 u = smoothstep(0.,1.,f); return mix(mix(a, b, u.x), mix(c, d, u.x), u.y); } // Generate a 3D gradient noise value -float lib_noise_gradient(vec3 p) { +float noise_gradient(vec3 p) { vec3 i = floor(p); vec3 f = fract(p); - float a = lib_noise_rand(i); - float b = lib_noise_rand(i + vec3(1.0, 0.0, 0.0)); - float c = lib_noise_rand(i + vec3(0.0, 1.0, 0.0)); - float d = lib_noise_rand(i + vec3(1.0, 1.0, 0.0)); - float e = lib_noise_rand(i + vec3(0.0, 0.0, 1.0)); - float f0 = lib_noise_rand(i + vec3(1.0, 0.0, 1.0)); - float g0 = lib_noise_rand(i + vec3(0.0, 1.0, 1.0)); - float h0 = lib_noise_rand(i + vec3(1.0, 1.0, 1.0)); + float a = noise_rand(i); + float b = noise_rand(i + vec3(1.0, 0.0, 0.0)); + float c = noise_rand(i + vec3(0.0, 1.0, 0.0)); + float d = noise_rand(i + vec3(1.0, 1.0, 0.0)); + float e = noise_rand(i + vec3(0.0, 0.0, 1.0)); + float f0 = noise_rand(i + vec3(1.0, 0.0, 1.0)); + float g0 = noise_rand(i + vec3(0.0, 1.0, 1.0)); + float h0 = noise_rand(i + vec3(1.0, 1.0, 1.0)); vec3 u = smoothstep(0.,1.,f); float v0 = mix(mix(a, b, u.x), mix(c, d, u.x), u.y); @@ -151,27 +231,27 @@ float lib_noise_gradient(vec3 p) { } // Generate a 4D gradient noise value -float lib_noise_gradient(vec4 p) { +float noise_gradient(vec4 p) { vec4 i = floor(p); vec4 f = fract(p); // Compute random values at the corners of the hypercube - float a = lib_noise_rand(i); - float b = lib_noise_rand(i + vec4(1.0, 0.0, 0.0, 0.0)); - float c = lib_noise_rand(i + vec4(0.0, 1.0, 0.0, 0.0)); - float d = lib_noise_rand(i + vec4(1.0, 1.0, 0.0, 0.0)); - float e = lib_noise_rand(i + vec4(0.0, 0.0, 1.0, 0.0)); - float f0 = lib_noise_rand(i + vec4(1.0, 0.0, 1.0, 0.0)); - float g0 = lib_noise_rand(i + vec4(0.0, 1.0, 1.0, 0.0)); - float h0 = lib_noise_rand(i + vec4(1.0, 1.0, 1.0, 0.0)); - float i1 = lib_noise_rand(i + vec4(0.0, 0.0, 0.0, 1.0)); - float j1 = lib_noise_rand(i + vec4(1.0, 0.0, 0.0, 1.0)); - float k1 = lib_noise_rand(i + vec4(0.0, 1.0, 0.0, 1.0)); - float l1 = lib_noise_rand(i + vec4(1.0, 1.0, 0.0, 1.0)); - float m1 = lib_noise_rand(i + vec4(0.0, 0.0, 1.0, 1.0)); - float n1 = lib_noise_rand(i + vec4(1.0, 0.0, 1.0, 1.0)); - float o1 = lib_noise_rand(i + vec4(0.0, 1.0, 1.0, 1.0)); - float p1 = lib_noise_rand(i + vec4(1.0, 1.0, 1.0, 1.0)); + float a = noise_rand(i); + float b = noise_rand(i + vec4(1.0, 0.0, 0.0, 0.0)); + float c = noise_rand(i + vec4(0.0, 1.0, 0.0, 0.0)); + float d = noise_rand(i + vec4(1.0, 1.0, 0.0, 0.0)); + float e = noise_rand(i + vec4(0.0, 0.0, 1.0, 0.0)); + float f0 = noise_rand(i + vec4(1.0, 0.0, 1.0, 0.0)); + float g0 = noise_rand(i + vec4(0.0, 1.0, 1.0, 0.0)); + float h0 = noise_rand(i + vec4(1.0, 1.0, 1.0, 0.0)); + float i1 = noise_rand(i + vec4(0.0, 0.0, 0.0, 1.0)); + float j1 = noise_rand(i + vec4(1.0, 0.0, 0.0, 1.0)); + float k1 = noise_rand(i + vec4(0.0, 1.0, 0.0, 1.0)); + float l1 = noise_rand(i + vec4(1.0, 1.0, 0.0, 1.0)); + float m1 = noise_rand(i + vec4(0.0, 0.0, 1.0, 1.0)); + float n1 = noise_rand(i + vec4(1.0, 0.0, 1.0, 1.0)); + float o1 = noise_rand(i + vec4(0.0, 1.0, 1.0, 1.0)); + float p1 = noise_rand(i + vec4(1.0, 1.0, 1.0, 1.0)); vec4 u = smoothstep(0.,1.,f); float v0 = mix(mix(mix(a, b, u.x), mix(c, d, u.x), u.y), @@ -188,7 +268,7 @@ float lib_noise_gradient(vec4 p) { #define MAX_OCTAVES 12 -float lib_noise_fbm(vec2 x, float H, int octaves) +float noise_fbm(vec2 x, float H, int octaves) { float G = exp2(-H); float f = 1.0; @@ -197,14 +277,14 @@ float lib_noise_fbm(vec2 x, float H, int octaves) octaves = min(octaves, MAX_OCTAVES); for( int i=0; i < octaves; i++ ) { - t += a * lib_noise_rand(f*x); + t += a * noise_rand(f*x); f *= 2.0; a *= G; } return t; } -float lib_noise_fbm(vec3 x, float H, int octaves) +float noise_fbm(vec3 x, float H, int octaves) { float G = exp2(-H); float f = 1.0; @@ -213,14 +293,14 @@ float lib_noise_fbm(vec3 x, float H, int octaves) octaves = min(octaves, MAX_OCTAVES); for( int i=0; i= 1.0) { - value += lib_noise_perlin(p / size) * size; + value += noise_perlin(p / size) * size; size /= 2.0; } @@ -686,24 +766,24 @@ float lib_noise_turbulence(vec2 p, float size) { } // Turbulence function using 3D Perlin noise -float lib_noise_turbulence(vec3 p, float size) { +float noise_turbulence(vec3 p, float size) { float value = 0.0; float initial_size = size; while (size >= 1.0) { - value += lib_noise_gradient(p / size) * size; + value += noise_gradient(p / size) * size; size /= 2.0; } return 0.5 * value / initial_size; } -float lib_noise_turbulence(vec4 p, float size) { +float noise_turbulence(vec4 p, float size) { float total = 0.0; float scale = 1.0; while (size > 1.0) { - total += abs(lib_noise_gradient(p * scale)) / scale; + total += abs(noise_gradient(p * scale)) / scale; scale *= 2.0; size /= 2.0; } @@ -716,7 +796,7 @@ float lib_noise_turbulence(vec4 p, float size) { //------------------------------------------------------------------------------ // Gradient function for 2D -vec2 lib_noise_smooth(int hash, vec2 p) { +vec2 noise_smooth(int hash, vec2 p) { const vec2 grad[4] = vec2[]( vec2( 1.0, 1.0), vec2(-1.0, 1.0), @@ -727,7 +807,7 @@ vec2 lib_noise_smooth(int hash, vec2 p) { } // Gradient function for 3D -vec3 lib_noise_smooth(int hash, vec3 p) { +vec3 noise_smooth(int hash, vec3 p) { const vec3 grad[12] = vec3[]( vec3( 1.0, 1.0, 0.0), vec3(-1.0, 1.0, 0.0), @@ -745,7 +825,7 @@ vec3 lib_noise_smooth(int hash, vec3 p) { return grad[hash % 12]; } -vec4 lib_noise_smooth(int hash, vec4 p) { +vec4 noise_smooth(int hash, vec4 p) { const vec4 grad[32] = vec4[]( vec4( 1.0, 1.0, 1.0, 0.0), vec4(-1.0, 1.0, 1.0, 0.0), @@ -782,3 +862,201 @@ vec4 lib_noise_smooth(int hash, vec4 p) { ); return grad[hash & 31]; } + +//------------------------------------------------------------------------------ +// FLOW NOISE +//------------------------------------------------------------------------------ + +float noise_flow(vec2 p, float time, float strength) { + vec2 flow = vec2( + noise_perlin(vec2(p.x * 0.5 + time * 0.5, p.y * 0.5)), + noise_perlin(vec2(p.x * 0.5 + 40.0 + time * 0.5, p.y * 0.5 + 40.0)) + ); + return noise_perlin(p + flow * strength); +} + +// Curl noise for 2D vector field +vec2 noise_curl(vec2 p, float epsilon) { + float n1 = noise_perlin(vec2(p.x, p.y + epsilon)); + float n2 = noise_perlin(vec2(p.x, p.y - epsilon)); + float n3 = noise_perlin(vec2(p.x + epsilon, p.y)); + float n4 = noise_perlin(vec2(p.x - epsilon, p.y)); + + float x = n1 - n2; + float y = n4 - n3; + + return vec2(x, y) / (2.0 * epsilon); +} + +//------------------------------------------------------------------------------ +// DOMAIN WARPING +//------------------------------------------------------------------------------ + +float noise_warp(vec2 p, float strength) { + vec2 q = vec2( + noise_perlin(p + vec2(0.0, 0.0)), + noise_perlin(p + vec2(5.2, 1.3)) + ); + + vec2 r = vec2( + noise_perlin(p + strength * q + vec2(1.7, 9.2)), + noise_perlin(p + strength * q + vec2(8.3, 2.8)) + ); + + return noise_perlin(p + strength * r); +} + +vec3 noise_warp3D(vec3 p, float strength) { + vec3 q = vec3( + noise_perlin(vec3(p.x, p.y, p.z)), + noise_perlin(vec3(p.x + 5.2, p.y + 1.3, p.z + 2.1)), + noise_perlin(vec3(p.x + 1.7, p.y + 9.2, p.z + 3.5)) + ); + + return q * strength; +} + +//------------------------------------------------------------------------------ +// RIDGED NOISE +//------------------------------------------------------------------------------ + +float noise_ridge(vec2 p, float offset) { + float n = noise_perlin(p); + n = abs(n); // Create creases + n = offset - n; // Invert so creases are at top + n = n * n; // Sharpen creases + return n; +} + +float noise_ridgeMult(vec2 p, float frequency, float lacunarity, float gain, int octaves) { + float sum = 0.0; + float amp = 0.5; + float prev = 1.0; + + for(int i = 0; i < octaves; i++) { + float n = noise_ridge(p * frequency, 1.0); + sum += n * amp * prev; + prev = n; + frequency *= lacunarity; + amp *= gain; + } + return sum; +} + +//------------------------------------------------------------------------------ +// HYBRID NOISE +//------------------------------------------------------------------------------ + +// Combines Perlin and Voronoi for organic patterns +float noise_hybrid(vec2 p, float voronoiWeight) { + float perlin = noise_perlin(p); + vec2 voronoi = noise_voronoi(p * 2.0); + return mix(perlin, voronoi.x, voronoiWeight); +} + +// Creates spiral noise pattern +float noise_spiral(vec2 p, float arms, float spin) { + float angle = atan(p.y, p.x); + float dist = length(p); + float spiral = noise_perlin(vec2(dist * arms + angle * spin, dist)); + return spiral; +} + +// Billowed noise (absolute value of Perlin) +float noise_billowed(vec2 p) { + return abs(noise_perlin(p * 2.0) * 2.0 - 1.0); +} + +// Swiss noise (multiplies different frequencies) +float noise_swiss(vec2 p, float scale) { + float noise1 = noise_perlin(p); + float noise2 = noise_perlin(p * scale); + return noise1 * noise2; +} + +//------------------------------------------------------------------------------ +// TERRAIN NOISE +//------------------------------------------------------------------------------ + +// Terraced noise for plateaus +float noise_terraced(vec2 p, float steps) { + float noise = noise_perlin(p); + return floor(noise * steps) / steps; +} + +// Erosion-like noise +float noise_erosion(vec2 p, float roughness) { + float base = noise_perlin(p); + float detail = noise_ridge(p * 4.0, 1.0); + return base - detail * roughness; +} + +// River network noise +float noise_river(vec2 p, float width) { + vec2 flow = noise_curl(p, 0.1); + float pattern = noise_perlin(p + flow); + return smoothstep(-width, width, pattern); +} + +//------------------------------------------------------------------------------ +// SPACE NOISE +//------------------------------------------------------------------------------ + +// Star field noise (creates points of light) +float noise_stars(vec2 p, float density, float size) { + vec2 cell = floor(p); + vec2 local = fract(p); + + float minDist = 1.0; + + for(int y = -1; y <= 1; y++) { + for(int x = -1; x <= 1; x++) { + vec2 offset = vec2(float(x), float(y)); + vec2 neighbor = cell + offset; + + float rand = noise_rand(neighbor); + if(rand > (1.0 - density)) { + vec2 pos = offset + vec2(noise_rand(neighbor * 49.0), + noise_rand(neighbor * 73.0)); + float dist = length(local - pos); + minDist = min(minDist, dist); + } + } + } + + return smoothstep(size, 0.0, minDist); +} + +// Galaxy-like spiral noise +float noise_galaxy(vec2 p, float arms, float twist, float chaos) { + float angle = atan(p.y, p.x); + float dist = length(p); + float arm_factor = (angle * arms + dist * twist) / (2.0 * M_PI); + float base = fract(arm_factor); + float noise = noise_perlin(p * chaos); + return smoothstep(0.5, 0.0, abs(base - 0.5) + noise * 0.3); +} + +// Nebula-like noise +float noise_nebula(vec2 p, float scale, float detail) { + float base = noise_fbm(p * scale, 0.5, 6); + float fine = noise_perlin(p * scale * detail); + return base * fine; +} + +// Cosmic web noise (interconnected structure) +float noise_cosmicWeb(vec2 p, float scale) { + vec2 id = floor(p * scale); + vec2 f = fract(p * scale); + + float min_dist = 1.0; + for(int y = -1; y <= 1; y++) { + for(int x = -1; x <= 1; x++) { + vec2 offset = vec2(x, y); + vec2 pos = offset + noise_hash33(vec3(id + offset, 0.0)).xy; + min_dist = min(min_dist, length(f - pos)); + } + } + + return 1.0 - smoothstep(0.0, 0.3, min_dist); +} \ No newline at end of file diff --git a/res/glsl/.lib/physics.lib b/res/glsl/.lib/physics.lib new file mode 100644 index 0000000..3d1af37 --- /dev/null +++ b/res/glsl/.lib/physics.lib @@ -0,0 +1,14 @@ +//------------------------------------------------------------------------------ +// CONSTANT +//------------------------------------------------------------------------------ + +#define M_C 299792458.0 // Speed of light in meters per second (m/s) +#define M_G 9.80665 // Gravitational acceleration on Earth (m/s²) +#define M_PLANCK 6.62607015e-34 // Planck's constant (Js) +#define M_KB 1.380649e-23 // Boltzmann constant (J/K) +#define M_MASS_E 9.10938356e-31 // Mass of electron (kg) +#define M_CHARGE_E 1.602176634e-19 // Elementary charge (C) + +#define M_AVOGADRO 6.02214076e23 // Avogadro's number +#define M_R_GAS 8.31446261815324 // Universal gas constant (J/(mol·K)) +#define M_STEFAN 5.670374419e-8 // Stefan-Boltzmann constant (W/(m²·K⁴)) \ No newline at end of file diff --git a/res/glsl/.lib/sdf.lib b/res/glsl/.lib/sdf.lib index bf3ba50..3a2e5e8 100644 --- a/res/glsl/.lib/sdf.lib +++ b/res/glsl/.lib/sdf.lib @@ -2,21 +2,21 @@ // SIGNED DISTANCE //------------------------------------------------------------------------------ -float lib_sdf_polygon2D(vec2 p, vec2 center, float radius, int sides, float starFactor); -float lib_sdf_star2D(vec2 p, float r, float t); -float lib_sdf_heart2D(vec2 p); -float lib_sdf_ellipse2D(vec2 p, vec2 radii); -float lib_sdf_circle2D(vec2 p, float r); +float sdf_polygon2D(vec2 p, vec2 center, float radius, int sides, float starFactor); +float sdf_star2D(vec2 p, float r, float t); +float sdf_heart2D(vec2 p); +float sdf_ellipse2D(vec2 p, vec2 radii); +float sdf_circle2D(vec2 p, float r); //------------------------------------------------------------------------------ // SUPPORT FUNCTIONS //------------------------------------------------------------------------------ -float lib_sdf_union(float d1, float d2); -float lib_sdf_subtract(float d1, float d2); -float lib_sdf_round(vec2 s, float r); -float lib_sdf_hollow(vec2 s, float thickness); -vec3 lib_sdf_hollow(vec3 shape, float r); +float sdf_union(float d1, float d2); +float sdf_subtract(float d1, float d2); +float sdf_round(vec2 s, float r); +float sdf_hollow(vec2 s, float thickness); +vec3 sdf_hollow(vec3 shape, float r); //------------------------------------------------------------------------------ // SHAPE @@ -27,30 +27,31 @@ vec3 lib_sdf_hollow(vec3 shape, float r); //------------------------------------------------------------------------------ // Signed distance box of size radius -float lib_sdf_box(vec2 p, vec2 radius) +float sdf_box(vec2 p, vec2 radius) { vec2 d = abs(p)-radius; return length(max(d,0.0)) + min(maxcomp(d),0.0); } -float lib_sdf_box(vec3 p, vec3 radius) +float sdf_box(vec3 p, vec3 radius) { vec2 d = abs(p)-radius; return length(max(d,0.0)) + min(maxcomp(d),0.0); + // return length(max(d, 0.0)) + min(max(d.x, max(d.y, d.z)), 0.0); } -float lib_sdf_box(vec4 p, vec4 radius) +float sdf_box(vec4 p, vec4 radius) { vec2 d = abs(p)-radius; return length(max(d,0.0)) + min(maxcomp(d),0.0); } // Computes the signed distance from a point to a sphere -float lib_sdf_sphere(vec3 p, float r) { +float sdf_sphere(vec3 p, float r) { return length(p) - r; } -float lib_sdf_cylinder(vec3 p, float r, float h) { +float sdf_cylinder(vec3 p, float r, float h) { vec2 d = vec2(length(p.xy) - r, abs(p.z) - h * 0.5); return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0); } @@ -59,7 +60,7 @@ float lib_sdf_cylinder(vec3 p, float r, float h) { -float lib_sdf_polygon(vec2 p, vec2 center, float r, int sides, float starFactor) { +float sdf_polygon(vec2 p, vec2 center, float r, int sides, float starFactor) { float angle = M_TAU / float(sides); float dist = 1e30; // Initialize to a large value @@ -86,16 +87,16 @@ float lib_sdf_polygon(vec2 p, vec2 center, float r, int sides, float starFactor) return dist; } -float lib_sdf_ellipse(vec2 p, vec2 radii) { +float sdf_ellipse(vec2 p, vec2 radii) { vec2 q = abs(p) - radii; return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0); } -float lib_sdf_circle(vec2 p, float r) { +float sdf_circle(vec2 p, float r) { return length(p) - r; } -float lib_sdf_star(vec2 p, float r, float t) { +float sdf_star(vec2 p, float r, float t) { float theta = atan(p.y, p.x); float radius = length(p); float angle = mod(theta, M_TAU / max(1., t)); @@ -105,7 +106,7 @@ float lib_sdf_star(vec2 p, float r, float t) { return d; } -float lib_sdf_heart(vec2 p) { +float sdf_heart(vec2 p) { float x = p.x; float y = p.y; float a = 1.0 - x * x - (5.0 * y / 4.0 - sqrt(abs(x))) * (5.0 * y / 4.0 - sqrt(abs(x))); @@ -117,46 +118,46 @@ float lib_sdf_heart(vec2 p) { //------------------------------------------------------------------------------ // Repeats the space with periodic boundary conditions -vec3 lib_sdf_repeat(vec3 p, vec3 c) { +vec3 sdf_repeat(vec3 p, vec3 c) { return mod(p, c) - 0.5 * c; } // Union of two distances -float lib_sdf_union(float d1, float d2) { +float sdf_union(float d1, float d2) { return min(d1, d2); } // Smooth union of two distances -float lib_sdf_unionSmooth(float a, float b, float k) { +float sdf_unionSmooth(float a, float b, float k) { float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0); return mix(b, a, h) - k * h * (1.0 - h); } // Intersection of two distances -float lib_sdf_intersection(float d1, float d2) { +float sdf_intersection(float d1, float d2) { return max(d1, d2); } // Subtraction of two distances -float lib_sdf_difference(float d1, float d2) { +float sdf_difference(float d1, float d2) { return max(d1, -d2); } -float lib_sdf_hollow2(vec2 s, float thickness) { +float sdf_hollow2(vec2 s, float thickness) { return abs(s) - thickness; } -vec3 lib_sdf_hollow3(vec3 shape, float r) { +vec3 sdf_hollow3(vec3 shape, float r) { return vec3(abs(shape.x) - r, sign(shape.x) * shape.yz); } // Displacement effect using sine functions -float lib_sdf_displacement(vec3 p) { +float sdf_displacement(vec3 p) { return sin(p.x) * sin(p.y) * sin(p.z); } // Applies a twisting transformation to a point -vec3 lib_sdf_twist(vec3 p, float a) { +vec3 sdf_twist(vec3 p, float a) { float c = cos(a * p.y); float s = sin(a * p.y); mat2 m = mat2(c, -s, s, c); @@ -168,7 +169,7 @@ vec3 lib_sdf_twist(vec3 p, float a) { //------------------------------------------------------------------------------ // Computes ray-box intersection and returns true if intersection occurs -bool lib_intersection_aabb(vec3 o, vec3 dir, vec3 bmin, vec3 bmax, inout vec2 e) { +bool intersection_aabb(vec3 o, vec3 dir, vec3 bmin, vec3 bmax, inout vec2 e) { vec3 a = (bmin - o) / dir; vec3 b = (bmax - o) / dir; vec3 s = min(a, b); @@ -190,11 +191,11 @@ float dist_field(vec3 p) { // p = sdTwist(p, 3.0); // Compute distances to box and sphere - float d0 = lib_sdf_box(p, vec3(0.5)); - float d1 = lib_sdf_sphere(p, 0.6); + float d0 = sdf_box(p, vec3(0.5)); + float d1 = sdf_sphere(p, 0.6); // Combine distances using intersection - return lib_sdf_intersection(d1, d0); + return sdf_intersection(d1, d0); // Optionally include displacement and smooth union // return d + sfDisp(p * 2.5); diff --git a/res/glsl/.lib/shading.lib b/res/glsl/.lib/shading.lib index 8586e43..a4f7db7 100644 --- a/res/glsl/.lib/shading.lib +++ b/res/glsl/.lib/shading.lib @@ -8,30 +8,30 @@ // PROTOTYPES // ============================================================================= -vec3 lib_shading_fresnel(vec3 F0, vec3 h, vec3 l); // Computes the Fresnel reflection factor -vec3 lib_shading_phong_light(vec3 pos, vec3 color); // -vec3 lib_shading_phong(vec3 v, vec3 n, vec3 dir, vec3 eye); // Computes Phong shading for a given point +vec3 shading_fresnel(vec3 F0, vec3 h, vec3 l); // Computes the Fresnel reflection factor +vec3 shading_phong_light(vec3 pos, vec3 color); // +vec3 shading_phong(vec3 v, vec3 n, vec3 dir, vec3 eye); // Computes Phong shading for a given point // ============================================================================= // PHONG // ============================================================================= // Computes the Fresnel reflection factor -vec3 lib_shading_fresnel(vec3 F0, vec3 h, vec3 l) { +vec3 shading_fresnel(vec3 F0, vec3 h, vec3 l) { return F0 + (1.0 - F0) * pow(clamp(1.0 - dot(h, l), 0.0, 1.0), 5.0); } -vec3 lib_shading_phong_light(vec3 pos, vec3 color) { +vec3 shading_phong_light(vec3 pos, vec3 color) { vec3 vl = normalize(pos - v); vec3 diffuse = Kd * vec3(max(0.0, dot(vl, n))); vec3 specular = vec3(max(0.0, dot(vl, ref))); - vec3 F = lib_shading_fresnel(Ks, normalize(vl - dir), vl); + vec3 F = shading_fresnel(Ks, normalize(vl - dir), vl); specular = pow(specular, vec3(shininess)); return color * mix(diffuse, specular, F); } // Computes Phong shading for a given point -vec3 lib_shading_phong(vec3 v, vec3 n, vec3 dir, vec3 eye) { +vec3 shading_phong(vec3 v, vec3 n, vec3 dir, vec3 eye) { vec3 final = vec3(0.0); // Define material properties @@ -44,14 +44,14 @@ vec3 lib_shading_phong(vec3 v, vec3 n, vec3 dir, vec3 eye) { { vec3 light_pos = vec3(20.0, 20.0, 20.0); vec3 light_color = vec3(1.0, 0.7, 0.7); - final += lib_shading_phong_light(light_pos, light_color); + final += shading_phong_light(light_pos, light_color); } // Light 1 { vec3 light_pos = vec3(-20.0, -20.0, -30.0); vec3 light_color = vec3(0.5, 0.7, 1.0); - final += lib_shading_phong_light(light_pos, light_color); + final += shading_phong_light(light_pos, light_color); } return final; } \ No newline at end of file diff --git a/res/glsl/.lib/vector.lib b/res/glsl/.lib/vector.lib index d206fee..76bb2fb 100644 --- a/res/glsl/.lib/vector.lib +++ b/res/glsl/.lib/vector.lib @@ -17,21 +17,21 @@ // PROTOTYPE // ============================================================================= -float lib_vec_ndot(in vec2 a, in vec2 b); -mat3 lib_vec_rotationXY(vec2 angle); -vec2 lib_vec_rotate2(vec2 v, float angle); +float vec_ndot(in vec2 a, in vec2 b); +mat3 vec_rotationXY(vec2 angle); +vec2 vec_rotate2(vec2 v, float angle); //------------------------------------------------------------------------------ // ANGLE //------------------------------------------------------------------------------ // Compute the "negative dot product" of two 2D vectors -float lib_vec_ndot(in vec2 a, in vec2 b) { +float vec_ndot(in vec2 a, in vec2 b) { return a.x*b.x - a.y*b.y; } // Creates a rotation matrix for pitch, yaw -mat3 lib_vec_rotationXY( vec2 angle ) { +mat3 vec_rotationXY( vec2 angle ) { vec2 c = cos( angle ); vec2 s = sin( angle ); @@ -43,7 +43,7 @@ mat3 lib_vec_rotationXY( vec2 angle ) { } // Rotates a 2D vector by angle in radians -vec2 lib_vec_rotate2(vec2 v, float angle) { +vec2 vec_rotate2(vec2 v, float angle) { float cosA = cos(angle); float sinA = sin(angle); return vec2( diff --git a/res/glsl/adjust/util-invert.frag b/res/glsl/adjust/util-invert.frag index c6cd3b8..c90910c 100644 --- a/res/glsl/adjust/util-invert.frag +++ b/res/glsl/adjust/util-invert.frag @@ -1,6 +1,6 @@ // name: INVERT // desc: Invert the channels of an image along a scalar [0..1] range. -// category: ADJUST +// category: COLOR uniform sampler2D image; // | 4-channel data uniform vec4 invert; // 0,0,0,0;0;1 | amount to invert each channel diff --git a/res/glsl/color/color-convert.frag b/res/glsl/color/color-convert.frag index 59c7556..a494a2a 100644 --- a/res/glsl/color/color-convert.frag +++ b/res/glsl/color/color-convert.frag @@ -2,7 +2,7 @@ // desc: Convert an image from one color space (RGB, HSV, LAB, XYZ) to another. // category: COLOR -#include .lib/color.lib +#include .lib/convert.lib uniform sampler2D image; // | Image to convert uniform int operator; // EnumGLSLColorConvert | conversion operation to perform. @@ -14,32 +14,32 @@ uniform int operator; // EnumGLSLColorConvert | conversion operation to perfo vec3 convertColor(vec3 color, int operator) { // RGB if (operator == 0) { - return rgb2hsv(color); + return convert_rgb2hsv(color); } else if (operator == 1) { - return rgb2lab(color); + return convert_rgb2lab(color); } else if (operator == 2) { - return rgb2xyz(color); + return convert_rgb2xyz(color); // HSV } else if (operator == 10) { - return hsv2rgb(color); + return convert_hsv2rgb(color); } else if (operator == 11) { - return hsv2lab(color); + return convert_hsv2lab(color); } else if (operator == 12) { - return hsv2xyz(color); + return convert_hsv2xyz(color); // LAB } else if (operator == 20) { - return lab2rgb(color); + return convert_lab2rgb(color); } else if (operator == 21) { - return lab2hsv(color); + return convert_lab2hsv(color); } else if (operator == 22) { - return lab2xyz(color); + return convert_lab2xyz(color); // XYZ } else if (operator == 30) { - return xyz2rgb(color); + return convert_xyz2rgb(color); } else if (operator == 31) { - return xyz2hsv(color); + return convert_xyz2hsv(color); } else if (operator == 32) { - return xyz2lab(color); + return convert_xyz2lab(color); } return color; } diff --git a/res/glsl/color/color-hsv.frag b/res/glsl/color/color-hsv.frag index fa45c97..0f1b486 100644 --- a/res/glsl/color/color-hsv.frag +++ b/res/glsl/color/color-hsv.frag @@ -2,18 +2,18 @@ // desc: Hue, Saturation and Value adjustment control. Maintains alpha/mask. // category: COLOR -#include .lib/color.lib +#include .lib/convert.lib -uniform sampler2D image; // | RGB(A) image +uniform sampler2D image; // | RGB(A) image uniform vec3 HSV; // 0.,1.,1.;-1;2;0.01 | Adjust the Hue, Saturation or Value void mainImage(out vec4 fragColor, vec2 fragCoord) { vec2 uv = fragCoord.xy / iResolution.xy; vec4 color = texture(image, uv); - vec3 hsv = rgb2hsv(color.rgb); + vec3 hsv = convert_rgb2hsv(color.rgb); hsv.x = mod(hsv.x + HSV.x, 1.0); hsv.y = clamp(hsv.y * HSV.y, 0.0, 1.0); hsv.z = clamp(hsv.z * HSV.z, 0.0, 1.0); - fragColor = vec4(hsv2rgb(hsv), color.a); + fragColor = vec4(convert_hsv2rgb(hsv), color.a); } \ No newline at end of file diff --git a/res/glsl/filter/filter-posterize.frag b/res/glsl/filter/filter-posterize.frag index 8bece4c..c3de3bd 100644 --- a/res/glsl/filter/filter-posterize.frag +++ b/res/glsl/filter/filter-posterize.frag @@ -1,15 +1,16 @@ // name: POSTERIZE // desc: Reduce the pixel color data range -// category: FILTER +// category: COLOR + +#include .lib/color.lib uniform sampler2D image; // | RGB(A) image -uniform int steps; // 63;1;255;1 | Pixel data range allowed +uniform int steps; // 16;2;255;1 | Pixel data range allowed void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord / iResolution.xy; vec4 orig = texture(image, uv.xy); - float step = max(1., min(255., float(steps) - 0.5)); - vec3 color = floor(orig.xyz * step) / step; + vec3 color = color_posterize(orig.rgb, steps); fragColor = vec4(color, orig.a); } \ No newline at end of file