[orx-shade-styles] Add luma gradient
This commit is contained in:
@@ -34,6 +34,7 @@ open class GradientBase<C>(
|
|||||||
var spreadMethod: Int by Parameter()
|
var spreadMethod: Int by Parameter()
|
||||||
var fillUnits: Int by Parameter()
|
var fillUnits: Int by Parameter()
|
||||||
var fillFit: Int by Parameter()
|
var fillFit: Int by Parameter()
|
||||||
|
var resetFill: Boolean by Parameter()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.quantization = 0
|
this.quantization = 0
|
||||||
@@ -42,7 +43,9 @@ open class GradientBase<C>(
|
|||||||
this.fillUnits = FillUnits.BOUNDS.ordinal
|
this.fillUnits = FillUnits.BOUNDS.ordinal
|
||||||
this.spreadMethod = SpreadMethod.PAD.ordinal
|
this.spreadMethod = SpreadMethod.PAD.ordinal
|
||||||
this.fillFit = FillFit.STRETCH.ordinal
|
this.fillFit = FillFit.STRETCH.ordinal
|
||||||
|
this.resetFill = false
|
||||||
fragmentPreamble = """
|
fragmentPreamble = """
|
||||||
|
|vec4 g_fill;
|
||||||
|vec2 rotate2D(vec2 x, float angle){
|
|vec2 rotate2D(vec2 x, float angle){
|
||||||
| float rad = angle / 180.0 * $PI;
|
| float rad = angle / 180.0 * $PI;
|
||||||
| mat2 m = mat2(cos(rad),-sin(rad), sin(rad),cos(rad));
|
| mat2 m = mat2(cos(rad),-sin(rad), sin(rad),cos(rad));
|
||||||
@@ -56,6 +59,7 @@ open class GradientBase<C>(
|
|||||||
|""".trimMargin()
|
|""".trimMargin()
|
||||||
|
|
||||||
fragmentTransform = """
|
fragmentTransform = """
|
||||||
|
g_fill = x_fill;
|
||||||
vec2 coord = vec2(0.0);
|
vec2 coord = vec2(0.0);
|
||||||
|
|
||||||
if (p_fillUnits == 0) { // BOUNDS
|
if (p_fillUnits == 0) { // BOUNDS
|
||||||
@@ -140,6 +144,9 @@ open class GradientBase<C>(
|
|||||||
if (gradient.a > 0.0) {
|
if (gradient.a > 0.0) {
|
||||||
gradient.rgb /= gradient.a;
|
gradient.rgb /= gradient.a;
|
||||||
}
|
}
|
||||||
|
if (p_resetFill) {
|
||||||
|
x_fill.rgb = vec3(1.0);
|
||||||
|
}
|
||||||
x_fill *= gradient;
|
x_fill *= gradient;
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,18 @@ class GradientBuilder<C>(val colorType: KClass<C>): StyleParameters
|
|||||||
var gradientFunction = """float gradientFunction(vec2 coord) { return 0.0; }"""
|
var gradientFunction = """float gradientFunction(vec2 coord) { return 0.0; }"""
|
||||||
var quantization = 0
|
var quantization = 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether to reset the fill state when building a gradient.
|
||||||
|
*
|
||||||
|
* If set to `true`, it ensures that the fill color is overridden with
|
||||||
|
* the defined gradient fill during the rendering process. When set to `false`,
|
||||||
|
* the previous fill state persists, allowing the gradient to blend with
|
||||||
|
* other graphical elements.
|
||||||
|
*
|
||||||
|
* The default value is `false`
|
||||||
|
*/
|
||||||
|
var resetFill = false
|
||||||
|
|
||||||
private fun setBaseParameters(style: GradientBase<C>) {
|
private fun setBaseParameters(style: GradientBase<C>) {
|
||||||
style.parameterTypes.putAll(parameterTypes)
|
style.parameterTypes.putAll(parameterTypes)
|
||||||
style.parameterValues.putAll(parameterValues)
|
style.parameterValues.putAll(parameterValues)
|
||||||
@@ -38,6 +50,7 @@ class GradientBuilder<C>(val colorType: KClass<C>): StyleParameters
|
|||||||
style.spreadMethod = spreadMethod.ordinal
|
style.spreadMethod = spreadMethod.ordinal
|
||||||
style.fillUnits = fillUnits.ordinal
|
style.fillUnits = fillUnits.ordinal
|
||||||
style.fillFit = fillFit.ordinal
|
style.fillFit = fillFit.ordinal
|
||||||
|
style.resetFill = resetFill
|
||||||
}
|
}
|
||||||
|
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
@@ -67,11 +80,29 @@ class GradientBuilder<C>(val colorType: KClass<C>): StyleParameters
|
|||||||
gradientFunction = RadialGradient.gradientFunction
|
gradientFunction = RadialGradient.gradientFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures an elliptical gradient by applying the provided builder block.
|
||||||
|
*
|
||||||
|
* @param builder A lambda function used to define the properties of the elliptical gradient.
|
||||||
|
*/
|
||||||
fun elliptic(builder: EllipticalGradientBuilder<C>.() -> Unit) {
|
fun elliptic(builder: EllipticalGradientBuilder<C>.() -> Unit) {
|
||||||
shadeStyleBuilder = EllipticalGradientBuilder(this).apply { builder() }
|
shadeStyleBuilder = EllipticalGradientBuilder(this).apply { builder() }
|
||||||
gradientFunction = EllipticalGradient.gradientFunction
|
gradientFunction = EllipticalGradient.gradientFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures a luma gradient by applying the provided builder block.
|
||||||
|
*
|
||||||
|
* @param builder A lambda function used to define the properties of the luma gradient.
|
||||||
|
* The builder block allows customization of attributes such as luminance-based
|
||||||
|
* transformations, including specifying minimum and maximum luminance levels.
|
||||||
|
*/
|
||||||
|
fun luma(builder: LumaGradientBuilder<C>.() -> Unit) {
|
||||||
|
shadeStyleBuilder = LumaGradientBuilder(this).apply { builder() }
|
||||||
|
gradientFunction = LumaGradient.gradientFunction
|
||||||
|
resetFill = true
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures a conic gradient by applying the provided builder block.
|
* Configures a conic gradient by applying the provided builder block.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
package org.openrndr.extra.shadestyles.fills.gradients
|
||||||
|
|
||||||
|
import org.openrndr.color.AlgebraicColor
|
||||||
|
import org.openrndr.color.ConvertibleToColorRGBa
|
||||||
|
import org.openrndr.math.CastableToVector4
|
||||||
|
import org.openrndr.math.Vector4
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
open class LumaGradient<C>(
|
||||||
|
colorType: KClass<C>,
|
||||||
|
minLevel: Double,
|
||||||
|
maxLevel: Double,
|
||||||
|
colors: Array<Vector4>,
|
||||||
|
points: Array<Double> = Array(colors.size) { it / (colors.size - 1.0) },
|
||||||
|
structure: GradientBaseStructure
|
||||||
|
|
||||||
|
) : GradientBase<C>(
|
||||||
|
colorType,
|
||||||
|
colors,
|
||||||
|
points,
|
||||||
|
structure
|
||||||
|
)
|
||||||
|
where C : ConvertibleToColorRGBa, C : AlgebraicColor<C>, C : CastableToVector4 {
|
||||||
|
|
||||||
|
var minLevel: Double by Parameter()
|
||||||
|
var maxLevel: Double by Parameter()
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.minLevel = minLevel
|
||||||
|
this.maxLevel = maxLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val gradientFunction = """
|
||||||
|
float gradientFunction(vec2 coord) {
|
||||||
|
float f = 0.2126 * g_fill.r + 0.7152 * g_fill.g + 0.0722 * g_fill.b;
|
||||||
|
f = (f - p_minLevel) / (p_maxLevel - p_minLevel);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LumaGradientBuilder<C>(private val gradientBuilder: GradientBuilder<C>) : GradientShadeStyleBuilder<C>
|
||||||
|
where C : ConvertibleToColorRGBa, C : AlgebraicColor<C>, C : CastableToVector4 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the minimum luminance level for manipulating the gradient's color representation.
|
||||||
|
* This value determines the lower bound of the luminance range applied to the gradient transformation.
|
||||||
|
* It is used in combination with `maxLevel` to define the range of luminance levels that
|
||||||
|
* affect the final gradient appearance.
|
||||||
|
*
|
||||||
|
* The default value is `0.0`, which represents the minimum possible luminance level.
|
||||||
|
*/
|
||||||
|
var minLevel = 0.0
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the maximum luminance level for manipulating the gradient's color representation.
|
||||||
|
* This value determines the upper bound of the luminance range applied to the gradient transformation.
|
||||||
|
* It is used in combination with `minLevel` to define the range of luminance levels that affect
|
||||||
|
* the final gradient appearance.
|
||||||
|
*
|
||||||
|
* The default value is `1.0`, which represents the maximum possible luminance level.
|
||||||
|
*/
|
||||||
|
var maxLevel = 1.0
|
||||||
|
|
||||||
|
override fun build(): GradientBase<C> {
|
||||||
|
val (stops, colors) = gradientBuilder.extractStepsUnzip()
|
||||||
|
return LumaGradient(
|
||||||
|
gradientBuilder.colorType,
|
||||||
|
minLevel,
|
||||||
|
maxLevel,
|
||||||
|
colors,
|
||||||
|
stops,
|
||||||
|
gradientBuilder.structure()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package gradients
|
||||||
|
|
||||||
|
import org.openrndr.application
|
||||||
|
import org.openrndr.color.ColorRGBa
|
||||||
|
import org.openrndr.draw.loadImage
|
||||||
|
import org.openrndr.extra.color.presets.CRIMSON
|
||||||
|
import org.openrndr.extra.color.presets.DODGER_BLUE
|
||||||
|
import org.openrndr.extra.color.presets.LIME_GREEN
|
||||||
|
import org.openrndr.extra.imageFit.imageFit
|
||||||
|
import org.openrndr.extra.shadestyles.fills.SpreadMethod
|
||||||
|
import org.openrndr.extra.shadestyles.fills.gradients.gradient
|
||||||
|
|
||||||
|
fun main() = application {
|
||||||
|
configure {
|
||||||
|
width = 720
|
||||||
|
height = 720
|
||||||
|
}
|
||||||
|
program {
|
||||||
|
val image = loadImage("demo-data/images/image-001.png")
|
||||||
|
extend {
|
||||||
|
drawer.shadeStyle = gradient<ColorRGBa> {
|
||||||
|
stops[0.0] = ColorRGBa.CRIMSON
|
||||||
|
stops[0.7] = ColorRGBa.DODGER_BLUE
|
||||||
|
stops[1.0] = ColorRGBa.LIME_GREEN
|
||||||
|
|
||||||
|
spreadMethod = SpreadMethod.REFLECT
|
||||||
|
luma {
|
||||||
|
minLevel = 0.1
|
||||||
|
maxLevel = 0.9
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drawer.imageFit(image, drawer.bounds.offsetEdges(-10.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user