diff --git a/src/doc/stdlib.md b/src/doc/stdlib.md index bcc803ebb..d818b7062 100644 --- a/src/doc/stdlib.md +++ b/src/doc/stdlib.md @@ -166,6 +166,12 @@ the computations are performed component-by-component (separately for `x`, $ x*(1-\alpha) + y*(\alpha) $ +*`type`* **`unmix`** (*`type`* `x`, *`type`* `y`, *`type`* `alpha`)
*`type`* **`unmix`** (*`type`* `x`, *`type`* `y, float alpha`) + : The `unmix` function returns a inverse of `mix`, similar to inverse linear interpolation: + $ (x - (\alpha)) / (y - x) $ + The x and y value can't be the same, as we can't divide by zero. + + *`type`* **`select`** (*`type`* `x`, *`type`* `y`, *`type`* `cond`)
*`type`* **`select`** (*`type`* `x`, *`type`* `y, float cond`)
*`type`* **`select`** (*`type`* `x`, *`type`* `y, int cond`) : The `select` function returns `x` if `cond` is zero, or `y` if `cond` is nonzero. This is roughly equivalent to `(cond ? y : x)`, diff --git a/src/shaders/color2.h b/src/shaders/color2.h index ca7bef3c4..1c6fa325a 100644 --- a/src/shaders/color2.h +++ b/src/shaders/color2.h @@ -183,6 +183,12 @@ color2 mix(color2 a, color2 b, float x ) mix(a.a, b.a, x)); } +color2 unmix(color2 a, color2 b, float x ) +{ + return color2(unmix(a.r, b.r, x), + unmix(a.a, b.a, x)); +} + color2 smoothstep(color2 edge0, color2 edge1, color2 c) { return color2(smoothstep(edge0.r, edge1.r, c.r), diff --git a/src/shaders/color4.h b/src/shaders/color4.h index 84610f0f1..4b216872c 100644 --- a/src/shaders/color4.h +++ b/src/shaders/color4.h @@ -183,6 +183,12 @@ color4 mix(color4 a, color4 b, float x ) mix(a.a, b.a, x)); } +color4 unmix(color4 a, color4 b, float x ) +{ + return color4(unmix(a.rgb, b.rgb, x), + unmix(a.a, b.a, x)); +} + color4 smoothstep(color4 edge0, color4 edge1, color4 c) { return color4(smoothstep(edge0.rgb, edge1.rgb, c.rgb), diff --git a/src/shaders/stdosl.h b/src/shaders/stdosl.h index ee86ae7be..be4e35a51 100644 --- a/src/shaders/stdosl.h +++ b/src/shaders/stdosl.h @@ -164,6 +164,32 @@ float mix (float x, float y, float a) BUILTIN; closure color mix (closure color x, closure color y, float a) { return x*(1-a) + y*a; } closure color mix (closure color x, closure color y, color a) { return x*(1-a) + y*a; } +#if 0 // Assuming x != y +normal unmix (normal x, normal y, normal a) { return (a - x) / (y - x); } +normal unmix (normal x, normal y, float a) { return (a - x) / (y - x); } +vector unmix (vector x, vector y, vector a) { return (a - x) / (y - x); } +vector unmix (vector x, vector y, float a) { return (a - x) / (y - x); } +point unmix (point x, point y, point a) { return (a - x) / (y - x); } +point unmix (point x, point y, float a) { return (a - x) / (y - x); } +color unmix (color x, color y, color a) { return (a - x) / (y - x); } +color unmix (color x, color y, float a) { return (a - x) / (y - x); } +float unmix (float x, float y, float a) { return (a - x) / (y - x); } +#else +normal unmix (normal x, normal y, normal a) BUILTIN; +normal unmix (normal x, normal y, float a) BUILTIN; +vector unmix (vector x, vector y, vector a) BUILTIN; +vector unmix (vector x, vector y, float a) BUILTIN; +point unmix (point x, point y, point a) BUILTIN; +point unmix (point x, point y, float a) BUILTIN; +color unmix (color x, color y, color a) BUILTIN; +color unmix (color x, color y, float a) BUILTIN; +float unmix (float x, float y, float a) BUILTIN; +#endif +// closure color unmix (closure color x, closure color y, float a) { return (a - x) / (y - x); } +// closure color unmix (closure color x, closure color y, color a) { return (a - x) / (y - x); } + +// TODO: ADD REMAP FROM MIX AND UNMIX + normal select (normal x, normal y, normal cond) BUILTIN; vector select (vector x, vector y, vector cond) BUILTIN; point select (point x, point y, point cond) BUILTIN; diff --git a/src/shaders/vector2.h b/src/shaders/vector2.h index f57307a66..39085e233 100644 --- a/src/shaders/vector2.h +++ b/src/shaders/vector2.h @@ -182,6 +182,11 @@ vector2 mix(vector2 a, vector2 b, float x ) return vector2 (mix(a.x, b.x, x), mix(a.y, b.y, x)); } +vector2 unmix(vector2 a, vector2 b, float x ) +{ + return vector2 (unmix(a.x, b.x, x), unmix(a.y, b.y, x)); +} + float dot(vector2 a, vector2 b) { return (a.x * b.x + a.y * b.y); diff --git a/src/shaders/vector4.h b/src/shaders/vector4.h index c30167bf9..573a769ba 100644 --- a/src/shaders/vector4.h +++ b/src/shaders/vector4.h @@ -209,6 +209,14 @@ vector4 mix(vector4 value1, vector4 value2, float x ) mix( value1.w, value2.w, x)); } +vector4 unmix(vector4 value1, vector4 value2, float x ) +{ + return vector4 (unmix( value1.x, value2.x, x), + unmix( value1.y, value2.y, x), + unmix( value1.z, value2.z, x), + unmix( value1.w, value2.w, x)); +} + vector vec4ToVec3(vector4 v) { return vector(v.x, v.y, v.z) / v.w;