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 "SkPerlinNoiseShader.h" | 9 #include "SkPerlinNoiseShader2.h" |
10 #include "SkColorFilter.h" | 10 #include "SkColorFilter.h" |
11 #include "SkReadBuffer.h" | 11 #include "SkReadBuffer.h" |
12 #include "SkWriteBuffer.h" | 12 #include "SkWriteBuffer.h" |
13 #include "SkShader.h" | 13 #include "SkShader.h" |
14 #include "SkUnPreMultiply.h" | 14 #include "SkUnPreMultiply.h" |
15 #include "SkString.h" | 15 #include "SkString.h" |
16 | 16 |
17 #if SK_SUPPORT_GPU | 17 #if SK_SUPPORT_GPU |
18 #include "GrContext.h" | 18 #include "GrContext.h" |
19 #include "GrCoordTransform.h" | 19 #include "GrCoordTransform.h" |
20 #include "GrInvariantOutput.h" | 20 #include "GrInvariantOutput.h" |
21 #include "SkGr.h" | 21 #include "SkGr.h" |
22 #include "effects/GrConstColorProcessor.h" | 22 #include "effects/GrConstColorProcessor.h" |
23 #include "gl/GrGLFragmentProcessor.h" | 23 #include "gl/GrGLFragmentProcessor.h" |
24 #include "gl/builders/GrGLProgramBuilder.h" | 24 #include "gl/builders/GrGLProgramBuilder.h" |
25 #include "glsl/GrGLSLProgramDataManager.h" | 25 #include "glsl/GrGLSLProgramDataManager.h" |
26 #endif | 26 #endif |
27 | 27 |
28 static const int kBlockSize = 256; | 28 static const int kBlockSize = 256; |
29 static const int kBlockMask = kBlockSize - 1; | 29 static const int kBlockMask = kBlockSize - 1; |
30 static const int kPerlinNoise = 4096; | 30 static const int kPerlinNoise = 4096; |
31 static const int kRandMaximum = SK_MaxS32; // 2**31 - 1 | 31 static const int kRandMaximum = SK_MaxS32; // 2**31 - 1 |
32 | 32 |
| 33 static uint8_t improved_noise_permutations[] = { |
| 34 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 2
25, 140, 36, 103, |
| 35 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 2
34, 75, 0, 26, |
| 36 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 1
49, 56, 87, 174, |
| 37 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166,
77, 146, 158, 231, |
| 38 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245,
40, 244, 102, 143, |
| 39 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89,
18, 169, 200, 196, |
| 40 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 2
17, 226, 250, 124, |
| 41 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227,
47, 16, 58, 17, |
| 42 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163,
70, 221, 153, 101, |
| 43 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 2
24, 232, 178, 185, |
| 44 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 1
79, 162, 241, 81, |
| 45 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 1
84, 84, 204, 176, |
| 46 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67,
29, 24, 72, 243, |
| 47 141, 128, 195, 78, 66, 215, 61, 156, 180, |
| 48 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 2
25, 140, 36, 103, |
| 49 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 2
34, 75, 0, 26, |
| 50 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 1
49, 56, 87, 174, |
| 51 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166,
77, 146, 158, 231, |
| 52 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245,
40, 244, 102, 143, |
| 53 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89,
18, 169, 200, 196, |
| 54 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 2
17, 226, 250, 124, |
| 55 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227,
47, 16, 58, 17, |
| 56 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163,
70, 221, 153, 101, |
| 57 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 2
24, 232, 178, 185, |
| 58 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 1
79, 162, 241, 81, |
| 59 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 1
84, 84, 204, 176, |
| 60 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67,
29, 24, 72, 243, |
| 61 141, 128, 195, 78, 66, 215, 61, 156, 180 |
| 62 }; |
| 63 |
33 namespace { | 64 namespace { |
34 | 65 |
35 // noiseValue is the color component's value (or color) | 66 // noiseValue is the color component's value (or color) |
36 // limitValue is the maximum perlin noise array index value allowed | 67 // limitValue is the maximum perlin noise array index value allowed |
37 // newValue is the current noise dimension (either width or height) | 68 // newValue is the current noise dimension (either width or height) |
38 inline int checkNoise(int noiseValue, int limitValue, int newValue) { | 69 inline int checkNoise(int noiseValue, int limitValue, int newValue) { |
39 // If the noise value would bring us out of bounds of the current noise arra
y while we are | 70 // If the noise value would bring us out of bounds of the current noise arra
y while we are |
40 // stiching noise tiles together, wrap the noise around the current dimensio
n of the noise to | 71 // stiching noise tiles together, wrap the noise around the current dimensio
n of the noise to |
41 // stay within the array bounds in a continuous fashion (so that tiling line
s are not visible) | 72 // stay within the array bounds in a continuous fashion (so that tiling line
s are not visible) |
42 if (noiseValue >= limitValue) { | 73 if (noiseValue >= limitValue) { |
43 noiseValue -= newValue; | 74 noiseValue -= newValue; |
44 } | 75 } |
45 return noiseValue; | 76 return noiseValue; |
46 } | 77 } |
47 | 78 |
48 inline SkScalar smoothCurve(SkScalar t) { | 79 inline SkScalar smoothCurve(SkScalar t) { |
49 static const SkScalar SK_Scalar3 = 3.0f; | 80 static const SkScalar SK_Scalar3 = 3.0f; |
50 | 81 |
51 // returns t * t * (3 - 2 * t) | 82 // returns t * t * (3 - 2 * t) |
52 return SkScalarMul(SkScalarSquare(t), SK_Scalar3 - 2 * t); | 83 return SkScalarMul(SkScalarSquare(t), SK_Scalar3 - 2 * t); |
53 } | 84 } |
54 | 85 |
55 } // end namespace | 86 } // end namespace |
56 | 87 |
57 struct SkPerlinNoiseShader::StitchData { | 88 struct SkPerlinNoiseShader2::StitchData { |
58 StitchData() | 89 StitchData() |
59 : fWidth(0) | 90 : fWidth(0) |
60 , fWrapX(0) | 91 , fWrapX(0) |
61 , fHeight(0) | 92 , fHeight(0) |
62 , fWrapY(0) | 93 , fWrapY(0) |
63 {} | 94 {} |
64 | 95 |
65 bool operator==(const StitchData& other) const { | 96 bool operator==(const StitchData& other) const { |
66 return fWidth == other.fWidth && | 97 return fWidth == other.fWidth && |
67 fWrapX == other.fWrapX && | 98 fWrapX == other.fWrapX && |
68 fHeight == other.fHeight && | 99 fHeight == other.fHeight && |
69 fWrapY == other.fWrapY; | 100 fWrapY == other.fWrapY; |
70 } | 101 } |
71 | 102 |
72 int fWidth; // How much to subtract to wrap for stitching. | 103 int fWidth; // How much to subtract to wrap for stitching. |
73 int fWrapX; // Minimum value to wrap. | 104 int fWrapX; // Minimum value to wrap. |
74 int fHeight; | 105 int fHeight; |
75 int fWrapY; | 106 int fWrapY; |
76 }; | 107 }; |
77 | 108 |
78 struct SkPerlinNoiseShader::PaintingData { | 109 struct SkPerlinNoiseShader2::PaintingData { |
79 PaintingData(const SkISize& tileSize, SkScalar seed, | 110 PaintingData(const SkISize& tileSize, SkScalar seed, |
80 SkScalar baseFrequencyX, SkScalar baseFrequencyY, | 111 SkScalar baseFrequencyX, SkScalar baseFrequencyY, |
81 const SkMatrix& matrix) | 112 const SkMatrix& matrix) |
82 { | 113 { |
83 SkVector vec[2] = { | 114 SkVector vec[2] = { |
84 { SkScalarInvert(baseFrequencyX), SkScalarInvert(baseFrequencyY)
}, | 115 { SkScalarInvert(baseFrequencyX), SkScalarInvert(baseFrequencyY)
}, |
85 { SkIntToScalar(tileSize.fWidth), SkIntToScalar(tileSize.fHeight)
}, | 116 { SkIntToScalar(tileSize.fWidth), SkIntToScalar(tileSize.fHeight)
}, |
86 }; | 117 }; |
87 matrix.mapVectors(vec, 2); | 118 matrix.mapVectors(vec, 2); |
88 | 119 |
89 fBaseFrequency.set(SkScalarInvert(vec[0].fX), SkScalarInvert(vec[0].fY))
; | 120 fBaseFrequency.set(SkScalarInvert(vec[0].fX), SkScalarInvert(vec[0].fY))
; |
90 fTileSize.set(SkScalarRoundToInt(vec[1].fX), SkScalarRoundToInt(vec[1].f
Y)); | 121 fTileSize.set(SkScalarRoundToInt(vec[1].fX), SkScalarRoundToInt(vec[1].f
Y)); |
91 this->init(seed); | 122 this->init(seed); |
92 if (!fTileSize.isEmpty()) { | 123 if (!fTileSize.isEmpty()) { |
93 this->stitch(); | 124 this->stitch(); |
94 } | 125 } |
95 | 126 |
96 #if SK_SUPPORT_GPU | 127 #if SK_SUPPORT_GPU |
97 fPermutationsBitmap.setInfo(SkImageInfo::MakeA8(kBlockSize, 1)); | 128 fPermutationsBitmap.setInfo(SkImageInfo::MakeA8(kBlockSize, 1)); |
98 fPermutationsBitmap.setPixels(fLatticeSelector); | 129 fPermutationsBitmap.setPixels(fLatticeSelector); |
99 | 130 |
100 fNoiseBitmap.setInfo(SkImageInfo::MakeN32Premul(kBlockSize, 4)); | 131 fNoiseBitmap.setInfo(SkImageInfo::MakeN32Premul(kBlockSize, 4)); |
101 fNoiseBitmap.setPixels(fNoise[0][0]); | 132 fNoiseBitmap.setPixels(fNoise[0][0]); |
| 133 |
| 134 fImprovedPermutationsBitmap.setInfo(SkImageInfo::MakeA8(256, 1)); |
| 135 fImprovedPermutationsBitmap.setPixels(improved_noise_permutations); |
| 136 |
| 137 fGradientBitmap.setInfo(SkImageInfo::MakeN32Premul(16, 1)); |
| 138 static uint8_t gradients[] = { 2, 2, 1, 0, |
| 139 0, 2, 1, 0, |
| 140 2, 0, 1, 0, |
| 141 0, 0, 1, 0, |
| 142 2, 1, 2, 0, |
| 143 0, 1, 2, 0, |
| 144 2, 1, 0, 0, |
| 145 0, 1, 0, 0, |
| 146 1, 2, 2, 0, |
| 147 1, 0, 2, 0, |
| 148 1, 2, 0, 0, |
| 149 1, 0, 0, 0, |
| 150 2, 2, 1, 0, |
| 151 1, 0, 2, 0, |
| 152 0, 2, 1, 0, |
| 153 1, 0, 0, 0 }; |
| 154 fGradientBitmap.setPixels(gradients); |
102 #endif | 155 #endif |
103 } | 156 } |
104 | 157 |
105 int fSeed; | 158 int fSeed; |
106 uint8_t fLatticeSelector[kBlockSize]; | 159 uint8_t fLatticeSelector[kBlockSize]; |
107 uint16_t fNoise[4][kBlockSize][2]; | 160 uint16_t fNoise[4][kBlockSize][2]; |
108 SkPoint fGradient[4][kBlockSize]; | 161 SkPoint fGradient[4][kBlockSize]; |
109 SkISize fTileSize; | 162 SkISize fTileSize; |
110 SkVector fBaseFrequency; | 163 SkVector fBaseFrequency; |
111 StitchData fStitchDataInit; | 164 StitchData fStitchDataInit; |
112 | 165 |
113 private: | 166 private: |
114 | 167 |
115 #if SK_SUPPORT_GPU | 168 #if SK_SUPPORT_GPU |
116 SkBitmap fPermutationsBitmap; | 169 SkBitmap fPermutationsBitmap; |
117 SkBitmap fNoiseBitmap; | 170 SkBitmap fNoiseBitmap; |
| 171 SkBitmap fImprovedPermutationsBitmap; |
| 172 SkBitmap fGradientBitmap; |
118 #endif | 173 #endif |
119 | 174 |
120 inline int random() { | 175 inline int random() { |
121 static const int gRandAmplitude = 16807; // 7**5; primitive root of m | 176 static const int gRandAmplitude = 16807; // 7**5; primitive root of m |
122 static const int gRandQ = 127773; // m / a | 177 static const int gRandQ = 127773; // m / a |
123 static const int gRandR = 2836; // m % a | 178 static const int gRandR = 2836; // m % a |
124 | 179 |
125 int result = gRandAmplitude * (fSeed % gRandQ) - gRandR * (fSeed / gRand
Q); | 180 int result = gRandAmplitude * (fSeed % gRandQ) - gRandR * (fSeed / gRand
Q); |
126 if (result <= 0) | 181 if (result <= 0) |
127 result += kRandMaximum; | 182 result += kRandMaximum; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 SkScalarRoundToInt(tileHeight * fBaseFrequency.fY); | 294 SkScalarRoundToInt(tileHeight * fBaseFrequency.fY); |
240 fStitchDataInit.fWrapY = kPerlinNoise + fStitchDataInit.fHeight; | 295 fStitchDataInit.fWrapY = kPerlinNoise + fStitchDataInit.fHeight; |
241 } | 296 } |
242 | 297 |
243 public: | 298 public: |
244 | 299 |
245 #if SK_SUPPORT_GPU | 300 #if SK_SUPPORT_GPU |
246 const SkBitmap& getPermutationsBitmap() const { return fPermutationsBitmap;
} | 301 const SkBitmap& getPermutationsBitmap() const { return fPermutationsBitmap;
} |
247 | 302 |
248 const SkBitmap& getNoiseBitmap() const { return fNoiseBitmap; } | 303 const SkBitmap& getNoiseBitmap() const { return fNoiseBitmap; } |
| 304 |
| 305 const SkBitmap& getImprovedPermutationsBitmap() const { return fImprovedPerm
utationsBitmap; } |
| 306 |
| 307 const SkBitmap& getGradientBitmap() const { return fGradientBitmap; } |
249 #endif | 308 #endif |
250 }; | 309 }; |
251 | 310 |
252 SkShader* SkPerlinNoiseShader::CreateFractalNoise(SkScalar baseFrequencyX, SkSca
lar baseFrequencyY, | 311 SkShader* SkPerlinNoiseShader2::CreateFractalNoise(SkScalar baseFrequencyX, SkSc
alar baseFrequencyY, |
253 int numOctaves, SkScalar seed, | 312 int numOctaves, SkScalar seed, |
254 const SkISize* tileSize) { | 313 const SkISize* tileSize) { |
255 return new SkPerlinNoiseShader(kFractalNoise_Type, baseFrequencyX, baseFrequ
encyY, numOctaves, | 314 return new SkPerlinNoiseShader2(kFractalNoise_Type, baseFrequencyX, baseFreq
uencyY, numOctaves, |
256 seed, tileSize); | 315 seed, tileSize); |
257 } | 316 } |
258 | 317 |
259 SkShader* SkPerlinNoiseShader::CreateTurbulence(SkScalar baseFrequencyX, SkScala
r baseFrequencyY, | 318 SkShader* SkPerlinNoiseShader2::CreateTurbulence(SkScalar baseFrequencyX, SkScal
ar baseFrequencyY, |
260 int numOctaves, SkScalar seed, | 319 int numOctaves, SkScalar seed, |
261 const SkISize* tileSize) { | 320 const SkISize* tileSize) { |
262 return new SkPerlinNoiseShader(kTurbulence_Type, baseFrequencyX, baseFrequen
cyY, numOctaves, | 321 return new SkPerlinNoiseShader2(kTurbulence_Type, baseFrequencyX, baseFreque
ncyY, numOctaves, |
263 seed, tileSize); | 322 seed, tileSize); |
264 } | 323 } |
265 | 324 |
266 SkPerlinNoiseShader::SkPerlinNoiseShader(SkPerlinNoiseShader::Type type, | 325 SkShader* SkPerlinNoiseShader2::CreateImprovedNoise(SkScalar baseFrequencyX, SkS
calar baseFrequencyY, |
| 326 int numOctaves, SkScalar z)
{ |
| 327 return new SkPerlinNoiseShader2(kImprovedNoise_Type, baseFrequencyX, baseFre
quencyY, numOctaves, |
| 328 z, NULL); |
| 329 } |
| 330 |
| 331 SkPerlinNoiseShader2::SkPerlinNoiseShader2(SkPerlinNoiseShader2::Type type, |
267 SkScalar baseFrequencyX, | 332 SkScalar baseFrequencyX, |
268 SkScalar baseFrequencyY, | 333 SkScalar baseFrequencyY, |
269 int numOctaves, | 334 int numOctaves, |
270 SkScalar seed, | 335 SkScalar seed, |
271 const SkISize* tileSize) | 336 const SkISize* tileSize) |
272 : fType(type) | 337 : fType(type) |
273 , fBaseFrequencyX(baseFrequencyX) | 338 , fBaseFrequencyX(baseFrequencyX) |
274 , fBaseFrequencyY(baseFrequencyY) | 339 , fBaseFrequencyY(baseFrequencyY) |
275 , fNumOctaves(numOctaves > 255 ? 255 : numOctaves/*[0,255] octaves allowed*/) | 340 , fNumOctaves(numOctaves > 255 ? 255 : numOctaves/*[0,255] octaves allowed*/) |
276 , fSeed(seed) | 341 , fSeed(seed) |
277 , fTileSize(nullptr == tileSize ? SkISize::Make(0, 0) : *tileSize) | 342 , fTileSize(nullptr == tileSize ? SkISize::Make(0, 0) : *tileSize) |
278 , fStitchTiles(!fTileSize.isEmpty()) | 343 , fStitchTiles(!fTileSize.isEmpty()) |
279 { | 344 { |
280 SkASSERT(numOctaves >= 0 && numOctaves < 256); | 345 SkASSERT(numOctaves >= 0 && numOctaves < 256); |
281 } | 346 } |
282 | 347 |
283 SkPerlinNoiseShader::~SkPerlinNoiseShader() { | 348 SkPerlinNoiseShader2::~SkPerlinNoiseShader2() { |
284 } | 349 } |
285 | 350 |
286 SkFlattenable* SkPerlinNoiseShader::CreateProc(SkReadBuffer& buffer) { | 351 SkFlattenable* SkPerlinNoiseShader2::CreateProc(SkReadBuffer& buffer) { |
287 Type type = (Type)buffer.readInt(); | 352 Type type = (Type)buffer.readInt(); |
288 SkScalar freqX = buffer.readScalar(); | 353 SkScalar freqX = buffer.readScalar(); |
289 SkScalar freqY = buffer.readScalar(); | 354 SkScalar freqY = buffer.readScalar(); |
290 int octaves = buffer.readInt(); | 355 int octaves = buffer.readInt(); |
291 SkScalar seed = buffer.readScalar(); | 356 SkScalar seed = buffer.readScalar(); |
292 SkISize tileSize; | 357 SkISize tileSize; |
293 tileSize.fWidth = buffer.readInt(); | 358 tileSize.fWidth = buffer.readInt(); |
294 tileSize.fHeight = buffer.readInt(); | 359 tileSize.fHeight = buffer.readInt(); |
295 | 360 |
296 switch (type) { | 361 switch (type) { |
297 case kFractalNoise_Type: | 362 case kFractalNoise_Type: |
298 return SkPerlinNoiseShader::CreateFractalNoise(freqX, freqY, octaves
, seed, &tileSize); | 363 return SkPerlinNoiseShader2::CreateFractalNoise(freqX, freqY, octave
s, seed, &tileSize); |
299 case kTurbulence_Type: | 364 case kTurbulence_Type: |
300 return SkPerlinNoiseShader::CreateTubulence(freqX, freqY, octaves, s
eed, &tileSize); | 365 return SkPerlinNoiseShader2::CreateTubulence(freqX, freqY, octaves,
seed, &tileSize); |
| 366 case kImprovedNoise_Type: |
| 367 return SkPerlinNoiseShader2::CreateImprovedNoise(freqX, freqY, octav
es, seed); |
301 default: | 368 default: |
302 return nullptr; | 369 return nullptr; |
303 } | 370 } |
304 } | 371 } |
305 | 372 |
306 void SkPerlinNoiseShader::flatten(SkWriteBuffer& buffer) const { | 373 void SkPerlinNoiseShader2::flatten(SkWriteBuffer& buffer) const { |
307 buffer.writeInt((int) fType); | 374 buffer.writeInt((int) fType); |
308 buffer.writeScalar(fBaseFrequencyX); | 375 buffer.writeScalar(fBaseFrequencyX); |
309 buffer.writeScalar(fBaseFrequencyY); | 376 buffer.writeScalar(fBaseFrequencyY); |
310 buffer.writeInt(fNumOctaves); | 377 buffer.writeInt(fNumOctaves); |
311 buffer.writeScalar(fSeed); | 378 buffer.writeScalar(fSeed); |
312 buffer.writeInt(fTileSize.fWidth); | 379 buffer.writeInt(fTileSize.fWidth); |
313 buffer.writeInt(fTileSize.fHeight); | 380 buffer.writeInt(fTileSize.fHeight); |
314 } | 381 } |
315 | 382 |
316 SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::noise2D( | 383 SkScalar SkPerlinNoiseShader2::PerlinNoiseShaderContext::noise2D( |
317 int channel, const StitchData& stitchData, const SkPoint& noiseVector) c
onst { | 384 int channel, const StitchData& stitchData, const SkPoint& noiseVector) c
onst { |
318 struct Noise { | 385 struct Noise { |
319 int noisePositionIntegerValue; | 386 int noisePositionIntegerValue; |
320 int nextNoisePositionIntegerValue; | 387 int nextNoisePositionIntegerValue; |
321 SkScalar noisePositionFractionValue; | 388 SkScalar noisePositionFractionValue; |
322 Noise(SkScalar component) | 389 Noise(SkScalar component) |
323 { | 390 { |
324 SkScalar position = component + kPerlinNoise; | 391 SkScalar position = component + kPerlinNoise; |
325 noisePositionIntegerValue = SkScalarFloorToInt(position); | 392 noisePositionIntegerValue = SkScalarFloorToInt(position); |
326 noisePositionFractionValue = position - SkIntToScalar(noisePositionI
ntegerValue); | 393 noisePositionFractionValue = position - SkIntToScalar(noisePositionI
ntegerValue); |
327 nextNoisePositionIntegerValue = noisePositionIntegerValue + 1; | 394 nextNoisePositionIntegerValue = noisePositionIntegerValue + 1; |
328 } | 395 } |
329 }; | 396 }; |
330 Noise noiseX(noiseVector.x()); | 397 Noise noiseX(noiseVector.x()); |
331 Noise noiseY(noiseVector.y()); | 398 Noise noiseY(noiseVector.y()); |
332 SkScalar u, v; | 399 SkScalar u, v; |
333 const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoi
seShader&>(fShader); | 400 const SkPerlinNoiseShader2& perlinNoiseShader = static_cast<const SkPerlinNo
iseShader2&>(fShader); |
334 // If stitching, adjust lattice points accordingly. | 401 // If stitching, adjust lattice points accordingly. |
335 if (perlinNoiseShader.fStitchTiles) { | 402 if (perlinNoiseShader.fStitchTiles) { |
336 noiseX.noisePositionIntegerValue = | 403 noiseX.noisePositionIntegerValue = |
337 checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stit
chData.fWidth); | 404 checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stit
chData.fWidth); |
338 noiseY.noisePositionIntegerValue = | 405 noiseY.noisePositionIntegerValue = |
339 checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stit
chData.fHeight); | 406 checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stit
chData.fHeight); |
340 noiseX.nextNoisePositionIntegerValue = | 407 noiseX.nextNoisePositionIntegerValue = |
341 checkNoise(noiseX.nextNoisePositionIntegerValue, stitchData.fWrapX,
stitchData.fWidth); | 408 checkNoise(noiseX.nextNoisePositionIntegerValue, stitchData.fWrapX,
stitchData.fWidth); |
342 noiseY.nextNoisePositionIntegerValue = | 409 noiseY.nextNoisePositionIntegerValue = |
343 checkNoise(noiseY.nextNoisePositionIntegerValue, stitchData.fWrapY,
stitchData.fHeight); | 410 checkNoise(noiseY.nextNoisePositionIntegerValue, stitchData.fWrapY,
stitchData.fHeight); |
(...skipping 20 matching lines...) Expand all Loading... |
364 v = fPaintingData->fGradient[channel][b10].dot(fractionValue); | 431 v = fPaintingData->fGradient[channel][b10].dot(fractionValue); |
365 SkScalar a = SkScalarInterp(u, v, sx); | 432 SkScalar a = SkScalarInterp(u, v, sx); |
366 fractionValue.fY -= SK_Scalar1; // Offset (-1,-1) | 433 fractionValue.fY -= SK_Scalar1; // Offset (-1,-1) |
367 v = fPaintingData->fGradient[channel][b11].dot(fractionValue); | 434 v = fPaintingData->fGradient[channel][b11].dot(fractionValue); |
368 fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1) | 435 fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1) |
369 u = fPaintingData->fGradient[channel][b01].dot(fractionValue); | 436 u = fPaintingData->fGradient[channel][b01].dot(fractionValue); |
370 SkScalar b = SkScalarInterp(u, v, sx); | 437 SkScalar b = SkScalarInterp(u, v, sx); |
371 return SkScalarInterp(a, b, sy); | 438 return SkScalarInterp(a, b, sy); |
372 } | 439 } |
373 | 440 |
374 SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::calculateTurbulenceValue
ForPoint( | 441 SkScalar SkPerlinNoiseShader2::PerlinNoiseShaderContext::calculateTurbulenceValu
eForPoint( |
375 int channel, StitchData& stitchData, const SkPoint& point) const { | 442 int channel, StitchData& stitchData, const SkPoint& point) const { |
376 const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoi
seShader&>(fShader); | 443 const SkPerlinNoiseShader2& perlinNoiseShader = static_cast<const SkPerlinNo
iseShader2&>(fShader); |
377 if (perlinNoiseShader.fStitchTiles) { | 444 if (perlinNoiseShader.fStitchTiles) { |
378 // Set up TurbulenceInitial stitch values. | 445 // Set up TurbulenceInitial stitch values. |
379 stitchData = fPaintingData->fStitchDataInit; | 446 stitchData = fPaintingData->fStitchDataInit; |
380 } | 447 } |
381 SkScalar turbulenceFunctionResult = 0; | 448 SkScalar turbulenceFunctionResult = 0; |
382 SkPoint noiseVector(SkPoint::Make(SkScalarMul(point.x(), fPaintingData->fBas
eFrequency.fX), | 449 SkPoint noiseVector(SkPoint::Make(SkScalarMul(point.x(), fPaintingData->fBas
eFrequency.fX), |
383 SkScalarMul(point.y(), fPaintingData->fBas
eFrequency.fY))); | 450 SkScalarMul(point.y(), fPaintingData->fBas
eFrequency.fY))); |
384 SkScalar ratio = SK_Scalar1; | 451 SkScalar ratio = SK_Scalar1; |
385 for (int octave = 0; octave < perlinNoiseShader.fNumOctaves; ++octave) { | 452 for (int octave = 0; octave < perlinNoiseShader.fNumOctaves; ++octave) { |
386 SkScalar noise = noise2D(channel, stitchData, noiseVector); | 453 SkScalar noise = noise2D(channel, stitchData, noiseVector); |
(...skipping 20 matching lines...) Expand all Loading... |
407 } | 474 } |
408 | 475 |
409 if (channel == 3) { // Scale alpha by paint value | 476 if (channel == 3) { // Scale alpha by paint value |
410 turbulenceFunctionResult *= SkIntToScalar(getPaintAlpha()) / 255; | 477 turbulenceFunctionResult *= SkIntToScalar(getPaintAlpha()) / 255; |
411 } | 478 } |
412 | 479 |
413 // Clamp result | 480 // Clamp result |
414 return SkScalarPin(turbulenceFunctionResult, 0, SK_Scalar1); | 481 return SkScalarPin(turbulenceFunctionResult, 0, SK_Scalar1); |
415 } | 482 } |
416 | 483 |
417 SkPMColor SkPerlinNoiseShader::PerlinNoiseShaderContext::shade( | 484 ////////////////////////////////////////////////////////////////////////////////
//////////////////// |
| 485 // Improved Perlin Noise based on Java implementation found at http://mrl.nyu.ed
u/~perlin/noise/ |
| 486 static SkScalar fade(SkScalar t) { |
| 487 return t * t * t * (t * (t * 6 - 15) + 10); |
| 488 } |
| 489 |
| 490 static SkScalar lerp(SkScalar t, SkScalar a, SkScalar b) { |
| 491 return a + t * (b - a); |
| 492 } |
| 493 |
| 494 static SkScalar grad(int hash, SkScalar x, SkScalar y, SkScalar z) { |
| 495 int h = hash & 15; |
| 496 SkScalar u = h < 8 ? x : y; |
| 497 SkScalar v = h < 4 ? y : h == 12 || h == 14 ? x : z; |
| 498 return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); |
| 499 } |
| 500 |
| 501 SkScalar SkPerlinNoiseShader2::PerlinNoiseShaderContext::calculateImprovedNoiseV
alueForPoint( |
| 502 int channel, const SkPoint& point) const { |
| 503 const SkPerlinNoiseShader2& perlinNoiseShader = static_cast<const SkPerlinNo
iseShader2&>(fShader); |
| 504 SkScalar x = point.fX * perlinNoiseShader.fBaseFrequencyX; |
| 505 SkScalar y = point.fY * perlinNoiseShader.fBaseFrequencyY; |
| 506 // z offset between different channels, chosen arbitrarily |
| 507 static const SkScalar CHANNEL_DELTA = 1000.0f; |
| 508 SkScalar z = channel * CHANNEL_DELTA + perlinNoiseShader.fSeed; |
| 509 SkScalar result = 0; |
| 510 SkScalar ratio = SK_Scalar1; |
| 511 for (int i = 0; i < perlinNoiseShader.fNumOctaves; i++) { |
| 512 int X = SkScalarFloorToInt(x) & 255; |
| 513 int Y = SkScalarFloorToInt(y) & 255; |
| 514 int Z = SkScalarFloorToInt(z) & 255; |
| 515 SkScalar px = x - SkScalarFloorToScalar(x); |
| 516 SkScalar py = y - SkScalarFloorToScalar(y); |
| 517 SkScalar pz = z - SkScalarFloorToScalar(z); |
| 518 SkScalar u = fade(px); |
| 519 SkScalar v = fade(py); |
| 520 SkScalar w = fade(pz); |
| 521 uint8_t* permutations = improved_noise_permutations; |
| 522 int A = permutations[X] + Y; |
| 523 int AA = permutations[A] + Z; |
| 524 int AB = permutations[A + 1] + Z; |
| 525 int B = permutations[X + 1] + Y; |
| 526 int BA = permutations[B] + Z; |
| 527 int BB = permutations[B + 1] + Z; |
| 528 result += lerp(w, lerp(v, lerp(u, grad(permutations[AA ], px , py
, pz ), |
| 529 grad(permutations[BA ], px - 1, py
, pz )), |
| 530 lerp(u, grad(permutations[AB ], px , py
- 1, pz ), |
| 531 grad(permutations[BB ], px - 1, py
- 1, pz ))), |
| 532 lerp(v, lerp(u, grad(permutations[AA + 1], px , py
, pz - 1), |
| 533 grad(permutations[BA + 1], px - 1, py
, pz - 1)), |
| 534 lerp(u, grad(permutations[AB + 1], px , py
- 1, pz - 1), |
| 535 grad(permutations[BB + 1], px - 1, py
- 1, pz - 1)))) / |
| 536 ratio; |
| 537 x *= 2; |
| 538 y *= 2; |
| 539 ratio *= 2; |
| 540 } |
| 541 result = SkScalarClampMax((result + 1.0f) / 2.0f, 1.0f); |
| 542 return result; |
| 543 } |
| 544 ////////////////////////////////////////////////////////////////////////////////
//////////////////// |
| 545 |
| 546 SkPMColor SkPerlinNoiseShader2::PerlinNoiseShaderContext::shade( |
418 const SkPoint& point, StitchData& stitchData) const { | 547 const SkPoint& point, StitchData& stitchData) const { |
| 548 const SkPerlinNoiseShader2& perlinNoiseShader = static_cast<const SkPerlinNo
iseShader2&>(fShader); |
419 SkPoint newPoint; | 549 SkPoint newPoint; |
420 fMatrix.mapPoints(&newPoint, &point, 1); | 550 fMatrix.mapPoints(&newPoint, &point, 1); |
421 newPoint.fX = SkScalarRoundToScalar(newPoint.fX); | 551 newPoint.fX = SkScalarRoundToScalar(newPoint.fX); |
422 newPoint.fY = SkScalarRoundToScalar(newPoint.fY); | 552 newPoint.fY = SkScalarRoundToScalar(newPoint.fY); |
423 | 553 |
424 U8CPU rgba[4]; | 554 U8CPU rgba[4]; |
425 for (int channel = 3; channel >= 0; --channel) { | 555 for (int channel = 3; channel >= 0; --channel) { |
426 rgba[channel] = SkScalarFloorToInt(255 * | 556 SkScalar value; |
427 calculateTurbulenceValueForPoint(channel, stitchData, newPoint)); | 557 if (perlinNoiseShader.fType == kImprovedNoise_Type) { |
| 558 value = calculateImprovedNoiseValueForPoint(channel, newPoint); |
| 559 } |
| 560 else { |
| 561 value = calculateTurbulenceValueForPoint(channel, stitchData, newPoi
nt); |
| 562 } |
| 563 rgba[channel] = SkScalarFloorToInt(255 * value); |
428 } | 564 } |
429 return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]); | 565 return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]); |
430 } | 566 } |
431 | 567 |
432 SkShader::Context* SkPerlinNoiseShader::onCreateContext(const ContextRec& rec, | 568 SkShader::Context* SkPerlinNoiseShader2::onCreateContext(const ContextRec& rec, |
433 void* storage) const { | 569 void* storage) const { |
434 return new (storage) PerlinNoiseShaderContext(*this, rec); | 570 return new (storage) PerlinNoiseShaderContext(*this, rec); |
435 } | 571 } |
436 | 572 |
437 size_t SkPerlinNoiseShader::contextSize() const { | 573 size_t SkPerlinNoiseShader2::contextSize() const { |
438 return sizeof(PerlinNoiseShaderContext); | 574 return sizeof(PerlinNoiseShaderContext); |
439 } | 575 } |
440 | 576 |
441 SkPerlinNoiseShader::PerlinNoiseShaderContext::PerlinNoiseShaderContext( | 577 SkPerlinNoiseShader2::PerlinNoiseShaderContext::PerlinNoiseShaderContext( |
442 const SkPerlinNoiseShader& shader, const ContextRec& rec) | 578 const SkPerlinNoiseShader2& shader, const ContextRec& rec) |
443 : INHERITED(shader, rec) | 579 : INHERITED(shader, rec) |
444 { | 580 { |
445 SkMatrix newMatrix = *rec.fMatrix; | 581 SkMatrix newMatrix = *rec.fMatrix; |
446 newMatrix.preConcat(shader.getLocalMatrix()); | 582 newMatrix.preConcat(shader.getLocalMatrix()); |
447 if (rec.fLocalMatrix) { | 583 if (rec.fLocalMatrix) { |
448 newMatrix.preConcat(*rec.fLocalMatrix); | 584 newMatrix.preConcat(*rec.fLocalMatrix); |
449 } | 585 } |
450 // This (1,1) translation is due to WebKit's 1 based coordinates for the noi
se | 586 // This (1,1) translation is due to WebKit's 1 based coordinates for the noi
se |
451 // (as opposed to 0 based, usually). The same adjustment is in the setData()
function. | 587 // (as opposed to 0 based, usually). The same adjustment is in the setData()
function. |
452 fMatrix.setTranslate(-newMatrix.getTranslateX() + SK_Scalar1, -newMatrix.get
TranslateY() + SK_Scalar1); | 588 fMatrix.setTranslate(-newMatrix.getTranslateX() + SK_Scalar1, -newMatrix.get
TranslateY() + SK_Scalar1); |
453 fPaintingData = new PaintingData(shader.fTileSize, shader.fSeed, shader.fBas
eFrequencyX, | 589 fPaintingData = new PaintingData(shader.fTileSize, shader.fSeed, shader.fBas
eFrequencyX, |
454 shader.fBaseFrequencyY, newMatrix); | 590 shader.fBaseFrequencyY, newMatrix); |
455 } | 591 } |
456 | 592 |
457 SkPerlinNoiseShader::PerlinNoiseShaderContext::~PerlinNoiseShaderContext() { del
ete fPaintingData; } | 593 SkPerlinNoiseShader2::PerlinNoiseShaderContext::~PerlinNoiseShaderContext() { de
lete fPaintingData; } |
458 | 594 |
459 void SkPerlinNoiseShader::PerlinNoiseShaderContext::shadeSpan( | 595 void SkPerlinNoiseShader2::PerlinNoiseShaderContext::shadeSpan( |
460 int x, int y, SkPMColor result[], int count) { | 596 int x, int y, SkPMColor result[], int count) { |
461 SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y)); | 597 SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y)); |
462 StitchData stitchData; | 598 StitchData stitchData; |
463 for (int i = 0; i < count; ++i) { | 599 for (int i = 0; i < count; ++i) { |
464 result[i] = shade(point, stitchData); | 600 result[i] = shade(point, stitchData); |
465 point.fX += SK_Scalar1; | 601 point.fX += SK_Scalar1; |
466 } | 602 } |
467 } | 603 } |
468 | 604 |
469 void SkPerlinNoiseShader::PerlinNoiseShaderContext::shadeSpan16( | 605 void SkPerlinNoiseShader2::PerlinNoiseShaderContext::shadeSpan16( |
470 int x, int y, uint16_t result[], int count) { | 606 int x, int y, uint16_t result[], int count) { |
471 SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y)); | 607 SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y)); |
472 StitchData stitchData; | 608 StitchData stitchData; |
473 DITHER_565_SCAN(y); | 609 DITHER_565_SCAN(y); |
474 for (int i = 0; i < count; ++i) { | 610 for (int i = 0; i < count; ++i) { |
475 unsigned dither = DITHER_VALUE(x); | 611 unsigned dither = DITHER_VALUE(x); |
476 result[i] = SkDitherRGB32To565(shade(point, stitchData), dither); | 612 result[i] = SkDitherRGB32To565(shade(point, stitchData), dither); |
477 DITHER_INC_X(x); | 613 DITHER_INC_X(x); |
478 point.fX += SK_Scalar1; | 614 point.fX += SK_Scalar1; |
479 } | 615 } |
480 } | 616 } |
481 | 617 |
482 ///////////////////////////////////////////////////////////////////// | 618 ///////////////////////////////////////////////////////////////////// |
483 | 619 |
484 #if SK_SUPPORT_GPU | 620 #if SK_SUPPORT_GPU |
485 | 621 |
486 class GrGLPerlinNoise : public GrGLFragmentProcessor { | 622 class GrGLPerlinNoise2 : public GrGLFragmentProcessor { |
487 public: | 623 public: |
488 GrGLPerlinNoise(const GrProcessor&); | 624 GrGLPerlinNoise2(const GrProcessor&); |
489 virtual ~GrGLPerlinNoise() {} | 625 virtual ~GrGLPerlinNoise2() {} |
490 | 626 |
491 virtual void emitCode(EmitArgs&) override; | 627 virtual void emitCode(EmitArgs&) override; |
492 | 628 |
493 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder* b); | 629 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder* b); |
494 | 630 |
495 protected: | 631 protected: |
496 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override
; | 632 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override
; |
497 | 633 |
498 private: | 634 private: |
499 | 635 |
500 GrGLSLProgramDataManager::UniformHandle fStitchDataUni; | 636 GrGLSLProgramDataManager::UniformHandle fStitchDataUni; |
501 SkPerlinNoiseShader::Type fType; | 637 SkPerlinNoiseShader2::Type fType; |
502 bool fStitchTiles; | 638 bool fStitchTiles; |
503 int fNumOctaves; | 639 int fNumOctaves; |
504 GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni; | 640 GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni; |
505 | 641 |
506 private: | 642 private: |
507 typedef GrGLFragmentProcessor INHERITED; | 643 typedef GrGLFragmentProcessor INHERITED; |
508 }; | 644 }; |
509 | 645 |
510 ///////////////////////////////////////////////////////////////////// | 646 ///////////////////////////////////////////////////////////////////// |
511 | 647 |
512 class GrPerlinNoiseEffect : public GrFragmentProcessor { | 648 class GrPerlinNoise2Effect : public GrFragmentProcessor { |
513 public: | 649 public: |
514 static GrFragmentProcessor* Create(SkPerlinNoiseShader::Type type, | 650 static GrFragmentProcessor* Create(SkPerlinNoiseShader2::Type type, |
515 int numOctaves, bool stitchTiles, | 651 int numOctaves, bool stitchTiles, |
516 SkPerlinNoiseShader::PaintingData* painti
ngData, | 652 SkPerlinNoiseShader2::PaintingData* paint
ingData, |
517 GrTexture* permutationsTexture, GrTexture
* noiseTexture, | 653 GrTexture* permutationsTexture, GrTexture
* noiseTexture, |
518 const SkMatrix& matrix) { | 654 const SkMatrix& matrix) { |
519 return new GrPerlinNoiseEffect(type, numOctaves, stitchTiles, paintingDa
ta, | 655 return new GrPerlinNoise2Effect(type, numOctaves, stitchTiles, paintingD
ata, |
520 permutationsTexture, noiseTexture, matrix
); | 656 permutationsTexture, noiseTexture, matrix
); |
521 } | 657 } |
522 | 658 |
523 virtual ~GrPerlinNoiseEffect() { delete fPaintingData; } | 659 virtual ~GrPerlinNoise2Effect() { delete fPaintingData; } |
524 | 660 |
525 const char* name() const override { return "PerlinNoise"; } | 661 const char* name() const override { return "PerlinNoise"; } |
526 | 662 |
527 const SkPerlinNoiseShader::StitchData& stitchData() const { return fPainting
Data->fStitchDataInit; } | 663 const SkPerlinNoiseShader2::StitchData& stitchData() const { return fPaintin
gData->fStitchDataInit; } |
528 | 664 |
529 SkPerlinNoiseShader::Type type() const { return fType; } | 665 SkPerlinNoiseShader2::Type type() const { return fType; } |
530 bool stitchTiles() const { return fStitchTiles; } | 666 bool stitchTiles() const { return fStitchTiles; } |
531 const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency
; } | 667 const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency
; } |
532 int numOctaves() const { return fNumOctaves; } | 668 int numOctaves() const { return fNumOctaves; } |
533 const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); } | 669 const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); } |
534 | 670 |
535 private: | 671 private: |
536 GrGLFragmentProcessor* onCreateGLInstance() const override { | 672 GrGLFragmentProcessor* onCreateGLInstance() const override { |
537 return new GrGLPerlinNoise(*this); | 673 return new GrGLPerlinNoise2(*this); |
538 } | 674 } |
539 | 675 |
540 virtual void onGetGLProcessorKey(const GrGLSLCaps& caps, | 676 virtual void onGetGLProcessorKey(const GrGLSLCaps& caps, |
541 GrProcessorKeyBuilder* b) const override { | 677 GrProcessorKeyBuilder* b) const override { |
542 GrGLPerlinNoise::GenKey(*this, caps, b); | 678 GrGLPerlinNoise2::GenKey(*this, caps, b); |
543 } | 679 } |
544 | 680 |
545 bool onIsEqual(const GrFragmentProcessor& sBase) const override { | 681 bool onIsEqual(const GrFragmentProcessor& sBase) const override { |
546 const GrPerlinNoiseEffect& s = sBase.cast<GrPerlinNoiseEffect>(); | 682 const GrPerlinNoise2Effect& s = sBase.cast<GrPerlinNoise2Effect>(); |
547 return fType == s.fType && | 683 return fType == s.fType && |
548 fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency
&& | 684 fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency
&& |
549 fNumOctaves == s.fNumOctaves && | 685 fNumOctaves == s.fNumOctaves && |
550 fStitchTiles == s.fStitchTiles && | 686 fStitchTiles == s.fStitchTiles && |
551 fPaintingData->fStitchDataInit == s.fPaintingData->fStitchDataIni
t; | 687 fPaintingData->fStitchDataInit == s.fPaintingData->fStitchDataIni
t; |
552 } | 688 } |
553 | 689 |
554 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { | 690 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
555 inout->setToUnknown(GrInvariantOutput::kWillNot_ReadInput); | 691 inout->setToUnknown(GrInvariantOutput::kWillNot_ReadInput); |
556 } | 692 } |
557 | 693 |
558 GrPerlinNoiseEffect(SkPerlinNoiseShader::Type type, | 694 GrPerlinNoise2Effect(SkPerlinNoiseShader2::Type type, |
559 int numOctaves, bool stitchTiles, | 695 int numOctaves, bool stitchTiles, |
560 SkPerlinNoiseShader::PaintingData* paintingData, | 696 SkPerlinNoiseShader2::PaintingData* paintingData, |
561 GrTexture* permutationsTexture, GrTexture* noiseTexture, | 697 GrTexture* permutationsTexture, GrTexture* noiseTexture, |
562 const SkMatrix& matrix) | 698 const SkMatrix& matrix) |
563 : fType(type) | 699 : fType(type) |
564 , fNumOctaves(numOctaves) | 700 , fNumOctaves(numOctaves) |
565 , fStitchTiles(stitchTiles) | 701 , fStitchTiles(stitchTiles) |
566 , fPermutationsAccess(permutationsTexture) | 702 , fPermutationsAccess(permutationsTexture) |
567 , fNoiseAccess(noiseTexture) | 703 , fNoiseAccess(noiseTexture) |
568 , fPaintingData(paintingData) { | 704 , fPaintingData(paintingData) { |
569 this->initClassID<GrPerlinNoiseEffect>(); | 705 this->initClassID<GrPerlinNoise2Effect>(); |
570 this->addTextureAccess(&fPermutationsAccess); | 706 this->addTextureAccess(&fPermutationsAccess); |
571 this->addTextureAccess(&fNoiseAccess); | 707 this->addTextureAccess(&fNoiseAccess); |
572 fCoordTransform.reset(kLocal_GrCoordSet, matrix); | 708 fCoordTransform.reset(kLocal_GrCoordSet, matrix); |
573 this->addCoordTransform(&fCoordTransform); | 709 this->addCoordTransform(&fCoordTransform); |
574 } | 710 } |
575 | 711 |
576 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 712 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
577 | 713 |
578 SkPerlinNoiseShader::Type fType; | 714 SkPerlinNoiseShader2::Type fType; |
579 GrCoordTransform fCoordTransform; | 715 GrCoordTransform fCoordTransform; |
580 int fNumOctaves; | 716 int fNumOctaves; |
581 bool fStitchTiles; | 717 bool fStitchTiles; |
582 GrTextureAccess fPermutationsAccess; | 718 GrTextureAccess fPermutationsAccess; |
583 GrTextureAccess fNoiseAccess; | 719 GrTextureAccess fNoiseAccess; |
584 SkPerlinNoiseShader::PaintingData *fPaintingData; | 720 SkPerlinNoiseShader2::PaintingData *fPaintingData; |
585 | 721 |
586 private: | 722 private: |
587 typedef GrFragmentProcessor INHERITED; | 723 typedef GrFragmentProcessor INHERITED; |
588 }; | 724 }; |
589 | 725 |
590 ///////////////////////////////////////////////////////////////////// | 726 ///////////////////////////////////////////////////////////////////// |
591 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrPerlinNoiseEffect); | 727 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrPerlinNoise2Effect); |
592 | 728 |
593 const GrFragmentProcessor* GrPerlinNoiseEffect::TestCreate(GrProcessorTestData*
d) { | 729 const GrFragmentProcessor* GrPerlinNoise2Effect::TestCreate(GrProcessorTestData*
d) { |
594 int numOctaves = d->fRandom->nextRangeU(2, 10); | 730 int numOctaves = d->fRandom->nextRangeU(2, 10); |
595 bool stitchTiles = d->fRandom->nextBool(); | 731 bool stitchTiles = d->fRandom->nextBool(); |
596 SkScalar seed = SkIntToScalar(d->fRandom->nextU()); | 732 SkScalar seed = SkIntToScalar(d->fRandom->nextU()); |
597 SkISize tileSize = SkISize::Make(d->fRandom->nextRangeU(4, 4096), | 733 SkISize tileSize = SkISize::Make(d->fRandom->nextRangeU(4, 4096), |
598 d->fRandom->nextRangeU(4, 4096)); | 734 d->fRandom->nextRangeU(4, 4096)); |
599 SkScalar baseFrequencyX = d->fRandom->nextRangeScalar(0.01f, | 735 SkScalar baseFrequencyX = d->fRandom->nextRangeScalar(0.01f, |
600 0.99f); | 736 0.99f); |
601 SkScalar baseFrequencyY = d->fRandom->nextRangeScalar(0.01f, | 737 SkScalar baseFrequencyY = d->fRandom->nextRangeScalar(0.01f, |
602 0.99f); | 738 0.99f); |
603 | 739 |
604 SkAutoTUnref<SkShader> shader(d->fRandom->nextBool() ? | 740 SkAutoTUnref<SkShader> shader(d->fRandom->nextBool() ? |
605 SkPerlinNoiseShader::CreateFractalNoise(baseFrequencyX, baseFrequencyY,
numOctaves, seed, | 741 SkPerlinNoiseShader2::CreateFractalNoise(baseFrequencyX, baseFrequencyY,
numOctaves, seed, |
606 stitchTiles ? &tileSize : nullpt
r) : | 742 stitchTiles ? &tileSize : nullpt
r) : |
607 SkPerlinNoiseShader::CreateTurbulence(baseFrequencyX, baseFrequencyY, nu
mOctaves, seed, | 743 SkPerlinNoiseShader2::CreateTurbulence(baseFrequencyX, baseFrequencyY, n
umOctaves, seed, |
608 stitchTiles ? &tileSize : nullptr))
; | 744 stitchTiles ? &tileSize : nullptr))
; |
609 | 745 |
610 GrPaint grPaint; | 746 GrPaint grPaint; |
611 return shader->asFragmentProcessor(d->fContext, | 747 return shader->asFragmentProcessor(d->fContext, |
612 GrTest::TestMatrix(d->fRandom), nullptr, | 748 GrTest::TestMatrix(d->fRandom), nullptr, |
613 kNone_SkFilterQuality); | 749 kNone_SkFilterQuality); |
614 } | 750 } |
615 | 751 |
616 GrGLPerlinNoise::GrGLPerlinNoise(const GrProcessor& processor) | 752 GrGLPerlinNoise2::GrGLPerlinNoise2(const GrProcessor& processor) |
617 : fType(processor.cast<GrPerlinNoiseEffect>().type()) | 753 : fType(processor.cast<GrPerlinNoise2Effect>().type()) |
618 , fStitchTiles(processor.cast<GrPerlinNoiseEffect>().stitchTiles()) | 754 , fStitchTiles(processor.cast<GrPerlinNoise2Effect>().stitchTiles()) |
619 , fNumOctaves(processor.cast<GrPerlinNoiseEffect>().numOctaves()) { | 755 , fNumOctaves(processor.cast<GrPerlinNoise2Effect>().numOctaves()) { |
620 } | 756 } |
621 | 757 |
622 void GrGLPerlinNoise::emitCode(EmitArgs& args) { | 758 void GrGLPerlinNoise2::emitCode(EmitArgs& args) { |
623 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); | 759 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); |
624 SkString vCoords = fsBuilder->ensureFSCoords2D(args.fCoords, 0); | 760 SkString vCoords = fsBuilder->ensureFSCoords2D(args.fCoords, 0); |
625 | 761 |
626 fBaseFrequencyUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_
Visibility, | 762 fBaseFrequencyUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_
Visibility, |
627 kVec2f_GrSLType, kDefault_GrSLPrecis
ion, | 763 kVec2f_GrSLType, kDefault_GrSLPrecis
ion, |
628 "baseFrequency"); | 764 "baseFrequency"); |
629 const char* baseFrequencyUni = args.fBuilder->getUniformCStr(fBaseFrequencyU
ni); | 765 const char* baseFrequencyUni = args.fBuilder->getUniformCStr(fBaseFrequencyU
ni); |
630 | 766 |
631 const char* stitchDataUni = nullptr; | 767 const char* stitchDataUni = nullptr; |
632 if (fStitchTiles) { | 768 if (fStitchTiles) { |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 // Set up TurbulenceInitial stitch values. | 948 // Set up TurbulenceInitial stitch values. |
813 fsBuilder->codeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni)
; | 949 fsBuilder->codeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni)
; |
814 } | 950 } |
815 | 951 |
816 fsBuilder->codeAppendf("\n\t\tfloat %s = 1.0;", ratio); | 952 fsBuilder->codeAppendf("\n\t\tfloat %s = 1.0;", ratio); |
817 | 953 |
818 // Loop over all octaves | 954 // Loop over all octaves |
819 fsBuilder->codeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave) {"
, fNumOctaves); | 955 fsBuilder->codeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave) {"
, fNumOctaves); |
820 | 956 |
821 fsBuilder->codeAppendf("\n\t\t\t%s += ", args.fOutputColor); | 957 fsBuilder->codeAppendf("\n\t\t\t%s += ", args.fOutputColor); |
822 if (fType != SkPerlinNoiseShader::kFractalNoise_Type) { | 958 if (fType != SkPerlinNoiseShader2::kFractalNoise_Type) { |
823 fsBuilder->codeAppend("abs("); | 959 fsBuilder->codeAppend("abs("); |
824 } | 960 } |
825 if (fStitchTiles) { | 961 if (fStitchTiles) { |
826 fsBuilder->codeAppendf( | 962 fsBuilder->codeAppendf( |
827 "vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s)," | 963 "vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s)," |
828 "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))", | 964 "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))", |
829 noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData, | 965 noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData, |
830 noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData, | 966 noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData, |
831 noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData, | 967 noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData, |
832 noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData); | 968 noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData); |
833 } else { | 969 } else { |
834 fsBuilder->codeAppendf( | 970 fsBuilder->codeAppendf( |
835 "vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s)," | 971 "vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s)," |
836 "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))", | 972 "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))", |
837 noiseFuncName.c_str(), chanCoordR, noiseVec, | 973 noiseFuncName.c_str(), chanCoordR, noiseVec, |
838 noiseFuncName.c_str(), chanCoordG, noiseVec, | 974 noiseFuncName.c_str(), chanCoordG, noiseVec, |
839 noiseFuncName.c_str(), chanCoordB, noiseVec, | 975 noiseFuncName.c_str(), chanCoordB, noiseVec, |
840 noiseFuncName.c_str(), chanCoordA, noiseVec); | 976 noiseFuncName.c_str(), chanCoordA, noiseVec); |
841 } | 977 } |
842 if (fType != SkPerlinNoiseShader::kFractalNoise_Type) { | 978 if (fType != SkPerlinNoiseShader2::kFractalNoise_Type) { |
843 fsBuilder->codeAppendf(")"); // end of "abs(" | 979 fsBuilder->codeAppendf(")"); // end of "abs(" |
844 } | 980 } |
845 fsBuilder->codeAppendf(" * %s;", ratio); | 981 fsBuilder->codeAppendf(" * %s;", ratio); |
846 | 982 |
847 fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec); | 983 fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec); |
848 fsBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio); | 984 fsBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio); |
849 | 985 |
850 if (fStitchTiles) { | 986 if (fStitchTiles) { |
851 fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData); | 987 fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData); |
852 } | 988 } |
853 fsBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves | 989 fsBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves |
854 | 990 |
855 if (fType == SkPerlinNoiseShader::kFractalNoise_Type) { | 991 if (fType == SkPerlinNoiseShader2::kFractalNoise_Type) { |
856 // The value of turbulenceFunctionResult comes from ((turbulenceFunction
Result) + 1) / 2 | 992 // The value of turbulenceFunctionResult comes from ((turbulenceFunction
Result) + 1) / 2 |
857 // by fractalNoise and (turbulenceFunctionResult) by turbulence. | 993 // by fractalNoise and (turbulenceFunctionResult) by turbulence. |
858 fsBuilder->codeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);", | 994 fsBuilder->codeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);", |
859 args.fOutputColor,args.fOutputColor); | 995 args.fOutputColor,args.fOutputColor); |
860 } | 996 } |
861 | 997 |
862 // Clamp values | 998 // Clamp values |
863 fsBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", args.fOutputColor,
args.fOutputColor); | 999 fsBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", args.fOutputColor,
args.fOutputColor); |
864 | 1000 |
865 // Pre-multiply the result | 1001 // Pre-multiply the result |
866 fsBuilder->codeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n", | 1002 fsBuilder->codeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n", |
867 args.fOutputColor, args.fOutputColor, | 1003 args.fOutputColor, args.fOutputColor, |
868 args.fOutputColor, args.fOutputColor); | 1004 args.fOutputColor, args.fOutputColor); |
869 } | 1005 } |
870 | 1006 |
871 void GrGLPerlinNoise::GenKey(const GrProcessor& processor, const GrGLSLCaps&, | 1007 void GrGLPerlinNoise2::GenKey(const GrProcessor& processor, const GrGLSLCaps&, |
872 GrProcessorKeyBuilder* b) { | 1008 GrProcessorKeyBuilder* b) { |
873 const GrPerlinNoiseEffect& turbulence = processor.cast<GrPerlinNoiseEffect>(
); | 1009 const GrPerlinNoise2Effect& turbulence = processor.cast<GrPerlinNoise2Effect
>(); |
874 | 1010 |
875 uint32_t key = turbulence.numOctaves(); | 1011 uint32_t key = turbulence.numOctaves(); |
876 | 1012 |
877 key = key << 3; // Make room for next 3 bits | 1013 key = key << 3; // Make room for next 3 bits |
878 | 1014 |
879 switch (turbulence.type()) { | 1015 switch (turbulence.type()) { |
880 case SkPerlinNoiseShader::kFractalNoise_Type: | 1016 case SkPerlinNoiseShader2::kFractalNoise_Type: |
881 key |= 0x1; | 1017 key |= 0x1; |
882 break; | 1018 break; |
883 case SkPerlinNoiseShader::kTurbulence_Type: | 1019 case SkPerlinNoiseShader2::kTurbulence_Type: |
884 key |= 0x2; | 1020 key |= 0x2; |
885 break; | 1021 break; |
886 default: | 1022 default: |
887 // leave key at 0 | 1023 // leave key at 0 |
888 break; | 1024 break; |
889 } | 1025 } |
890 | 1026 |
891 if (turbulence.stitchTiles()) { | 1027 if (turbulence.stitchTiles()) { |
892 key |= 0x4; // Flip the 3rd bit if tile stitching is on | 1028 key |= 0x4; // Flip the 3rd bit if tile stitching is on |
893 } | 1029 } |
894 | 1030 |
895 b->add32(key); | 1031 b->add32(key); |
896 } | 1032 } |
897 | 1033 |
898 void GrGLPerlinNoise::onSetData(const GrGLSLProgramDataManager& pdman, | 1034 void GrGLPerlinNoise2::onSetData(const GrGLSLProgramDataManager& pdman, |
899 const GrProcessor& processor) { | 1035 const GrProcessor& processor) { |
900 INHERITED::onSetData(pdman, processor); | 1036 INHERITED::onSetData(pdman, processor); |
901 | 1037 |
902 const GrPerlinNoiseEffect& turbulence = processor.cast<GrPerlinNoiseEffect>(
); | 1038 const GrPerlinNoise2Effect& turbulence = processor.cast<GrPerlinNoise2Effect
>(); |
903 | 1039 |
904 const SkVector& baseFrequency = turbulence.baseFrequency(); | 1040 const SkVector& baseFrequency = turbulence.baseFrequency(); |
905 pdman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY); | 1041 pdman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY); |
906 | 1042 |
907 if (turbulence.stitchTiles()) { | 1043 if (turbulence.stitchTiles()) { |
908 const SkPerlinNoiseShader::StitchData& stitchData = turbulence.stitchDat
a(); | 1044 const SkPerlinNoiseShader2::StitchData& stitchData = turbulence.stitchDa
ta(); |
909 pdman.set2f(fStitchDataUni, SkIntToScalar(stitchData.fWidth), | 1045 pdman.set2f(fStitchDataUni, SkIntToScalar(stitchData.fWidth), |
910 SkIntToScalar(stitchData.fHeight)); | 1046 SkIntToScalar(stitchData.fHeight)); |
911 } | 1047 } |
912 } | 1048 } |
913 | 1049 |
914 ///////////////////////////////////////////////////////////////////// | 1050 ///////////////////////////////////////////////////////////////////// |
915 const GrFragmentProcessor* SkPerlinNoiseShader::asFragmentProcessor( | 1051 |
| 1052 class GrGLImprovedPerlinNoise : public GrGLFragmentProcessor { |
| 1053 public: |
| 1054 GrGLImprovedPerlinNoise(const GrProcessor&); |
| 1055 virtual ~GrGLImprovedPerlinNoise() {} |
| 1056 |
| 1057 virtual void emitCode(EmitArgs&) override; |
| 1058 |
| 1059 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessor
KeyBuilder* b); |
| 1060 |
| 1061 protected: |
| 1062 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override
; |
| 1063 |
| 1064 private: |
| 1065 |
| 1066 SkScalar fZ; |
| 1067 GrGLSLProgramDataManager::UniformHandle fZUni; |
| 1068 GrGLSLProgramDataManager::UniformHandle fOctavesUni; |
| 1069 GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni; |
| 1070 |
| 1071 private: |
| 1072 typedef GrGLFragmentProcessor INHERITED; |
| 1073 }; |
| 1074 |
| 1075 ///////////////////////////////////////////////////////////////////// |
| 1076 |
| 1077 class GrImprovedPerlinNoiseEffect : public GrFragmentProcessor { |
| 1078 public: |
| 1079 static GrFragmentProcessor* Create(SkScalar octaves, SkScalar z, |
| 1080 SkPerlinNoiseShader2::PaintingData* paint
ingData, |
| 1081 GrTexture* permutationsTexture, GrTexture
* gradientTexture, |
| 1082 const SkMatrix& matrix) { |
| 1083 return new GrImprovedPerlinNoiseEffect(octaves, z, paintingData, permuta
tionsTexture, |
| 1084 gradientTexture, matrix); |
| 1085 } |
| 1086 |
| 1087 virtual ~GrImprovedPerlinNoiseEffect() { delete fPaintingData; } |
| 1088 |
| 1089 const char* name() const override { return "ImprovedPerlinNoise"; } |
| 1090 |
| 1091 const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency
; } |
| 1092 SkScalar z() const { return fZ; } |
| 1093 int octaves() const { return fOctaves; } |
| 1094 const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); } |
| 1095 |
| 1096 private: |
| 1097 GrGLFragmentProcessor* onCreateGLInstance() const override { |
| 1098 return new GrGLImprovedPerlinNoise(*this); |
| 1099 } |
| 1100 |
| 1101 virtual void onGetGLProcessorKey(const GrGLSLCaps& caps, |
| 1102 GrProcessorKeyBuilder* b) const override { |
| 1103 GrGLImprovedPerlinNoise::GenKey(*this, caps, b); |
| 1104 } |
| 1105 |
| 1106 bool onIsEqual(const GrFragmentProcessor& sBase) const override { |
| 1107 const GrImprovedPerlinNoiseEffect& s = sBase.cast<GrImprovedPerlinNoiseE
ffect>(); |
| 1108 return fZ == fZ && |
| 1109 fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency; |
| 1110 } |
| 1111 |
| 1112 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
| 1113 inout->setToUnknown(GrInvariantOutput::kWillNot_ReadInput); |
| 1114 } |
| 1115 |
| 1116 GrImprovedPerlinNoiseEffect(int octaves, SkScalar z, |
| 1117 SkPerlinNoiseShader2::PaintingData* paintingData
, |
| 1118 GrTexture* permutationsTexture, GrTexture* gradi
entTexture, |
| 1119 const SkMatrix& matrix) |
| 1120 : fOctaves(octaves) |
| 1121 , fZ(z) |
| 1122 , fPermutationsAccess(permutationsTexture) |
| 1123 , fGradientAccess(gradientTexture) |
| 1124 , fPaintingData(paintingData) { |
| 1125 this->initClassID<GrImprovedPerlinNoiseEffect>(); |
| 1126 this->addTextureAccess(&fPermutationsAccess); |
| 1127 this->addTextureAccess(&fGradientAccess); |
| 1128 fCoordTransform.reset(kLocal_GrCoordSet, matrix); |
| 1129 this->addCoordTransform(&fCoordTransform); |
| 1130 } |
| 1131 |
| 1132 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
| 1133 |
| 1134 GrCoordTransform fCoordTransform; |
| 1135 int fOctaves; |
| 1136 SkScalar fZ; |
| 1137 GrTextureAccess fPermutationsAccess; |
| 1138 GrTextureAccess fGradientAccess; |
| 1139 SkPerlinNoiseShader2::PaintingData *fPaintingData; |
| 1140 |
| 1141 private: |
| 1142 typedef GrFragmentProcessor INHERITED; |
| 1143 }; |
| 1144 |
| 1145 ///////////////////////////////////////////////////////////////////// |
| 1146 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrImprovedPerlinNoiseEffect); |
| 1147 |
| 1148 const GrFragmentProcessor* GrImprovedPerlinNoiseEffect::TestCreate(GrProcessorTe
stData* d) { |
| 1149 SkScalar baseFrequencyX = d->fRandom->nextRangeScalar(0.01f, |
| 1150 0.99f); |
| 1151 SkScalar baseFrequencyY = d->fRandom->nextRangeScalar(0.01f, |
| 1152 0.99f); |
| 1153 int numOctaves = d->fRandom->nextRangeU(2, 10); |
| 1154 SkScalar z = SkIntToScalar(d->fRandom->nextU()); |
| 1155 |
| 1156 SkAutoTUnref<SkShader> shader(SkPerlinNoiseShader2::CreateImprovedNoise(base
FrequencyX, |
| 1157 baseF
requencyY, |
| 1158 numOc
taves, |
| 1159 z)); |
| 1160 |
| 1161 GrPaint grPaint; |
| 1162 return shader->asFragmentProcessor(d->fContext, |
| 1163 GrTest::TestMatrix(d->fRandom), nullptr, |
| 1164 kNone_SkFilterQuality); |
| 1165 } |
| 1166 |
| 1167 GrGLImprovedPerlinNoise::GrGLImprovedPerlinNoise(const GrProcessor& processor) |
| 1168 : fZ(processor.cast<GrImprovedPerlinNoiseEffect>().z()) { |
| 1169 } |
| 1170 |
| 1171 void GrGLImprovedPerlinNoise::emitCode(EmitArgs& args) { |
| 1172 GrGLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder(); |
| 1173 SkString vCoords = fsBuilder->ensureFSCoords2D(args.fCoords, 0); |
| 1174 |
| 1175 fBaseFrequencyUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_
Visibility, |
| 1176 kVec2f_GrSLType, kDefault_GrSLPrecis
ion, |
| 1177 "baseFrequency"); |
| 1178 const char* baseFrequencyUni = args.fBuilder->getUniformCStr(fBaseFrequencyU
ni); |
| 1179 |
| 1180 fOctavesUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibi
lity, |
| 1181 kFloat_GrSLType, kDefault_GrSLPrecision, |
| 1182 "octaves"); |
| 1183 const char* octavesUni = args.fBuilder->getUniformCStr(fOctavesUni); |
| 1184 |
| 1185 fZUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
| 1186 kFloat_GrSLType, kDefault_GrSLPrecision, |
| 1187 "z"); |
| 1188 const char* zUni = args.fBuilder->getUniformCStr(fZUni); |
| 1189 |
| 1190 // fade function |
| 1191 static const GrGLSLShaderVar fadeArgs[] = { |
| 1192 GrGLSLShaderVar("t", kVec3f_GrSLType) |
| 1193 }; |
| 1194 SkString fadeFuncName; |
| 1195 fsBuilder->emitFunction(kVec3f_GrSLType, "fade", SK_ARRAY_COUNT(fadeArgs), |
| 1196 fadeArgs, |
| 1197 "return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);",
|
| 1198 &fadeFuncName); |
| 1199 |
| 1200 // perm function |
| 1201 static const GrGLSLShaderVar permArgs[] = { |
| 1202 GrGLSLShaderVar("x", kFloat_GrSLType) |
| 1203 }; |
| 1204 SkString permFuncName; |
| 1205 SkString permCode("return "); |
| 1206 // FIXME even though I'm creating these textures with kRepeat_TileMode, they
're clamped. Not |
| 1207 // sure why. Using fract() (here and the next texture lookup) as a workaroun
d. |
| 1208 fsBuilder->appendTextureLookup(&permCode, args.fSamplers[0], "vec2(fract(x /
256.0), 0.0)", |
| 1209 kVec2f_GrSLType); |
| 1210 permCode.append(".r * 255.0;"); |
| 1211 fsBuilder->emitFunction(kFloat_GrSLType, "perm", SK_ARRAY_COUNT(permArgs), p
ermArgs, |
| 1212 permCode.c_str(), &permFuncName); |
| 1213 |
| 1214 // grad function |
| 1215 static const GrGLSLShaderVar gradArgs[] = { |
| 1216 GrGLSLShaderVar("x", kFloat_GrSLType), |
| 1217 GrGLSLShaderVar("p", kVec3f_GrSLType) |
| 1218 }; |
| 1219 SkString gradFuncName; |
| 1220 SkString gradCode("return dot("); |
| 1221 fsBuilder->appendTextureLookup(&gradCode, args.fSamplers[1], "vec2(fract(x /
16.0), 0.0)", |
| 1222 kVec2f_GrSLType); |
| 1223 gradCode.append(".rgb * 255.0 - vec3(1.0), p);"); |
| 1224 fsBuilder->emitFunction(kFloat_GrSLType, "grad", SK_ARRAY_COUNT(gradArgs), g
radArgs, |
| 1225 gradCode.c_str(), &gradFuncName); |
| 1226 |
| 1227 // lerp function |
| 1228 static const GrGLSLShaderVar lerpArgs[] = { |
| 1229 GrGLSLShaderVar("a", kFloat_GrSLType), |
| 1230 GrGLSLShaderVar("b", kFloat_GrSLType), |
| 1231 GrGLSLShaderVar("w", kFloat_GrSLType) |
| 1232 }; |
| 1233 SkString lerpFuncName; |
| 1234 fsBuilder->emitFunction(kFloat_GrSLType, "lerp", SK_ARRAY_COUNT(lerpArgs), l
erpArgs, |
| 1235 "return a + w * (b - a);", &lerpFuncName); |
| 1236 |
| 1237 // noise function |
| 1238 static const GrGLSLShaderVar noiseArgs[] = { |
| 1239 GrGLSLShaderVar("p", kVec3f_GrSLType), |
| 1240 }; |
| 1241 SkString noiseFuncName; |
| 1242 SkString noiseCode; |
| 1243 noiseCode.append("vec3 P = mod(floor(p), 256.0);"); |
| 1244 noiseCode.append("p -= floor(p);"); |
| 1245 noiseCode.appendf("vec3 f = %s(p);", fadeFuncName.c_str()); |
| 1246 noiseCode.appendf("float A = %s(P.x) + P.y;", permFuncName.c_str()); |
| 1247 noiseCode.appendf("float AA = %s(A) + P.z;", permFuncName.c_str()); |
| 1248 noiseCode.appendf("float AB = %s(A + 1.0) + P.z;", permFuncName.c_str()); |
| 1249 noiseCode.appendf("float B = %s(P.x + 1.0) + P.y;", permFuncName.c_str()); |
| 1250 noiseCode.appendf("float BA = %s(B) + P.z;", permFuncName.c_str()); |
| 1251 noiseCode.appendf("float BB = %s(B + 1.0) + P.z;", permFuncName.c_str()); |
| 1252 noiseCode.appendf("float result = %s(", lerpFuncName.c_str()); |
| 1253 noiseCode.appendf("%s(%s(%s(%s(AA), p),", lerpFuncName.c_str(), lerpFuncName
.c_str(), |
| 1254 gradFuncName.c_str(), permFuncName.c_str()); |
| 1255 noiseCode.appendf("%s(%s(BA), p + vec3(-1.0, 0.0, 0.0)), f.x),", gradFuncNam
e.c_str(), |
| 1256 permFuncName.c_str()); |
| 1257 noiseCode.appendf("%s(%s(%s(AB), p + vec3(0.0, -1.0, 0.0)),", lerpFuncName.c
_str(), |
| 1258 gradFuncName.c_str(), permFuncName.c_str()); |
| 1259 noiseCode.appendf("%s(%s(BB), p + vec3(-1.0, -1.0, 0.0)), f.x), f.y),", |
| 1260 gradFuncName.c_str(), permFuncName.c_str()); |
| 1261 noiseCode.appendf("%s(%s(%s(%s(AA + 1.0), p + vec3(0.0, 0.0, -1.0)),", |
| 1262 lerpFuncName.c_str(), lerpFuncName.c_str(), gradFuncName.c
_str(), |
| 1263 permFuncName.c_str()); |
| 1264 noiseCode.appendf("%s(%s(BA + 1.0), p + vec3(-1.0, 0.0, -1.0)), f.x),", |
| 1265 gradFuncName.c_str(), permFuncName.c_str()); |
| 1266 noiseCode.appendf("%s(%s(%s(AB + 1.0), p + vec3(0.0, -1.0, -1.0)),", |
| 1267 lerpFuncName.c_str(), gradFuncName.c_str(), permFuncName.c
_str()); |
| 1268 noiseCode.appendf("%s(%s(BB + 1.0), p + vec3(-1.0, -1.0, -1.0)), f.x), f.y),
f.z);", |
| 1269 gradFuncName.c_str(), permFuncName.c_str()); |
| 1270 noiseCode.append("return result;"); |
| 1271 fsBuilder->emitFunction(kFloat_GrSLType, "noise", SK_ARRAY_COUNT(noiseArgs),
noiseArgs, |
| 1272 noiseCode.c_str(), &noiseFuncName); |
| 1273 |
| 1274 // noiseOctaves function |
| 1275 static const GrGLSLShaderVar noiseOctavesArgs[] = { |
| 1276 GrGLSLShaderVar("p", kVec3f_GrSLType), |
| 1277 GrGLSLShaderVar("octaves", kFloat_GrSLType), |
| 1278 }; |
| 1279 SkString noiseOctavesFuncName; |
| 1280 SkString noiseOctavesCode; |
| 1281 noiseOctavesCode.append("float result = 0.0;"); |
| 1282 noiseOctavesCode.append("float ratio = 1.0;"); |
| 1283 noiseOctavesCode.append("for (float i = 0.0; i < octaves; i++) {"); |
| 1284 noiseOctavesCode.appendf("result += %s(p) / ratio;", noiseFuncName.c_str()); |
| 1285 noiseOctavesCode.append("p *= 2.0;"); |
| 1286 noiseOctavesCode.append("ratio *= 2.0;"); |
| 1287 noiseOctavesCode.append("}"); |
| 1288 noiseOctavesCode.append("return (result + 1.0) / 2.0;"); |
| 1289 fsBuilder->emitFunction(kFloat_GrSLType, "noiseOctaves", SK_ARRAY_COUNT(nois
eOctavesArgs), |
| 1290 noiseOctavesArgs, noiseOctavesCode.c_str(), &noiseOc
tavesFuncName); |
| 1291 |
| 1292 fsBuilder->codeAppendf("vec2 coords = %s * %s;", vCoords.c_str(), baseFreque
ncyUni); |
| 1293 fsBuilder->codeAppendf("float r = %s(vec3(coords, %s), %s);", noiseOctavesFu
ncName.c_str(), |
| 1294 zUni, octavesUni); |
| 1295 fsBuilder->codeAppendf("float g = %s(vec3(coords, %s + 1000.0), %s);", |
| 1296 noiseOctavesFuncName.c_str(), zUni, octavesUni); |
| 1297 fsBuilder->codeAppendf("float b = %s(vec3(coords, %s + 2000.0), %s);", |
| 1298 noiseOctavesFuncName.c_str(), zUni, octavesUni); |
| 1299 fsBuilder->codeAppendf("float a = %s(vec3(coords, %s + 3000.0), %s);", |
| 1300 noiseOctavesFuncName.c_str(), zUni, octavesUni); |
| 1301 fsBuilder->codeAppendf("%s = vec4(r, g, b, a);", args.fOutputColor); |
| 1302 |
| 1303 // Clamp values |
| 1304 fsBuilder->codeAppendf("%s = clamp(%s, 0.0, 1.0);", args.fOutputColor, args.
fOutputColor); |
| 1305 |
| 1306 // Pre-multiply the result |
| 1307 fsBuilder->codeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n", |
| 1308 args.fOutputColor, args.fOutputColor, |
| 1309 args.fOutputColor, args.fOutputColor); |
| 1310 } |
| 1311 |
| 1312 void GrGLImprovedPerlinNoise::GenKey(const GrProcessor& processor, const GrGLSLC
aps&, |
| 1313 GrProcessorKeyBuilder* b) { |
| 1314 } |
| 1315 |
| 1316 void GrGLImprovedPerlinNoise::onSetData(const GrGLSLProgramDataManager& pdman, |
| 1317 const GrProcessor& processor) { |
| 1318 INHERITED::onSetData(pdman, processor); |
| 1319 |
| 1320 const GrImprovedPerlinNoiseEffect& noise = processor.cast<GrImprovedPerlinNo
iseEffect>(); |
| 1321 |
| 1322 const SkVector& baseFrequency = noise.baseFrequency(); |
| 1323 pdman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY); |
| 1324 |
| 1325 pdman.set1f(fOctavesUni, noise.octaves()); |
| 1326 |
| 1327 pdman.set1f(fZUni, noise.z()); |
| 1328 } |
| 1329 |
| 1330 ///////////////////////////////////////////////////////////////////// |
| 1331 const GrFragmentProcessor* SkPerlinNoiseShader2::asFragmentProcessor( |
916 GrContext* context, | 1332 GrContext* context, |
917 const SkMatrix& viewM, | 1333 const SkMatrix& viewM, |
918 const SkMatrix* externalLoca
lMatrix, | 1334 const SkMatrix* externalLoca
lMatrix, |
919 SkFilterQuality) const { | 1335 SkFilterQuality) const { |
920 SkASSERT(context); | 1336 SkASSERT(context); |
921 | 1337 |
922 SkMatrix localMatrix = this->getLocalMatrix(); | 1338 SkMatrix localMatrix = this->getLocalMatrix(); |
923 if (externalLocalMatrix) { | 1339 if (externalLocalMatrix) { |
924 localMatrix.preConcat(*externalLocalMatrix); | 1340 localMatrix.preConcat(*externalLocalMatrix); |
925 } | 1341 } |
926 | 1342 |
927 SkMatrix matrix = viewM; | 1343 SkMatrix matrix = viewM; |
928 matrix.preConcat(localMatrix); | 1344 matrix.preConcat(localMatrix); |
929 | 1345 |
| 1346 // Either we don't stitch tiles, either we have a valid tile size |
| 1347 SkASSERT(!fStitchTiles || !fTileSize.isEmpty()); |
| 1348 |
| 1349 SkPerlinNoiseShader2::PaintingData* paintingData = |
| 1350 new PaintingData(fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY,
matrix); |
| 1351 |
| 1352 SkMatrix m = viewM; |
| 1353 m.setTranslateX(-localMatrix.getTranslateX() + SK_Scalar1); |
| 1354 m.setTranslateY(-localMatrix.getTranslateY() + SK_Scalar1); |
| 1355 |
| 1356 if (fType == kImprovedNoise_Type) { |
| 1357 GrTextureParams textureParams(SkShader::TileMode::kRepeat_TileMode, |
| 1358 GrTextureParams::FilterMode::kNone_FilterM
ode); |
| 1359 SkAutoTUnref<GrTexture> permutationsTexture( |
| 1360 GrRefCachedBitmapTexture(context, paintingData->getImprovedPermutati
onsBitmap(), |
| 1361 textureParams)); |
| 1362 SkAutoTUnref<GrTexture> gradientTexture( |
| 1363 GrRefCachedBitmapTexture(context, paintingData->getGradientBitmap(), |
| 1364 textureParams)); |
| 1365 return GrImprovedPerlinNoiseEffect::Create(fNumOctaves, fSeed, paintingD
ata, |
| 1366 permutationsTexture, gradient
Texture, m); |
| 1367 } |
| 1368 |
930 if (0 == fNumOctaves) { | 1369 if (0 == fNumOctaves) { |
931 if (kFractalNoise_Type == fType) { | 1370 if (kFractalNoise_Type == fType) { |
932 // Extract the incoming alpha and emit rgba = (a/4, a/4, a/4, a/2) | 1371 // Extract the incoming alpha and emit rgba = (a/4, a/4, a/4, a/2) |
933 SkAutoTUnref<const GrFragmentProcessor> inner( | 1372 SkAutoTUnref<const GrFragmentProcessor> inner( |
934 GrConstColorProcessor::Create(0x80404040, | 1373 GrConstColorProcessor::Create(0x80404040, |
935 GrConstColorProcessor::kModulateRG
BA_InputMode)); | 1374 GrConstColorProcessor::kModulateRG
BA_InputMode)); |
936 return GrFragmentProcessor::MulOutputByInputAlpha(inner); | 1375 return GrFragmentProcessor::MulOutputByInputAlpha(inner); |
937 } | 1376 } |
938 // Emit zero. | 1377 // Emit zero. |
939 return GrConstColorProcessor::Create(0x0, GrConstColorProcessor::kIgnore
_InputMode); | 1378 return GrConstColorProcessor::Create(0x0, GrConstColorProcessor::kIgnore
_InputMode); |
940 } | 1379 } |
941 | 1380 |
942 // Either we don't stitch tiles, either we have a valid tile size | |
943 SkASSERT(!fStitchTiles || !fTileSize.isEmpty()); | |
944 | |
945 SkPerlinNoiseShader::PaintingData* paintingData = | |
946 new PaintingData(fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY,
matrix); | |
947 SkAutoTUnref<GrTexture> permutationsTexture( | 1381 SkAutoTUnref<GrTexture> permutationsTexture( |
948 GrRefCachedBitmapTexture(context, paintingData->getPermutationsBitmap(), | 1382 GrRefCachedBitmapTexture(context, paintingData->getPermutationsBitmap(), |
949 GrTextureParams::ClampNoFilter())); | 1383 GrTextureParams::ClampNoFilter())); |
950 SkAutoTUnref<GrTexture> noiseTexture( | 1384 SkAutoTUnref<GrTexture> noiseTexture( |
951 GrRefCachedBitmapTexture(context, paintingData->getNoiseBitmap(), | 1385 GrRefCachedBitmapTexture(context, paintingData->getNoiseBitmap(), |
952 GrTextureParams::ClampNoFilter())); | 1386 GrTextureParams::ClampNoFilter())); |
953 | 1387 |
954 SkMatrix m = viewM; | |
955 m.setTranslateX(-localMatrix.getTranslateX() + SK_Scalar1); | |
956 m.setTranslateY(-localMatrix.getTranslateY() + SK_Scalar1); | |
957 if ((permutationsTexture) && (noiseTexture)) { | 1388 if ((permutationsTexture) && (noiseTexture)) { |
958 SkAutoTUnref<GrFragmentProcessor> inner( | 1389 SkAutoTUnref<GrFragmentProcessor> inner( |
959 GrPerlinNoiseEffect::Create(fType, | 1390 GrPerlinNoise2Effect::Create(fType, |
960 fNumOctaves, | 1391 fNumOctaves, |
961 fStitchTiles, | 1392 fStitchTiles, |
962 paintingData, | 1393 paintingData, |
963 permutationsTexture, noiseTexture, | 1394 permutationsTexture, noiseTexture, |
964 m)); | 1395 m)); |
965 return GrFragmentProcessor::MulOutputByInputAlpha(inner); | 1396 return GrFragmentProcessor::MulOutputByInputAlpha(inner); |
966 } | 1397 } |
967 delete paintingData; | 1398 delete paintingData; |
968 return nullptr; | 1399 return nullptr; |
969 } | 1400 } |
970 | 1401 |
971 #endif | 1402 #endif |
972 | 1403 |
973 #ifndef SK_IGNORE_TO_STRING | 1404 #ifndef SK_IGNORE_TO_STRING |
974 void SkPerlinNoiseShader::toString(SkString* str) const { | 1405 void SkPerlinNoiseShader2::toString(SkString* str) const { |
975 str->append("SkPerlinNoiseShader: ("); | 1406 str->append("SkPerlinNoiseShader2: ("); |
976 | 1407 |
977 str->append("type: "); | 1408 str->append("type: "); |
978 switch (fType) { | 1409 switch (fType) { |
979 case kFractalNoise_Type: | 1410 case kFractalNoise_Type: |
980 str->append("\"fractal noise\""); | 1411 str->append("\"fractal noise\""); |
981 break; | 1412 break; |
982 case kTurbulence_Type: | 1413 case kTurbulence_Type: |
983 str->append("\"turbulence\""); | 1414 str->append("\"turbulence\""); |
984 break; | 1415 break; |
985 default: | 1416 default: |
986 str->append("\"unknown\""); | 1417 str->append("\"unknown\""); |
987 break; | 1418 break; |
988 } | 1419 } |
989 str->append(" base frequency: ("); | 1420 str->append(" base frequency: ("); |
990 str->appendScalar(fBaseFrequencyX); | 1421 str->appendScalar(fBaseFrequencyX); |
991 str->append(", "); | 1422 str->append(", "); |
992 str->appendScalar(fBaseFrequencyY); | 1423 str->appendScalar(fBaseFrequencyY); |
993 str->append(") number of octaves: "); | 1424 str->append(") number of octaves: "); |
994 str->appendS32(fNumOctaves); | 1425 str->appendS32(fNumOctaves); |
995 str->append(" seed: "); | 1426 str->append(" seed: "); |
996 str->appendScalar(fSeed); | 1427 str->appendScalar(fSeed); |
997 str->append(" stitch tiles: "); | 1428 str->append(" stitch tiles: "); |
998 str->append(fStitchTiles ? "true " : "false "); | 1429 str->append(fStitchTiles ? "true " : "false "); |
999 | 1430 |
1000 this->INHERITED::toString(str); | 1431 this->INHERITED::toString(str); |
1001 | 1432 |
1002 str->append(")"); | 1433 str->append(")"); |
1003 } | 1434 } |
1004 #endif | 1435 #endif |
OLD | NEW |