add blur and spread radius
This commit is contained in:
parent
75c39a8e3e
commit
2705fbec31
|
@ -287,7 +287,8 @@ namespace
|
||||||
auto sliderStart = new SliderBox( "Angle", 0.0, 360.0, metrics.startAngle() );
|
auto sliderStart = new SliderBox( "Angle", 0.0, 360.0, metrics.startAngle() );
|
||||||
auto sliderSpan = new SliderBox( "Span", -360.0, 360.0, metrics.spanAngle() );
|
auto sliderSpan = new SliderBox( "Span", -360.0, 360.0, metrics.spanAngle() );
|
||||||
auto sliderExtent = new SliderBox( "Extent", 10.0, 100.0, metrics.thickness() );
|
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 sliderOffsetX = new SliderBox( "Offset X", -1.0, +1.0, 0 );
|
||||||
auto sliderOffsetY = new SliderBox( "Offset Y", -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 );
|
auto sliderStrokeWidth = new SliderBox( "Stroke Width", 0, 10, 1 );
|
||||||
|
@ -313,8 +314,11 @@ namespace
|
||||||
connect( sliderOffsetY, &SliderBox::valueChanged,
|
connect( sliderOffsetY, &SliderBox::valueChanged,
|
||||||
this, &ControlPanel::offsetYChanged );
|
this, &ControlPanel::offsetYChanged );
|
||||||
|
|
||||||
connect( shadowExtent, &SliderBox::valueChanged,
|
connect( spreadRadius, &SliderBox::valueChanged,
|
||||||
this, &ControlPanel::shadowExtendChanged );
|
this, &ControlPanel::spreadRadiusChanged );
|
||||||
|
|
||||||
|
connect( blurRadius, &SliderBox::valueChanged,
|
||||||
|
this, &ControlPanel::blurRadiusChanged );
|
||||||
|
|
||||||
connect( sliderStrokeWidth, &SliderBox::valueChanged,
|
connect( sliderStrokeWidth, &SliderBox::valueChanged,
|
||||||
this, &ControlPanel::strokeWidthChanged );
|
this, &ControlPanel::strokeWidthChanged );
|
||||||
|
@ -336,7 +340,8 @@ namespace
|
||||||
|
|
||||||
addItem( sliderStart, 0, 0 );
|
addItem( sliderStart, 0, 0 );
|
||||||
addItem( sliderExtent, 0, 1 );
|
addItem( sliderExtent, 0, 1 );
|
||||||
addItem( shadowExtent, 0, 2 );
|
addItem( spreadRadius, 0, 2 );
|
||||||
|
addItem( blurRadius, 0, 3 );
|
||||||
addItem( sliderSpan, 1, 0, 1, 1 );
|
addItem( sliderSpan, 1, 0, 1, 1 );
|
||||||
addItem( sliderStrokeWidth, 1, 1, 1, 1 );
|
addItem( sliderStrokeWidth, 1, 1, 1, 1 );
|
||||||
addItem( sliderOffsetX, 2, 0, 1, 1 );
|
addItem( sliderOffsetX, 2, 0, 1, 1 );
|
||||||
|
@ -355,7 +360,8 @@ namespace
|
||||||
void fillColorChanged( QColor );
|
void fillColorChanged( QColor );
|
||||||
void strokeColorChanged( QColor );
|
void strokeColorChanged( QColor );
|
||||||
void shadowColorChanged( QColor );
|
void shadowColorChanged( QColor );
|
||||||
void shadowExtendChanged( qreal );
|
void spreadRadiusChanged( qreal );
|
||||||
|
void blurRadiusChanged( qreal );
|
||||||
void strokeWidthChanged( qreal );
|
void strokeWidthChanged( qreal );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -461,12 +467,18 @@ ChartView::ChartView( ArcControl* chart, QQuickItem* parent )
|
||||||
chart->setShadowMetricsHint( subcontrol, h );
|
chart->setShadowMetricsHint( subcontrol, h );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
connect( controlPanel, &ControlPanel::shadowExtendChanged, chart, [ = ]( qreal v ) {
|
connect( controlPanel, &ControlPanel::spreadRadiusChanged, chart, [ = ]( qreal v ) {
|
||||||
auto h = chart->shadowMetricsHint( subcontrol );
|
auto h = chart->shadowMetricsHint( subcontrol );
|
||||||
h.setSpreadRadius( v );
|
h.setSpreadRadius( v );
|
||||||
chart->setShadowMetricsHint( subcontrol, h );
|
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,
|
connect( controlPanel, &ControlPanel::fillColorChanged, chart,
|
||||||
[ = ]( QColor c ) { chart->setColor( subcontrol, c ); } );
|
[ = ]( QColor c ) { chart->setColor( subcontrol, c ); } );
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,8 @@ int main( int argc, char* argv[] )
|
||||||
metrics.setThickness(10);
|
metrics.setThickness(10);
|
||||||
|
|
||||||
QskShadowMetrics shadowMetrics;
|
QskShadowMetrics shadowMetrics;
|
||||||
shadowMetrics.setSpreadRadius(0.1);
|
shadowMetrics.setSpreadRadius(0.01);
|
||||||
|
shadowMetrics.setBlurRadius(0.01);
|
||||||
shadowMetrics.setSizeMode(Qt::SizeMode::RelativeSize);
|
shadowMetrics.setSizeMode(Qt::SizeMode::RelativeSize);
|
||||||
|
|
||||||
control->setGradientHint(Q::Arc, {Qt::red});
|
control->setGradientHint(Q::Arc, {Qt::red});
|
||||||
|
|
|
@ -37,14 +37,15 @@ namespace
|
||||||
float thickness = 0.0f;
|
float thickness = 0.0f;
|
||||||
float startAngle = 0.0f;
|
float startAngle = 0.0f;
|
||||||
float spanAngle = M_PI;
|
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
|
Q_REQUIRED_RESULT inline bool operator==(const MaterialProperties& rhs) const noexcept
|
||||||
{
|
{
|
||||||
return color == rhs.color && offset == rhs.offset &&
|
return color == rhs.color && offset == rhs.offset &&
|
||||||
radius == rhs.radius && thickness == rhs.thickness &&
|
radius == rhs.radius && thickness == rhs.thickness &&
|
||||||
startAngle == rhs.startAngle && spanAngle == rhs.spanAngle &&
|
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
|
Q_REQUIRED_RESULT inline bool operator!=(const MaterialProperties& rhs) const noexcept
|
||||||
|
@ -81,7 +82,7 @@ namespace
|
||||||
MaterialProperties properties;
|
MaterialProperties properties;
|
||||||
float opacity = 1.0f;
|
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:
|
public:
|
||||||
|
@ -138,7 +139,8 @@ namespace
|
||||||
int thickness = -1;
|
int thickness = -1;
|
||||||
int startAngle = -1;
|
int startAngle = -1;
|
||||||
int spanAngle = -1;
|
int spanAngle = -1;
|
||||||
int extend = -1;
|
int spreadRadius = -1;
|
||||||
|
int blurRadius = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -168,7 +170,8 @@ namespace
|
||||||
id.thickness = p->uniformLocation( "thickness" );
|
id.thickness = p->uniformLocation( "thickness" );
|
||||||
id.startAngle = p->uniformLocation( "startAngle" );
|
id.startAngle = p->uniformLocation( "startAngle" );
|
||||||
id.spanAngle = p->uniformLocation( "spanAngle" );
|
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,
|
void updateState( const QSGMaterialShader::RenderState& state,
|
||||||
|
@ -201,7 +204,8 @@ namespace
|
||||||
p->setUniformValue( id.thickness, properties.thickness);
|
p->setUniformValue( id.thickness, properties.thickness);
|
||||||
p->setUniformValue( id.startAngle, properties.startAngle);
|
p->setUniformValue( id.startAngle, properties.startAngle);
|
||||||
p->setUniformValue( id.spanAngle, properties.spanAngle);
|
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);
|
(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 startAngle = (float) qDegreesToRadians(arcMetrics.startAngle() + 90.0); // why +90 ?
|
||||||
const auto spanAngle = (float) qDegreesToRadians(arcMetrics.spanAngle());
|
const auto spanAngle = (float) qDegreesToRadians(arcMetrics.spanAngle());
|
||||||
const auto radius = ( float ) ( 1.0 - thickness - 2 * w / size );
|
const auto radius = ( float ) ( 1.0 - thickness - 2 * w / size );
|
||||||
|
@ -381,7 +396,8 @@ void QskArcShadowNode::update( const QRectF& rect, const QskArcMetrics& arcMetri
|
||||||
thickness,
|
thickness,
|
||||||
startAngle,
|
startAngle,
|
||||||
spanAngle,
|
spanAngle,
|
||||||
spreadRadius
|
spreadRadius,
|
||||||
|
blurRadius
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto dirtyGeometry = ( d->rect != shadowRect );
|
const auto dirtyGeometry = ( d->rect != shadowRect );
|
||||||
|
|
|
@ -6,14 +6,15 @@ layout( location = 0 ) out vec4 fragColor;
|
||||||
layout( std140, binding = 0 ) uniform buf
|
layout( std140, binding = 0 ) uniform buf
|
||||||
{
|
{
|
||||||
mat4 matrix;
|
mat4 matrix;
|
||||||
vec4 color; // shadow's color
|
vec4 color; // shadow's color
|
||||||
vec2 offset; // shadow's offset (x,y) : [-1.0, +1.0]x[-1.0,+1.0]
|
vec2 offset; // shadow's offset (x,y) : [-1.0, +1.0]x[-1.0,+1.0]
|
||||||
float radius; // arc's radius [0.0, 1.0]
|
float radius; // arc's radius [0.0, 1.0]
|
||||||
float thickness; // arc's thickness [0.0, 1.0]
|
float thickness; // arc's thickness [0.0, 1.0]
|
||||||
float startAngle; // arc's start angle [rad]
|
float startAngle; // arc's start angle [rad]
|
||||||
float spanAngle; // arc's span 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 opacity; // overall opacity [0.0, 1.0]
|
float blurRadius; // extended shadow blurring length [0.0, 1.0]
|
||||||
|
float opacity; // overall opacity [0.0, 1.0]
|
||||||
} ubuf;
|
} ubuf;
|
||||||
|
|
||||||
float sdRing( in vec2 p, in vec2 n, in float r, in float th )
|
float sdRing( in vec2 p, in vec2 n, in float r, in float th )
|
||||||
|
@ -45,8 +46,8 @@ void main()
|
||||||
|
|
||||||
float t = abs(ubuf.spanAngle) / 2.0; // half span angle
|
float t = abs(ubuf.spanAngle) / 2.0; // half span angle
|
||||||
vec2 cs = vec2(cos(t),sin(t));
|
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;
|
fragColor = ubuf.color * a * ubuf.opacity;
|
||||||
}
|
}
|
|
@ -1,15 +1,15 @@
|
||||||
uniform lowp mat4 matrix;
|
varying lowp vec2 coord; // [-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 opacity; // overall opacity [0.0, 1.0]
|
|
||||||
|
|
||||||
// position
|
uniform lowp mat4 matrix;
|
||||||
varying lowp vec2 coord; // [-1.0,+1.0]x[-1.0,+1.0]
|
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 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]
|
||||||
|
|
||||||
float sdRing( in vec2 p, in vec2 n, in float r, in float th )
|
float sdRing( in vec2 p, in vec2 n, in float r, in float th )
|
||||||
{
|
{
|
||||||
|
@ -40,8 +40,8 @@ void main()
|
||||||
|
|
||||||
float t = abs(spanAngle) / 2.0; // half span angle
|
float t = abs(spanAngle) / 2.0; // half span angle
|
||||||
vec2 cs = vec2(cos(t),sin(t));
|
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;
|
gl_FragColor = color * a * opacity;
|
||||||
}
|
}
|
Loading…
Reference in New Issue