OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkLightingImageFilter.h" | 8 #include "SkLightingImageFilter.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 | 57 |
58 class DiffuseLightingType { | 58 class DiffuseLightingType { |
59 public: | 59 public: |
60 DiffuseLightingType(SkScalar kd) | 60 DiffuseLightingType(SkScalar kd) |
61 : fKD(kd) {} | 61 : fKD(kd) {} |
62 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, cons
t SkPoint3& lightColor) const { | 62 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, cons
t SkPoint3& lightColor) const { |
63 SkScalar colorScale = SkScalarMul(fKD, normal.dot(surfaceTolight)); | 63 SkScalar colorScale = SkScalarMul(fKD, normal.dot(surfaceTolight)); |
64 colorScale = SkScalarClampMax(colorScale, SK_Scalar1); | 64 colorScale = SkScalarClampMax(colorScale, SK_Scalar1); |
65 SkPoint3 color(lightColor * colorScale); | 65 SkPoint3 color(lightColor * colorScale); |
66 return SkPackARGB32(255, | 66 return SkPackARGB32(255, |
67 SkScalarFloorToInt(color.fX), | 67 SkClampMax(SkScalarFloorToInt(color.fX), 255), |
68 SkScalarFloorToInt(color.fY), | 68 SkClampMax(SkScalarFloorToInt(color.fY), 255), |
69 SkScalarFloorToInt(color.fZ)); | 69 SkClampMax(SkScalarFloorToInt(color.fZ), 255)); |
70 } | 70 } |
71 private: | 71 private: |
72 SkScalar fKD; | 72 SkScalar fKD; |
73 }; | 73 }; |
74 | 74 |
75 class SpecularLightingType { | 75 class SpecularLightingType { |
76 public: | 76 public: |
77 SpecularLightingType(SkScalar ks, SkScalar shininess) | 77 SpecularLightingType(SkScalar ks, SkScalar shininess) |
78 : fKS(ks), fShininess(shininess) {} | 78 : fKS(ks), fShininess(shininess) {} |
79 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, cons
t SkPoint3& lightColor) const { | 79 SkPMColor light(const SkPoint3& normal, const SkPoint3& surfaceTolight, cons
t SkPoint3& lightColor) const { |
80 SkPoint3 halfDir(surfaceTolight); | 80 SkPoint3 halfDir(surfaceTolight); |
81 halfDir.fZ += SK_Scalar1; // eye position is always (0, 0, 1) | 81 halfDir.fZ += SK_Scalar1; // eye position is always (0, 0, 1) |
82 halfDir.normalize(); | 82 halfDir.normalize(); |
83 SkScalar colorScale = SkScalarMul(fKS, | 83 SkScalar colorScale = SkScalarMul(fKS, |
84 SkScalarPow(normal.dot(halfDir), fShininess)); | 84 SkScalarPow(normal.dot(halfDir), fShininess)); |
85 colorScale = SkScalarClampMax(colorScale, SK_Scalar1); | 85 colorScale = SkScalarClampMax(colorScale, SK_Scalar1); |
86 SkPoint3 color(lightColor * colorScale); | 86 SkPoint3 color(lightColor * colorScale); |
87 return SkPackARGB32(SkScalarFloorToInt(color.maxComponent()), | 87 return SkPackARGB32(SkClampMax(SkScalarFloorToInt(color.maxComponent()),
255), |
88 SkScalarFloorToInt(color.fX), | 88 SkClampMax(SkScalarFloorToInt(color.fX), 255), |
89 SkScalarFloorToInt(color.fY), | 89 SkClampMax(SkScalarFloorToInt(color.fY), 255), |
90 SkScalarFloorToInt(color.fZ)); | 90 SkClampMax(SkScalarFloorToInt(color.fZ), 255)); |
91 } | 91 } |
92 private: | 92 private: |
93 SkScalar fKS; | 93 SkScalar fKS; |
94 SkScalar fShininess; | 94 SkScalar fShininess; |
95 }; | 95 }; |
96 | 96 |
97 inline SkScalar sobel(int a, int b, int c, int d, int e, int f, SkScalar scale)
{ | 97 inline SkScalar sobel(int a, int b, int c, int d, int e, int f, SkScalar scale)
{ |
98 return SkScalarMul(SkIntToScalar(-a + b - 2 * c + 2 * d -e + f), scale); | 98 return SkScalarMul(SkIntToScalar(-a + b - 2 * c + 2 * d -e + f), scale); |
99 } | 99 } |
100 | 100 |
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 }; | 653 }; |
654 | 654 |
655 /////////////////////////////////////////////////////////////////////////////// | 655 /////////////////////////////////////////////////////////////////////////////// |
656 | 656 |
657 class SkSpotLight : public SkLight { | 657 class SkSpotLight : public SkLight { |
658 public: | 658 public: |
659 SkSpotLight(const SkPoint3& location, const SkPoint3& target, SkScalar specu
larExponent, SkScalar cutoffAngle, SkColor color) | 659 SkSpotLight(const SkPoint3& location, const SkPoint3& target, SkScalar specu
larExponent, SkScalar cutoffAngle, SkColor color) |
660 : INHERITED(color), | 660 : INHERITED(color), |
661 fLocation(location), | 661 fLocation(location), |
662 fTarget(target), | 662 fTarget(target), |
663 fSpecularExponent(specularExponent) | 663 fSpecularExponent(SkScalarPin(specularExponent, kSpecularExponentMin, kSp
ecularExponentMax)) |
664 { | 664 { |
665 fS = target - location; | 665 fS = target - location; |
666 fS.normalize(); | 666 fS.normalize(); |
667 fCosOuterConeAngle = SkScalarCos(SkDegreesToRadians(cutoffAngle)); | 667 fCosOuterConeAngle = SkScalarCos(SkDegreesToRadians(cutoffAngle)); |
668 const SkScalar antiAliasThreshold = SkFloatToScalar(0.016f); | 668 const SkScalar antiAliasThreshold = SkFloatToScalar(0.016f); |
669 fCosInnerConeAngle = fCosOuterConeAngle + antiAliasThreshold; | 669 fCosInnerConeAngle = fCosOuterConeAngle + antiAliasThreshold; |
670 fConeScale = SkScalarInvert(antiAliasThreshold); | 670 fConeScale = SkScalarInvert(antiAliasThreshold); |
671 } | 671 } |
672 | 672 |
673 SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const { | 673 SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
737 | 737 |
738 const SkSpotLight& o = static_cast<const SkSpotLight&>(other); | 738 const SkSpotLight& o = static_cast<const SkSpotLight&>(other); |
739 return INHERITED::isEqual(other) && | 739 return INHERITED::isEqual(other) && |
740 fLocation == o.fLocation && | 740 fLocation == o.fLocation && |
741 fTarget == o.fTarget && | 741 fTarget == o.fTarget && |
742 fSpecularExponent == o.fSpecularExponent && | 742 fSpecularExponent == o.fSpecularExponent && |
743 fCosOuterConeAngle == o.fCosOuterConeAngle; | 743 fCosOuterConeAngle == o.fCosOuterConeAngle; |
744 } | 744 } |
745 | 745 |
746 private: | 746 private: |
| 747 static const SkScalar kSpecularExponentMin; |
| 748 static const SkScalar kSpecularExponentMax; |
| 749 |
747 typedef SkLight INHERITED; | 750 typedef SkLight INHERITED; |
748 SkPoint3 fLocation; | 751 SkPoint3 fLocation; |
749 SkPoint3 fTarget; | 752 SkPoint3 fTarget; |
750 SkScalar fSpecularExponent; | 753 SkScalar fSpecularExponent; |
751 SkScalar fCosOuterConeAngle; | 754 SkScalar fCosOuterConeAngle; |
752 SkScalar fCosInnerConeAngle; | 755 SkScalar fCosInnerConeAngle; |
753 SkScalar fConeScale; | 756 SkScalar fConeScale; |
754 SkPoint3 fS; | 757 SkPoint3 fS; |
755 }; | 758 }; |
756 | 759 |
| 760 // According to the spec, the specular term should be in the range [1, 128] : |
| 761 // http://www.w3.org/TR/SVG/filters.html#feSpecularLightingSpecularExponentAttri
bute |
| 762 const SkScalar SkSpotLight::kSpecularExponentMin = SkFloatToScalar(1.0f); |
| 763 const SkScalar SkSpotLight::kSpecularExponentMax = SkFloatToScalar(128.0f); |
| 764 |
757 /////////////////////////////////////////////////////////////////////////////// | 765 /////////////////////////////////////////////////////////////////////////////// |
758 | 766 |
759 SkLightingImageFilter::SkLightingImageFilter(SkLight* light, SkScalar surfaceSca
le, SkImageFilter* input, const SkIRect* cropRect) | 767 SkLightingImageFilter::SkLightingImageFilter(SkLight* light, SkScalar surfaceSca
le, SkImageFilter* input, const SkIRect* cropRect) |
760 : INHERITED(input, cropRect), | 768 : INHERITED(input, cropRect), |
761 fLight(light), | 769 fLight(light), |
762 fSurfaceScale(SkScalarDiv(surfaceScale, SkIntToScalar(255))) | 770 fSurfaceScale(SkScalarDiv(surfaceScale, SkIntToScalar(255))) |
763 { | 771 { |
764 SkASSERT(fLight); | 772 SkASSERT(fLight); |
765 // our caller knows that we take ownership of the light, so we don't | 773 // our caller knows that we take ownership of the light, so we don't |
766 // need to call ref() here. | 774 // need to call ref() here. |
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1538 | 1546 |
1539 #endif | 1547 #endif |
1540 | 1548 |
1541 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingImageFilter) | 1549 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingImageFilter) |
1542 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiffuseLightingImageFilter) | 1550 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiffuseLightingImageFilter) |
1543 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpecularLightingImageFilter) | 1551 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpecularLightingImageFilter) |
1544 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDistantLight) | 1552 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDistantLight) |
1545 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPointLight) | 1553 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPointLight) |
1546 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpotLight) | 1554 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpotLight) |
1547 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1555 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |