Implement oklab, oklch color space conversion functions, add example, restructure comments in the shaderlib, implements #37
This commit is contained in:
parent
35959290d3
commit
1a21589fc1
8 changed files with 127 additions and 34 deletions
12
examples/oklab.gdshader
Normal file
12
examples/oklab.gdshader
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
shader_type canvas_item;
|
||||||
|
|
||||||
|
#include "res://shaderlib/colorspaces.gdshaderinc"
|
||||||
|
|
||||||
|
//!load ./images/swamp.jpg
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
vec4 oklab = rgb2oklab(COLOR);
|
||||||
|
vec4 oklch = oklab2oklch(oklab);
|
||||||
|
oklch.z -= 2.0;
|
||||||
|
COLOR = oklab2rgb(oklch2oklab(oklch));
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
|
|
||||||
// gaussian_blur adapted from https://godotshaders.com/shader/customizable-gausian-blur/
|
/*
|
||||||
// original code by https://godotshaders.com/author/djbob-gaming-yt/
|
gaussian_blur adapted from https://godotshaders.com/shader/customizable-gausian-blur/
|
||||||
// maximum radius is 64
|
original code by https://godotshaders.com/author/djbob-gaming-yt/
|
||||||
|
maximum radius is 64
|
||||||
|
*/
|
||||||
vec4 gaussian_blur(sampler2D texture, vec2 uv, int radius, float sigma) {
|
vec4 gaussian_blur(sampler2D texture, vec2 uv, int radius, float sigma) {
|
||||||
vec2 resolution = 1.0 / vec2(textureSize(texture, 0));
|
vec2 resolution = 1.0 / vec2(textureSize(texture, 0));
|
||||||
// calculate kernel
|
// calculate kernel
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
|
|
||||||
// rgb2hsv and hsv2rgb functions adapted
|
/*
|
||||||
// from https://godotshaders.com/shader/hsv-adjustment/
|
Color space conversion functions always work with vec4.
|
||||||
// original code by https://godotshaders.com/author/al1-ce/
|
The fourth value is always alpha.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "res://shaderlib/common.gdshaderinc"
|
||||||
|
|
||||||
|
/*
|
||||||
|
rgb2hsv and hsv2rgb functions adapted
|
||||||
|
from https://godotshaders.com/shader/hsv-adjustment/
|
||||||
|
original code by https://godotshaders.com/author/al1-ce/
|
||||||
|
*/
|
||||||
|
|
||||||
// Convert RGB to HSV (hue, saturation, brightness)
|
// Convert RGB to HSV (hue, saturation, brightness)
|
||||||
vec4 rgb2hsv(vec4 c) {
|
vec4 rgb2hsv(vec4 c) {
|
||||||
|
@ -20,3 +29,62 @@ vec4 hsv2rgb(vec4 c) {
|
||||||
vec3 rgb = c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
vec3 rgb = c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||||
return vec4(rgb.r, rgb.g, rgb.b, c.a);
|
return vec4(rgb.r, rgb.g, rgb.b, c.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
OkLab and OkLCh
|
||||||
|
For more details on oklab, see
|
||||||
|
- https://bottosson.github.io/posts/oklab/
|
||||||
|
- https://en.wikipedia.org/wiki/Oklab_color_space
|
||||||
|
*/
|
||||||
|
|
||||||
|
vec4 rgb2oklab(vec4 c) {
|
||||||
|
float l = 0.4122214708f * c.r + 0.5363325363f * c.g + 0.0514459929f * c.b;
|
||||||
|
float m = 0.2119034982f * c.r + 0.6806995451f * c.g + 0.1073969566f * c.b;
|
||||||
|
float s = 0.0883024619f * c.r + 0.2817188376f * c.g + 0.6299787005f * c.b;
|
||||||
|
|
||||||
|
float l_ = cbrt(l);
|
||||||
|
float m_ = cbrt(m);
|
||||||
|
float s_ = cbrt(s);
|
||||||
|
|
||||||
|
return vec4(
|
||||||
|
0.2104542553f*l_ + 0.7936177850f*m_ - 0.0040720468f*s_,
|
||||||
|
1.9779984951f*l_ - 2.4285922050f*m_ + 0.4505937099f*s_,
|
||||||
|
0.0259040371f*l_ + 0.7827717662f*m_ - 0.8086757660f*s_,
|
||||||
|
c.a
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 oklab2rgb(vec4 c) {
|
||||||
|
float l_ = c.x + 0.3963377774f * c.y + 0.2158037573f * c.z;
|
||||||
|
float m_ = c.x - 0.1055613458f * c.y - 0.0638541728f * c.z;
|
||||||
|
float s_ = c.x - 0.0894841775f * c.y - 1.2914855480f * c.z;
|
||||||
|
|
||||||
|
float l = l_*l_*l_;
|
||||||
|
float m = m_*m_*m_;
|
||||||
|
float s = s_*s_*s_;
|
||||||
|
|
||||||
|
return vec4(
|
||||||
|
+4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s,
|
||||||
|
-1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s,
|
||||||
|
-0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s,
|
||||||
|
c.a
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 oklab2oklch(vec4 c) {
|
||||||
|
return vec4(
|
||||||
|
c.x,
|
||||||
|
sqrt((c.y * c.y) + (c.z * c.z)),
|
||||||
|
atan(c.z, c.y),
|
||||||
|
c.a
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 oklch2oklab(vec4 c) {
|
||||||
|
return vec4(
|
||||||
|
c.x,
|
||||||
|
c.y * cos(c.z),
|
||||||
|
c.y * sin(c.z),
|
||||||
|
c.a
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
5
shaderlib/common.gdshaderinc
Normal file
5
shaderlib/common.gdshaderinc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
// inefficient cuberoot function
|
||||||
|
float cbrt(float x) {
|
||||||
|
return pow(x, 1.0/3.0);
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
|
|
||||||
/* glslSmartDenoise by Michele Morrone, adapted
|
/*
|
||||||
|
glslSmartDenoise by Michele Morrone, adapted
|
||||||
original code: https://github.com/BrutPitt/glslSmartDeNoise
|
original code: https://github.com/BrutPitt/glslSmartDeNoise
|
||||||
license of the original code:
|
license of the original code:
|
||||||
|
|
||||||
BSD 2-Clause License
|
BSD 2-Clause License
|
||||||
|
|
||||||
Copyright (c) 2019-2020 Michele Morrone
|
Copyright (c) 2019-2020 Michele Morrone
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
// Load in a texture from a sampler2D with an offset and scale
|
/*
|
||||||
// See examples/place_texture.gdshader
|
Load in a texture from a sampler2D with an offset and scale
|
||||||
|
See examples/place_texture.gdshader
|
||||||
|
*/
|
||||||
vec4 place_texture(sampler2D sampler, vec2 uv, vec2 texture_pixel_size, vec2 offset, vec2 scale) {
|
vec4 place_texture(sampler2D sampler, vec2 uv, vec2 texture_pixel_size, vec2 offset, vec2 scale) {
|
||||||
vec2 texture_size = vec2(textureSize(sampler, 0));
|
vec2 texture_size = vec2(textureSize(sampler, 0));
|
||||||
// position of current pixel; sample color c
|
// position of current pixel; sample color c
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
// Alpha Blending a over b after Bruce A. Wallace
|
/*
|
||||||
// source: https://en.wikipedia.org/wiki/Alpha_compositing
|
Alpha Blending a over b after Bruce A. Wallace
|
||||||
|
source: https://en.wikipedia.org/wiki/Alpha_compositing
|
||||||
|
*/
|
||||||
vec4 alpha_blend(vec4 b, vec4 a) {
|
vec4 alpha_blend(vec4 b, vec4 a) {
|
||||||
float alpha = a.a + (b.a * (1.0 - a.a));
|
float alpha = a.a + (b.a * (1.0 - a.a));
|
||||||
vec3 col = ((a.rgb*a.a) + ((b.rgb*b.a) * (1.0 - a.a)) / alpha);
|
vec3 col = ((a.rgb*a.a) + ((b.rgb*b.a) * (1.0 - a.a)) / alpha);
|
||||||
|
|
|
@ -137,7 +137,7 @@ var shaderlib_regex = {
|
||||||
"blur": RegEx.create_from_string(r'\s*\#include\s+\"res\:\/\/shaderlib\/blur\.gdshaderinc\"'),
|
"blur": RegEx.create_from_string(r'\s*\#include\s+\"res\:\/\/shaderlib\/blur\.gdshaderinc\"'),
|
||||||
}
|
}
|
||||||
const shaderlib_functions = {
|
const shaderlib_functions = {
|
||||||
"colorspaces": ["rgb2hsv", "hsv2rgb"],
|
"colorspaces": ["rgb2hsv", "hsv2rgb", "oklab2rgb", "rgb2oklab", "oklab2oklch", "oklch2oklab"],
|
||||||
"transform": ["place_texture"],
|
"transform": ["place_texture"],
|
||||||
"transparency": ["alpha_blend"],
|
"transparency": ["alpha_blend"],
|
||||||
"effects": ["pixelate"],
|
"effects": ["pixelate"],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue