aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/utils/SkShadowUtils.h27
-rw-r--r--samplecode/SampleAndroidShadows.cpp9
-rw-r--r--src/utils/SkShadowTessellator.cpp88
-rw-r--r--src/utils/SkShadowTessellator.h13
-rw-r--r--src/utils/SkShadowUtils.cpp108
-rw-r--r--tests/ShadowUtilsTest.cpp22
6 files changed, 185 insertions, 82 deletions
diff --git a/include/utils/SkShadowUtils.h b/include/utils/SkShadowUtils.h
index 3339812c34..01514a46ff 100644
--- a/include/utils/SkShadowUtils.h
+++ b/include/utils/SkShadowUtils.h
@@ -11,6 +11,7 @@
#include "SkColor.h"
#include "SkScalar.h"
#include "../private/SkShadowFlags.h"
+#include <functional>
class SkCanvas;
class SkPath;
@@ -25,7 +26,7 @@ public:
* @param canvas The canvas on which to draw the shadows.
* @param path The occluder used to generate the shadows.
* @param occluderHeight The vertical offset of the occluder from the canvas. This is
- * indepdendent of the canvas's current matrix.
+ * independent of the canvas's current matrix.
* @param lightPos The 3D position of the light relative to the canvas plane. This is
* independent of the canvas's current matrix.
* @param lightRadius The radius of the disc light.
@@ -41,6 +42,30 @@ public:
SkScalar spotAlpha, SkColor color,
uint32_t flags = SkShadowFlags::kNone_ShadowFlag,
SkResourceCache* cache = nullptr);
+
+ /**
+ * Draw an offset spot shadow and outlining ambient shadow for the given path using a disc
+ * light. Takes a function to vary the z value based on the transformed x and y position.
+ * This shadow will not be cached, as the assumption is that this will be used for animation.
+ *
+ * @param canvas The canvas on which to draw the shadows.
+ * @param path The occluder used to generate the shadows.
+ * @param heightFunc A function which returns the vertical offset of the occluder from the
+ * canvas based on local x and y values (the current matrix is not applied).
+ * @param lightPos The 3D position of the light relative to the canvas plane. This is
+ * independent of the canvas's current matrix.
+ * @param lightRadius The radius of the disc light.
+ * @param ambientAlpha The maximum alpha of the ambient shadow.
+ * @param spotAlpha The maxium alpha of the spot shadow.
+ * @param color The shadow color.
+ * @param flags Options controlling opaque occluder optimizations and shadow appearance. See
+ * SkShadowFlags.
+ */
+ static void DrawUncachedShadow(SkCanvas* canvas, const SkPath& path,
+ std::function<SkScalar(SkScalar, SkScalar)> heightFunc,
+ const SkPoint3& lightPos, SkScalar lightRadius,
+ SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
+ uint32_t flags = SkShadowFlags::kNone_ShadowFlag);
};
#endif
diff --git a/samplecode/SampleAndroidShadows.cpp b/samplecode/SampleAndroidShadows.cpp
index 271004ed10..bb56b7ed17 100644
--- a/samplecode/SampleAndroidShadows.cpp
+++ b/samplecode/SampleAndroidShadows.cpp
@@ -421,8 +421,15 @@ protected:
if (!fShowSpot) {
spotAlpha = 0;
}
- SkShadowUtils::DrawShadow(canvas, path, zValue, lightPos, lightWidth,
+
+ SkShadowUtils::DrawShadow(canvas, path,
+ zValue,
+ lightPos, lightWidth,
ambientAlpha, spotAlpha, SK_ColorBLACK);
+ //SkShadowUtils::DrawUncachedShadow(canvas, path,
+ // [zValue](SkScalar, SkScalar) { return zValue; },
+ // lightPos, lightWidth,
+ // ambientAlpha, spotAlpha, SK_ColorBLACK);
}
#else
if (fShowAmbient) {
diff --git a/src/utils/SkShadowTessellator.cpp b/src/utils/SkShadowTessellator.cpp
index ef8ce3212f..ce161ca8de 100644
--- a/src/utils/SkShadowTessellator.cpp
+++ b/src/utils/SkShadowTessellator.cpp
@@ -22,8 +22,7 @@
*/
class SkBaseShadowTessellator {
public:
- SkBaseShadowTessellator(SkScalar radius, SkColor umbraColor, SkColor penumbraColor,
- bool transparent);
+ SkBaseShadowTessellator(SkShadowTessellator::HeightFunc, bool transparent);
virtual ~SkBaseShadowTessellator() {}
sk_sp<SkVertices> releaseVertices() {
@@ -53,6 +52,8 @@ protected:
void finishArcAndAddEdge(const SkVector& nextPoint, const SkVector& nextNormal);
virtual void addEdge(const SkVector& nextPoint, const SkVector& nextNormal) = 0;
+ SkShadowTessellator::HeightFunc fHeightFunc;
+
// first three points
SkTDArray<SkPoint> fInitPoints;
// temporary buffer
@@ -108,14 +109,12 @@ static void compute_radial_steps(const SkVector& v1, const SkVector& v2, SkScala
*n = SkScalarFloorToInt(steps);
}
-SkBaseShadowTessellator::SkBaseShadowTessellator(SkScalar radius, SkColor umbraColor,
- SkColor penumbraColor, bool transparent)
- : fFirstVertex(-1)
+SkBaseShadowTessellator::SkBaseShadowTessellator(SkShadowTessellator::HeightFunc heightFunc,
+ bool transparent)
+ : fHeightFunc(heightFunc)
+ , fFirstVertex(-1)
, fSucceeded(false)
, fTransparent(transparent)
- , fUmbraColor(umbraColor)
- , fPenumbraColor(penumbraColor)
- , fRadius(radius)
, fDirection(1)
, fPrevUmbraIndex(-1) {
fInitPoints.setReserve(3);
@@ -235,8 +234,8 @@ void SkBaseShadowTessellator::finishArcAndAddEdge(const SkPoint& nextPoint,
class SkAmbientShadowTessellator : public SkBaseShadowTessellator {
public:
SkAmbientShadowTessellator(const SkPath& path, const SkMatrix& ctm,
- SkScalar radius, SkColor umbraColor,
- SkColor penumbraColor, bool transparent);
+ SkShadowTessellator::HeightFunc heightFunc,
+ SkScalar ambientAlpha, bool transparent);
private:
void handleLine(const SkPoint& p) override;
@@ -247,13 +246,27 @@ private:
typedef SkBaseShadowTessellator INHERITED;
};
+static const float kHeightFactor = 1.0f / 128.0f;
+static const float kGeomFactor = 64.0f;
+
SkAmbientShadowTessellator::SkAmbientShadowTessellator(const SkPath& path,
const SkMatrix& ctm,
- SkScalar radius,
- SkColor umbraColor,
- SkColor penumbraColor,
+ SkShadowTessellator::HeightFunc heightFunc,
+ SkScalar ambientAlpha,
bool transparent)
- : INHERITED(radius, umbraColor, penumbraColor, transparent) {
+ : INHERITED(heightFunc, transparent) {
+ // Set radius and colors
+ // TODO: vary colors and radius based on heightFunc
+ SkScalar occluderHeight = heightFunc(0, 0);
+ fRadius = occluderHeight * kHeightFactor * kGeomFactor;
+ SkScalar umbraAlpha = SkScalarInvert((1.0f + SkTMax(occluderHeight*kHeightFactor, 0.0f)));
+ // umbraColor is the interior value, penumbraColor the exterior value.
+ // umbraAlpha is the factor that is linearly interpolated from outside to inside, and
+ // then "blurred" by the GrBlurredEdgeFP. It is then multiplied by fAmbientAlpha to get
+ // the final alpha.
+ fUmbraColor = SkColorSetARGB(255, 0, ambientAlpha * 255.9999f, umbraAlpha * 255.9999f);
+ fPenumbraColor = SkColorSetARGB(255, 0, ambientAlpha * 255.9999f, 0);
+
// Outer ring: 3*numPts
// Middle ring: numPts
fPositions.setReserve(4 * path.countPoints());
@@ -269,7 +282,7 @@ SkAmbientShadowTessellator::SkAmbientShadowTessellator(const SkPath& path,
SkPath::Verb verb;
if (fTransparent) {
*fPositions.push() = SkPoint::Make(0, 0);
- *fColors.push() = umbraColor;
+ *fColors.push() = fUmbraColor;
fCentroidCount = 0;
}
while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
@@ -435,9 +448,9 @@ void SkAmbientShadowTessellator::addEdge(const SkPoint& nextPoint, const SkVecto
class SkSpotShadowTessellator : public SkBaseShadowTessellator {
public:
SkSpotShadowTessellator(const SkPath& path, const SkMatrix& ctm,
- SkScalar scale, const SkVector& translate,
- SkScalar radius, SkColor umbraColor, SkColor penumbraColor,
- bool transparent);
+ SkShadowTessellator::HeightFunc heightFunc,
+ const SkPoint3& lightPos, SkScalar lightRadius,
+ SkScalar spotAlpha, bool transparent);
private:
void computeClipAndPathPolygons(const SkPath& path, const SkMatrix& ctm,
@@ -470,14 +483,31 @@ private:
};
SkSpotShadowTessellator::SkSpotShadowTessellator(const SkPath& path, const SkMatrix& ctm,
- SkScalar scale, const SkVector& translate,
- SkScalar radius, SkColor umbraColor,
- SkColor penumbraColor, bool transparent)
- : INHERITED(radius, umbraColor, penumbraColor, transparent)
+ SkShadowTessellator::HeightFunc heightFunc,
+ const SkPoint3& lightPos, SkScalar lightRadius,
+ SkScalar spotAlpha, bool transparent)
+ : INHERITED(heightFunc, transparent)
, fCurrClipPoint(0)
, fPrevUmbraOutside(false)
, fFirstUmbraOutside(false)
, fValidUmbra(true) {
+
+ // Set radius and colors
+ // TODO: vary colors and radius based on heightFunc
+ SkPoint center = SkPoint::Make(path.getBounds().centerX(), path.getBounds().centerY());
+ SkScalar occluderHeight = heightFunc(center.fX, center.fY);
+ float zRatio = SkTPin(occluderHeight / (lightPos.fZ - occluderHeight), 0.0f, 0.95f);
+ SkScalar radius = lightRadius * zRatio;
+ fRadius = radius;
+ fUmbraColor = SkColorSetARGB(255, 0, spotAlpha * 255.9999f, 255);
+ fPenumbraColor = SkColorSetARGB(255, 0, spotAlpha * 255.9999f, 0);
+
+ // Compute the scale and translation for the spot shadow.
+ SkScalar scale = lightPos.fZ / (lightPos.fZ - occluderHeight);
+ ctm.mapPoints(&center, 1);
+ SkVector translate = SkVector::Make(zRatio * (center.fX - lightPos.fX),
+ zRatio * (center.fY - lightPos.fY));
+
// TODO: calculate these reserves better
// Penumbra ring: 3*numPts
// Umbra ring: numPts
@@ -993,17 +1023,17 @@ void SkSpotShadowTessellator::addEdge(const SkPoint& nextPoint, const SkVector&
///////////////////////////////////////////////////////////////////////////////////////////////////
sk_sp<SkVertices> SkShadowTessellator::MakeAmbient(const SkPath& path, const SkMatrix& ctm,
- SkScalar radius, SkColor umbra, SkColor penumbra,
+ HeightFunc heightFunc, SkScalar ambientAlpha,
bool transparent) {
- SkAmbientShadowTessellator ambientTess(path, ctm, radius, umbra, penumbra, transparent);
+ SkAmbientShadowTessellator ambientTess(path, ctm, heightFunc, ambientAlpha, transparent);
return ambientTess.releaseVertices();
}
sk_sp<SkVertices> SkShadowTessellator::MakeSpot(const SkPath& path, const SkMatrix& ctm,
- SkScalar scale, const SkVector& translate,
- SkScalar radius, SkColor umbraColor,
- SkColor penumbraColor, bool transparent) {
- SkSpotShadowTessellator spotTess(path, ctm, scale, translate, radius, umbraColor,
- penumbraColor, transparent);
+ HeightFunc heightFunc,
+ const SkPoint3& lightPos, SkScalar lightRadius,
+ SkScalar spotAlpha, bool transparent) {
+ SkSpotShadowTessellator spotTess(path, ctm, heightFunc, lightPos, lightRadius,
+ spotAlpha, transparent);
return spotTess.releaseVertices();
}
diff --git a/src/utils/SkShadowTessellator.h b/src/utils/SkShadowTessellator.h
index eb49bbee3f..f9f4a144c9 100644
--- a/src/utils/SkShadowTessellator.h
+++ b/src/utils/SkShadowTessellator.h
@@ -17,22 +17,25 @@ class SkPath;
class SkVertices;
namespace SkShadowTessellator {
+
+typedef std::function<SkScalar(SkScalar, SkScalar)> HeightFunc;
+
/**
* This function generates an ambient shadow mesh for a path by walking the path, outsetting by
* the radius, and setting inner and outer colors to umbraColor and penumbraColor, respectively.
* If transparent is true, then the center of the ambient shadow will be filled in.
*/
-sk_sp<SkVertices> MakeAmbient(const SkPath& path, const SkMatrix& ctm, SkScalar radius,
- SkColor umbraColor, SkColor penumbraColor, bool transparent);
+sk_sp<SkVertices> MakeAmbient(const SkPath& path, const SkMatrix& ctm,
+ HeightFunc heightFunc, SkScalar ambientAlpha, bool transparent);
/**
* This function generates a spot shadow mesh for a path by walking the transformed path,
* further transforming by the scale and translation, and outsetting and insetting by a radius.
* The center will be clipped against the original path unless transparent is true.
*/
-sk_sp<SkVertices> MakeSpot(const SkPath& path, const SkMatrix& ctm, SkScalar scale,
- const SkVector& translate, SkScalar radius, SkColor umbraColor,
- SkColor penumbraColor, bool transparent);
+sk_sp<SkVertices> MakeSpot(const SkPath& path, const SkMatrix& ctm, HeightFunc heightFunc,
+ const SkPoint3& lightPos, SkScalar lightRadius,
+ SkScalar spotAlpha, bool transparent);
}
#endif
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp
index 402dca5c92..2e560b454e 100644
--- a/src/utils/SkShadowUtils.cpp
+++ b/src/utils/SkShadowUtils.cpp
@@ -92,14 +92,13 @@ uint64_t resource_cache_shared_id() {
/** Factory for an ambient shadow mesh with particular shadow properties. */
struct AmbientVerticesFactory {
- SkScalar fRadius = SK_ScalarNaN; // NaN so that isCompatible will always fail until init'ed.
- SkColor fUmbraColor;
- SkColor fPenumbraColor;
+ SkScalar fOccluderHeight = SK_ScalarNaN; // NaN so that isCompatible will fail until init'ed.
+ SkScalar fAmbientAlpha;
bool fTransparent;
bool isCompatible(const AmbientVerticesFactory& that, SkVector* translate) const {
- if (fRadius != that.fRadius || fUmbraColor != that.fUmbraColor ||
- fPenumbraColor != that.fPenumbraColor || fTransparent != that.fTransparent) {
+ if (fOccluderHeight != that.fOccluderHeight || fAmbientAlpha != that.fAmbientAlpha ||
+ fTransparent != that.fTransparent) {
return false;
}
translate->set(0, 0);
@@ -107,8 +106,10 @@ struct AmbientVerticesFactory {
}
sk_sp<SkVertices> makeVertices(const SkPath& path, const SkMatrix& ctm) const {
- return SkShadowTessellator::MakeAmbient(path, ctm, fRadius, fUmbraColor, fPenumbraColor,
- fTransparent);
+ SkScalar z = fOccluderHeight;
+ return SkShadowTessellator::MakeAmbient(path, ctm,
+ [z](SkScalar, SkScalar) { return z; },
+ fAmbientAlpha, fTransparent);
}
};
@@ -123,17 +124,17 @@ struct SpotVerticesFactory {
kOpaqueCoversUmbra
};
- SkScalar fRadius = SK_ScalarNaN; // NaN so that isCompatible will always fail until init'ed.
- SkColor fUmbraColor;
- SkColor fPenumbraColor;
- SkScalar fScale;
SkVector fOffset;
+ SkScalar fOccluderHeight = SK_ScalarNaN; // NaN so that isCompatible will fail until init'ed.
+ SkPoint3 fDevLightPos;
+ SkScalar fLightRadius;
+ SkScalar fSpotAlpha;
OccluderType fOccluderType;
bool isCompatible(const SpotVerticesFactory& that, SkVector* translate) const {
- if (fRadius != that.fRadius || fUmbraColor != that.fUmbraColor ||
- fPenumbraColor != that.fPenumbraColor || fOccluderType != that.fOccluderType ||
- fScale != that.fScale) {
+ if (fOccluderHeight != that.fOccluderHeight || fDevLightPos.fZ != that.fDevLightPos.fZ ||
+ fLightRadius != that.fLightRadius || fSpotAlpha != that.fSpotAlpha ||
+ fOccluderType != that.fOccluderType) {
return false;
}
switch (fOccluderType) {
@@ -158,8 +159,11 @@ struct SpotVerticesFactory {
sk_sp<SkVertices> makeVertices(const SkPath& path, const SkMatrix& ctm) const {
bool transparent = OccluderType::kTransparent == fOccluderType;
- return SkShadowTessellator::MakeSpot(path, ctm, fScale, fOffset, fRadius, fUmbraColor,
- fPenumbraColor, transparent);
+ SkScalar z = fOccluderHeight;
+ return SkShadowTessellator::MakeSpot(path, ctm,
+ [z](SkScalar, SkScalar) -> SkScalar { return z; },
+ fDevLightPos, fLightRadius,
+ fSpotAlpha, transparent);
}
};
@@ -450,9 +454,6 @@ void draw_shadow(const FACTORY& factory, SkCanvas* canvas, ShadowedPath& path, S
}
}
-static const float kHeightFactor = 1.0f / 128.0f;
-static const float kGeomFactor = 64.0f;
-
// Draw an offset spot shadow and outlining ambient shadow for the given path.
void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, SkScalar occluderHeight,
const SkPoint3& devLightPos, SkScalar lightRadius,
@@ -489,15 +490,8 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, SkScalar oc
if (ambientAlpha > 0) {
ambientAlpha = SkTMin(ambientAlpha, 1.f);
AmbientVerticesFactory factory;
- factory.fRadius = occluderHeight * kHeightFactor * kGeomFactor;
- SkScalar umbraAlpha = SkScalarInvert((1.0f + SkTMax(occluderHeight*kHeightFactor, 0.0f)));
- // umbraColor is the interior value, penumbraColor the exterior value.
- // umbraAlpha is the factor that is linearly interpolated from outside to inside, and
- // then "blurred" by the GrBlurredEdgeFP. It is then multiplied by fAmbientAlpha to get
- // the final alpha.
- factory.fUmbraColor =
- SkColorSetARGB(255, 0, ambientAlpha * 255.9999f, umbraAlpha * 255.9999f);
- factory.fPenumbraColor = SkColorSetARGB(255, 0, ambientAlpha * 255.9999f, 0);
+ factory.fOccluderHeight = occluderHeight;
+ factory.fAmbientAlpha = ambientAlpha;
factory.fTransparent = transparent;
draw_shadow(factory, canvas, shadowedPath, color, cache);
@@ -507,17 +501,19 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, SkScalar oc
spotAlpha = SkTMin(spotAlpha, 1.f);
SpotVerticesFactory factory;
float zRatio = SkTPin(occluderHeight / (devLightPos.fZ - occluderHeight), 0.0f, 0.95f);
- factory.fRadius = lightRadius * zRatio;
+ SkScalar radius = lightRadius * zRatio;
// Compute the scale and translation for the spot shadow.
- factory.fScale = devLightPos.fZ / (devLightPos.fZ - occluderHeight);
+ SkScalar scale = devLightPos.fZ / (devLightPos.fZ - occluderHeight);
SkPoint center = SkPoint::Make(path.getBounds().centerX(), path.getBounds().centerY());
viewMatrix.mapPoints(&center, 1);
factory.fOffset = SkVector::Make(zRatio * (center.fX - devLightPos.fX),
zRatio * (center.fY - devLightPos.fY));
- factory.fUmbraColor = SkColorSetARGB(255, 0, spotAlpha * 255.9999f, 255);
- factory.fPenumbraColor = SkColorSetARGB(255, 0, spotAlpha * 255.9999f, 0);
+ factory.fOccluderHeight = occluderHeight;
+ factory.fDevLightPos = devLightPos;
+ factory.fLightRadius = lightRadius;
+ factory.fSpotAlpha = spotAlpha;
SkRRect rrect;
if (transparent) {
@@ -527,13 +523,13 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, SkScalar oc
if (shadowedPath.isRRect(&rrect)) {
SkRRect devRRect;
if (rrect.transform(viewMatrix, &devRRect)) {
- SkScalar s = 1.f - factory.fScale;
+ SkScalar s = 1.f - scale;
SkScalar w = devRRect.width();
SkScalar h = devRRect.height();
SkScalar hw = w / 2.f;
SkScalar hh = h / 2.f;
- SkScalar umbraInsetX = s * hw + factory.fRadius;
- SkScalar umbraInsetY = s * hh + factory.fRadius;
+ SkScalar umbraInsetX = s * hw + radius;
+ SkScalar umbraInsetY = s * hh + radius;
// The umbra is inset by radius along the diagonal, so adjust for that.
SkScalar d = 1.f / SkScalarSqrt(hw * hw + hh * hh);
umbraInsetX *= hw * d;
@@ -559,3 +555,45 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, SkScalar oc
draw_shadow(factory, canvas, shadowedPath, color, cache);
}
}
+
+// Draw an offset spot shadow and outlining ambient shadow for the given path,
+// without caching and using a function based on local position to compute the height.
+void SkShadowUtils::DrawUncachedShadow(SkCanvas* canvas, const SkPath& path,
+ std::function<SkScalar(SkScalar, SkScalar)> heightFunc,
+ const SkPoint3& lightPos, SkScalar lightRadius,
+ SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
+ uint32_t flags) {
+ SkAutoCanvasRestore acr(canvas, true);
+ SkMatrix viewMatrix = canvas->getTotalMatrix();
+ canvas->resetMatrix();
+
+ bool transparent = SkToBool(flags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
+
+ if (ambientAlpha > 0) {
+ ambientAlpha = SkTMin(ambientAlpha, 1.f);
+ sk_sp<SkVertices> vertices = SkShadowTessellator::MakeAmbient(path, viewMatrix,
+ heightFunc, ambientAlpha,
+ transparent);
+ SkPaint paint;
+ // Run the vertex color through a GaussianColorFilter and then modulate the grayscale
+ // result of that against our 'color' param.
+ paint.setColorFilter(SkColorFilter::MakeComposeFilter(
+ SkColorFilter::MakeModeFilter(color, SkBlendMode::kModulate),
+ SkGaussianColorFilter::Make()));
+ canvas->drawVertices(vertices, SkBlendMode::kModulate, paint);
+ }
+
+ if (spotAlpha > 0) {
+ spotAlpha = SkTMin(spotAlpha, 1.f);
+ sk_sp<SkVertices> vertices = SkShadowTessellator::MakeSpot(path, viewMatrix, heightFunc,
+ lightPos, lightRadius,
+ spotAlpha, transparent);
+ SkPaint paint;
+ // Run the vertex color through a GaussianColorFilter and then modulate the grayscale
+ // result of that against our 'color' param.
+ paint.setColorFilter(SkColorFilter::MakeComposeFilter(
+ SkColorFilter::MakeModeFilter(color, SkBlendMode::kModulate),
+ SkGaussianColorFilter::Make()));
+ canvas->drawVertices(vertices, SkBlendMode::kModulate, paint);
+ }
+}
diff --git a/tests/ShadowUtilsTest.cpp b/tests/ShadowUtilsTest.cpp
index 7f9ce91158..e2aa1d117e 100644
--- a/tests/ShadowUtilsTest.cpp
+++ b/tests/ShadowUtilsTest.cpp
@@ -14,29 +14,29 @@
void tessellate_shadow(skiatest::Reporter* reporter, const SkPath& path, const SkMatrix& ctm,
bool expectSuccess) {
- static constexpr SkScalar kRadius = 2.f;
- static constexpr SkColor kUmbraColor = 0xFFFFFFFF;
- static constexpr SkColor kPenumbraColor = 0x20202020;
- auto verts =
- SkShadowTessellator::MakeAmbient(path, ctm, kRadius, kUmbraColor, kPenumbraColor, true);
+ static constexpr SkScalar kAmbientAlpha = 0.25f;
+ static constexpr SkScalar kSpotAlpha = 0.25f;
+
+ auto heightFunc = [] (SkScalar, SkScalar) { return 4; };
+
+ auto verts = SkShadowTessellator::MakeAmbient(path, ctm, heightFunc, kAmbientAlpha, true);
if (expectSuccess != SkToBool(verts)) {
ERRORF(reporter, "Expected shadow tessellation to %s but it did not.",
expectSuccess ? "succeed" : "fail");
}
- verts = SkShadowTessellator::MakeAmbient(path, ctm, kRadius, kUmbraColor, kPenumbraColor,
- false);
+ verts = SkShadowTessellator::MakeAmbient(path, ctm, heightFunc, kAmbientAlpha, false);
if (expectSuccess != SkToBool(verts)) {
ERRORF(reporter, "Expected shadow tessellation to %s but it did not.",
expectSuccess ? "succeed" : "fail");
}
- verts = SkShadowTessellator::MakeSpot(path, ctm, 1.5f, {0, 0}, kRadius, kUmbraColor,
- kPenumbraColor, false);
+ verts = SkShadowTessellator::MakeSpot(path, ctm, heightFunc, {0, 0, 128}, 128.f,
+ kSpotAlpha, false);
if (expectSuccess != SkToBool(verts)) {
ERRORF(reporter, "Expected shadow tessellation to %s but it did not.",
expectSuccess ? "succeed" : "fail");
}
- verts = SkShadowTessellator::MakeSpot(path, ctm, 1.5f, {0, 0}, kRadius, kUmbraColor,
- kPenumbraColor, true);
+ verts = SkShadowTessellator::MakeSpot(path, ctm, heightFunc, {0, 0, 128}, 128.f,
+ kSpotAlpha, false);
if (expectSuccess != SkToBool(verts)) {
ERRORF(reporter, "Expected shadow tessellation to %s but it did not.",
expectSuccess ? "succeed" : "fail");