diff options
author | Jim Van Verth <jvanverth@google.com> | 2017-05-11 17:05:28 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-05-11 21:38:51 +0000 |
commit | a783c3623d3cf8b0d2106f055ae4a21d4f8d23d8 (patch) | |
tree | 73a2a9da23cfc534140b76d55df3ff07818dcbae | |
parent | cd9af1bfa8aa0efafabe59da5e7cda0fc9e7eb1f (diff) |
Classify spot shadows for general shapes
Add some simple checks so we can tell whether a shadow's umbra is
completely covered by the occluder, partially covered, or less than
halfway covered.
Change-Id: I092281c4933bd0380946eb0fdd458ce04b0d713c
Reviewed-on: https://skia-review.googlesource.com/16603
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
-rw-r--r-- | src/utils/SkShadowUtils.cpp | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp index caf918e4f2..355fb2df75 100644 --- a/src/utils/SkShadowUtils.cpp +++ b/src/utils/SkShadowUtils.cpp @@ -640,6 +640,9 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi SpotVerticesFactory factory; SkScalar occluderHeight = zPlaneParams.fZ; float zRatio = SkTPin(occluderHeight / (devLightPos.fZ - occluderHeight), 0.0f, 0.95f); + SkScalar radius = lightRadius * zRatio; + + // Compute the translation for the spot shadow. SkPoint center = SkPoint::Make(path.getBounds().centerX(), path.getBounds().centerY()); viewMatrix.mapPoints(¢er, 1); factory.fOffset = SkVector::Make(zRatio * (center.fX - devLightPos.fX), @@ -647,9 +650,34 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoi factory.fOccluderHeight = occluderHeight; factory.fDevLightPos = devLightPos; factory.fLightRadius = lightRadius; - // the only valid choice we have right now - factory.fOccluderType = SpotVerticesFactory::OccluderType::kTransparent; + SkRect devBounds; + viewMatrix.mapRect(&devBounds, path.getBounds()); + if (transparent || + // if the translation of the shadow is big enough we're going to end up + // filling the entire umbra, so we can treat this as transparent + SkTAbs(factory.fOffset.fX) > 0.5f*devBounds.width() || + SkTAbs(factory.fOffset.fY) > 0.5f*devBounds.height()) { + factory.fOccluderType = SpotVerticesFactory::OccluderType::kTransparent; + } else if (factory.fOffset.length() < radius) { + // if we don't translate more than the blur distance, can assume umbra is covered + factory.fOccluderType = SpotVerticesFactory::OccluderType::kOpaqueCoversUmbra; + } else { + factory.fOccluderType = SpotVerticesFactory::OccluderType::kOpaque; + } +#ifdef DEBUG_SHADOW_CHECKS + switch (factory.fOccluderType) { + case SpotVerticesFactory::OccluderType::kTransparent: + color = 0xFFD2B48C; // tan for transparent + break; + case SpotVerticesFactory::OccluderType::kOpaque: + color = 0xFFFFA500; // orange for opaque + break; + case SpotVerticesFactory::OccluderType::kOpaqueCoversUmbra: + color = SK_ColorYELLOW; // corn yellow for covered + break; + } +#endif SkColor renderColor = compute_render_color(color, spotAlpha); draw_shadow(factory, canvas, shadowedPath, renderColor); } |