diff options
author | Jim Van Verth <jvanverth@google.com> | 2017-05-08 14:19:30 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-05-08 18:42:48 +0000 |
commit | e308a122ef996a64a21a6339e3b50b9edfdf654f (patch) | |
tree | cdc38ee996e86789f198f93d4a86c240f03d2317 /src/utils/SkShadowTessellator.cpp | |
parent | 6f24180a99bc486cf4cee5da1a45225e7ff263d7 (diff) |
Remove height functor for shadows and replace with plane equation params
Change-Id: I948eceb2c58dc50468993dba54c209f18e440e48
Reviewed-on: https://skia-review.googlesource.com/15873
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/utils/SkShadowTessellator.cpp')
-rwxr-xr-x | src/utils/SkShadowTessellator.cpp | 88 |
1 files changed, 46 insertions, 42 deletions
diff --git a/src/utils/SkShadowTessellator.cpp b/src/utils/SkShadowTessellator.cpp index 32a114253a..9a82ec3bfa 100755 --- a/src/utils/SkShadowTessellator.cpp +++ b/src/utils/SkShadowTessellator.cpp @@ -22,7 +22,7 @@ */ class SkBaseShadowTessellator { public: - SkBaseShadowTessellator(SkShadowTessellator::HeightFunc, bool transparent); + SkBaseShadowTessellator(const SkPoint3& zPlaneParams, bool transparent); virtual ~SkBaseShadowTessellator() {} sk_sp<SkVertices> releaseVertices() { @@ -56,11 +56,15 @@ protected: bool addArc(const SkVector& nextNormal, bool finishArc); - SkShadowTessellator::HeightFunc fHeightFunc; + SkScalar heightFunc(SkScalar x, SkScalar y) { + return fZPlaneParams.fX*x + fZPlaneParams.fY*y + fZPlaneParams.fZ; + } + + SkPoint3 fZPlaneParams; std::function<SkScalar(const SkPoint&)> fTransformedHeightFunc; SkScalar fZOffset; // members for perspective height function - SkScalar fZParams[3]; + SkPoint3 fPerspZParams; SkScalar fPartialDeterminants[3]; // first two points @@ -118,9 +122,8 @@ static void compute_radial_steps(const SkVector& v1, const SkVector& v2, SkScala *n = steps; } -SkBaseShadowTessellator::SkBaseShadowTessellator(SkShadowTessellator::HeightFunc heightFunc, - bool transparent) - : fHeightFunc(heightFunc) +SkBaseShadowTessellator::SkBaseShadowTessellator(const SkPoint3& zPlaneParams, bool transparent) + : fZPlaneParams(zPlaneParams) , fZOffset(0) , fFirstVertex(-1) , fSucceeded(false) @@ -133,17 +136,17 @@ SkBaseShadowTessellator::SkBaseShadowTessellator(SkShadowTessellator::HeightFunc } bool SkBaseShadowTessellator::setZOffset(const SkRect& bounds, bool perspective) { - SkScalar minZ = fHeightFunc(bounds.fLeft, bounds.fTop); + SkScalar minZ = this->heightFunc(bounds.fLeft, bounds.fTop); if (perspective) { - SkScalar z = fHeightFunc(bounds.fLeft, bounds.fBottom); + SkScalar z = this->heightFunc(bounds.fLeft, bounds.fBottom); if (z < minZ) { minZ = z; } - z = fHeightFunc(bounds.fRight, bounds.fTop); + z = this->heightFunc(bounds.fRight, bounds.fTop); if (z < minZ) { minZ = z; } - z = fHeightFunc(bounds.fRight, bounds.fBottom); + z = this->heightFunc(bounds.fRight, bounds.fBottom); if (z < minZ) { minZ = z; } @@ -267,27 +270,28 @@ bool SkBaseShadowTessellator::addArc(const SkVector& nextNormal, bool finishArc) bool SkBaseShadowTessellator::setTransformedHeightFunc(const SkMatrix& ctm) { if (!ctm.hasPerspective()) { fTransformedHeightFunc = [this](const SkPoint& p) { - return this->fHeightFunc(0, 0); + return fZPlaneParams.fZ; }; } else { SkMatrix ctmInverse; if (!ctm.invert(&ctmInverse)) { return false; } - SkScalar C = fHeightFunc(0, 0); - SkScalar A = fHeightFunc(1, 0) - C; - SkScalar B = fHeightFunc(0, 1) - C; // multiply by transpose - fZParams[0] = ctmInverse[SkMatrix::kMScaleX] * A + - ctmInverse[SkMatrix::kMSkewY] * B + - ctmInverse[SkMatrix::kMPersp0] * C; - fZParams[1] = ctmInverse[SkMatrix::kMSkewX] * A + - ctmInverse[SkMatrix::kMScaleY] * B + - ctmInverse[SkMatrix::kMPersp1] * C; - fZParams[2] = ctmInverse[SkMatrix::kMTransX] * A + - ctmInverse[SkMatrix::kMTransY] * B + - ctmInverse[SkMatrix::kMPersp2] * C; + fPerspZParams = SkPoint3::Make( + ctmInverse[SkMatrix::kMScaleX] * fZPlaneParams.fX + + ctmInverse[SkMatrix::kMSkewY] * fZPlaneParams.fY + + ctmInverse[SkMatrix::kMPersp0] * fZPlaneParams.fZ, + + ctmInverse[SkMatrix::kMSkewX] * fZPlaneParams.fX + + ctmInverse[SkMatrix::kMScaleY] * fZPlaneParams.fY + + ctmInverse[SkMatrix::kMPersp1] * fZPlaneParams.fZ, + + ctmInverse[SkMatrix::kMTransX] * fZPlaneParams.fX + + ctmInverse[SkMatrix::kMTransY] * fZPlaneParams.fY + + ctmInverse[SkMatrix::kMPersp2] * fZPlaneParams.fZ + ); // We use Cramer's rule to solve for the W value for a given post-divide X and Y, // so pre-compute those values that are independent of X and Y. @@ -304,17 +308,17 @@ bool SkBaseShadowTessellator::setTransformedHeightFunc(const SkMatrix& ctm) { // Pre-bake the numerator of Cramer's rule into the zParams to avoid another multiply. // TODO: this may introduce numerical instability, but I haven't seen any issues yet. - fZParams[0] *= ctmDeterminant; - fZParams[1] *= ctmDeterminant; - fZParams[2] *= ctmDeterminant; + fPerspZParams.fX *= ctmDeterminant; + fPerspZParams.fY *= ctmDeterminant; + fPerspZParams.fZ *= ctmDeterminant; fTransformedHeightFunc = [this](const SkPoint& p) { - SkScalar denom = p.fX * this->fPartialDeterminants[0] + - p.fY * this->fPartialDeterminants[1] + - this->fPartialDeterminants[2]; + SkScalar denom = p.fX * fPartialDeterminants[0] + + p.fY * fPartialDeterminants[1] + + fPartialDeterminants[2]; SkScalar w = SkScalarFastInvert(denom); - return (this->fZParams[0] * p.fX + this->fZParams[1] * p.fY + this->fZParams[2])*w + - this->fZOffset; + return (fPerspZParams.fX * p.fX + fPerspZParams.fY * p.fY + fPerspZParams.fZ)*w + + fZOffset; }; } @@ -327,7 +331,7 @@ bool SkBaseShadowTessellator::setTransformedHeightFunc(const SkMatrix& ctm) { class SkAmbientShadowTessellator : public SkBaseShadowTessellator { public: SkAmbientShadowTessellator(const SkPath& path, const SkMatrix& ctm, - SkShadowTessellator::HeightFunc heightFunc, bool transparent); + const SkPoint3& zPlaneParams, bool transparent); private: void handleLine(const SkPoint& p) override; @@ -352,9 +356,9 @@ private: SkAmbientShadowTessellator::SkAmbientShadowTessellator(const SkPath& path, const SkMatrix& ctm, - SkShadowTessellator::HeightFunc heightFunc, + const SkPoint3& zPlaneParams, bool transparent) - : INHERITED(heightFunc, transparent) { + : INHERITED(zPlaneParams, transparent) { // Set base colors SkScalar occluderHeight = heightFunc(0, 0); SkScalar umbraAlpha = SkScalarInvert((1.0f + SkTMax(occluderHeight*kHeightFactor, 0.0f))); @@ -650,7 +654,7 @@ void SkAmbientShadowTessellator::addEdge(const SkPoint& nextPoint, const SkVecto class SkSpotShadowTessellator : public SkBaseShadowTessellator { public: SkSpotShadowTessellator(const SkPath& path, const SkMatrix& ctm, - SkShadowTessellator::HeightFunc heightFunc, const SkPoint3& lightPos, + const SkPoint3& zPlaneParams, const SkPoint3& lightPos, SkScalar lightRadius, bool transparent); private: @@ -693,10 +697,10 @@ private: }; SkSpotShadowTessellator::SkSpotShadowTessellator(const SkPath& path, const SkMatrix& ctm, - SkShadowTessellator::HeightFunc heightFunc, + const SkPoint3& zPlaneParams, const SkPoint3& lightPos, SkScalar lightRadius, bool transparent) - : INHERITED(heightFunc, transparent) + : INHERITED(zPlaneParams, transparent) , fLightZ(lightPos.fZ) , fLightRadius(lightRadius) , fOffsetAdjust(0) @@ -714,7 +718,7 @@ SkSpotShadowTessellator::SkSpotShadowTessellator(const SkPath& path, const SkMat // Set radius and colors SkPoint center = SkPoint::Make(path.getBounds().centerX(), path.getBounds().centerY()); - SkScalar occluderHeight = heightFunc(center.fX, center.fY) + fZOffset; + SkScalar occluderHeight = this->heightFunc(center.fX, center.fY) + fZOffset; float zRatio = SkTPin(occluderHeight / (fLightZ - occluderHeight), 0.0f, 0.95f); SkScalar radius = lightRadius * zRatio; fRadius = radius; @@ -1287,14 +1291,14 @@ void SkSpotShadowTessellator::addEdge(const SkPoint& nextPoint, const SkVector& /////////////////////////////////////////////////////////////////////////////////////////////////// sk_sp<SkVertices> SkShadowTessellator::MakeAmbient(const SkPath& path, const SkMatrix& ctm, - HeightFunc heightFunc, bool transparent) { - SkAmbientShadowTessellator ambientTess(path, ctm, heightFunc, transparent); + const SkPoint3& zPlane, bool transparent) { + SkAmbientShadowTessellator ambientTess(path, ctm, zPlane, transparent); return ambientTess.releaseVertices(); } sk_sp<SkVertices> SkShadowTessellator::MakeSpot(const SkPath& path, const SkMatrix& ctm, - HeightFunc heightFunc, const SkPoint3& lightPos, + const SkPoint3& zPlane, const SkPoint3& lightPos, SkScalar lightRadius, bool transparent) { - SkSpotShadowTessellator spotTess(path, ctm, heightFunc, lightPos, lightRadius, transparent); + SkSpotShadowTessellator spotTess(path, ctm, zPlane, lightPos, lightRadius, transparent); return spotTess.releaseVertices(); } |