[orx-shade-styles] convert to MPP

This commit is contained in:
Edwin Jakobs
2021-06-29 13:55:16 +02:00
parent f85de6c163
commit bfd7414594
13 changed files with 196 additions and 23 deletions

View File

@@ -0,0 +1,71 @@
package org.openrndr.extra.shadestyles
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.ShadeStyle
import org.openrndr.extra.parameters.ColorParameter
import org.openrndr.extra.parameters.Description
import org.openrndr.extra.parameters.DoubleParameter
import org.openrndr.math.Vector2
@Description("Angular gradient")
class AngularGradient(
color0: ColorRGBa,
color1: ColorRGBa,
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
exponent: Double = 1.0) : ShadeStyle() {
@ColorParameter("start color", order = 0)
var color0 : ColorRGBa by Parameter()
@ColorParameter("end color", order = 1)
var color1 : ColorRGBa by Parameter()
@ColorParameter("offset", order = 2)
var offset : Vector2 by Parameter()
@ColorParameter("rotation", order = 3)
var rotation : Double by Parameter()
@DoubleParameter("exponent", 0.01, 10.0, order = 4)
var exponent: Double by Parameter()
init {
this.color0 = color0
this.color1 = color1
this.offset = offset
this.rotation = rotation
this.exponent = exponent
fragmentTransform = """
vec2 coord = (c_boundsPosition.xy - 0.5 + p_offset/2.0) * 2.0;
float cr = cos(radians(p_rotation));
float sr = sin(radians(p_rotation));
mat2 rm = mat2(cr, -sr, sr, cr);
vec2 rc = rm * coord;
float f = (atan(rc.y, rc.x) + 3.1415926536) / (2.0 * 3.1415926536);
vec4 color0 = p_color0;
color0.rgb *= color0.a;
vec4 color1 = p_color1;
color1.rgb *= color1.a;
vec4 gradient = mix(color0, color1, pow(f, p_exponent));
vec4 fn = vec4(x_fill.rgb, 1.0) * x_fill.a;
x_fill = fn * gradient;
if (x_fill.a != 0) {
x_fill.rgb /= x_fill.a;
}
"""
}
}
fun angularGradient(
color0: ColorRGBa,
color1: ColorRGBa,
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
exponent: Double = 1.0
): ShadeStyle {
return AngularGradient(color0, color1, offset, rotation, exponent)
}

View File

@@ -0,0 +1,13 @@
package org.openrndr.extra.shadestyles
import org.openrndr.color.ColorRGBa
import org.openrndr.extras.color.spaces.ColorOKLABa
import kotlin.reflect.KClass
internal fun generateColorTransform(kClass: KClass<*>): String {
return when (kClass) {
ColorRGBa::class -> """"""
ColorOKLABa::class -> """gradient = linear_rgb_to_srgb(oklab_to_linear_rgb(gradient));"""
else -> error("color space not supported $kClass")
}
}

View File

@@ -0,0 +1,73 @@
package org.openrndr.extra.shadestyles
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.ShadeStyle
import org.openrndr.extra.parameters.ColorParameter
import org.openrndr.extra.parameters.Description
import org.openrndr.extra.parameters.DoubleParameter
import org.openrndr.math.Vector2
@Description("Half-angular gradient")
class HalfAngularGradient(
color0: ColorRGBa,
color1: ColorRGBa,
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
exponent: Double = 1.0) : ShadeStyle() {
@ColorParameter("start color", order = 0)
var color0: ColorRGBa by Parameter()
@ColorParameter("end color", order = 1)
var color1: ColorRGBa by Parameter()
var offset: Vector2 by Parameter()
@DoubleParameter("rotation", -180.0, 180.0, order = 2)
var rotation: Double by Parameter()
@DoubleParameter("exponent", 0.01, 10.0, order = 3)
var exponent: Double by Parameter()
init {
this.color0 = color0
this.color1 = color1
this.offset = offset
this.rotation = rotation
this.exponent = exponent
fragmentTransform = """
vec2 coord = (c_boundsPosition.xy - 0.5 + p_offset/2.0) * 2.0;
float cr = cos(radians(p_rotation));
float sr = sin(radians(p_rotation));
mat2 rm = mat2(cr, -sr, sr, cr);
vec2 rc = rm * coord;
float f = abs(atan(rc.y, rc.x)) / (3.1415926536);
//float f = abs(atan(rc.y/rc.x)) / (3.1415926536/2.0);
//float f = (atan(rc.y/rc.x) + 3.1415926536/2.0) / (3.1415926536);
vec4 color0 = p_color0;
color0.rgb *= color0.a;
vec4 color1 = p_color1;
color1.rgb *= color1.a;
vec4 gradient = mix(color0, color1, pow(f, p_exponent));
vec4 fn = vec4(x_fill.rgb, 1.0) * x_fill.a;
x_fill = fn * gradient;
if (x_fill.a != 0) {
x_fill.rgb /= x_fill.a;
}
"""
}
}
fun halfAngularGradient(
color0: ColorRGBa,
color1: ColorRGBa,
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
exponent: Double = 1.0
): ShadeStyle {
return HalfAngularGradient(color0, color1, offset, rotation, exponent)
}

View File

@@ -0,0 +1,103 @@
package org.openrndr.extra.shadestyles
import org.openrndr.color.*
import org.openrndr.draw.ShadeStyle
import org.openrndr.extra.parameters.ColorParameter
import org.openrndr.extra.parameters.Description
import org.openrndr.extra.parameters.DoubleParameter
import org.openrndr.extra.shaderphrases.preprocess
import org.openrndr.extras.color.phrases.ColorPhraseBook
import org.openrndr.extras.color.spaces.ColorOKLABa
import org.openrndr.math.CastableToVector4
import org.openrndr.math.Vector2
import kotlin.reflect.KClass
@Description("Linear gradient")
open class LinearGradientBase<C>(
color0: C,
color1: C,
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
exponent: Double = 1.0
) : ShadeStyle()
where C : ConvertibleToColorRGBa, C : AlgebraicColor<C>, C: CastableToVector4 {
@ColorParameter("start color", order = 0)
var color0: C by Parameter()
@ColorParameter("end color", order = 1)
var color1: C by Parameter()
var offset: Vector2 by Parameter()
@DoubleParameter("rotation", -180.0, 180.0, order = 2)
var rotation: Double by Parameter()
@DoubleParameter("exponent", 0.01, 10.0, order = 3)
var exponent: Double by Parameter()
init {
ColorPhraseBook.register()
this.color0 = color0
this.color1 = color1
this.offset = offset
this.rotation = rotation
this.exponent = exponent
fragmentPreamble = """
|#pragma import color.oklab_to_linear_rgb
|#pragma import color.linear_rgb_to_srgb""".trimMargin().preprocess()
fragmentTransform = """
vec2 coord = (c_boundsPosition.xy - 0.5 + p_offset);
float cr = cos(radians(p_rotation));
float sr = sin(radians(p_rotation));
mat2 rm = mat2(cr, -sr, sr, cr);
vec2 rc = rm * coord;
float f = clamp(rc.y + 0.5, 0.0, 1.0);
vec4 color0 = p_color0;
vec4 color1 = p_color1;
vec4 gradient = mix(color0, color1, pow(f, p_exponent));
${generateColorTransform(color0::class)}
x_fill *= gradient;
"""
}
}
class LinearGradient(
color0: ColorRGBa,
color1: ColorRGBa,
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
exponent: Double = 1.0
): LinearGradientBase<ColorRGBa>(color0, color1, offset, rotation, exponent)
class LinearGradientOKLab(
color0: ColorOKLABa,
color1: ColorOKLABa,
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
exponent: Double = 1.0
): LinearGradientBase<ColorOKLABa>(color0, color1, offset, rotation, exponent)
fun linearGradient(
color0: ColorRGBa,
color1: ColorRGBa,
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
exponent: Double = 1.0
): LinearGradient {
return LinearGradient(color0, color1, offset, rotation, exponent)
}
fun linearGradient(
color0: ColorOKLABa,
color1: ColorOKLABa,
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
exponent: Double = 1.0
): LinearGradientOKLab {
return LinearGradientOKLab(color0, color1, offset, rotation, exponent)
}

View File

@@ -0,0 +1,31 @@
package org.openrndr.extra.shadestyles
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.ShadeStyle
import org.openrndr.extra.parameters.Description
import org.openrndr.math.Vector2
@Description("N-Point gradient")
class NPointGradient(
colors: Array<ColorRGBa>,
points: Array<Vector2> = arrayOf(Vector2.ZERO)) : ShadeStyle() {
var colors: Array<ColorRGBa> by Parameter()
var points: Array<Vector2> by Parameter()
init {
this.colors = colors
this.points = points
fragmentTransform = """
float sum = 0;
vec4 rgba = vec4(0.0);
for(int i=0; i<p_points_SIZE; i++) {
float dist = 1.0 / (1.0 + distance(p_points[i], c_screenPosition));
sum += dist;
rgba += p_colors[i] * dist;
}
x_fill = rgba/sum;
"""
}
}

View File

@@ -0,0 +1,77 @@
package org.openrndr.extra.shadestyles
import org.openrndr.color.AlgebraicColor
import org.openrndr.color.ColorRGBa
import org.openrndr.color.ConvertibleToColorRGBa
import org.openrndr.draw.ShadeStyle
import org.openrndr.extra.parameters.Description
import org.openrndr.extras.color.spaces.ColorOKLABa
import org.openrndr.math.CastableToVector4
import org.openrndr.math.Vector2
@Description("Multicolor linear gradient")
open class NPointLinearGradientBase<C>(
colors: Array<C>,
points: Array<Double> = Array(colors.size) { it / (colors.size - 1.0) },
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0
) : ShadeStyle()
where C : ConvertibleToColorRGBa, C : AlgebraicColor<C>, C : CastableToVector4 {
var colors: Array<C> by Parameter()
// Sorted normalized values defining relative positions of colors
var points: Array<Double> by Parameter()
var offset: Vector2 by Parameter()
var rotation: Double by Parameter()
init {
this.colors = colors
this.points = points
this.offset = offset
this.rotation = rotation
fragmentTransform = """
vec2 coord = (c_boundsPosition.xy - 0.5 + p_offset);
float cr = cos(radians(p_rotation));
float sr = sin(radians(p_rotation));
mat2 rm = mat2(cr, -sr, sr, cr);
vec2 rc = rm * coord;
float f = clamp(rc.y + 0.5, 0.0, 1.0);
int i=0;
while(i < p_points_SIZE - 1 && f >= p_points[i+1]) { i++; }
vec4 color0 = p_colors[i];
vec4 color1 = p_colors[i+1];
float g = (f - p_points[i]) / (p_points[i+1] - p_points[i]);
vec4 gradient = mix(color0, color1, clamp(g, 0.0, 1.0));
${generateColorTransform(colors[0]::class)}
x_fill *= gradient;
if (x_fill.a != 0) {
x_fill.rgb /= x_fill.a;
}
"""
}
}
class NPointLinearGradient(
colors: Array<ColorRGBa>,
points: Array<Double> = Array(colors.size) { it / (colors.size - 1.0) },
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0
) : NPointLinearGradientBase<ColorRGBa>(colors, points, offset, rotation)
class NPointLinearGradientOKLab(
colors: Array<ColorOKLABa>,
points: Array<Double> = Array(colors.size) { it / (colors.size - 1.0) },
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0
) : NPointLinearGradientBase<ColorOKLABa>(colors, points, offset, rotation)

View File

@@ -0,0 +1,63 @@
package org.openrndr.extra.shadestyles
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.ShadeStyle
import org.openrndr.extra.parameters.Description
import org.openrndr.math.Vector2
@Description("Multicolor radial gradient")
class NPointRadialGradient(
colors: Array<ColorRGBa>,
points: Array<Double> = Array(colors.size) { it / (colors.size - 1.0) },
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
length: Double = 1.0) : ShadeStyle()
{
var colors: Array<ColorRGBa> by Parameter()
// Sorted normalized values defining relative positions of colors
var points: Array<Double> by Parameter()
var offset: Vector2 by Parameter()
var rotation: Double by Parameter()
var length: Double by Parameter()
init {
this.colors = colors
this.points = points
this.offset = offset
this.rotation = rotation
this.length = length
fragmentTransform = """
vec2 coord = (c_boundsPosition.xy - 0.5 + p_offset/2.0) * 2.0;
float cr = cos(radians(p_rotation));
float sr = sin(radians(p_rotation));
mat2 rm = mat2(cr, -sr, sr, cr);
vec2 rc = rm * coord;
float f = clamp(p_length * length(rc), 0.0, 1.0);
int i=0;
while(i < p_points_SIZE - 1 && f >= p_points[i+1]) { i++; }
vec4 color0 = p_colors[i];
color0.rgb *= color0.a;
vec4 color1 = p_colors[i+1];
color1.rgb *= color1.a;
float g = (f - p_points[i]) / (p_points[i+1] - p_points[i]);
vec4 gradient = mix(color0, color1, clamp(g, 0.0, 1.0));
vec4 fn = vec4(x_fill.rgb, 1.0) * x_fill.a;
x_fill = fn * gradient;
if (x_fill.a != 0) {
x_fill.rgb /= x_fill.a;
}
"""
}
}

View File

@@ -0,0 +1,103 @@
package org.openrndr.extra.shadestyles
import org.openrndr.color.*
import org.openrndr.draw.ShadeStyle
import org.openrndr.draw.shadeStyle
import org.openrndr.extra.parameters.ColorParameter
import org.openrndr.extra.parameters.Description
import org.openrndr.extra.parameters.DoubleParameter
import org.openrndr.extras.color.spaces.ColorOKLABa
import org.openrndr.math.CastableToVector4
import org.openrndr.math.Vector2
@Description("Radial gradient")
open class RadialGradientBase<C>(
color0: C,
color1: C,
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
length: Double = 1.0,
exponent: Double = 1.0)
: ShadeStyle()
where C : ConvertibleToColorRGBa, C : AlgebraicColor<C>, C: CastableToVector4 {
@ColorParameter("start color", order = 0)
var color0 : C by Parameter()
@ColorParameter("end color", order = 1)
var color1 : C by Parameter()
var offset : Vector2 by Parameter()
@DoubleParameter("rotation", -180.0, 180.0, order = 2)
var rotation : Double by Parameter()
@DoubleParameter("length", 0.0, 10.0)
var length: Double by Parameter()
@DoubleParameter("exponent", 0.01, 10.0, order = 3)
var exponent: Double by Parameter()
init {
this.color0 = color0
this.color1 = color1
this.offset = offset
this.rotation = rotation
this.length = length
this.exponent = exponent
fragmentTransform = """
vec2 coord = (c_boundsPosition.xy - 0.5 + p_offset/2.0) * 2.0;
float cr = cos(radians(p_rotation));
float sr = sin(radians(p_rotation));
mat2 rm = mat2(cr, -sr, sr, cr);
vec2 rc = rm * coord;
float f = clamp(p_length * length(rc), 0.0, 1.0);
vec4 color0 = p_color0;
vec4 color1 = p_color1;
vec4 gradient = mix(color0, color1, pow(f, p_exponent));
${generateColorTransform(color0::class)}
x_fill *= gradient;
"""
}
}
class RadialGradient(
color0: ColorRGBa,
color1: ColorRGBa,
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
length: Double = 1.0,
exponent: Double = 1.0
): RadialGradientBase<ColorRGBa>(color0, color1, offset, rotation, length, exponent)
class RadialGradientOKLab(
color0: ColorOKLABa,
color1: ColorOKLABa,
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
length: Double = 1.0,
exponent: Double = 1.0
): RadialGradientBase<ColorOKLABa>(color0, color1, offset, rotation, length, exponent)
fun radialGradient(
color0: ColorRGBa,
color1: ColorRGBa,
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
length: Double = 1.0,
exponent: Double = 1.0
): RadialGradient {
return RadialGradient(color0, color1, offset, rotation, length, exponent)
}
fun radialGradient(
color0: ColorOKLABa,
color1: ColorOKLABa,
offset: Vector2 = Vector2.ZERO,
rotation: Double = 0.0,
length: Double = 1.0,
exponent: Double = 1.0
): RadialGradientOKLab {
return RadialGradientOKLab(color0, color1, offset, rotation, length, exponent)
}