Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 7b617a7

Browse files
jvanverthSkia Commit-Bot
authored andcommitted
Fix some issues with shadow tesselation
Bug: oss-fuzz:10348 Change-Id: I818f741452bdb8092796f78bb73d9b518502e4c9 Reviewed-on: https://skia-review.googlesource.com/154627 Reviewed-by: Brian Salomon <[email protected]> Commit-Queue: Jim Van Verth <[email protected]>
1 parent 04e0c8b commit 7b617a7

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

src/utils/SkShadowTessellator.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,6 +1005,10 @@ SkSpotShadowTessellator::SkSpotShadowTessellator(const SkPath& path, const SkMat
10051005
// get rotated quad in 3D
10061006
SkPoint pts[4];
10071007
ctm.mapRectToQuad(pts, pathBounds);
1008+
// No shadows for bowties or other degenerate cases
1009+
if (!SkIsConvexPolygon(pts, 4)) {
1010+
return;
1011+
}
10081012
SkPoint3 pts3D[4];
10091013
SkScalar z = this->heightFunc(pathBounds.fLeft, pathBounds.fTop);
10101014
pts3D[0].set(pts[0].fX, pts[0].fY, z);
@@ -1017,20 +1021,30 @@ SkSpotShadowTessellator::SkSpotShadowTessellator(const SkPath& path, const SkMat
10171021

10181022
// project from light through corners to z=0 plane
10191023
for (int i = 0; i < 4; ++i) {
1020-
SkScalar zRatio = pts3D[i].fZ / (lightPos.fZ - pts3D[i].fZ);
1024+
SkScalar dz = lightPos.fZ - pts3D[i].fZ;
1025+
// light shouldn't be below or at a corner's z-location
1026+
if (dz <= SK_ScalarNearlyZero) {
1027+
return;
1028+
}
1029+
SkScalar zRatio = pts3D[i].fZ / dz;
10211030
pts3D[i].fX -= (lightPos.fX - pts3D[i].fX)*zRatio;
10221031
pts3D[i].fY -= (lightPos.fY - pts3D[i].fY)*zRatio;
10231032
pts3D[i].fZ = SK_Scalar1;
10241033
}
10251034

10261035
// Generate matrix that projects from [-1,1]x[-1,1] square to projected quad
10271036
SkPoint3 h0, h1, h2;
1028-
// Compute crossing point between top and bottom edges (gives new x-axis).
1037+
// Compute homogenous crossing point between top and bottom edges (gives new x-axis).
10291038
h0 = (pts3D[1].cross(pts3D[0])).cross(pts3D[2].cross(pts3D[3]));
1030-
// Compute crossing point between left and right edges (gives new y-axis).
1039+
// Compute homogenous crossing point between left and right edges (gives new y-axis).
10311040
h1 = (pts3D[0].cross(pts3D[3])).cross(pts3D[1].cross(pts3D[2]));
1032-
// Compute crossing point between diagonals (gives new origin).
1041+
// Compute homogenous crossing point between diagonals (gives new origin).
10331042
h2 = (pts3D[0].cross(pts3D[2])).cross(pts3D[1].cross(pts3D[3]));
1043+
// If h2 is a vector (z=0 in 2D homogeneous space), that means that at least
1044+
// two of the quad corners are coincident and we don't have a realistic projection
1045+
if (SkScalarNearlyZero(h2.fZ)) {
1046+
return;
1047+
}
10341048
// In some cases the crossing points are in the wrong direction
10351049
// to map (-1,-1) to pts3D[0], so we need to correct for that.
10361050
// Want h0 to be to the right of the left edge.

0 commit comments

Comments
 (0)