2 * Copyright 2013 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
9 #include "SkPerlinNoiseShader2.h"
10 #include "SkColorFilter.h"
11 #include "SkReadBuffer.h"
12 #include "SkWriteBuffer.h"
14 #include "SkUnPreMultiply.h"
18 #include "GrContext.h"
19 #include "GrCoordTransform.h"
20 #include "GrInvariantOutput.h"
22 #include "effects/GrConstColorProcessor.h"
23 #include "glsl/GrGLSLFragmentProcessor.h"
24 #include "glsl/GrGLSLFragmentShaderBuilder.h"
25 #include "glsl/GrGLSLProgramBuilder.h"
26 #include "glsl/GrGLSLProgramDataManager.h"
29 static const int kBlockSize = 256;
30 static const int kBlockMask = kBlockSize - 1;
31 static const int kPerlinNoise = 4096;
32 static const int kRandMaximum = SK_MaxS32; // 2**31 - 1
34 static uint8_t improved_noise_permutations[] = {
35 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103,
36 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26,
37 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174,
38 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231,
39 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143,
40 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196,
41 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124,
42 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17,
43 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101,
44 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185,
45 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81,
46 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176,
47 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243,
48 141, 128, 195, 78, 66, 215, 61, 156, 180,
49 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103,
50 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26,
51 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174,
52 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231,
53 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143,
54 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196,
55 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124,
56 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17,
57 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101,
58 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185,
59 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81,
60 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176,
61 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243,
62 141, 128, 195, 78, 66, 215, 61, 156, 180
67 // noiseValue is the color component's value (or color)
68 // limitValue is the maximum perlin noise array index value allowed
69 // newValue is the current noise dimension (either width or height)
70 inline int checkNoise(int noiseValue, int limitValue, int newValue) {
71 // If the noise value would bring us out of bounds of the current noise array while we are
72 // stiching noise tiles together, wrap the noise around the current dimension of the noise to
73 // stay within the array bounds in a continuous fashion (so that tiling lines are not visible)
74 if (noiseValue >= limitValue) {
75 noiseValue -= newValue;
80 inline SkScalar smoothCurve(SkScalar t) {
81 static const SkScalar SK_Scalar3 = 3.0f;
83 // returns t * t * (3 - 2 * t)
84 return SkScalarMul(SkScalarSquare(t), SK_Scalar3 - 2 * t);
89 struct SkPerlinNoiseShader2::StitchData {
97 bool operator==(const StitchData& other) const {
98 return fWidth == other.fWidth &&
99 fWrapX == other.fWrapX &&
100 fHeight == other.fHeight &&
101 fWrapY == other.fWrapY;
104 int fWidth; // How much to subtract to wrap for stitching.
105 int fWrapX; // Minimum value to wrap.
110 struct SkPerlinNoiseShader2::PaintingData {
111 PaintingData(const SkISize& tileSize, SkScalar seed,
112 SkScalar baseFrequencyX, SkScalar baseFrequencyY,
113 const SkMatrix& matrix)
116 { SkScalarInvert(baseFrequencyX), SkScalarInvert(baseFrequencyY) },
117 { SkIntToScalar(tileSize.fWidth), SkIntToScalar(tileSize.fHeight) },
119 matrix.mapVectors(vec, 2);
121 fBaseFrequency.set(SkScalarInvert(vec[0].fX), SkScalarInvert(vec[0].fY));
122 fTileSize.set(SkScalarRoundToInt(vec[1].fX), SkScalarRoundToInt(vec[1].fY));
124 if (!fTileSize.isEmpty()) {
129 fPermutationsBitmap.setInfo(SkImageInfo::MakeA8(kBlockSize, 1));
130 fPermutationsBitmap.setPixels(fLatticeSelector);
132 fNoiseBitmap.setInfo(SkImageInfo::MakeN32Premul(kBlockSize, 4));
133 fNoiseBitmap.setPixels(fNoise[0][0]);
135 fImprovedPermutationsBitmap.setInfo(SkImageInfo::MakeA8(256, 1));
136 fImprovedPermutationsBitmap.setPixels(improved_noise_permutations);
138 fGradientBitmap.setInfo(SkImageInfo::MakeN32Premul(16, 1));
139 static uint8_t gradients[] = { 2, 2, 1, 0,
155 fGradientBitmap.setPixels(gradients);
160 uint8_t fLatticeSelector[kBlockSize];
161 uint16_t fNoise[4][kBlockSize][2];
162 SkPoint fGradient[4][kBlockSize];
164 SkVector fBaseFrequency;
165 StitchData fStitchDataInit;
170 SkBitmap fPermutationsBitmap;
171 SkBitmap fNoiseBitmap;
172 SkBitmap fImprovedPermutationsBitmap;
173 SkBitmap fGradientBitmap;
176 inline int random() {
177 static const int gRandAmplitude = 16807; // 7**5; primitive root of m
178 static const int gRandQ = 127773; // m / a
179 static const int gRandR = 2836; // m % a
181 int result = gRandAmplitude * (fSeed % gRandQ) - gRandR * (fSeed / gRandQ);
183 result += kRandMaximum;
188 // Only called once. Could be part of the constructor.
189 void init(SkScalar seed)
191 static const SkScalar gInvBlockSizef = SkScalarInvert(SkIntToScalar(kBlockSize));
193 // According to the SVG spec, we must truncate (not round) the seed value.
194 fSeed = SkScalarTruncToInt(seed);
195 // The seed value clamp to the range [1, kRandMaximum - 1].
197 fSeed = -(fSeed % (kRandMaximum - 1)) + 1;
199 if (fSeed > kRandMaximum - 1) {
200 fSeed = kRandMaximum - 1;
202 for (int channel = 0; channel < 4; ++channel) {
203 for (int i = 0; i < kBlockSize; ++i) {
204 fLatticeSelector[i] = i;
205 fNoise[channel][i][0] = (random() % (2 * kBlockSize));
206 fNoise[channel][i][1] = (random() % (2 * kBlockSize));
209 for (int i = kBlockSize - 1; i > 0; --i) {
210 int k = fLatticeSelector[i];
211 int j = random() % kBlockSize;
213 SkASSERT(j < kBlockSize);
214 fLatticeSelector[i] = fLatticeSelector[j];
215 fLatticeSelector[j] = k;
218 // Perform the permutations now
221 uint16_t noise[4][kBlockSize][2];
222 for (int i = 0; i < kBlockSize; ++i) {
223 for (int channel = 0; channel < 4; ++channel) {
224 for (int j = 0; j < 2; ++j) {
225 noise[channel][i][j] = fNoise[channel][i][j];
229 // Do permutations on noise data
230 for (int i = 0; i < kBlockSize; ++i) {
231 for (int channel = 0; channel < 4; ++channel) {
232 for (int j = 0; j < 2; ++j) {
233 fNoise[channel][i][j] = noise[channel][fLatticeSelector[i]][j];
239 // Half of the largest possible value for 16 bit unsigned int
240 static const SkScalar gHalfMax16bits = 32767.5f;
242 // Compute gradients from permutated noise data
243 for (int channel = 0; channel < 4; ++channel) {
244 for (int i = 0; i < kBlockSize; ++i) {
245 fGradient[channel][i] = SkPoint::Make(
246 SkScalarMul(SkIntToScalar(fNoise[channel][i][0] - kBlockSize),
248 SkScalarMul(SkIntToScalar(fNoise[channel][i][1] - kBlockSize),
250 fGradient[channel][i].normalize();
251 // Put the normalized gradient back into the noise data
252 fNoise[channel][i][0] = SkScalarRoundToInt(SkScalarMul(
253 fGradient[channel][i].fX + SK_Scalar1, gHalfMax16bits));
254 fNoise[channel][i][1] = SkScalarRoundToInt(SkScalarMul(
255 fGradient[channel][i].fY + SK_Scalar1, gHalfMax16bits));
260 // Only called once. Could be part of the constructor.
262 SkScalar tileWidth = SkIntToScalar(fTileSize.width());
263 SkScalar tileHeight = SkIntToScalar(fTileSize.height());
264 SkASSERT(tileWidth > 0 && tileHeight > 0);
265 // When stitching tiled turbulence, the frequencies must be adjusted
266 // so that the tile borders will be continuous.
267 if (fBaseFrequency.fX) {
268 SkScalar lowFrequencx =
269 SkScalarFloorToScalar(tileWidth * fBaseFrequency.fX) / tileWidth;
270 SkScalar highFrequencx =
271 SkScalarCeilToScalar(tileWidth * fBaseFrequency.fX) / tileWidth;
272 // BaseFrequency should be non-negative according to the standard.
273 if (fBaseFrequency.fX / lowFrequencx < highFrequencx / fBaseFrequency.fX) {
274 fBaseFrequency.fX = lowFrequencx;
276 fBaseFrequency.fX = highFrequencx;
279 if (fBaseFrequency.fY) {
280 SkScalar lowFrequency =
281 SkScalarFloorToScalar(tileHeight * fBaseFrequency.fY) / tileHeight;
282 SkScalar highFrequency =
283 SkScalarCeilToScalar(tileHeight * fBaseFrequency.fY) / tileHeight;
284 if (fBaseFrequency.fY / lowFrequency < highFrequency / fBaseFrequency.fY) {
285 fBaseFrequency.fY = lowFrequency;
287 fBaseFrequency.fY = highFrequency;
290 // Set up TurbulenceInitial stitch values.
291 fStitchDataInit.fWidth =
292 SkScalarRoundToInt(tileWidth * fBaseFrequency.fX);
293 fStitchDataInit.fWrapX = kPerlinNoise + fStitchDataInit.fWidth;
294 fStitchDataInit.fHeight =
295 SkScalarRoundToInt(tileHeight * fBaseFrequency.fY);
296 fStitchDataInit.fWrapY = kPerlinNoise + fStitchDataInit.fHeight;
302 const SkBitmap& getPermutationsBitmap() const { return fPermutationsBitmap; }
304 const SkBitmap& getNoiseBitmap() const { return fNoiseBitmap; }
306 const SkBitmap& getImprovedPermutationsBitmap() const { return fImprovedPermutationsBitmap; }
308 const SkBitmap& getGradientBitmap() const { return fGradientBitmap; }
312 SkShader* SkPerlinNoiseShader2::CreateFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY,
313 int numOctaves, SkScalar seed,
314 const SkISize* tileSize) {
315 return new SkPerlinNoiseShader2(kFractalNoise_Type, baseFrequencyX, baseFrequencyY, numOctaves,
319 SkShader* SkPerlinNoiseShader2::CreateTurbulence(SkScalar baseFrequencyX, SkScalar baseFrequencyY,
320 int numOctaves, SkScalar seed,
321 const SkISize* tileSize) {
322 return new SkPerlinNoiseShader2(kTurbulence_Type, baseFrequencyX, baseFrequencyY, numOctaves,
326 SkShader* SkPerlinNoiseShader2::CreateImprovedNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY,
327 int numOctaves, SkScalar z) {
328 return new SkPerlinNoiseShader2(kImprovedNoise_Type, baseFrequencyX, baseFrequencyY, numOctaves,
332 SkPerlinNoiseShader2::SkPerlinNoiseShader2(SkPerlinNoiseShader2::Type type,
333 SkScalar baseFrequencyX,
334 SkScalar baseFrequencyY,
337 const SkISize* tileSize)
339 , fBaseFrequencyX(baseFrequencyX)
340 , fBaseFrequencyY(baseFrequencyY)
341 , fNumOctaves(numOctaves > 255 ? 255 : numOctaves/*[0,255] octaves allowed*/)
343 , fTileSize(nullptr == tileSize ? SkISize::Make(0, 0) : *tileSize)
344 , fStitchTiles(!fTileSize.isEmpty())
346 SkASSERT(numOctaves >= 0 && numOctaves < 256);
349 SkPerlinNoiseShader2::~SkPerlinNoiseShader2() {
352 SkFlattenable* SkPerlinNoiseShader2::CreateProc(SkReadBuffer& buffer) {
353 Type type = (Type)buffer.readInt();
354 SkScalar freqX = buffer.readScalar();
355 SkScalar freqY = buffer.readScalar();
356 int octaves = buffer.readInt();
357 SkScalar seed = buffer.readScalar();
359 tileSize.fWidth = buffer.readInt();
360 tileSize.fHeight = buffer.readInt();
363 case kFractalNoise_Type:
364 return SkPerlinNoiseShader2::CreateFractalNoise(freqX, freqY, octaves, seed, &tileSize);
365 case kTurbulence_Type:
366 return SkPerlinNoiseShader2::CreateTubulence(freqX, freqY, octaves, seed, &tileSize);
367 case kImprovedNoise_Type:
368 return SkPerlinNoiseShader2::CreateImprovedNoise(freqX, freqY, octaves, seed);
374 void SkPerlinNoiseShader2::flatten(SkWriteBuffer& buffer) const {
375 buffer.writeInt((int) fType);
376 buffer.writeScalar(fBaseFrequencyX);
377 buffer.writeScalar(fBaseFrequencyY);
378 buffer.writeInt(fNumOctaves);
379 buffer.writeScalar(fSeed);
380 buffer.writeInt(fTileSize.fWidth);
381 buffer.writeInt(fTileSize.fHeight);
384 SkScalar SkPerlinNoiseShader2::PerlinNoiseShaderContext::noise2D(
385 int channel, const StitchData& stitchData, const SkPoint& noiseVector) const {
387 int noisePositionIntegerValue;
388 int nextNoisePositionIntegerValue;
389 SkScalar noisePositionFractionValue;
390 Noise(SkScalar component)
392 SkScalar position = component + kPerlinNoise;
393 noisePositionIntegerValue = SkScalarFloorToInt(position);
394 noisePositionFractionValue = position - SkIntToScalar(noisePositionIntegerValue);
395 nextNoisePositionIntegerValue = noisePositionIntegerValue + 1;
398 Noise noiseX(noiseVector.x());
399 Noise noiseY(noiseVector.y());
401 const SkPerlinNoiseShader2& perlinNoiseShader = static_cast<const SkPerlinNoiseShader2&>(fShader);
402 // If stitching, adjust lattice points accordingly.
403 if (perlinNoiseShader.fStitchTiles) {
404 noiseX.noisePositionIntegerValue =
405 checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stitchData.fWidth);
406 noiseY.noisePositionIntegerValue =
407 checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stitchData.fHeight);
408 noiseX.nextNoisePositionIntegerValue =
409 checkNoise(noiseX.nextNoisePositionIntegerValue, stitchData.fWrapX, stitchData.fWidth);
410 noiseY.nextNoisePositionIntegerValue =
411 checkNoise(noiseY.nextNoisePositionIntegerValue, stitchData.fWrapY, stitchData.fHeight);
413 noiseX.noisePositionIntegerValue &= kBlockMask;
414 noiseY.noisePositionIntegerValue &= kBlockMask;
415 noiseX.nextNoisePositionIntegerValue &= kBlockMask;
416 noiseY.nextNoisePositionIntegerValue &= kBlockMask;
418 fPaintingData->fLatticeSelector[noiseX.noisePositionIntegerValue];
420 fPaintingData->fLatticeSelector[noiseX.nextNoisePositionIntegerValue];
421 int b00 = (i + noiseY.noisePositionIntegerValue) & kBlockMask;
422 int b10 = (j + noiseY.noisePositionIntegerValue) & kBlockMask;
423 int b01 = (i + noiseY.nextNoisePositionIntegerValue) & kBlockMask;
424 int b11 = (j + noiseY.nextNoisePositionIntegerValue) & kBlockMask;
425 SkScalar sx = smoothCurve(noiseX.noisePositionFractionValue);
426 SkScalar sy = smoothCurve(noiseY.noisePositionFractionValue);
427 // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement
428 SkPoint fractionValue = SkPoint::Make(noiseX.noisePositionFractionValue,
429 noiseY.noisePositionFractionValue); // Offset (0,0)
430 u = fPaintingData->fGradient[channel][b00].dot(fractionValue);
431 fractionValue.fX -= SK_Scalar1; // Offset (-1,0)
432 v = fPaintingData->fGradient[channel][b10].dot(fractionValue);
433 SkScalar a = SkScalarInterp(u, v, sx);
434 fractionValue.fY -= SK_Scalar1; // Offset (-1,-1)
435 v = fPaintingData->fGradient[channel][b11].dot(fractionValue);
436 fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1)
437 u = fPaintingData->fGradient[channel][b01].dot(fractionValue);
438 SkScalar b = SkScalarInterp(u, v, sx);
439 return SkScalarInterp(a, b, sy);
442 SkScalar SkPerlinNoiseShader2::PerlinNoiseShaderContext::calculateTurbulenceValueForPoint(
443 int channel, StitchData& stitchData, const SkPoint& point) const {
444 const SkPerlinNoiseShader2& perlinNoiseShader = static_cast<const SkPerlinNoiseShader2&>(fShader);
445 if (perlinNoiseShader.fStitchTiles) {
446 // Set up TurbulenceInitial stitch values.
447 stitchData = fPaintingData->fStitchDataInit;
449 SkScalar turbulenceFunctionResult = 0;
450 SkPoint noiseVector(SkPoint::Make(SkScalarMul(point.x(), fPaintingData->fBaseFrequency.fX),
451 SkScalarMul(point.y(), fPaintingData->fBaseFrequency.fY)));
452 SkScalar ratio = SK_Scalar1;
453 for (int octave = 0; octave < perlinNoiseShader.fNumOctaves; ++octave) {
454 SkScalar noise = noise2D(channel, stitchData, noiseVector);
455 SkScalar numer = (perlinNoiseShader.fType == kFractalNoise_Type) ?
456 noise : SkScalarAbs(noise);
457 turbulenceFunctionResult += numer / ratio;
461 if (perlinNoiseShader.fStitchTiles) {
462 // Update stitch values
463 stitchData.fWidth *= 2;
464 stitchData.fWrapX = stitchData.fWidth + kPerlinNoise;
465 stitchData.fHeight *= 2;
466 stitchData.fWrapY = stitchData.fHeight + kPerlinNoise;
470 // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
471 // by fractalNoise and (turbulenceFunctionResult) by turbulence.
472 if (perlinNoiseShader.fType == kFractalNoise_Type) {
473 turbulenceFunctionResult =
474 SkScalarMul(turbulenceFunctionResult, SK_ScalarHalf) + SK_ScalarHalf;
477 if (channel == 3) { // Scale alpha by paint value
478 turbulenceFunctionResult *= SkIntToScalar(getPaintAlpha()) / 255;
482 return SkScalarPin(turbulenceFunctionResult, 0, SK_Scalar1);
485 ////////////////////////////////////////////////////////////////////////////////////////////////////
486 // Improved Perlin Noise based on Java implementation found at http://mrl.nyu.edu/~perlin/noise/
487 static SkScalar fade(SkScalar t) {
488 return t * t * t * (t * (t * 6 - 15) + 10);
491 static SkScalar lerp(SkScalar t, SkScalar a, SkScalar b) {
492 return a + t * (b - a);
495 static SkScalar grad(int hash, SkScalar x, SkScalar y, SkScalar z) {
497 SkScalar u = h < 8 ? x : y;
498 SkScalar v = h < 4 ? y : h == 12 || h == 14 ? x : z;
499 return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
502 SkScalar SkPerlinNoiseShader2::PerlinNoiseShaderContext::calculateImprovedNoiseValueForPoint(
503 int channel, const SkPoint& point) const {
504 const SkPerlinNoiseShader2& perlinNoiseShader = static_cast<const SkPerlinNoiseShader2&>(fShader);
505 SkScalar x = point.fX * perlinNoiseShader.fBaseFrequencyX;
506 SkScalar y = point.fY * perlinNoiseShader.fBaseFrequencyY;
507 // z offset between different channels, chosen arbitrarily
508 static const SkScalar CHANNEL_DELTA = 1000.0f;
509 SkScalar z = channel * CHANNEL_DELTA + perlinNoiseShader.fSeed;
511 SkScalar ratio = SK_Scalar1;
512 for (int i = 0; i < perlinNoiseShader.fNumOctaves; i++) {
513 int X = SkScalarFloorToInt(x) & 255;
514 int Y = SkScalarFloorToInt(y) & 255;
515 int Z = SkScalarFloorToInt(z) & 255;
516 SkScalar px = x - SkScalarFloorToScalar(x);
517 SkScalar py = y - SkScalarFloorToScalar(y);
518 SkScalar pz = z - SkScalarFloorToScalar(z);
519 SkScalar u = fade(px);
520 SkScalar v = fade(py);
521 SkScalar w = fade(pz);
522 uint8_t* permutations = improved_noise_permutations;
523 int A = permutations[X] + Y;
524 int AA = permutations[A] + Z;
525 int AB = permutations[A + 1] + Z;
526 int B = permutations[X + 1] + Y;
527 int BA = permutations[B] + Z;
528 int BB = permutations[B + 1] + Z;
529 result += lerp(w, lerp(v, lerp(u, grad(permutations[AA ], px , py , pz ),
530 grad(permutations[BA ], px - 1, py , pz )),
531 lerp(u, grad(permutations[AB ], px , py - 1, pz ),
532 grad(permutations[BB ], px - 1, py - 1, pz ))),
533 lerp(v, lerp(u, grad(permutations[AA + 1], px , py , pz - 1),
534 grad(permutations[BA + 1], px - 1, py , pz - 1)),
535 lerp(u, grad(permutations[AB + 1], px , py - 1, pz - 1),
536 grad(permutations[BB + 1], px - 1, py - 1, pz - 1)))) /
542 result = SkScalarClampMax((result + 1.0f) / 2.0f, 1.0f);
545 ////////////////////////////////////////////////////////////////////////////////////////////////////
547 SkPMColor SkPerlinNoiseShader2::PerlinNoiseShaderContext::shade(
548 const SkPoint& point, StitchData& stitchData) const {
549 const SkPerlinNoiseShader2& perlinNoiseShader = static_cast<const SkPerlinNoiseShader2&>(fShader);
551 fMatrix.mapPoints(&newPoint, &point, 1);
552 newPoint.fX = SkScalarRoundToScalar(newPoint.fX);
553 newPoint.fY = SkScalarRoundToScalar(newPoint.fY);
556 for (int channel = 3; channel >= 0; --channel) {
558 if (perlinNoiseShader.fType == kImprovedNoise_Type) {
559 value = calculateImprovedNoiseValueForPoint(channel, newPoint);
562 value = calculateTurbulenceValueForPoint(channel, stitchData, newPoint);
564 rgba[channel] = SkScalarFloorToInt(255 * value);
566 return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
569 SkShader::Context* SkPerlinNoiseShader2::onCreateContext(const ContextRec& rec,
570 void* storage) const {
571 return new (storage) PerlinNoiseShaderContext(*this, rec);
574 size_t SkPerlinNoiseShader2::contextSize() const {
575 return sizeof(PerlinNoiseShaderContext);
578 SkPerlinNoiseShader2::PerlinNoiseShaderContext::PerlinNoiseShaderContext(
579 const SkPerlinNoiseShader2& shader, const ContextRec& rec)
580 : INHERITED(shader, rec)
582 SkMatrix newMatrix = *rec.fMatrix;
583 newMatrix.preConcat(shader.getLocalMatrix());
584 if (rec.fLocalMatrix) {
585 newMatrix.preConcat(*rec.fLocalMatrix);
587 // This (1,1) translation is due to WebKit's 1 based coordinates for the noise
588 // (as opposed to 0 based, usually). The same adjustment is in the setData() function.
589 fMatrix.setTranslate(-newMatrix.getTranslateX() + SK_Scalar1, -newMatrix.getTranslateY() + SK_Scalar1);
590 fPaintingData = new PaintingData(shader.fTileSize, shader.fSeed, shader.fBaseFrequencyX,
591 shader.fBaseFrequencyY, newMatrix);
594 SkPerlinNoiseShader2::PerlinNoiseShaderContext::~PerlinNoiseShaderContext() { delete fPaintingData; }
596 void SkPerlinNoiseShader2::PerlinNoiseShaderContext::shadeSpan(
597 int x, int y, SkPMColor result[], int count) {
598 SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y));
599 StitchData stitchData;
600 for (int i = 0; i < count; ++i) {
601 result[i] = shade(point, stitchData);
602 point.fX += SK_Scalar1;
606 void SkPerlinNoiseShader2::PerlinNoiseShaderContext::shadeSpan16(
607 int x, int y, uint16_t result[], int count) {
608 SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y));
609 StitchData stitchData;
611 for (int i = 0; i < count; ++i) {
612 unsigned dither = DITHER_VALUE(x);
613 result[i] = SkDitherRGB32To565(shade(point, stitchData), dither);
615 point.fX += SK_Scalar1;
619 /////////////////////////////////////////////////////////////////////
623 class GrGLPerlinNoise2 : public GrGLSLFragmentProcessor {
625 GrGLPerlinNoise2(const GrProcessor&);
626 virtual ~GrGLPerlinNoise2() {}
628 virtual void emitCode(EmitArgs&) override;
630 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder* b);
633 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
637 GrGLSLProgramDataManager::UniformHandle fStitchDataUni;
638 SkPerlinNoiseShader2::Type fType;
641 GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni;
644 typedef GrGLSLFragmentProcessor INHERITED;
647 /////////////////////////////////////////////////////////////////////
649 class GrPerlinNoise2Effect : public GrFragmentProcessor {
651 static GrFragmentProcessor* Create(SkPerlinNoiseShader2::Type type,
652 int numOctaves, bool stitchTiles,
653 SkPerlinNoiseShader2::PaintingData* paintingData,
654 GrTexture* permutationsTexture, GrTexture* noiseTexture,
655 const SkMatrix& matrix) {
656 return new GrPerlinNoise2Effect(type, numOctaves, stitchTiles, paintingData,
657 permutationsTexture, noiseTexture, matrix);
660 virtual ~GrPerlinNoise2Effect() { delete fPaintingData; }
662 const char* name() const override { return "PerlinNoise"; }
664 const SkPerlinNoiseShader2::StitchData& stitchData() const { return fPaintingData->fStitchDataInit; }
666 SkPerlinNoiseShader2::Type type() const { return fType; }
667 bool stitchTiles() const { return fStitchTiles; }
668 const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency; }
669 int numOctaves() const { return fNumOctaves; }
670 const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); }
673 GrGLSLFragmentProcessor* onCreateGLInstance() const override {
674 return new GrGLPerlinNoise2(*this);
677 virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
678 GrProcessorKeyBuilder* b) const override {
679 GrGLPerlinNoise2::GenKey(*this, caps, b);
682 bool onIsEqual(const GrFragmentProcessor& sBase) const override {
683 const GrPerlinNoise2Effect& s = sBase.cast<GrPerlinNoise2Effect>();
684 return fType == s.fType &&
685 fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency &&
686 fNumOctaves == s.fNumOctaves &&
687 fStitchTiles == s.fStitchTiles &&
688 fPaintingData->fStitchDataInit == s.fPaintingData->fStitchDataInit;
691 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
692 inout->setToUnknown(GrInvariantOutput::kWillNot_ReadInput);
695 GrPerlinNoise2Effect(SkPerlinNoiseShader2::Type type,
696 int numOctaves, bool stitchTiles,
697 SkPerlinNoiseShader2::PaintingData* paintingData,
698 GrTexture* permutationsTexture, GrTexture* noiseTexture,
699 const SkMatrix& matrix)
701 , fNumOctaves(numOctaves)
702 , fStitchTiles(stitchTiles)
703 , fPermutationsAccess(permutationsTexture)
704 , fNoiseAccess(noiseTexture)
705 , fPaintingData(paintingData) {
706 this->initClassID<GrPerlinNoise2Effect>();
707 this->addTextureAccess(&fPermutationsAccess);
708 this->addTextureAccess(&fNoiseAccess);
709 fCoordTransform.reset(kLocal_GrCoordSet, matrix);
710 this->addCoordTransform(&fCoordTransform);
713 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
715 SkPerlinNoiseShader2::Type fType;
716 GrCoordTransform fCoordTransform;
719 GrTextureAccess fPermutationsAccess;
720 GrTextureAccess fNoiseAccess;
721 SkPerlinNoiseShader2::PaintingData *fPaintingData;
724 typedef GrFragmentProcessor INHERITED;
727 /////////////////////////////////////////////////////////////////////
728 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrPerlinNoise2Effect);
730 const GrFragmentProcessor* GrPerlinNoise2Effect::TestCreate(GrProcessorTestData* d) {
731 int numOctaves = d->fRandom->nextRangeU(2, 10);
732 bool stitchTiles = d->fRandom->nextBool();
733 SkScalar seed = SkIntToScalar(d->fRandom->nextU());
734 SkISize tileSize = SkISize::Make(d->fRandom->nextRangeU(4, 4096),
735 d->fRandom->nextRangeU(4, 4096));
736 SkScalar baseFrequencyX = d->fRandom->nextRangeScalar(0.01f,
738 SkScalar baseFrequencyY = d->fRandom->nextRangeScalar(0.01f,
741 SkAutoTUnref<SkShader> shader(d->fRandom->nextBool() ?
742 SkPerlinNoiseShader2::CreateFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves, seed,
743 stitchTiles ? &tileSize : nullptr) :
744 SkPerlinNoiseShader2::CreateTurbulence(baseFrequencyX, baseFrequencyY, numOctaves, seed,
745 stitchTiles ? &tileSize : nullptr));
748 return shader->asFragmentProcessor(d->fContext,
749 GrTest::TestMatrix(d->fRandom), nullptr,
750 kNone_SkFilterQuality);
753 GrGLPerlinNoise2::GrGLPerlinNoise2(const GrProcessor& processor)
754 : fType(processor.cast<GrPerlinNoise2Effect>().type())
755 , fStitchTiles(processor.cast<GrPerlinNoise2Effect>().stitchTiles())
756 , fNumOctaves(processor.cast<GrPerlinNoise2Effect>().numOctaves()) {
759 void GrGLPerlinNoise2::emitCode(EmitArgs& args) {
760 GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
761 SkString vCoords = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
763 fBaseFrequencyUni = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
764 kVec2f_GrSLType, kDefault_GrSLPrecision,
766 const char* baseFrequencyUni = args.fBuilder->getUniformCStr(fBaseFrequencyUni);
768 const char* stitchDataUni = nullptr;
770 fStitchDataUni = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
771 kVec2f_GrSLType, kDefault_GrSLPrecision,
773 stitchDataUni = args.fBuilder->getUniformCStr(fStitchDataUni);
776 // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8
777 const char* chanCoordR = "0.125";
778 const char* chanCoordG = "0.375";
779 const char* chanCoordB = "0.625";
780 const char* chanCoordA = "0.875";
781 const char* chanCoord = "chanCoord";
782 const char* stitchData = "stitchData";
783 const char* ratio = "ratio";
784 const char* noiseVec = "noiseVec";
785 const char* noiseSmooth = "noiseSmooth";
786 const char* floorVal = "floorVal";
787 const char* fractVal = "fractVal";
788 const char* uv = "uv";
789 const char* ab = "ab";
790 const char* latticeIdx = "latticeIdx";
791 const char* bcoords = "bcoords";
792 const char* lattice = "lattice";
793 const char* inc8bit = "0.00390625"; // 1.0 / 256.0
794 // This is the math to convert the two 16bit integer packed into rgba 8 bit input into a
795 // [-1,1] vector and perform a dot product between that vector and the provided vector.
796 const char* dotLattice = "dot(((%s.ga + %s.rb * vec2(%s)) * vec2(2.0) - vec2(1.0)), %s);";
798 // Add noise function
799 static const GrGLSLShaderVar gPerlinNoiseArgs[] = {
800 GrGLSLShaderVar(chanCoord, kFloat_GrSLType),
801 GrGLSLShaderVar(noiseVec, kVec2f_GrSLType)
804 static const GrGLSLShaderVar gPerlinNoiseStitchArgs[] = {
805 GrGLSLShaderVar(chanCoord, kFloat_GrSLType),
806 GrGLSLShaderVar(noiseVec, kVec2f_GrSLType),
807 GrGLSLShaderVar(stitchData, kVec2f_GrSLType)
812 noiseCode.appendf("\tvec4 %s;\n", floorVal);
813 noiseCode.appendf("\t%s.xy = floor(%s);\n", floorVal, noiseVec);
814 noiseCode.appendf("\t%s.zw = %s.xy + vec2(1.0);\n", floorVal, floorVal);
815 noiseCode.appendf("\tvec2 %s = fract(%s);\n", fractVal, noiseVec);
817 // smooth curve : t * t * (3 - 2 * t)
818 noiseCode.appendf("\n\tvec2 %s = %s * %s * (vec2(3.0) - vec2(2.0) * %s);",
819 noiseSmooth, fractVal, fractVal, fractVal);
821 // Adjust frequencies if we're stitching tiles
823 noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }",
824 floorVal, stitchData, floorVal, stitchData);
825 noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }",
826 floorVal, stitchData, floorVal, stitchData);
827 noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }",
828 floorVal, stitchData, floorVal, stitchData);
829 noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }",
830 floorVal, stitchData, floorVal, stitchData);
833 // Get texture coordinates and normalize
834 noiseCode.appendf("\n\t%s = fract(floor(mod(%s, 256.0)) / vec4(256.0));\n",
837 // Get permutation for x
839 SkString xCoords("");
840 xCoords.appendf("vec2(%s.x, 0.5)", floorVal);
842 noiseCode.appendf("\n\tvec2 %s;\n\t%s.x = ", latticeIdx, latticeIdx);
843 fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[0], xCoords.c_str(),
845 noiseCode.append(".r;");
848 // Get permutation for x + 1
850 SkString xCoords("");
851 xCoords.appendf("vec2(%s.z, 0.5)", floorVal);
853 noiseCode.appendf("\n\t%s.y = ", latticeIdx);
854 fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[0], xCoords.c_str(),
856 noiseCode.append(".r;");
859 #if defined(SK_BUILD_FOR_ANDROID)
860 // Android rounding for Tegra devices, like, for example: Xoom (Tegra 2), Nexus 7 (Tegra 3).
861 // The issue is that colors aren't accurate enough on Tegra devices. For example, if an 8 bit
862 // value of 124 (or 0.486275 here) is entered, we can get a texture value of 123.513725
863 // (or 0.484368 here). The following rounding operation prevents these precision issues from
864 // affecting the result of the noise by making sure that we only have multiples of 1/255.
865 // (Note that 1/255 is about 0.003921569, which is the value used here).
866 noiseCode.appendf("\n\t%s = floor(%s * vec2(255.0) + vec2(0.5)) * vec2(0.003921569);",
867 latticeIdx, latticeIdx);
870 // Get (x,y) coordinates with the permutated x
871 noiseCode.appendf("\n\tvec4 %s = fract(%s.xyxy + %s.yyww);", bcoords, latticeIdx, floorVal);
873 noiseCode.appendf("\n\n\tvec2 %s;", uv);
874 // Compute u, at offset (0,0)
876 SkString latticeCoords("");
877 latticeCoords.appendf("vec2(%s.x, %s)", bcoords, chanCoord);
878 noiseCode.appendf("\n\tvec4 %s = ", lattice);
879 fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
881 noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
882 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
885 noiseCode.appendf("\n\t%s.x -= 1.0;", fractVal);
886 // Compute v, at offset (-1,0)
888 SkString latticeCoords("");
889 latticeCoords.appendf("vec2(%s.y, %s)", bcoords, chanCoord);
890 noiseCode.append("\n\tlattice = ");
891 fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
893 noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
894 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
897 // Compute 'a' as a linear interpolation of 'u' and 'v'
898 noiseCode.appendf("\n\tvec2 %s;", ab);
899 noiseCode.appendf("\n\t%s.x = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth);
901 noiseCode.appendf("\n\t%s.y -= 1.0;", fractVal);
902 // Compute v, at offset (-1,-1)
904 SkString latticeCoords("");
905 latticeCoords.appendf("vec2(%s.w, %s)", bcoords, chanCoord);
906 noiseCode.append("\n\tlattice = ");
907 fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
909 noiseCode.appendf(".bgra;\n\t%s.y = ", uv);
910 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
913 noiseCode.appendf("\n\t%s.x += 1.0;", fractVal);
914 // Compute u, at offset (0,-1)
916 SkString latticeCoords("");
917 latticeCoords.appendf("vec2(%s.z, %s)", bcoords, chanCoord);
918 noiseCode.append("\n\tlattice = ");
919 fsBuilder->appendTextureLookup(&noiseCode, args.fSamplers[1], latticeCoords.c_str(),
921 noiseCode.appendf(".bgra;\n\t%s.x = ", uv);
922 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal);
925 // Compute 'b' as a linear interpolation of 'u' and 'v'
926 noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth);
927 // Compute the noise as a linear interpolation of 'a' and 'b'
928 noiseCode.appendf("\n\treturn mix(%s.x, %s.y, %s.y);\n", ab, ab, noiseSmooth);
930 SkString noiseFuncName;
932 fsBuilder->emitFunction(kFloat_GrSLType,
933 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStitchArgs),
934 gPerlinNoiseStitchArgs, noiseCode.c_str(), &noiseFuncName);
936 fsBuilder->emitFunction(kFloat_GrSLType,
937 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs),
938 gPerlinNoiseArgs, noiseCode.c_str(), &noiseFuncName);
941 // There are rounding errors if the floor operation is not performed here
942 fsBuilder->codeAppendf("\n\t\tvec2 %s = floor(%s.xy) * %s;",
943 noiseVec, vCoords.c_str(), baseFrequencyUni);
945 // Clear the color accumulator
946 fsBuilder->codeAppendf("\n\t\t%s = vec4(0.0);", args.fOutputColor);
949 // Set up TurbulenceInitial stitch values.
950 fsBuilder->codeAppendf("\n\t\tvec2 %s = %s;", stitchData, stitchDataUni);
953 fsBuilder->codeAppendf("\n\t\tfloat %s = 1.0;", ratio);
955 // Loop over all octaves
956 fsBuilder->codeAppendf("\n\t\tfor (int octave = 0; octave < %d; ++octave) {", fNumOctaves);
958 fsBuilder->codeAppendf("\n\t\t\t%s += ", args.fOutputColor);
959 if (fType != SkPerlinNoiseShader2::kFractalNoise_Type) {
960 fsBuilder->codeAppend("abs(");
963 fsBuilder->codeAppendf(
964 "vec4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s),"
965 "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))",
966 noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData,
967 noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData,
968 noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData,
969 noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData);
971 fsBuilder->codeAppendf(
972 "vec4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s),"
973 "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))",
974 noiseFuncName.c_str(), chanCoordR, noiseVec,
975 noiseFuncName.c_str(), chanCoordG, noiseVec,
976 noiseFuncName.c_str(), chanCoordB, noiseVec,
977 noiseFuncName.c_str(), chanCoordA, noiseVec);
979 if (fType != SkPerlinNoiseShader2::kFractalNoise_Type) {
980 fsBuilder->codeAppendf(")"); // end of "abs("
982 fsBuilder->codeAppendf(" * %s;", ratio);
984 fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", noiseVec);
985 fsBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio);
988 fsBuilder->codeAppendf("\n\t\t\t%s *= vec2(2.0);", stitchData);
990 fsBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves
992 if (fType == SkPerlinNoiseShader2::kFractalNoise_Type) {
993 // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2
994 // by fractalNoise and (turbulenceFunctionResult) by turbulence.
995 fsBuilder->codeAppendf("\n\t\t%s = %s * vec4(0.5) + vec4(0.5);",
996 args.fOutputColor,args.fOutputColor);
1000 fsBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", args.fOutputColor, args.fOutputColor);
1002 // Pre-multiply the result
1003 fsBuilder->codeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
1004 args.fOutputColor, args.fOutputColor,
1005 args.fOutputColor, args.fOutputColor);
1008 void GrGLPerlinNoise2::GenKey(const GrProcessor& processor, const GrGLSLCaps&,
1009 GrProcessorKeyBuilder* b) {
1010 const GrPerlinNoise2Effect& turbulence = processor.cast<GrPerlinNoise2Effect>();
1012 uint32_t key = turbulence.numOctaves();
1014 key = key << 3; // Make room for next 3 bits
1016 switch (turbulence.type()) {
1017 case SkPerlinNoiseShader2::kFractalNoise_Type:
1020 case SkPerlinNoiseShader2::kTurbulence_Type:
1028 if (turbulence.stitchTiles()) {
1029 key |= 0x4; // Flip the 3rd bit if tile stitching is on
1035 void GrGLPerlinNoise2::onSetData(const GrGLSLProgramDataManager& pdman,
1036 const GrProcessor& processor) {
1037 INHERITED::onSetData(pdman, processor);
1039 const GrPerlinNoise2Effect& turbulence = processor.cast<GrPerlinNoise2Effect>();
1041 const SkVector& baseFrequency = turbulence.baseFrequency();
1042 pdman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY);
1044 if (turbulence.stitchTiles()) {
1045 const SkPerlinNoiseShader2::StitchData& stitchData = turbulence.stitchData();
1046 pdman.set2f(fStitchDataUni, SkIntToScalar(stitchData.fWidth),
1047 SkIntToScalar(stitchData.fHeight));
1051 /////////////////////////////////////////////////////////////////////
1053 class GrGLImprovedPerlinNoise : public GrGLSLFragmentProcessor {
1055 GrGLImprovedPerlinNoise(const GrProcessor&);
1056 virtual ~GrGLImprovedPerlinNoise() {}
1058 virtual void emitCode(EmitArgs&) override;
1060 static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder* b);
1063 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
1068 GrGLSLProgramDataManager::UniformHandle fZUni;
1069 GrGLSLProgramDataManager::UniformHandle fOctavesUni;
1070 GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni;
1073 typedef GrGLSLFragmentProcessor INHERITED;
1076 /////////////////////////////////////////////////////////////////////
1078 class GrImprovedPerlinNoiseEffect : public GrFragmentProcessor {
1080 static GrFragmentProcessor* Create(int octaves, SkScalar z,
1081 SkPerlinNoiseShader2::PaintingData* paintingData,
1082 GrTexture* permutationsTexture, GrTexture* gradientTexture,
1083 const SkMatrix& matrix) {
1084 return new GrImprovedPerlinNoiseEffect(octaves, z, paintingData, permutationsTexture,
1085 gradientTexture, matrix);
1088 virtual ~GrImprovedPerlinNoiseEffect() { delete fPaintingData; }
1090 const char* name() const override { return "ImprovedPerlinNoise"; }
1092 const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency; }
1093 SkScalar z() const { return fZ; }
1094 int octaves() const { return fOctaves; }
1095 const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); }
1098 GrGLSLFragmentProcessor* onCreateGLInstance() const override {
1099 return new GrGLImprovedPerlinNoise(*this);
1102 virtual void onGetGLProcessorKey(const GrGLSLCaps& caps,
1103 GrProcessorKeyBuilder* b) const override {
1104 GrGLImprovedPerlinNoise::GenKey(*this, caps, b);
1107 bool onIsEqual(const GrFragmentProcessor& sBase) const override {
1108 const GrImprovedPerlinNoiseEffect& s = sBase.cast<GrImprovedPerlinNoiseEffect>();
1110 fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency;
1113 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
1114 inout->setToUnknown(GrInvariantOutput::kWillNot_ReadInput);
1117 GrImprovedPerlinNoiseEffect(int octaves, SkScalar z,
1118 SkPerlinNoiseShader2::PaintingData* paintingData,
1119 GrTexture* permutationsTexture, GrTexture* gradientTexture,
1120 const SkMatrix& matrix)
1123 , fPermutationsAccess(permutationsTexture)
1124 , fGradientAccess(gradientTexture)
1125 , fPaintingData(paintingData) {
1126 this->initClassID<GrImprovedPerlinNoiseEffect>();
1127 this->addTextureAccess(&fPermutationsAccess);
1128 this->addTextureAccess(&fGradientAccess);
1129 fCoordTransform.reset(kLocal_GrCoordSet, matrix);
1130 this->addCoordTransform(&fCoordTransform);
1133 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
1135 GrCoordTransform fCoordTransform;
1138 GrTextureAccess fPermutationsAccess;
1139 GrTextureAccess fGradientAccess;
1140 SkPerlinNoiseShader2::PaintingData *fPaintingData;
1143 typedef GrFragmentProcessor INHERITED;
1146 /////////////////////////////////////////////////////////////////////
1147 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrImprovedPerlinNoiseEffect);
1149 const GrFragmentProcessor* GrImprovedPerlinNoiseEffect::TestCreate(GrProcessorTestData* d) {
1150 SkScalar baseFrequencyX = d->fRandom->nextRangeScalar(0.01f,
1152 SkScalar baseFrequencyY = d->fRandom->nextRangeScalar(0.01f,
1154 int numOctaves = d->fRandom->nextRangeU(2, 10);
1155 SkScalar z = SkIntToScalar(d->fRandom->nextU());
1157 SkAutoTUnref<SkShader> shader(SkPerlinNoiseShader2::CreateImprovedNoise(baseFrequencyX,
1163 return shader->asFragmentProcessor(d->fContext,
1164 GrTest::TestMatrix(d->fRandom), nullptr,
1165 kNone_SkFilterQuality);
1168 GrGLImprovedPerlinNoise::GrGLImprovedPerlinNoise(const GrProcessor& processor)
1169 : fZ(processor.cast<GrImprovedPerlinNoiseEffect>().z()) {
1172 void GrGLImprovedPerlinNoise::emitCode(EmitArgs& args) {
1173 GrGLSLFragmentBuilder* fsBuilder = args.fBuilder->getFragmentShaderBuilder();
1174 SkString vCoords = fsBuilder->ensureFSCoords2D(args.fCoords, 0);
1176 fBaseFrequencyUni = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
1177 kVec2f_GrSLType, kDefault_GrSLPrecision,
1179 const char* baseFrequencyUni = args.fBuilder->getUniformCStr(fBaseFrequencyUni);
1181 fOctavesUni = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
1182 kFloat_GrSLType, kDefault_GrSLPrecision,
1184 const char* octavesUni = args.fBuilder->getUniformCStr(fOctavesUni);
1186 fZUni = args.fBuilder->addUniform(GrGLSLProgramBuilder::kFragment_Visibility,
1187 kFloat_GrSLType, kDefault_GrSLPrecision,
1189 const char* zUni = args.fBuilder->getUniformCStr(fZUni);
1192 static const GrGLSLShaderVar fadeArgs[] = {
1193 GrGLSLShaderVar("t", kVec3f_GrSLType)
1195 SkString fadeFuncName;
1196 fsBuilder->emitFunction(kVec3f_GrSLType, "fade", SK_ARRAY_COUNT(fadeArgs),
1198 "return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);",
1202 static const GrGLSLShaderVar permArgs[] = {
1203 GrGLSLShaderVar("x", kFloat_GrSLType)
1205 SkString permFuncName;
1206 SkString permCode("return ");
1207 // FIXME even though I'm creating these textures with kRepeat_TileMode, they're clamped. Not
1208 // sure why. Using fract() (here and the next texture lookup) as a workaround.
1209 fsBuilder->appendTextureLookup(&permCode, args.fSamplers[0], "vec2(fract(x / 256.0), 0.0)",
1211 permCode.append(".r * 255.0;");
1212 fsBuilder->emitFunction(kFloat_GrSLType, "perm", SK_ARRAY_COUNT(permArgs), permArgs,
1213 permCode.c_str(), &permFuncName);
1216 static const GrGLSLShaderVar gradArgs[] = {
1217 GrGLSLShaderVar("x", kFloat_GrSLType),
1218 GrGLSLShaderVar("p", kVec3f_GrSLType)
1220 SkString gradFuncName;
1221 SkString gradCode("return dot(");
1222 fsBuilder->appendTextureLookup(&gradCode, args.fSamplers[1], "vec2(fract(x / 16.0), 0.0)",
1224 gradCode.append(".rgb * 255.0 - vec3(1.0), p);");
1225 fsBuilder->emitFunction(kFloat_GrSLType, "grad", SK_ARRAY_COUNT(gradArgs), gradArgs,
1226 gradCode.c_str(), &gradFuncName);
1229 static const GrGLSLShaderVar lerpArgs[] = {
1230 GrGLSLShaderVar("a", kFloat_GrSLType),
1231 GrGLSLShaderVar("b", kFloat_GrSLType),
1232 GrGLSLShaderVar("w", kFloat_GrSLType)
1234 SkString lerpFuncName;
1235 fsBuilder->emitFunction(kFloat_GrSLType, "lerp", SK_ARRAY_COUNT(lerpArgs), lerpArgs,
1236 "return a + w * (b - a);", &lerpFuncName);
1239 static const GrGLSLShaderVar noiseArgs[] = {
1240 GrGLSLShaderVar("p", kVec3f_GrSLType),
1242 SkString noiseFuncName;
1244 noiseCode.append("vec3 P = mod(floor(p), 256.0);");
1245 noiseCode.append("p -= floor(p);");
1246 noiseCode.appendf("vec3 f = %s(p);", fadeFuncName.c_str());
1247 noiseCode.appendf("float A = %s(P.x) + P.y;", permFuncName.c_str());
1248 noiseCode.appendf("float AA = %s(A) + P.z;", permFuncName.c_str());
1249 noiseCode.appendf("float AB = %s(A + 1.0) + P.z;", permFuncName.c_str());
1250 noiseCode.appendf("float B = %s(P.x + 1.0) + P.y;", permFuncName.c_str());
1251 noiseCode.appendf("float BA = %s(B) + P.z;", permFuncName.c_str());
1252 noiseCode.appendf("float BB = %s(B + 1.0) + P.z;", permFuncName.c_str());
1253 noiseCode.appendf("float result = %s(", lerpFuncName.c_str());
1254 noiseCode.appendf("%s(%s(%s(%s(AA), p),", lerpFuncName.c_str(), lerpFuncName.c_str(),
1255 gradFuncName.c_str(), permFuncName.c_str());
1256 noiseCode.appendf("%s(%s(BA), p + vec3(-1.0, 0.0, 0.0)), f.x),", gradFuncName.c_str(),
1257 permFuncName.c_str());
1258 noiseCode.appendf("%s(%s(%s(AB), p + vec3(0.0, -1.0, 0.0)),", lerpFuncName.c_str(),
1259 gradFuncName.c_str(), permFuncName.c_str());
1260 noiseCode.appendf("%s(%s(BB), p + vec3(-1.0, -1.0, 0.0)), f.x), f.y),",
1261 gradFuncName.c_str(), permFuncName.c_str());
1262 noiseCode.appendf("%s(%s(%s(%s(AA + 1.0), p + vec3(0.0, 0.0, -1.0)),",
1263 lerpFuncName.c_str(), lerpFuncName.c_str(), gradFuncName.c_str(),
1264 permFuncName.c_str());
1265 noiseCode.appendf("%s(%s(BA + 1.0), p + vec3(-1.0, 0.0, -1.0)), f.x),",
1266 gradFuncName.c_str(), permFuncName.c_str());
1267 noiseCode.appendf("%s(%s(%s(AB + 1.0), p + vec3(0.0, -1.0, -1.0)),",
1268 lerpFuncName.c_str(), gradFuncName.c_str(), permFuncName.c_str());
1269 noiseCode.appendf("%s(%s(BB + 1.0), p + vec3(-1.0, -1.0, -1.0)), f.x), f.y), f.z);",
1270 gradFuncName.c_str(), permFuncName.c_str());
1271 noiseCode.append("return result;");
1272 fsBuilder->emitFunction(kFloat_GrSLType, "noise", SK_ARRAY_COUNT(noiseArgs), noiseArgs,
1273 noiseCode.c_str(), &noiseFuncName);
1275 // noiseOctaves function
1276 static const GrGLSLShaderVar noiseOctavesArgs[] = {
1277 GrGLSLShaderVar("p", kVec3f_GrSLType),
1278 GrGLSLShaderVar("octaves", kFloat_GrSLType),
1280 SkString noiseOctavesFuncName;
1281 SkString noiseOctavesCode;
1282 noiseOctavesCode.append("float result = 0.0;");
1283 noiseOctavesCode.append("float ratio = 1.0;");
1284 noiseOctavesCode.append("for (float i = 0.0; i < octaves; i++) {");
1285 noiseOctavesCode.appendf("result += %s(p) / ratio;", noiseFuncName.c_str());
1286 noiseOctavesCode.append("p *= 2.0;");
1287 noiseOctavesCode.append("ratio *= 2.0;");
1288 noiseOctavesCode.append("}");
1289 noiseOctavesCode.append("return (result + 1.0) / 2.0;");
1290 fsBuilder->emitFunction(kFloat_GrSLType, "noiseOctaves", SK_ARRAY_COUNT(noiseOctavesArgs),
1291 noiseOctavesArgs, noiseOctavesCode.c_str(), &noiseOctavesFuncName);
1293 fsBuilder->codeAppendf("vec2 coords = %s * %s;", vCoords.c_str(), baseFrequencyUni);
1294 fsBuilder->codeAppendf("float r = %s(vec3(coords, %s), %s);", noiseOctavesFuncName.c_str(),
1296 fsBuilder->codeAppendf("float g = %s(vec3(coords, %s + 0000.0), %s);",
1297 noiseOctavesFuncName.c_str(), zUni, octavesUni);
1298 fsBuilder->codeAppendf("float b = %s(vec3(coords, %s + 0000.0), %s);",
1299 noiseOctavesFuncName.c_str(), zUni, octavesUni);
1300 fsBuilder->codeAppendf("float a = %s(vec3(coords, %s + 0000.0), %s);",
1301 noiseOctavesFuncName.c_str(), zUni, octavesUni);
1302 fsBuilder->codeAppendf("%s = vec4(r, g, b, a);", args.fOutputColor);
1305 fsBuilder->codeAppendf("%s = clamp(%s, 0.0, 1.0);", args.fOutputColor, args.fOutputColor);
1307 // Pre-multiply the result
1308 fsBuilder->codeAppendf("\n\t\t%s = vec4(%s.rgb * %s.aaa, %s.a);\n",
1309 args.fOutputColor, args.fOutputColor,
1310 args.fOutputColor, args.fOutputColor);
1313 void GrGLImprovedPerlinNoise::GenKey(const GrProcessor& processor, const GrGLSLCaps&,
1314 GrProcessorKeyBuilder* b) {
1317 void GrGLImprovedPerlinNoise::onSetData(const GrGLSLProgramDataManager& pdman,
1318 const GrProcessor& processor) {
1319 INHERITED::onSetData(pdman, processor);
1321 const GrImprovedPerlinNoiseEffect& noise = processor.cast<GrImprovedPerlinNoiseEffect>();
1323 const SkVector& baseFrequency = noise.baseFrequency();
1324 pdman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY);
1326 pdman.set1f(fOctavesUni, SkIntToScalar(noise.octaves()));
1328 pdman.set1f(fZUni, noise.z());
1331 /////////////////////////////////////////////////////////////////////
1332 const GrFragmentProcessor* SkPerlinNoiseShader2::asFragmentProcessor(
1334 const SkMatrix& viewM,
1335 const SkMatrix* externalLocalMatrix,
1336 SkFilterQuality) const {
1339 SkMatrix localMatrix = this->getLocalMatrix();
1340 if (externalLocalMatrix) {
1341 localMatrix.preConcat(*externalLocalMatrix);
1344 SkMatrix matrix = viewM;
1345 matrix.preConcat(localMatrix);
1347 // Either we don't stitch tiles, either we have a valid tile size
1348 SkASSERT(!fStitchTiles || !fTileSize.isEmpty());
1350 SkPerlinNoiseShader2::PaintingData* paintingData =
1351 new PaintingData(fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY, matrix);
1354 m.setTranslateX(-localMatrix.getTranslateX() + SK_Scalar1);
1355 m.setTranslateY(-localMatrix.getTranslateY() + SK_Scalar1);
1357 if (fType == kImprovedNoise_Type) {
1358 GrTextureParams textureParams(SkShader::TileMode::kRepeat_TileMode,
1359 GrTextureParams::FilterMode::kNone_FilterMode);
1360 SkAutoTUnref<GrTexture> permutationsTexture(
1361 GrRefCachedBitmapTexture(context, paintingData->getImprovedPermutationsBitmap(),
1363 SkAutoTUnref<GrTexture> gradientTexture(
1364 GrRefCachedBitmapTexture(context, paintingData->getGradientBitmap(),
1366 return GrImprovedPerlinNoiseEffect::Create(fNumOctaves, fSeed, paintingData,
1367 permutationsTexture, gradientTexture, m);
1370 if (0 == fNumOctaves) {
1371 if (kFractalNoise_Type == fType) {
1372 // Extract the incoming alpha and emit rgba = (a/4, a/4, a/4, a/2)
1373 SkAutoTUnref<const GrFragmentProcessor> inner(
1374 GrConstColorProcessor::Create(0x80404040,
1375 GrConstColorProcessor::kModulateRGBA_InputMode));
1376 return GrFragmentProcessor::MulOutputByInputAlpha(inner);
1379 return GrConstColorProcessor::Create(0x0, GrConstColorProcessor::kIgnore_InputMode);
1382 SkAutoTUnref<GrTexture> permutationsTexture(
1383 GrRefCachedBitmapTexture(context, paintingData->getPermutationsBitmap(),
1384 GrTextureParams::ClampNoFilter()));
1385 SkAutoTUnref<GrTexture> noiseTexture(
1386 GrRefCachedBitmapTexture(context, paintingData->getNoiseBitmap(),
1387 GrTextureParams::ClampNoFilter()));
1389 if ((permutationsTexture) && (noiseTexture)) {
1390 SkAutoTUnref<GrFragmentProcessor> inner(
1391 GrPerlinNoise2Effect::Create(fType,
1395 permutationsTexture, noiseTexture,
1397 return GrFragmentProcessor::MulOutputByInputAlpha(inner);
1399 delete paintingData;
1405 #ifndef SK_IGNORE_TO_STRING
1406 void SkPerlinNoiseShader2::toString(SkString* str) const {
1407 str->append("SkPerlinNoiseShader2: (");
1409 str->append("type: ");
1411 case kFractalNoise_Type:
1412 str->append("\"fractal noise\"");
1414 case kTurbulence_Type:
1415 str->append("\"turbulence\"");
1418 str->append("\"unknown\"");
1421 str->append(" base frequency: (");
1422 str->appendScalar(fBaseFrequencyX);
1424 str->appendScalar(fBaseFrequencyY);
1425 str->append(") number of octaves: ");
1426 str->appendS32(fNumOctaves);
1427 str->append(" seed: ");
1428 str->appendScalar(fSeed);
1429 str->append(" stitch tiles: ");
1430 str->append(fStitchTiles ? "true " : "false ");
1432 this->INHERITED::toString(str);