add blur and spread radius

This commit is contained in:
Vogel, Rick 2023-12-18 13:04:30 +01:00
parent 75c39a8e3e
commit 2705fbec31
5 changed files with 67 additions and 37 deletions

View File

@ -287,7 +287,8 @@ namespace
auto sliderStart = new SliderBox( "Angle", 0.0, 360.0, metrics.startAngle() );
auto sliderSpan = new SliderBox( "Span", -360.0, 360.0, metrics.spanAngle() );
auto sliderExtent = new SliderBox( "Extent", 10.0, 100.0, metrics.thickness() );
auto shadowExtent = new SliderBox( "Shadow Extent", 0.0, 1.0, 0.5 );
auto spreadRadius = new SliderBox( "Spread Radius", 0.0, 1.0, 0.01 );
auto blurRadius = new SliderBox( "Blur Radius", 0.0, 1.0, 0.01 );
auto sliderOffsetX = new SliderBox( "Offset X", -1.0, +1.0, 0 );
auto sliderOffsetY = new SliderBox( "Offset Y", -1.0, +1.0, 0 );
auto sliderStrokeWidth = new SliderBox( "Stroke Width", 0, 10, 1 );
@ -313,8 +314,11 @@ namespace
connect( sliderOffsetY, &SliderBox::valueChanged,
this, &ControlPanel::offsetYChanged );
connect( shadowExtent, &SliderBox::valueChanged,
this, &ControlPanel::shadowExtendChanged );
connect( spreadRadius, &SliderBox::valueChanged,
this, &ControlPanel::spreadRadiusChanged );
connect( blurRadius, &SliderBox::valueChanged,
this, &ControlPanel::blurRadiusChanged );
connect( sliderStrokeWidth, &SliderBox::valueChanged,
this, &ControlPanel::strokeWidthChanged );
@ -336,7 +340,8 @@ namespace
addItem( sliderStart, 0, 0 );
addItem( sliderExtent, 0, 1 );
addItem( shadowExtent, 0, 2 );
addItem( spreadRadius, 0, 2 );
addItem( blurRadius, 0, 3 );
addItem( sliderSpan, 1, 0, 1, 1 );
addItem( sliderStrokeWidth, 1, 1, 1, 1 );
addItem( sliderOffsetX, 2, 0, 1, 1 );
@ -355,7 +360,8 @@ namespace
void fillColorChanged( QColor );
void strokeColorChanged( QColor );
void shadowColorChanged( QColor );
void shadowExtendChanged( qreal );
void spreadRadiusChanged( qreal );
void blurRadiusChanged( qreal );
void strokeWidthChanged( qreal );
};
@ -461,12 +467,18 @@ ChartView::ChartView( ArcControl* chart, QQuickItem* parent )
chart->setShadowMetricsHint( subcontrol, h );
} );
connect( controlPanel, &ControlPanel::shadowExtendChanged, chart, [ = ]( qreal v ) {
connect( controlPanel, &ControlPanel::spreadRadiusChanged, chart, [ = ]( qreal v ) {
auto h = chart->shadowMetricsHint( subcontrol );
h.setSpreadRadius( v );
chart->setShadowMetricsHint( subcontrol, h );
} );
connect( controlPanel, &ControlPanel::blurRadiusChanged, chart, [ = ]( qreal v ) {
auto h = chart->shadowMetricsHint( subcontrol );
h.setBlurRadius( v );
chart->setShadowMetricsHint( subcontrol, h );
} );
connect( controlPanel, &ControlPanel::fillColorChanged, chart,
[ = ]( QColor c ) { chart->setColor( subcontrol, c ); } );

View File

@ -129,7 +129,8 @@ int main( int argc, char* argv[] )
metrics.setThickness(10);
QskShadowMetrics shadowMetrics;
shadowMetrics.setSpreadRadius(0.1);
shadowMetrics.setSpreadRadius(0.01);
shadowMetrics.setBlurRadius(0.01);
shadowMetrics.setSizeMode(Qt::SizeMode::RelativeSize);
control->setGradientHint(Q::Arc, {Qt::red});

View File

@ -37,14 +37,15 @@ namespace
float thickness = 0.0f;
float startAngle = 0.0f;
float spanAngle = M_PI;
float extend = 0.0f;
float spreadRadius = 0.0f;
float blurRadius = 0.0f;
Q_REQUIRED_RESULT inline bool operator==(const MaterialProperties& rhs) const noexcept
{
return color == rhs.color && offset == rhs.offset &&
radius == rhs.radius && thickness == rhs.thickness &&
startAngle == rhs.startAngle && spanAngle == rhs.spanAngle &&
extend == rhs.extend;
spreadRadius == rhs.spreadRadius && blurRadius == rhs.blurRadius;
}
Q_REQUIRED_RESULT inline bool operator!=(const MaterialProperties& rhs) const noexcept
@ -81,7 +82,7 @@ namespace
MaterialProperties properties;
float opacity = 1.0f;
static_assert(sizeof(properties) == sizeof(float) * 11, "Layout mustn't have trailing paddings");
static_assert(sizeof(properties) == sizeof(float) * 12, "Assuming packed layout!");
};
public:
@ -138,7 +139,8 @@ namespace
int thickness = -1;
int startAngle = -1;
int spanAngle = -1;
int extend = -1;
int spreadRadius = -1;
int blurRadius = -1;
};
public:
@ -168,7 +170,8 @@ namespace
id.thickness = p->uniformLocation( "thickness" );
id.startAngle = p->uniformLocation( "startAngle" );
id.spanAngle = p->uniformLocation( "spanAngle" );
id.extend = p->uniformLocation( "extend" );
id.spreadRadius = p->uniformLocation( "spreadRadius" );
id.blurRadius = p->uniformLocation( "blurRadius" );
}
void updateState( const QSGMaterialShader::RenderState& state,
@ -201,7 +204,8 @@ namespace
p->setUniformValue( id.thickness, properties.thickness);
p->setUniformValue( id.startAngle, properties.startAngle);
p->setUniformValue( id.spanAngle, properties.spanAngle);
p->setUniformValue( id.extend, properties.extend);
p->setUniformValue( id.spreadRadius, properties.spreadRadius);
p->setUniformValue( id.blurRadius, properties.blurRadius);
}
}
@ -370,6 +374,17 @@ void QskArcShadowNode::update( const QRectF& rect, const QskArcMetrics& arcMetri
}
(shadowMetrics, shadowRect);
const auto blurRadius = [](const QskShadowMetrics& metrics, const QRectF& rect){
auto blurRadius = metrics.blurRadius();
const auto size = qMin( rect.width(), rect.height() );
if ( metrics.sizeMode() == Qt::AbsoluteSize )
{
blurRadius = blurRadius / size;
}
blurRadius = qBound( 0.0, blurRadius, 1.0 );
return (float) blurRadius;
}(shadowMetrics, shadowRect);
const auto startAngle = (float) qDegreesToRadians(arcMetrics.startAngle() + 90.0); // why +90 ?
const auto spanAngle = (float) qDegreesToRadians(arcMetrics.spanAngle());
const auto radius = ( float ) ( 1.0 - thickness - 2 * w / size );
@ -381,7 +396,8 @@ void QskArcShadowNode::update( const QRectF& rect, const QskArcMetrics& arcMetri
thickness,
startAngle,
spanAngle,
spreadRadius
spreadRadius,
blurRadius
};
const auto dirtyGeometry = ( d->rect != shadowRect );

View File

@ -12,7 +12,8 @@ layout( std140, binding = 0 ) uniform buf
float thickness; // arc's thickness [0.0, 1.0]
float startAngle; // arc's start angle [rad]
float spanAngle; // arc's span angle [rad]
float extend; // shadow length [0.0, 1.0]
float spreadRadius; // extended shadow length [0.0, 1.0]
float blurRadius; // extended shadow blurring length [0.0, 1.0]
float opacity; // overall opacity [0.0, 1.0]
} ubuf;
@ -45,8 +46,8 @@ void main()
float t = abs(ubuf.spanAngle) / 2.0; // half span angle
vec2 cs = vec2(cos(t),sin(t));
float d = sdRing(p, cs, ubuf.radius / 2.0, ubuf.thickness);
float d = sdRing(p, cs, ubuf.radius / 2.0, ubuf.thickness + spreadRadius);
float a = 1.0 - smoothstep(0.0, ubuf.extend, d);
float a = 1.0 - smoothstep(0.0, ubuf.blurRadius, d);
fragColor = ubuf.color * a * ubuf.opacity;
}

View File

@ -1,16 +1,16 @@
varying lowp vec2 coord; // [-1.0,+1.0]x[-1.0,+1.0]
uniform lowp mat4 matrix;
uniform lowp vec4 color; // shadow's color
uniform lowp vec2 offset; // shadow's offset (x,y) : [-1.0, +1.0]x[-1.0,+1.0]
uniform lowp float radius; // arc's radius [0.0, 1.0]
uniform lowp float thickness; // arc's thickness [0.0, 1.0]
uniform lowp float startAngle; // arc's start angle [rad]
uniform lowp float spanAngle; // arc's span angle [rad]
uniform lowp vec4 color; // shadow's color
uniform lowp vec2 offset; // shadow's offset (x,y) : [-1.0, +1.0]x[-1.0,+1.0]
uniform lowp float extend; // shadow length [0.0, 1.0]
uniform lowp float spreadRadius; // extended shadow length [0.0, 1.0]
uniform lowp float blurRadius; // extended shadow blurring length [0.0, 1.0]
uniform lowp float opacity; // overall opacity [0.0, 1.0]
// position
varying lowp vec2 coord; // [-1.0,+1.0]x[-1.0,+1.0]
float sdRing( in vec2 p, in vec2 n, in float r, in float th )
{
p.x = abs(p.x);
@ -40,8 +40,8 @@ void main()
float t = abs(spanAngle) / 2.0; // half span angle
vec2 cs = vec2(cos(t),sin(t));
float d = sdRing(p, cs, radius / 2.0, thickness);
float d = sdRing(p, cs, radius / 2.0, thickness + spreadRadius);
float a = 1.0 - smoothstep(0.0, extend, d);
float a = 1.0 - smoothstep(0.0, blurRadius, d);
gl_FragColor = color * a * opacity;
}