Fix transparent ambient shadows
Add a clamp value to indicate the percentage of the blurWidth to apply. Change-Id: I962dc57ed786fa67ed1606b1148f1b2c568025e5 Reviewed-on: https://skia-review.googlesource.com/16424 Commit-Queue: Jim Van Verth <jvanverth@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
1c4c1144c9
commit
a8b5cf3550
@ -221,8 +221,12 @@ bool SkAmbientShadowMaskFilterImpl::directFilterRRectMaskGPU(GrContext*,
|
||||
devSpaceInsetWidth = ambientRRect.width();
|
||||
}
|
||||
|
||||
// the fraction of the blur we want to apply is devSpaceInsetWidth/devSpaceAmbientBlur,
|
||||
// which is just 1/umbraAlpha.
|
||||
SkScalar blurClamp = SkScalarInvert(umbraAlpha);
|
||||
rtContext->drawShadowRRect(clip, std::move(newPaint), viewMatrix, ambientRRect,
|
||||
devSpaceAmbientBlur, devSpaceInsetWidth);
|
||||
devSpaceAmbientBlur, devSpaceInsetWidth,
|
||||
blurClamp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -986,7 +986,8 @@ void GrRenderTargetContext::drawShadowRRect(const GrClip& clip,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkRRect& rrect,
|
||||
SkScalar blurWidth,
|
||||
SkScalar insetWidth) {
|
||||
SkScalar insetWidth,
|
||||
SkScalar blurClamp) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
RETURN_IF_ABANDONED
|
||||
SkDEBUGCODE(this->validate();)
|
||||
@ -999,7 +1000,8 @@ void GrRenderTargetContext::drawShadowRRect(const GrClip& clip,
|
||||
// TODO: add instancing support?
|
||||
|
||||
std::unique_ptr<GrLegacyMeshDrawOp> op = GrShadowRRectOp::Make(paint.getColor(), viewMatrix,
|
||||
rrect, blurWidth, insetWidth);
|
||||
rrect, blurWidth, insetWidth,
|
||||
blurClamp);
|
||||
if (op) {
|
||||
GrPipelineBuilder pipelineBuilder(std::move(paint), GrAAType::kNone);
|
||||
this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op));
|
||||
|
@ -161,13 +161,15 @@ public:
|
||||
* @param blurWidth amount of shadow blur to apply (in device space)
|
||||
* @param insetWidth minimum amount to inset from the rrect edge (in local space).
|
||||
* We may inset more depending on the blur radius and geometry.
|
||||
* @param blurClamp Optional parameter used to indicate fraction of blur to actually apply
|
||||
*/
|
||||
void drawShadowRRect(const GrClip&,
|
||||
GrPaint&&,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkRRect& rrect,
|
||||
SkScalar blurRadius,
|
||||
SkScalar insetWidth);
|
||||
SkScalar insetWidth,
|
||||
SkScalar blurClamp = 1);
|
||||
|
||||
/**
|
||||
* Shortcut for filling a SkPath consisting of nested rrects using a paint. The result is
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
|
||||
// emit attributes
|
||||
varyingHandler->emitAttributes(rsgp);
|
||||
fragBuilder->codeAppend("vec3 shadowParams;");
|
||||
fragBuilder->codeAppend("vec4 shadowParams;");
|
||||
varyingHandler->addPassThroughAttribute(rsgp.inShadowParams(), "shadowParams");
|
||||
|
||||
// setup pass through color
|
||||
@ -47,7 +47,7 @@ public:
|
||||
fragBuilder->codeAppend("float d = length(shadowParams.xy);");
|
||||
fragBuilder->codeAppend("float distance = shadowParams.z * (1.0 - d);");
|
||||
|
||||
fragBuilder->codeAppend("float factor = 1.0 - clamp(distance, 0.0, 1.0);");
|
||||
fragBuilder->codeAppend("float factor = 1.0 - clamp(distance, 0.0, shadowParams.w);");
|
||||
fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;");
|
||||
fragBuilder->codeAppendf("%s = vec4(factor);",
|
||||
args.fOutputCoverage);
|
||||
@ -81,7 +81,7 @@ GrRRectShadowGeoProc::GrRRectShadowGeoProc(const SkMatrix& localMatrix)
|
||||
fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
|
||||
kHigh_GrSLPrecision);
|
||||
fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
|
||||
fInShadowParams = &this->addVertexAttrib("inShadowParams", kVec3f_GrVertexAttribType);
|
||||
fInShadowParams = &this->addVertexAttrib("inShadowParams", kVec4f_GrVertexAttribType);
|
||||
}
|
||||
|
||||
void GrRRectShadowGeoProc::getGLSLProcessorKey(const GrShaderCaps& caps,
|
||||
|
@ -190,7 +190,8 @@ public:
|
||||
|
||||
// An insetWidth > 1/2 rect width or height indicates a simple fill.
|
||||
ShadowCircularRRectOp(GrColor color, const SkMatrix& viewMatrix, const SkRect& devRect,
|
||||
float devRadius, bool isCircle, float blurRadius, float insetWidth)
|
||||
float devRadius, bool isCircle, float blurRadius, float insetWidth,
|
||||
float blurClamp)
|
||||
: INHERITED(ClassID()), fViewMatrixIfUsingLocalCoords(viewMatrix) {
|
||||
SkRect bounds = devRect;
|
||||
SkASSERT(insetWidth > 0);
|
||||
@ -226,7 +227,7 @@ public:
|
||||
this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo);
|
||||
|
||||
fGeoData.emplace_back(Geometry{color, outerRadius, umbraInset, innerRadius,
|
||||
blurRadius, bounds, type, isCircle});
|
||||
blurRadius, blurClamp, bounds, type, isCircle});
|
||||
if (isCircle) {
|
||||
fVertCount = circle_type_to_vert_count(kStroke_RRectType == type);
|
||||
fIndexCount = circle_type_to_index_count(kStroke_RRectType == type);
|
||||
@ -274,6 +275,7 @@ private:
|
||||
SkScalar fUmbraInset;
|
||||
SkScalar fInnerRadius;
|
||||
SkScalar fBlurRadius;
|
||||
SkScalar fClampValue;
|
||||
SkRect fDevBounds;
|
||||
RRectType fType;
|
||||
bool fIsCircle;
|
||||
@ -284,6 +286,7 @@ private:
|
||||
GrColor fColor;
|
||||
SkPoint fOffset;
|
||||
SkScalar fDistanceCorrection;
|
||||
SkScalar fClampValue;
|
||||
};
|
||||
|
||||
void fillInCircleVerts(const Geometry& args, bool isStroked, CircleVertex** verts) const {
|
||||
@ -293,6 +296,7 @@ private:
|
||||
SkScalar innerRadius = args.fInnerRadius;
|
||||
SkScalar blurRadius = args.fBlurRadius;
|
||||
SkScalar distanceCorrection = outerRadius / blurRadius;
|
||||
SkScalar clampValue = args.fClampValue;
|
||||
|
||||
const SkRect& bounds = args.fDevBounds;
|
||||
|
||||
@ -307,48 +311,56 @@ private:
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(-octOffset, -1);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = center + SkPoint::Make(octOffset * halfWidth, -halfWidth);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(octOffset, -1);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = center + SkPoint::Make(halfWidth, -octOffset * halfWidth);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(1, -octOffset);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = center + SkPoint::Make(halfWidth, octOffset * halfWidth);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(1, octOffset);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = center + SkPoint::Make(octOffset * halfWidth, halfWidth);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(octOffset, 1);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = center + SkPoint::Make(-octOffset * halfWidth, halfWidth);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(-octOffset, 1);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = center + SkPoint::Make(-halfWidth, octOffset * halfWidth);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(-1, octOffset);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = center + SkPoint::Make(-halfWidth, -octOffset * halfWidth);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(-1, -octOffset);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
if (isStroked) {
|
||||
@ -363,48 +375,56 @@ private:
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(-s * innerRadius, -c * innerRadius);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = center + SkPoint::Make(s * r, -c * r);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(s * innerRadius, -c * innerRadius);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = center + SkPoint::Make(c * r, -s * r);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(c * innerRadius, -s * innerRadius);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = center + SkPoint::Make(c * r, s * r);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(c * innerRadius, s * innerRadius);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = center + SkPoint::Make(s * r, c * r);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(s * innerRadius, c * innerRadius);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = center + SkPoint::Make(-s * r, c * r);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(-s * innerRadius, c * innerRadius);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = center + SkPoint::Make(-c * r, s * r);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(-c * innerRadius, s * innerRadius);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = center + SkPoint::Make(-c * r, -s * r);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(-c * innerRadius, -s * innerRadius);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
} else {
|
||||
// filled
|
||||
@ -412,6 +432,7 @@ private:
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(0, 0);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
}
|
||||
}
|
||||
@ -454,6 +475,7 @@ private:
|
||||
outerVec.fX + outerVec.fY);
|
||||
diagVec *= umbraInset / (2 * umbraInset - outerRadius);
|
||||
SkScalar distanceCorrection = umbraInset / blurRadius;
|
||||
SkScalar clampValue = args.fClampValue;
|
||||
|
||||
// build corner by corner
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
@ -462,6 +484,7 @@ private:
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkVector::Make(0, 0);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
// outer points
|
||||
@ -469,30 +492,35 @@ private:
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkVector::Make(0, -1);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = SkPoint::Make(xOuter[i], yMid[i]);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = outerVec;
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = SkPoint::Make(xOuter[i], yOuter[i]);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = diagVec;
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = SkPoint::Make(xMid[i], yOuter[i]);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = outerVec;
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
(*verts)->fPos = SkPoint::Make(xInner[i], yOuter[i]);
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkVector::Make(0, -1);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
}
|
||||
|
||||
@ -510,6 +538,7 @@ private:
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(0, 0);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
// TR
|
||||
@ -517,6 +546,7 @@ private:
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(0, 0);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
// BL
|
||||
@ -524,6 +554,7 @@ private:
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(0, 0);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
|
||||
// BR
|
||||
@ -531,6 +562,7 @@ private:
|
||||
(*verts)->fColor = color;
|
||||
(*verts)->fOffset = SkPoint::Make(0, 0);
|
||||
(*verts)->fDistanceCorrection = distanceCorrection;
|
||||
(*verts)->fClampValue = clampValue;
|
||||
(*verts)++;
|
||||
}
|
||||
|
||||
@ -640,7 +672,8 @@ std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkRRect& rrect,
|
||||
SkScalar blurWidth,
|
||||
SkScalar insetWidth) {
|
||||
SkScalar insetWidth,
|
||||
SkScalar blurClamp) {
|
||||
// Shadow rrect ops only handle simple circular rrects.
|
||||
SkASSERT(viewMatrix.isSimilarity() &&
|
||||
(rrect.isSimpleCircular() || rrect.isRect() || rrect.isCircle()));
|
||||
@ -660,7 +693,8 @@ std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color,
|
||||
scaledRadius,
|
||||
rrect.isOval(),
|
||||
blurWidth,
|
||||
scaledInsetWidth));
|
||||
scaledInsetWidth,
|
||||
blurClamp));
|
||||
}
|
||||
}
|
||||
|
||||
@ -681,14 +715,15 @@ DRAW_OP_TEST_DEFINE(ShadowRRectOp) {
|
||||
GrColor color = GrRandomColor(random);
|
||||
SkScalar insetWidth = random->nextSScalar1() * 72.f;
|
||||
SkScalar blurWidth = random->nextSScalar1() * 72.f;
|
||||
SkScalar blurClamp = random->nextSScalar1();
|
||||
bool isCircle = random->nextBool();
|
||||
if (isCircle) {
|
||||
SkRect circle = GrTest::TestSquare(random);
|
||||
SkRRect rrect = SkRRect::MakeOval(circle);
|
||||
return GrShadowRRectOp::Make(color, viewMatrix, rrect, blurWidth, insetWidth);
|
||||
return GrShadowRRectOp::Make(color, viewMatrix, rrect, blurWidth, insetWidth, blurClamp);
|
||||
} else {
|
||||
const SkRRect& rrect = GrTest::TestRRectSimple(random);
|
||||
return GrShadowRRectOp::Make(color, viewMatrix, rrect, blurWidth, insetWidth);
|
||||
return GrShadowRRectOp::Make(color, viewMatrix, rrect, blurWidth, insetWidth, blurClamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,8 @@ class SkStrokeRec;
|
||||
namespace GrShadowRRectOp {
|
||||
|
||||
std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor, const SkMatrix& viewMatrix, const SkRRect& rrect,
|
||||
SkScalar blurWidth, SkScalar insetWidth);
|
||||
SkScalar blurWidth, SkScalar insetWidth,
|
||||
SkScalar blurClamp = 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user