OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
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 "SkDither.h" | 8 #include "SkDither.h" |
9 #include "SkPerlinNoiseShader2.h" | 9 #include "SkPerlinNoiseShader2.h" |
10 #include "SkColorFilter.h" | 10 #include "SkColorFilter.h" |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 point.fX += SK_Scalar1; | 602 point.fX += SK_Scalar1; |
603 } | 603 } |
604 } | 604 } |
605 | 605 |
606 ///////////////////////////////////////////////////////////////////// | 606 ///////////////////////////////////////////////////////////////////// |
607 | 607 |
608 #if SK_SUPPORT_GPU | 608 #if SK_SUPPORT_GPU |
609 | 609 |
610 class GrGLPerlinNoise2 : public GrGLSLFragmentProcessor { | 610 class GrGLPerlinNoise2 : public GrGLSLFragmentProcessor { |
611 public: | 611 public: |
612 GrGLPerlinNoise2(const GrProcessor&); | |
613 | |
614 void emitCode(EmitArgs&) override; | 612 void emitCode(EmitArgs&) override; |
615 | 613 |
616 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder* b); | 614 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder* b); |
617 | 615 |
618 protected: | 616 protected: |
619 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override
; | 617 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override
; |
620 | 618 |
621 private: | 619 private: |
622 | |
623 GrGLSLProgramDataManager::UniformHandle fStitchDataUni; | 620 GrGLSLProgramDataManager::UniformHandle fStitchDataUni; |
624 SkPerlinNoiseShader2::Type fType; | |
625 bool fStitchTiles; | |
626 int fNumOctaves; | |
627 GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni; | 621 GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni; |
628 | 622 |
629 private: | |
630 typedef GrGLSLFragmentProcessor INHERITED; | 623 typedef GrGLSLFragmentProcessor INHERITED; |
631 }; | 624 }; |
632 | 625 |
633 ///////////////////////////////////////////////////////////////////// | 626 ///////////////////////////////////////////////////////////////////// |
634 | 627 |
635 class GrPerlinNoise2Effect : public GrFragmentProcessor { | 628 class GrPerlinNoise2Effect : public GrFragmentProcessor { |
636 public: | 629 public: |
637 static GrFragmentProcessor* Create(SkPerlinNoiseShader2::Type type, | 630 static GrFragmentProcessor* Create(SkPerlinNoiseShader2::Type type, |
638 int numOctaves, bool stitchTiles, | 631 int numOctaves, bool stitchTiles, |
639 SkPerlinNoiseShader2::PaintingData* paint
ingData, | 632 SkPerlinNoiseShader2::PaintingData* paint
ingData, |
(...skipping 10 matching lines...) Expand all Loading... |
650 const SkPerlinNoiseShader2::StitchData& stitchData() const { return fPaintin
gData->fStitchDataInit; } | 643 const SkPerlinNoiseShader2::StitchData& stitchData() const { return fPaintin
gData->fStitchDataInit; } |
651 | 644 |
652 SkPerlinNoiseShader2::Type type() const { return fType; } | 645 SkPerlinNoiseShader2::Type type() const { return fType; } |
653 bool stitchTiles() const { return fStitchTiles; } | 646 bool stitchTiles() const { return fStitchTiles; } |
654 const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency
; } | 647 const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency
; } |
655 int numOctaves() const { return fNumOctaves; } | 648 int numOctaves() const { return fNumOctaves; } |
656 const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); } | 649 const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); } |
657 | 650 |
658 private: | 651 private: |
659 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { | 652 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { |
660 return new GrGLPerlinNoise2(*this); | 653 return new GrGLPerlinNoise2; |
661 } | 654 } |
662 | 655 |
663 virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps, | 656 virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps, |
664 GrProcessorKeyBuilder* b) const override
{ | 657 GrProcessorKeyBuilder* b) const override
{ |
665 GrGLPerlinNoise2::GenKey(*this, caps, b); | 658 GrGLPerlinNoise2::GenKey(*this, caps, b); |
666 } | 659 } |
667 | 660 |
668 bool onIsEqual(const GrFragmentProcessor& sBase) const override { | 661 bool onIsEqual(const GrFragmentProcessor& sBase) const override { |
669 const GrPerlinNoise2Effect& s = sBase.cast<GrPerlinNoise2Effect>(); | 662 const GrPerlinNoise2Effect& s = sBase.cast<GrPerlinNoise2Effect>(); |
670 return fType == s.fType && | 663 return fType == s.fType && |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
729 stitchTiles ? &tileSize : nullpt
r) : | 722 stitchTiles ? &tileSize : nullpt
r) : |
730 SkPerlinNoiseShader2::CreateTurbulence(baseFrequencyX, baseFrequencyY, n
umOctaves, seed, | 723 SkPerlinNoiseShader2::CreateTurbulence(baseFrequencyX, baseFrequencyY, n
umOctaves, seed, |
731 stitchTiles ? &tileSize : nullptr))
; | 724 stitchTiles ? &tileSize : nullptr))
; |
732 | 725 |
733 GrPaint grPaint; | 726 GrPaint grPaint; |
734 return shader->asFragmentProcessor(d->fContext, | 727 return shader->asFragmentProcessor(d->fContext, |
735 GrTest::TestMatrix(d->fRandom), nullptr, | 728 GrTest::TestMatrix(d->fRandom), nullptr, |
736 kNone_SkFilterQuality); | 729 kNone_SkFilterQuality); |
737 } | 730 } |
738 | 731 |
739 GrGLPerlinNoise2::GrGLPerlinNoise2(const GrProcessor& processor) | 732 void GrGLPerlinNoise2::emitCode(EmitArgs& args) { |
740 : fType(processor.cast<GrPerlinNoise2Effect>().type()) | 733 const GrPerlinNoise2Effect& pne = args.fFp.cast<GrPerlinNoise2Effect>(); |
741 , fStitchTiles(processor.cast<GrPerlinNoise2Effect>().stitchTiles()) | |
742 , fNumOctaves(processor.cast<GrPerlinNoise2Effect>().numOctaves()) { | |
743 } | |
744 | 734 |
745 void GrGLPerlinNoise2::emitCode(EmitArgs& args) { | |
746 GrGLSLFragmentBuilder* fsBuilder = args.fFragBuilder; | 735 GrGLSLFragmentBuilder* fsBuilder = args.fFragBuilder; |
747 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; | 736 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; |
748 SkString vCoords = fsBuilder->ensureFSCoords2D(args.fCoords, 0); | 737 SkString vCoords = fsBuilder->ensureFSCoords2D(args.fCoords, 0); |
749 | 738 |
750 fBaseFrequencyUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragme
nt_Visibility, | 739 fBaseFrequencyUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragme
nt_Visibility, |
751 kVec2f_GrSLType, kDefault_GrS
LPrecision, | 740 kVec2f_GrSLType, kDefault_GrS
LPrecision, |
752 "baseFrequency"); | 741 "baseFrequency"); |
753 const char* baseFrequencyUni = uniformHandler->getUniformCStr(fBaseFrequency
Uni); | 742 const char* baseFrequencyUni = uniformHandler->getUniformCStr(fBaseFrequency
Uni); |
754 | 743 |
755 const char* stitchDataUni = nullptr; | 744 const char* stitchDataUni = nullptr; |
756 if (fStitchTiles) { | 745 if (pne.stitchTiles()) { |
757 fStitchDataUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragm
ent_Visibility, | 746 fStitchDataUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragm
ent_Visibility, |
758 kVec2f_GrSLType, kDefault_Gr
SLPrecision, | 747 kVec2f_GrSLType, kDefault_Gr
SLPrecision, |
759 "stitchData"); | 748 "stitchData"); |
760 stitchDataUni = uniformHandler->getUniformCStr(fStitchDataUni); | 749 stitchDataUni = uniformHandler->getUniformCStr(fStitchDataUni); |
761 } | 750 } |
762 | 751 |
763 // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8 | 752 // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8 |
764 const char* chanCoordR = "0.125"; | 753 const char* chanCoordR = "0.125"; |
765 const char* chanCoordG = "0.375"; | 754 const char* chanCoordG = "0.375"; |
766 const char* chanCoordB = "0.625"; | 755 const char* chanCoordB = "0.625"; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 noiseCode.appendf("\tvec4 %s;\n", floorVal); | 788 noiseCode.appendf("\tvec4 %s;\n", floorVal); |
800 noiseCode.appendf("\t%s.xy = floor(%s);\n", floorVal, noiseVec); | 789 noiseCode.appendf("\t%s.xy = floor(%s);\n", floorVal, noiseVec); |
801 noiseCode.appendf("\t%s.zw = %s.xy + vec2(1.0);\n", floorVal, floorVal); | 790 noiseCode.appendf("\t%s.zw = %s.xy + vec2(1.0);\n", floorVal, floorVal); |
802 noiseCode.appendf("\tvec2 %s = fract(%s);\n", fractVal, noiseVec); | 791 noiseCode.appendf("\tvec2 %s = fract(%s);\n", fractVal, noiseVec); |
803 | 792 |
804 // smooth curve : t * t * (3 - 2 * t) | 793 // smooth curve : t * t * (3 - 2 * t) |
805 noiseCode.appendf("\n\tvec2 %s = %s * %s * (vec2(3.0) - vec2(2.0) * %s);", | 794 noiseCode.appendf("\n\tvec2 %s = %s * %s * (vec2(3.0) - vec2(2.0) * %s);", |
806 noiseSmooth, fractVal, fractVal, fractVal); | 795 noiseSmooth, fractVal, fractVal, fractVal); |
807 | 796 |
808 // Adjust frequencies if we're stitching tiles | 797 // Adjust frequencies if we're stitching tiles |
809 if (fStitchTiles) { | 798 if (pne.stitchTiles()) { |
810 noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }", | 799 noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }", |
811 floorVal, stitchData, floorVal, stitchData); | 800 floorVal, stitchData, floorVal, stitchData); |
812 noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }", | 801 noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }", |
813 floorVal, stitchData, floorVal, stitchData); | 802 floorVal, stitchData, floorVal, stitchData); |
814 noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }", | 803 noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }", |
815 floorVal, stitchData, floorVal, stitchData); | 804 floorVal, stitchData, floorVal, stitchData); |
816 noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }", | 805 noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }", |
817 floorVal, stitchData, floorVal, stitchData); | 806 floorVal, stitchData, floorVal, stitchData); |
818 } | 807 } |
819 | 808 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 noiseCode.appendf(".bgra;\n\t%s.x = ", uv); | 897 noiseCode.appendf(".bgra;\n\t%s.x = ", uv); |
909 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); | 898 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); |
910 } | 899 } |
911 | 900 |
912 // Compute 'b' as a linear interpolation of 'u' and 'v' | 901 // Compute 'b' as a linear interpolation of 'u' and 'v' |
913 noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmoo
th); | 902 noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmoo
th); |
914 // Compute the noise as a linear interpolation of 'a' and 'b' | 903 // Compute the noise as a linear interpolation of 'a' and 'b' |
915 noiseCode.appendf("\n\treturn mix(%s.x, %s.y, %s.y);\n", ab, ab, noiseSmooth
); | 904 noiseCode.appendf("\n\treturn mix(%s.x, %s.y, %s.y);\n", ab, ab, noiseSmooth
); |
916 | 905 |
917 SkString noiseFuncName; | 906 SkString noiseFuncName; |
918 if (fStitchTiles) { | 907 if (pne.stitchTiles()) { |
919 fsBuilder->emitFunction(kFloat_GrSLType, | 908 fsBuilder->emitFunction(kFloat_GrSLType, |
920 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStitch
Args), | 909 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStitch
Args), |
921 gPerlinNoiseStitchArgs, noiseCode.c_str(), &nois
eFuncName); | 910 gPerlinNoiseStitchArgs, noiseCode.c_str(), &nois
eFuncName); |
922 } else { | 911 } else { |
923 fsBuilder->emitFunction(kFloat_GrSLType, | 912 fsBuilder->emitFunction(kFloat_GrSLType, |
924 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs), | 913 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs), |
925 gPerlinNoiseArgs, noiseCode.c_str(), &noiseFuncN
ame); | 914 gPerlinNoiseArgs, noiseCode.c_str(), &noiseFuncN
ame); |
926 } | 915 } |
927 | 916 |
928 // There are rounding errors if the floor operation is not performed here | 917 // There are rounding errors if the floor operation is not performed here |
929 fsBuilder->codeAppendf("\n\t\tvec2 %s = floor(%s.xy) * %s;", | 918 fsBuilder->codeAppendf("\n\t\tvec2 %s = floor(%s.xy) * %s;", |
930 noiseVec, vCoords.c_str(), baseFrequencyUni); | 919 noiseVec, vCoords.c_str(), baseFrequencyUni); |
931 | 920 |
932 // Clear the color accumulator | 921 // Clear the color accumulator |
933 fsBuilder->codeAppendf("\n\t\t%s = vec4(0.0);", args.fOutputColor); | 922 fsBuilder->codeAppendf("\n\t\t%s = vec4(0.0);", args.fOutputColor); |
934 | 923 |
935 if (fStitchTiles) { | 924 if (pne.stitchTiles()) { |
936 // Set up TurbulenceInitial stitch values. | 925 // Set up TurbulenceInitial stitch values. |
937 fsBuilder->codeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni)
; | 926 fsBuilder->codeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni)
; |
938 } | 927 } |
939 | 928 |
940 fsBuilder->codeAppendf("\n\t\tfloat %s = 1.0;", ratio); | 929 fsBuilder->codeAppendf("\n\t\tfloat %s = 1.0;", ratio); |
941 | 930 |
942 // Loop over all octaves | 931 // Loop over all octaves |
943 fsBuilder->codeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave) {"
, fNumOctaves); | 932 fsBuilder->codeAppendf("for (int octave = 0; octave < %d; ++octave) {", pne.
numOctaves()); |
944 | 933 |
945 fsBuilder->codeAppendf("\n\t\t\t%s += ", args.fOutputColor); | 934 fsBuilder->codeAppendf("\n\t\t\t%s += ", args.fOutputColor); |
946 if (fType != SkPerlinNoiseShader2::kFractalNoise_Type) { | 935 if (pne.type() != SkPerlinNoiseShader2::kFractalNoise_Type) { |
947 fsBuilder->codeAppend("abs("); | 936 fsBuilder->codeAppend("abs("); |
948 } | 937 } |
949 if (fStitchTiles) { | 938 if (pne.stitchTiles()) { |
950 fsBuilder->codeAppendf( | 939 fsBuilder->codeAppendf( |
951 "vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s)," | 940 "vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s)," |
952 "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))", | 941 "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))", |
953 noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData, | 942 noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData, |
954 noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData, | 943 noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData, |
955 noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData, | 944 noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData, |
956 noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData); | 945 noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData); |
957 } else { | 946 } else { |
958 fsBuilder->codeAppendf( | 947 fsBuilder->codeAppendf( |
959 "vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s)," | 948 "vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s)," |
960 "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))", | 949 "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))", |
961 noiseFuncName.c_str(), chanCoordR, noiseVec, | 950 noiseFuncName.c_str(), chanCoordR, noiseVec, |
962 noiseFuncName.c_str(), chanCoordG, noiseVec, | 951 noiseFuncName.c_str(), chanCoordG, noiseVec, |
963 noiseFuncName.c_str(), chanCoordB, noiseVec, | 952 noiseFuncName.c_str(), chanCoordB, noiseVec, |
964 noiseFuncName.c_str(), chanCoordA, noiseVec); | 953 noiseFuncName.c_str(), chanCoordA, noiseVec); |
965 } | 954 } |
966 if (fType != SkPerlinNoiseShader2::kFractalNoise_Type) { | 955 if (pne.type() != SkPerlinNoiseShader2::kFractalNoise_Type) { |
967 fsBuilder->codeAppendf(")"); // end of "abs(" | 956 fsBuilder->codeAppendf(")"); // end of "abs(" |
968 } | 957 } |
969 fsBuilder->codeAppendf(" * %s;", ratio); | 958 fsBuilder->codeAppendf(" * %s;", ratio); |
970 | 959 |
971 fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec); | 960 fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec); |
972 fsBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio); | 961 fsBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio); |
973 | 962 |
974 if (fStitchTiles) { | 963 if (pne.stitchTiles()) { |
975 fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData); | 964 fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData); |
976 } | 965 } |
977 fsBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves | 966 fsBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves |
978 | 967 |
979 if (fType == SkPerlinNoiseShader2::kFractalNoise_Type) { | 968 if (pne.type() == SkPerlinNoiseShader2::kFractalNoise_Type) { |
980 // The value of turbulenceFunctionResult comes from ((turbulenceFunction
Result) + 1) / 2 | 969 // The value of turbulenceFunctionResult comes from ((turbulenceFunction
Result) + 1) / 2 |
981 // by fractalNoise and (turbulenceFunctionResult) by turbulence. | 970 // by fractalNoise and (turbulenceFunctionResult) by turbulence. |
982 fsBuilder->codeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);", | 971 fsBuilder->codeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);", |
983 args.fOutputColor,args.fOutputColor); | 972 args.fOutputColor,args.fOutputColor); |
984 } | 973 } |
985 | 974 |
986 // Clamp values | 975 // Clamp values |
987 fsBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", args.fOutputColor,
args.fOutputColor); | 976 fsBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", args.fOutputColor,
args.fOutputColor); |
988 | 977 |
989 // Pre-multiply the result | 978 // Pre-multiply the result |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1404 str->append(" seed: "); | 1393 str->append(" seed: "); |
1405 str->appendScalar(fSeed); | 1394 str->appendScalar(fSeed); |
1406 str->append(" stitch tiles: "); | 1395 str->append(" stitch tiles: "); |
1407 str->append(fStitchTiles ? "true " : "false "); | 1396 str->append(fStitchTiles ? "true " : "false "); |
1408 | 1397 |
1409 this->INHERITED::toString(str); | 1398 this->INHERITED::toString(str); |
1410 | 1399 |
1411 str->append(")"); | 1400 str->append(")"); |
1412 } | 1401 } |
1413 #endif | 1402 #endif |
OLD | NEW |