1/* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "SkPerlinNoiseShader.h" 9 10#include "SkArenaAlloc.h" 11#include "SkDither.h" 12#include "SkColorFilter.h" 13#include "SkMakeUnique.h" 14#include "SkReadBuffer.h" 15#include "SkShader.h" 16#include "SkString.h" 17#include "SkUnPreMultiply.h" 18#include "SkWriteBuffer.h" 19 20#if SK_SUPPORT_GPU 21#include "GrContext.h" 22#include "GrContextPriv.h" 23#include "GrCoordTransform.h" 24#include "SkGr.h" 25#include "effects/GrConstColorProcessor.h" 26#include "glsl/GrGLSLFragmentProcessor.h" 27#include "glsl/GrGLSLFragmentShaderBuilder.h" 28#include "glsl/GrGLSLProgramDataManager.h" 29#include "glsl/GrGLSLUniformHandler.h" 30#endif 31 32static const int kBlockSize = 256; 33static const int kBlockMask = kBlockSize - 1; 34static const int kPerlinNoise = 4096; 35static const int kRandMaximum = SK_MaxS32; // 2**31 - 1 36 37static uint8_t improved_noise_permutations[] = { 38 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 39 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 40 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 41 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 42 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 43 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 44 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 45 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 46 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 47 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 48 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 49 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 50 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 51 141, 128, 195, 78, 66, 215, 61, 156, 180, 52 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 53 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 54 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 55 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 56 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 57 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 58 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 59 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 60 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 61 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 62 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 63 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 64 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 65 141, 128, 195, 78, 66, 215, 61, 156, 180 66}; 67 68class SkPerlinNoiseShaderImpl : public SkShaderBase { 69public: 70 struct StitchData { 71 StitchData() 72 : fWidth(0) 73 , fWrapX(0) 74 , fHeight(0) 75 , fWrapY(0) 76 {} 77 78 bool operator==(const StitchData& other) const { 79 return fWidth == other.fWidth && 80 fWrapX == other.fWrapX && 81 fHeight == other.fHeight && 82 fWrapY == other.fWrapY; 83 } 84 85 int fWidth; // How much to subtract to wrap for stitching. 86 int fWrapX; // Minimum value to wrap. 87 int fHeight; 88 int fWrapY; 89 }; 90 91 struct PaintingData { 92 PaintingData(const SkISize& tileSize, SkScalar seed, 93 SkScalar baseFrequencyX, SkScalar baseFrequencyY, 94 const SkMatrix& matrix) 95 { 96 SkVector vec[2] = { 97 { SkScalarInvert(baseFrequencyX), SkScalarInvert(baseFrequencyY) }, 98 { SkIntToScalar(tileSize.fWidth), SkIntToScalar(tileSize.fHeight) }, 99 }; 100 matrix.mapVectors(vec, 2); 101 102 fBaseFrequency.set(SkScalarInvert(vec[0].fX), SkScalarInvert(vec[0].fY)); 103 fTileSize.set(SkScalarRoundToInt(vec[1].fX), SkScalarRoundToInt(vec[1].fY)); 104 this->init(seed); 105 if (!fTileSize.isEmpty()) { 106 this->stitch(); 107 } 108 109 #if SK_SUPPORT_GPU 110 SkImageInfo info = SkImageInfo::MakeA8(kBlockSize, 1); 111 SkPixmap permutationsPixmap(info, fLatticeSelector, info.minRowBytes()); 112 fPermutationsImage = SkImage::MakeFromRaster(permutationsPixmap, nullptr, nullptr); 113 114 info = SkImageInfo::MakeN32Premul(kBlockSize, 4); 115 SkPixmap noisePixmap(info, fNoise[0][0], info.minRowBytes()); 116 fNoiseImage = SkImage::MakeFromRaster(noisePixmap, nullptr, nullptr); 117 118 info = SkImageInfo::MakeA8(256, 1); 119 SkPixmap impPermutationsPixmap(info, improved_noise_permutations, info.minRowBytes()); 120 fImprovedPermutationsImage = SkImage::MakeFromRaster(impPermutationsPixmap, nullptr, 121 nullptr); 122 123 static uint8_t gradients[] = { 2, 2, 1, 0, 124 0, 2, 1, 0, 125 2, 0, 1, 0, 126 0, 0, 1, 0, 127 2, 1, 2, 0, 128 0, 1, 2, 0, 129 2, 1, 0, 0, 130 0, 1, 0, 0, 131 1, 2, 2, 0, 132 1, 0, 2, 0, 133 1, 2, 0, 0, 134 1, 0, 0, 0, 135 2, 2, 1, 0, 136 1, 0, 2, 0, 137 0, 2, 1, 0, 138 1, 0, 0, 0 }; 139 info = SkImageInfo::MakeN32Premul(16, 1); 140 SkPixmap gradPixmap(info, gradients, info.minRowBytes()); 141 fGradientImage = SkImage::MakeFromRaster(gradPixmap, nullptr, nullptr); 142 #endif 143 } 144 145 #if SK_SUPPORT_GPU 146 PaintingData(const PaintingData& that) 147 : fSeed(that.fSeed) 148 , fTileSize(that.fTileSize) 149 , fBaseFrequency(that.fBaseFrequency) 150 , fStitchDataInit(that.fStitchDataInit) 151 , fPermutationsImage(that.fPermutationsImage) 152 , fNoiseImage(that.fNoiseImage) 153 , fImprovedPermutationsImage(that.fImprovedPermutationsImage) 154 , fGradientImage(that.fGradientImage) { 155 memcpy(fLatticeSelector, that.fLatticeSelector, sizeof(fLatticeSelector)); 156 memcpy(fNoise, that.fNoise, sizeof(fNoise)); 157 memcpy(fGradient, that.fGradient, sizeof(fGradient)); 158 } 159 #endif 160 161 int fSeed; 162 uint8_t fLatticeSelector[kBlockSize]; 163 uint16_t fNoise[4][kBlockSize][2]; 164 SkPoint fGradient[4][kBlockSize]; 165 SkISize fTileSize; 166 SkVector fBaseFrequency; 167 StitchData fStitchDataInit; 168 169 private: 170 171 #if SK_SUPPORT_GPU 172 sk_sp<SkImage> fPermutationsImage; 173 sk_sp<SkImage> fNoiseImage; 174 sk_sp<SkImage> fImprovedPermutationsImage; 175 sk_sp<SkImage> fGradientImage; 176 #endif 177 178 inline int random() { 179 static const int gRandAmplitude = 16807; // 7**5; primitive root of m 180 static const int gRandQ = 127773; // m / a 181 static const int gRandR = 2836; // m % a 182 183 int result = gRandAmplitude * (fSeed % gRandQ) - gRandR * (fSeed / gRandQ); 184 if (result <= 0) 185 result += kRandMaximum; 186 fSeed = result; 187 return result; 188 } 189 190 // Only called once. Could be part of the constructor. 191 void init(SkScalar seed) 192 { 193 static const SkScalar gInvBlockSizef = SkScalarInvert(SkIntToScalar(kBlockSize)); 194 195 // According to the SVG spec, we must truncate (not round) the seed value. 196 fSeed = SkScalarTruncToInt(seed); 197 // The seed value clamp to the range [1, kRandMaximum - 1]. 198 if (fSeed <= 0) { 199 fSeed = -(fSeed % (kRandMaximum - 1)) + 1; 200 } 201 if (fSeed > kRandMaximum - 1) { 202 fSeed = kRandMaximum - 1; 203 } 204 for (int channel = 0; channel < 4; ++channel) { 205 for (int i = 0; i < kBlockSize; ++i) { 206 fLatticeSelector[i] = i; 207 fNoise[channel][i][0] = (random() % (2 * kBlockSize)); 208 fNoise[channel][i][1] = (random() % (2 * kBlockSize)); 209 } 210 } 211 for (int i = kBlockSize - 1; i > 0; --i) { 212 int k = fLatticeSelector[i]; 213 int j = random() % kBlockSize; 214 SkASSERT(j >= 0); 215 SkASSERT(j < kBlockSize); 216 fLatticeSelector[i] = fLatticeSelector[j]; 217 fLatticeSelector[j] = k; 218 } 219 220 // Perform the permutations now 221 { 222 // Copy noise data 223 uint16_t noise[4][kBlockSize][2]; 224 for (int i = 0; i < kBlockSize; ++i) { 225 for (int channel = 0; channel < 4; ++channel) { 226 for (int j = 0; j < 2; ++j) { 227 noise[channel][i][j] = fNoise[channel][i][j]; 228 } 229 } 230 } 231 // Do permutations on noise data 232 for (int i = 0; i < kBlockSize; ++i) { 233 for (int channel = 0; channel < 4; ++channel) { 234 for (int j = 0; j < 2; ++j) { 235 fNoise[channel][i][j] = noise[channel][fLatticeSelector[i]][j]; 236 } 237 } 238 } 239 } 240 241 // Half of the largest possible value for 16 bit unsigned int 242 static const SkScalar gHalfMax16bits = 32767.5f; 243 244 // Compute gradients from permutated noise data 245 for (int channel = 0; channel < 4; ++channel) { 246 for (int i = 0; i < kBlockSize; ++i) { 247 fGradient[channel][i] = SkPoint::Make( 248 (fNoise[channel][i][0] - kBlockSize) * gInvBlockSizef, 249 (fNoise[channel][i][1] - kBlockSize) * gInvBlockSizef); 250 fGradient[channel][i].normalize(); 251 // Put the normalized gradient back into the noise data 252 fNoise[channel][i][0] = SkScalarRoundToInt( 253 (fGradient[channel][i].fX + 1) * gHalfMax16bits); 254 fNoise[channel][i][1] = SkScalarRoundToInt( 255 (fGradient[channel][i].fY + 1) * gHalfMax16bits); 256 } 257 } 258 } 259 260 // Only called once. Could be part of the constructor. 261 void stitch() { 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; 275 } else { 276 fBaseFrequency.fX = highFrequencx; 277 } 278 } 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; 286 } else { 287 fBaseFrequency.fY = highFrequency; 288 } 289 } 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; 297 } 298 299 public: 300 301#if SK_SUPPORT_GPU 302 const sk_sp<SkImage> getPermutationsImage() const { return fPermutationsImage; } 303 304 const sk_sp<SkImage> getNoiseImage() const { return fNoiseImage; } 305 306 const sk_sp<SkImage> getImprovedPermutationsImage() const { 307 return fImprovedPermutationsImage; 308 } 309 310 const sk_sp<SkImage> getGradientImage() const { return fGradientImage; } 311#endif 312 }; 313 314 /** 315 * About the noise types : the difference between the first 2 is just minor tweaks to the 316 * algorithm, they're not 2 entirely different noises. The output looks different, but once the 317 * noise is generated in the [1, -1] range, the output is brought back in the [0, 1] range by 318 * doing : 319 * kFractalNoise_Type : noise * 0.5 + 0.5 320 * kTurbulence_Type : abs(noise) 321 * Very little differences between the 2 types, although you can tell the difference visually. 322 * "Improved" is based on the Improved Perlin Noise algorithm described at 323 * http://mrl.nyu.edu/~perlin/noise/. It is quite distinct from the other two, and the noise is 324 * a 2D slice of a 3D noise texture. Minor changes to the Z coordinate will result in minor 325 * changes to the noise, making it suitable for animated noise. 326 */ 327 enum Type { 328 kFractalNoise_Type, 329 kTurbulence_Type, 330 kImprovedNoise_Type, 331 kLast_Type = kImprovedNoise_Type 332 }; 333 334 static const int kMaxOctaves = 255; // numOctaves must be <= 0 and <= kMaxOctaves 335 336 SkPerlinNoiseShaderImpl(SkPerlinNoiseShaderImpl::Type type, SkScalar baseFrequencyX, 337 SkScalar baseFrequencyY, int numOctaves, SkScalar seed, 338 const SkISize* tileSize); 339 340 class PerlinNoiseShaderContext : public Context { 341 public: 342 PerlinNoiseShaderContext(const SkPerlinNoiseShaderImpl& shader, const ContextRec&); 343 344 void shadeSpan(int x, int y, SkPMColor[], int count) override; 345 346 private: 347 SkPMColor shade(const SkPoint& point, StitchData& stitchData) const; 348 SkScalar calculateTurbulenceValueForPoint( 349 int channel, 350 StitchData& stitchData, const SkPoint& point) const; 351 SkScalar calculateImprovedNoiseValueForPoint(int channel, const SkPoint& point) const; 352 SkScalar noise2D(int channel, 353 const StitchData& stitchData, const SkPoint& noiseVector) const; 354 355 SkMatrix fMatrix; 356 PaintingData fPaintingData; 357 358 typedef Context INHERITED; 359 }; 360 361#if SK_SUPPORT_GPU 362 std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const override; 363#endif 364 365 SK_TO_STRING_OVERRIDE() 366 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPerlinNoiseShaderImpl) 367 368protected: 369 void flatten(SkWriteBuffer&) const override; 370 Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override; 371 372private: 373 const SkPerlinNoiseShaderImpl::Type fType; 374 const SkScalar fBaseFrequencyX; 375 const SkScalar fBaseFrequencyY; 376 const int fNumOctaves; 377 const SkScalar fSeed; 378 const SkISize fTileSize; 379 const bool fStitchTiles; 380 381 friend class ::SkPerlinNoiseShader; 382 383 typedef SkShaderBase INHERITED; 384}; 385 386namespace { 387 388// noiseValue is the color component's value (or color) 389// limitValue is the maximum perlin noise array index value allowed 390// newValue is the current noise dimension (either width or height) 391inline int checkNoise(int noiseValue, int limitValue, int newValue) { 392 // If the noise value would bring us out of bounds of the current noise array while we are 393 // stiching noise tiles together, wrap the noise around the current dimension of the noise to 394 // stay within the array bounds in a continuous fashion (so that tiling lines are not visible) 395 if (noiseValue >= limitValue) { 396 noiseValue -= newValue; 397 } 398 return noiseValue; 399} 400 401inline SkScalar smoothCurve(SkScalar t) { 402 return t * t * (3 - 2 * t); 403} 404 405} // end namespace 406 407SkPerlinNoiseShaderImpl::SkPerlinNoiseShaderImpl(SkPerlinNoiseShaderImpl::Type type, 408 SkScalar baseFrequencyX, 409 SkScalar baseFrequencyY, 410 int numOctaves, 411 SkScalar seed, 412 const SkISize* tileSize) 413 : fType(type) 414 , fBaseFrequencyX(baseFrequencyX) 415 , fBaseFrequencyY(baseFrequencyY) 416 , fNumOctaves(numOctaves > kMaxOctaves ? kMaxOctaves : numOctaves/*[0,255] octaves allowed*/) 417 , fSeed(seed) 418 , fTileSize(nullptr == tileSize ? SkISize::Make(0, 0) : *tileSize) 419 , fStitchTiles(!fTileSize.isEmpty()) 420{ 421 SkASSERT(numOctaves >= 0 && numOctaves <= kMaxOctaves); 422} 423 424sk_sp<SkFlattenable> SkPerlinNoiseShaderImpl::CreateProc(SkReadBuffer& buffer) { 425 Type type = buffer.read32LE(kLast_Type); 426 427 SkScalar freqX = buffer.readScalar(); 428 SkScalar freqY = buffer.readScalar(); 429 430 int octaves = buffer.read32LE<int>(kMaxOctaves); 431 432 SkScalar seed = buffer.readScalar(); 433 SkISize tileSize; 434 tileSize.fWidth = buffer.readInt(); 435 tileSize.fHeight = buffer.readInt(); 436 437 switch (type) { 438 case kFractalNoise_Type: 439 return SkPerlinNoiseShader::MakeFractalNoise(freqX, freqY, octaves, seed, &tileSize); 440 case kTurbulence_Type: 441 return SkPerlinNoiseShader::MakeTurbulence(freqX, freqY, octaves, seed, &tileSize); 442 case kImprovedNoise_Type: 443 return SkPerlinNoiseShader::MakeImprovedNoise(freqX, freqY, octaves, seed); 444 default: 445 // Really shouldn't get here b.c. of earlier check on type 446 buffer.validate(false); 447 return nullptr; 448 } 449} 450 451void SkPerlinNoiseShaderImpl::flatten(SkWriteBuffer& buffer) const { 452 buffer.writeInt((int) fType); 453 buffer.writeScalar(fBaseFrequencyX); 454 buffer.writeScalar(fBaseFrequencyY); 455 buffer.writeInt(fNumOctaves); 456 buffer.writeScalar(fSeed); 457 buffer.writeInt(fTileSize.fWidth); 458 buffer.writeInt(fTileSize.fHeight); 459} 460 461SkScalar SkPerlinNoiseShaderImpl::PerlinNoiseShaderContext::noise2D( 462 int channel, const StitchData& stitchData, const SkPoint& noiseVector) const { 463 struct Noise { 464 int noisePositionIntegerValue; 465 int nextNoisePositionIntegerValue; 466 SkScalar noisePositionFractionValue; 467 Noise(SkScalar component) 468 { 469 SkScalar position = component + kPerlinNoise; 470 noisePositionIntegerValue = SkScalarFloorToInt(position); 471 noisePositionFractionValue = position - SkIntToScalar(noisePositionIntegerValue); 472 nextNoisePositionIntegerValue = noisePositionIntegerValue + 1; 473 } 474 }; 475 Noise noiseX(noiseVector.x()); 476 Noise noiseY(noiseVector.y()); 477 SkScalar u, v; 478 const SkPerlinNoiseShaderImpl& perlinNoiseShader = static_cast<const SkPerlinNoiseShaderImpl&>(fShader); 479 // If stitching, adjust lattice points accordingly. 480 if (perlinNoiseShader.fStitchTiles) { 481 noiseX.noisePositionIntegerValue = 482 checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stitchData.fWidth); 483 noiseY.noisePositionIntegerValue = 484 checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stitchData.fHeight); 485 noiseX.nextNoisePositionIntegerValue = 486 checkNoise(noiseX.nextNoisePositionIntegerValue, stitchData.fWrapX, stitchData.fWidth); 487 noiseY.nextNoisePositionIntegerValue = 488 checkNoise(noiseY.nextNoisePositionIntegerValue, stitchData.fWrapY, stitchData.fHeight); 489 } 490 noiseX.noisePositionIntegerValue &= kBlockMask; 491 noiseY.noisePositionIntegerValue &= kBlockMask; 492 noiseX.nextNoisePositionIntegerValue &= kBlockMask; 493 noiseY.nextNoisePositionIntegerValue &= kBlockMask; 494 int i = fPaintingData.fLatticeSelector[noiseX.noisePositionIntegerValue]; 495 int j = fPaintingData.fLatticeSelector[noiseX.nextNoisePositionIntegerValue]; 496 int b00 = (i + noiseY.noisePositionIntegerValue) & kBlockMask; 497 int b10 = (j + noiseY.noisePositionIntegerValue) & kBlockMask; 498 int b01 = (i + noiseY.nextNoisePositionIntegerValue) & kBlockMask; 499 int b11 = (j + noiseY.nextNoisePositionIntegerValue) & kBlockMask; 500 SkScalar sx = smoothCurve(noiseX.noisePositionFractionValue); 501 SkScalar sy = smoothCurve(noiseY.noisePositionFractionValue); 502 503 if (sx < 0 || sy < 0 || sx > 1 || sy > 1) { 504 return 0; // Check for pathological inputs. 505 } 506 507 // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement 508 SkPoint fractionValue = SkPoint::Make(noiseX.noisePositionFractionValue, 509 noiseY.noisePositionFractionValue); // Offset (0,0) 510 u = fPaintingData.fGradient[channel][b00].dot(fractionValue); 511 fractionValue.fX -= SK_Scalar1; // Offset (-1,0) 512 v = fPaintingData.fGradient[channel][b10].dot(fractionValue); 513 SkScalar a = SkScalarInterp(u, v, sx); 514 fractionValue.fY -= SK_Scalar1; // Offset (-1,-1) 515 v = fPaintingData.fGradient[channel][b11].dot(fractionValue); 516 fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1) 517 u = fPaintingData.fGradient[channel][b01].dot(fractionValue); 518 SkScalar b = SkScalarInterp(u, v, sx); 519 return SkScalarInterp(a, b, sy); 520} 521 522SkScalar SkPerlinNoiseShaderImpl::PerlinNoiseShaderContext::calculateTurbulenceValueForPoint( 523 int channel, StitchData& stitchData, const SkPoint& point) const { 524 const SkPerlinNoiseShaderImpl& perlinNoiseShader = static_cast<const SkPerlinNoiseShaderImpl&>(fShader); 525 if (perlinNoiseShader.fStitchTiles) { 526 // Set up TurbulenceInitial stitch values. 527 stitchData = fPaintingData.fStitchDataInit; 528 } 529 SkScalar turbulenceFunctionResult = 0; 530 SkPoint noiseVector(SkPoint::Make(point.x() * fPaintingData.fBaseFrequency.fX, 531 point.y() * fPaintingData.fBaseFrequency.fY)); 532 SkScalar ratio = SK_Scalar1; 533 for (int octave = 0; octave < perlinNoiseShader.fNumOctaves; ++octave) { 534 SkScalar noise = noise2D(channel, stitchData, noiseVector); 535 SkScalar numer = (perlinNoiseShader.fType == kFractalNoise_Type) ? 536 noise : SkScalarAbs(noise); 537 turbulenceFunctionResult += numer / ratio; 538 noiseVector.fX *= 2; 539 noiseVector.fY *= 2; 540 ratio *= 2; 541 if (perlinNoiseShader.fStitchTiles) { 542 // Update stitch values 543 stitchData.fWidth *= 2; 544 stitchData.fWrapX = stitchData.fWidth + kPerlinNoise; 545 stitchData.fHeight *= 2; 546 stitchData.fWrapY = stitchData.fHeight + kPerlinNoise; 547 } 548 } 549 550 // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2 551 // by fractalNoise and (turbulenceFunctionResult) by turbulence. 552 if (perlinNoiseShader.fType == kFractalNoise_Type) { 553 turbulenceFunctionResult = SkScalarHalf(turbulenceFunctionResult + 1); 554 } 555 556 if (channel == 3) { // Scale alpha by paint value 557 turbulenceFunctionResult *= SkIntToScalar(getPaintAlpha()) / 255; 558 } 559 560 // Clamp result 561 return SkScalarPin(turbulenceFunctionResult, 0, SK_Scalar1); 562} 563 564//////////////////////////////////////////////////////////////////////////////////////////////////// 565// Improved Perlin Noise based on Java implementation found at http://mrl.nyu.edu/~perlin/noise/ 566static SkScalar fade(SkScalar t) { 567 return t * t * t * (t * (t * 6 - 15) + 10); 568} 569 570static SkScalar lerp(SkScalar t, SkScalar a, SkScalar b) { 571 return a + t * (b - a); 572} 573 574static SkScalar grad(int hash, SkScalar x, SkScalar y, SkScalar z) { 575 int h = hash & 15; 576 SkScalar u = h < 8 ? x : y; 577 SkScalar v = h < 4 ? y : h == 12 || h == 14 ? x : z; 578 return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); 579} 580 581SkScalar SkPerlinNoiseShaderImpl::PerlinNoiseShaderContext::calculateImprovedNoiseValueForPoint( 582 int channel, const SkPoint& point) const { 583 const SkPerlinNoiseShaderImpl& perlinNoiseShader = static_cast<const SkPerlinNoiseShaderImpl&>(fShader); 584 SkScalar x = point.fX * perlinNoiseShader.fBaseFrequencyX; 585 SkScalar y = point.fY * perlinNoiseShader.fBaseFrequencyY; 586 // z offset between different channels, chosen arbitrarily 587 static const SkScalar CHANNEL_DELTA = 1000.0f; 588 SkScalar z = channel * CHANNEL_DELTA + perlinNoiseShader.fSeed; 589 SkScalar result = 0; 590 SkScalar ratio = SK_Scalar1; 591 for (int i = 0; i < perlinNoiseShader.fNumOctaves; i++) { 592 int X = SkScalarFloorToInt(x) & 255; 593 int Y = SkScalarFloorToInt(y) & 255; 594 int Z = SkScalarFloorToInt(z) & 255; 595 SkScalar px = x - SkScalarFloorToScalar(x); 596 SkScalar py = y - SkScalarFloorToScalar(y); 597 SkScalar pz = z - SkScalarFloorToScalar(z); 598 SkScalar u = fade(px); 599 SkScalar v = fade(py); 600 SkScalar w = fade(pz); 601 uint8_t* permutations = improved_noise_permutations; 602 int A = permutations[X] + Y; 603 int AA = permutations[A] + Z; 604 int AB = permutations[A + 1] + Z; 605 int B = permutations[X + 1] + Y; 606 int BA = permutations[B] + Z; 607 int BB = permutations[B + 1] + Z; 608 result += lerp(w, lerp(v, lerp(u, grad(permutations[AA ], px , py , pz ), 609 grad(permutations[BA ], px - 1, py , pz )), 610 lerp(u, grad(permutations[AB ], px , py - 1, pz ), 611 grad(permutations[BB ], px - 1, py - 1, pz ))), 612 lerp(v, lerp(u, grad(permutations[AA + 1], px , py , pz - 1), 613 grad(permutations[BA + 1], px - 1, py , pz - 1)), 614 lerp(u, grad(permutations[AB + 1], px , py - 1, pz - 1), 615 grad(permutations[BB + 1], px - 1, py - 1, pz - 1)))) / 616 ratio; 617 x *= 2; 618 y *= 2; 619 ratio *= 2; 620 } 621 result = SkScalarClampMax((result + 1.0f) / 2.0f, 1.0f); 622 return result; 623} 624//////////////////////////////////////////////////////////////////////////////////////////////////// 625 626SkPMColor SkPerlinNoiseShaderImpl::PerlinNoiseShaderContext::shade( 627 const SkPoint& point, StitchData& stitchData) const { 628 const SkPerlinNoiseShaderImpl& perlinNoiseShader = static_cast<const SkPerlinNoiseShaderImpl&>(fShader); 629 SkPoint newPoint; 630 fMatrix.mapPoints(&newPoint, &point, 1); 631 newPoint.fX = SkScalarRoundToScalar(newPoint.fX); 632 newPoint.fY = SkScalarRoundToScalar(newPoint.fY); 633 634 U8CPU rgba[4]; 635 for (int channel = 3; channel >= 0; --channel) { 636 SkScalar value; 637 if (perlinNoiseShader.fType == kImprovedNoise_Type) { 638 value = calculateImprovedNoiseValueForPoint(channel, newPoint); 639 } 640 else { 641 value = calculateTurbulenceValueForPoint(channel, stitchData, newPoint); 642 } 643 rgba[channel] = SkScalarFloorToInt(255 * value); 644 } 645 return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]); 646} 647 648SkShaderBase::Context* SkPerlinNoiseShaderImpl::onMakeContext(const ContextRec& rec, 649 SkArenaAlloc* alloc) const { 650 return alloc->make<PerlinNoiseShaderContext>(*this, rec); 651} 652 653static inline SkMatrix total_matrix(const SkShaderBase::ContextRec& rec, 654 const SkShaderBase& shader) { 655 SkMatrix matrix = SkMatrix::Concat(*rec.fMatrix, shader.getLocalMatrix()); 656 if (rec.fLocalMatrix) { 657 matrix.preConcat(*rec.fLocalMatrix); 658 } 659 660 return matrix; 661} 662 663SkPerlinNoiseShaderImpl::PerlinNoiseShaderContext::PerlinNoiseShaderContext( 664 const SkPerlinNoiseShaderImpl& shader, const ContextRec& rec) 665 : INHERITED(shader, rec) 666 , fMatrix(total_matrix(rec, shader)) // used for temp storage, adjusted below 667 , fPaintingData(shader.fTileSize, shader.fSeed, shader.fBaseFrequencyX, 668 shader.fBaseFrequencyY, fMatrix) 669{ 670 // This (1,1) translation is due to WebKit's 1 based coordinates for the noise 671 // (as opposed to 0 based, usually). The same adjustment is in the setData() function. 672 fMatrix.setTranslate(-fMatrix.getTranslateX() + SK_Scalar1, 673 -fMatrix.getTranslateY() + SK_Scalar1); 674} 675 676void SkPerlinNoiseShaderImpl::PerlinNoiseShaderContext::shadeSpan( 677 int x, int y, SkPMColor result[], int count) { 678 SkPoint point = SkPoint::Make(SkIntToScalar(x), SkIntToScalar(y)); 679 StitchData stitchData; 680 for (int i = 0; i < count; ++i) { 681 result[i] = shade(point, stitchData); 682 point.fX += SK_Scalar1; 683 } 684} 685 686///////////////////////////////////////////////////////////////////// 687 688#if SK_SUPPORT_GPU 689 690class GrGLPerlinNoise : public GrGLSLFragmentProcessor { 691public: 692 void emitCode(EmitArgs&) override; 693 694 static inline void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder* b); 695 696protected: 697 void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override; 698 699private: 700 GrGLSLProgramDataManager::UniformHandle fStitchDataUni; 701 GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni; 702 703 typedef GrGLSLFragmentProcessor INHERITED; 704}; 705 706///////////////////////////////////////////////////////////////////// 707 708class GrPerlinNoise2Effect : public GrFragmentProcessor { 709public: 710 static std::unique_ptr<GrFragmentProcessor> Make( 711 SkPerlinNoiseShaderImpl::Type type, int numOctaves, bool stitchTiles, 712 std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData, 713 sk_sp<GrTextureProxy> permutationsProxy, sk_sp<GrTextureProxy> noiseProxy, 714 const SkMatrix& matrix) { 715 return std::unique_ptr<GrFragmentProcessor>(new GrPerlinNoise2Effect( 716 type, numOctaves, stitchTiles, std::move(paintingData), 717 std::move(permutationsProxy), std::move(noiseProxy), matrix)); 718 } 719 720 const char* name() const override { return "PerlinNoise"; } 721 722 std::unique_ptr<GrFragmentProcessor> clone() const override { 723 return std::unique_ptr<GrFragmentProcessor>(new GrPerlinNoise2Effect(*this)); 724 } 725 726 const SkPerlinNoiseShaderImpl::StitchData& stitchData() const { return fPaintingData->fStitchDataInit; } 727 728 SkPerlinNoiseShaderImpl::Type type() const { return fType; } 729 bool stitchTiles() const { return fStitchTiles; } 730 const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency; } 731 int numOctaves() const { return fNumOctaves; } 732 const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); } 733 734private: 735 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 736 return new GrGLPerlinNoise; 737 } 738 739 virtual void onGetGLSLProcessorKey(const GrShaderCaps& caps, 740 GrProcessorKeyBuilder* b) const override { 741 GrGLPerlinNoise::GenKey(*this, caps, b); 742 } 743 744 bool onIsEqual(const GrFragmentProcessor& sBase) const override { 745 const GrPerlinNoise2Effect& s = sBase.cast<GrPerlinNoise2Effect>(); 746 return fType == s.fType && 747 fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency && 748 fNumOctaves == s.fNumOctaves && 749 fStitchTiles == s.fStitchTiles && 750 fPaintingData->fStitchDataInit == s.fPaintingData->fStitchDataInit; 751 } 752 753 GrPerlinNoise2Effect(SkPerlinNoiseShaderImpl::Type type, int numOctaves, bool stitchTiles, 754 std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData, 755 sk_sp<GrTextureProxy> permutationsProxy, 756 sk_sp<GrTextureProxy> noiseProxy, 757 const SkMatrix& matrix) 758 : INHERITED(kGrPerlinNoise2Effect_ClassID, kNone_OptimizationFlags) 759 , fType(type) 760 , fNumOctaves(numOctaves) 761 , fStitchTiles(stitchTiles) 762 , fPermutationsSampler(std::move(permutationsProxy)) 763 , fNoiseSampler(std::move(noiseProxy)) 764 , fPaintingData(std::move(paintingData)) { 765 this->addTextureSampler(&fPermutationsSampler); 766 this->addTextureSampler(&fNoiseSampler); 767 fCoordTransform.reset(matrix); 768 this->addCoordTransform(&fCoordTransform); 769 } 770 771 GrPerlinNoise2Effect(const GrPerlinNoise2Effect& that) 772 : INHERITED(kGrPerlinNoise2Effect_ClassID, kNone_OptimizationFlags) 773 , fType(that.fType) 774 , fCoordTransform(that.fCoordTransform) 775 , fNumOctaves(that.fNumOctaves) 776 , fStitchTiles(that.fStitchTiles) 777 , fPermutationsSampler(that.fPermutationsSampler) 778 , fNoiseSampler(that.fNoiseSampler) 779 , fPaintingData(new SkPerlinNoiseShaderImpl::PaintingData(*that.fPaintingData)) { 780 this->addTextureSampler(&fPermutationsSampler); 781 this->addTextureSampler(&fNoiseSampler); 782 this->addCoordTransform(&fCoordTransform); 783 } 784 785 GR_DECLARE_FRAGMENT_PROCESSOR_TEST 786 787 SkPerlinNoiseShaderImpl::Type fType; 788 GrCoordTransform fCoordTransform; 789 int fNumOctaves; 790 bool fStitchTiles; 791 TextureSampler fPermutationsSampler; 792 TextureSampler fNoiseSampler; 793 std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> fPaintingData; 794 795 typedef GrFragmentProcessor INHERITED; 796}; 797 798///////////////////////////////////////////////////////////////////// 799GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrPerlinNoise2Effect); 800 801#if GR_TEST_UTILS 802std::unique_ptr<GrFragmentProcessor> GrPerlinNoise2Effect::TestCreate(GrProcessorTestData* d) { 803 int numOctaves = d->fRandom->nextRangeU(2, 10); 804 bool stitchTiles = d->fRandom->nextBool(); 805 SkScalar seed = SkIntToScalar(d->fRandom->nextU()); 806 SkISize tileSize = SkISize::Make(d->fRandom->nextRangeU(4, 4096), 807 d->fRandom->nextRangeU(4, 4096)); 808 SkScalar baseFrequencyX = d->fRandom->nextRangeScalar(0.01f, 809 0.99f); 810 SkScalar baseFrequencyY = d->fRandom->nextRangeScalar(0.01f, 811 0.99f); 812 813 sk_sp<SkShader> shader(d->fRandom->nextBool() ? 814 SkPerlinNoiseShader::MakeFractalNoise(baseFrequencyX, baseFrequencyY, numOctaves, seed, 815 stitchTiles ? &tileSize : nullptr) : 816 SkPerlinNoiseShader::MakeTurbulence(baseFrequencyX, baseFrequencyY, numOctaves, seed, 817 stitchTiles ? &tileSize : nullptr)); 818 819 GrTest::TestAsFPArgs asFPArgs(d); 820 return as_SB(shader)->asFragmentProcessor(asFPArgs.args()); 821} 822#endif 823 824void GrGLPerlinNoise::emitCode(EmitArgs& args) { 825 const GrPerlinNoise2Effect& pne = args.fFp.cast<GrPerlinNoise2Effect>(); 826 827 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; 828 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 829 SkString vCoords = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]); 830 831 fBaseFrequencyUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, 832 "baseFrequency"); 833 const char* baseFrequencyUni = uniformHandler->getUniformCStr(fBaseFrequencyUni); 834 835 const char* stitchDataUni = nullptr; 836 if (pne.stitchTiles()) { 837 fStitchDataUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, 838 "stitchData"); 839 stitchDataUni = uniformHandler->getUniformCStr(fStitchDataUni); 840 } 841 842 // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8 843 const char* chanCoordR = "0.125"; 844 const char* chanCoordG = "0.375"; 845 const char* chanCoordB = "0.625"; 846 const char* chanCoordA = "0.875"; 847 const char* chanCoord = "chanCoord"; 848 const char* stitchData = "stitchData"; 849 const char* ratio = "ratio"; 850 const char* noiseVec = "noiseVec"; 851 const char* noiseSmooth = "noiseSmooth"; 852 const char* floorVal = "floorVal"; 853 const char* fractVal = "fractVal"; 854 const char* uv = "uv"; 855 const char* ab = "ab"; 856 const char* latticeIdx = "latticeIdx"; 857 const char* bcoords = "bcoords"; 858 const char* lattice = "lattice"; 859 const char* inc8bit = "0.00390625"; // 1.0 / 256.0 860 // This is the math to convert the two 16bit integer packed into rgba 8 bit input into a 861 // [-1,1] vector and perform a dot product between that vector and the provided vector. 862 const char* dotLattice = "dot(((%s.ga + %s.rb * half2(%s)) * half2(2.0) - half2(1.0)), %s);"; 863 864 // Add noise function 865 static const GrShaderVar gPerlinNoiseArgs[] = { 866 GrShaderVar(chanCoord, kHalf_GrSLType), 867 GrShaderVar(noiseVec, kHalf2_GrSLType) 868 }; 869 870 static const GrShaderVar gPerlinNoiseStitchArgs[] = { 871 GrShaderVar(chanCoord, kHalf_GrSLType), 872 GrShaderVar(noiseVec, kHalf2_GrSLType), 873 GrShaderVar(stitchData, kHalf2_GrSLType) 874 }; 875 876 SkString noiseCode; 877 878 noiseCode.appendf("\thalf4 %s;\n", floorVal); 879 noiseCode.appendf("\t%s.xy = floor(%s);\n", floorVal, noiseVec); 880 noiseCode.appendf("\t%s.zw = %s.xy + half2(1.0);\n", floorVal, floorVal); 881 noiseCode.appendf("\thalf2 %s = fract(%s);\n", fractVal, noiseVec); 882 883 // smooth curve : t * t * (3 - 2 * t) 884 noiseCode.appendf("\n\thalf2 %s = %s * %s * (half2(3.0) - half2(2.0) * %s);", 885 noiseSmooth, fractVal, fractVal, fractVal); 886 887 // Adjust frequencies if we're stitching tiles 888 if (pne.stitchTiles()) { 889 noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }", 890 floorVal, stitchData, floorVal, stitchData); 891 noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }", 892 floorVal, stitchData, floorVal, stitchData); 893 noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }", 894 floorVal, stitchData, floorVal, stitchData); 895 noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }", 896 floorVal, stitchData, floorVal, stitchData); 897 } 898 899 // Get texture coordinates and normalize 900 noiseCode.appendf("\n\t%s = fract(floor(mod(%s, 256.0)) / half4(256.0));\n", 901 floorVal, floorVal); 902 903 // Get permutation for x 904 { 905 SkString xCoords(""); 906 xCoords.appendf("half2(%s.x, 0.5)", floorVal); 907 908 noiseCode.appendf("\n\thalf2 %s;\n\t%s.x = ", latticeIdx, latticeIdx); 909 fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[0], xCoords.c_str(), 910 kHalf2_GrSLType); 911 noiseCode.append(".r;"); 912 } 913 914 // Get permutation for x + 1 915 { 916 SkString xCoords(""); 917 xCoords.appendf("half2(%s.z, 0.5)", floorVal); 918 919 noiseCode.appendf("\n\t%s.y = ", latticeIdx); 920 fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[0], xCoords.c_str(), 921 kHalf2_GrSLType); 922 noiseCode.append(".r;"); 923 } 924 925#if defined(SK_BUILD_FOR_ANDROID) 926 // Android rounding for Tegra devices, like, for example: Xoom (Tegra 2), Nexus 7 (Tegra 3). 927 // The issue is that colors aren't accurate enough on Tegra devices. For example, if an 8 bit 928 // value of 124 (or 0.486275 here) is entered, we can get a texture value of 123.513725 929 // (or 0.484368 here). The following rounding operation prevents these precision issues from 930 // affecting the result of the noise by making sure that we only have multiples of 1/255. 931 // (Note that 1/255 is about 0.003921569, which is the value used here). 932 noiseCode.appendf("\n\t%s = floor(%s * half2(255.0) + half2(0.5)) * half2(0.003921569);", 933 latticeIdx, latticeIdx); 934#endif 935 936 // Get (x,y) coordinates with the permutated x 937 noiseCode.appendf("\n\thalf4 %s = fract(%s.xyxy + %s.yyww);", bcoords, latticeIdx, floorVal); 938 939 noiseCode.appendf("\n\n\thalf2 %s;", uv); 940 // Compute u, at offset (0,0) 941 { 942 SkString latticeCoords(""); 943 latticeCoords.appendf("half2(%s.x, %s)", bcoords, chanCoord); 944 noiseCode.appendf("\n\thalf4 %s = ", lattice); 945 fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[1], latticeCoords.c_str(), 946 kHalf2_GrSLType); 947 noiseCode.appendf(".bgra;\n\t%s.x = ", uv); 948 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); 949 } 950 951 noiseCode.appendf("\n\t%s.x -= 1.0;", fractVal); 952 // Compute v, at offset (-1,0) 953 { 954 SkString latticeCoords(""); 955 latticeCoords.appendf("half2(%s.y, %s)", bcoords, chanCoord); 956 noiseCode.append("\n\tlattice = "); 957 fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[1], latticeCoords.c_str(), 958 kHalf2_GrSLType); 959 noiseCode.appendf(".bgra;\n\t%s.y = ", uv); 960 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); 961 } 962 963 // Compute 'a' as a linear interpolation of 'u' and 'v' 964 noiseCode.appendf("\n\thalf2 %s;", ab); 965 noiseCode.appendf("\n\t%s.x = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth); 966 967 noiseCode.appendf("\n\t%s.y -= 1.0;", fractVal); 968 // Compute v, at offset (-1,-1) 969 { 970 SkString latticeCoords(""); 971 latticeCoords.appendf("half2(%s.w, %s)", bcoords, chanCoord); 972 noiseCode.append("\n\tlattice = "); 973 fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[1], latticeCoords.c_str(), 974 kHalf2_GrSLType); 975 noiseCode.appendf(".bgra;\n\t%s.y = ", uv); 976 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); 977 } 978 979 noiseCode.appendf("\n\t%s.x += 1.0;", fractVal); 980 // Compute u, at offset (0,-1) 981 { 982 SkString latticeCoords(""); 983 latticeCoords.appendf("half2(%s.z, %s)", bcoords, chanCoord); 984 noiseCode.append("\n\tlattice = "); 985 fragBuilder->appendTextureLookup(&noiseCode, args.fTexSamplers[1], latticeCoords.c_str(), 986 kHalf2_GrSLType); 987 noiseCode.appendf(".bgra;\n\t%s.x = ", uv); 988 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); 989 } 990 991 // Compute 'b' as a linear interpolation of 'u' and 'v' 992 noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmooth); 993 // Compute the noise as a linear interpolation of 'a' and 'b' 994 noiseCode.appendf("\n\treturn mix(%s.x, %s.y, %s.y);\n", ab, ab, noiseSmooth); 995 996 SkString noiseFuncName; 997 if (pne.stitchTiles()) { 998 fragBuilder->emitFunction(kHalf_GrSLType, 999 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseStitchArgs), 1000 gPerlinNoiseStitchArgs, noiseCode.c_str(), &noiseFuncName); 1001 } else { 1002 fragBuilder->emitFunction(kHalf_GrSLType, 1003 "perlinnoise", SK_ARRAY_COUNT(gPerlinNoiseArgs), 1004 gPerlinNoiseArgs, noiseCode.c_str(), &noiseFuncName); 1005 } 1006 1007 // There are rounding errors if the floor operation is not performed here 1008 fragBuilder->codeAppendf("\n\t\thalf2 %s = floor(%s.xy) * %s;", 1009 noiseVec, vCoords.c_str(), baseFrequencyUni); 1010 1011 // Clear the color accumulator 1012 fragBuilder->codeAppendf("\n\t\t%s = half4(0.0);", args.fOutputColor); 1013 1014 if (pne.stitchTiles()) { 1015 // Set up TurbulenceInitial stitch values. 1016 fragBuilder->codeAppendf("\n\t\thalf2 %s = %s;", stitchData, stitchDataUni); 1017 } 1018 1019 fragBuilder->codeAppendf("\n\t\thalf %s = 1.0;", ratio); 1020 1021 // Loop over all octaves 1022 fragBuilder->codeAppendf("for (int octave = 0; octave < %d; ++octave) {", pne.numOctaves()); 1023 1024 fragBuilder->codeAppendf("\n\t\t\t%s += ", args.fOutputColor); 1025 if (pne.type() != SkPerlinNoiseShaderImpl::kFractalNoise_Type) { 1026 fragBuilder->codeAppend("abs("); 1027 } 1028 if (pne.stitchTiles()) { 1029 fragBuilder->codeAppendf( 1030 "half4(\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s)," 1031 "\n\t\t\t\t%s(%s, %s, %s),\n\t\t\t\t%s(%s, %s, %s))", 1032 noiseFuncName.c_str(), chanCoordR, noiseVec, stitchData, 1033 noiseFuncName.c_str(), chanCoordG, noiseVec, stitchData, 1034 noiseFuncName.c_str(), chanCoordB, noiseVec, stitchData, 1035 noiseFuncName.c_str(), chanCoordA, noiseVec, stitchData); 1036 } else { 1037 fragBuilder->codeAppendf( 1038 "half4(\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s)," 1039 "\n\t\t\t\t%s(%s, %s),\n\t\t\t\t%s(%s, %s))", 1040 noiseFuncName.c_str(), chanCoordR, noiseVec, 1041 noiseFuncName.c_str(), chanCoordG, noiseVec, 1042 noiseFuncName.c_str(), chanCoordB, noiseVec, 1043 noiseFuncName.c_str(), chanCoordA, noiseVec); 1044 } 1045 if (pne.type() != SkPerlinNoiseShaderImpl::kFractalNoise_Type) { 1046 fragBuilder->codeAppendf(")"); // end of "abs(" 1047 } 1048 fragBuilder->codeAppendf(" * %s;", ratio); 1049 1050 fragBuilder->codeAppendf("\n\t\t\t%s *= half2(2.0);", noiseVec); 1051 fragBuilder->codeAppendf("\n\t\t\t%s *= 0.5;", ratio); 1052 1053 if (pne.stitchTiles()) { 1054 fragBuilder->codeAppendf("\n\t\t\t%s *= half2(2.0);", stitchData); 1055 } 1056 fragBuilder->codeAppend("\n\t\t}"); // end of the for loop on octaves 1057 1058 if (pne.type() == SkPerlinNoiseShaderImpl::kFractalNoise_Type) { 1059 // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2 1060 // by fractalNoise and (turbulenceFunctionResult) by turbulence. 1061 fragBuilder->codeAppendf("\n\t\t%s = %s * half4(0.5) + half4(0.5);", 1062 args.fOutputColor,args.fOutputColor); 1063 } 1064 1065 // Clamp values 1066 fragBuilder->codeAppendf("\n\t\t%s = clamp(%s, 0.0, 1.0);", args.fOutputColor, args.fOutputColor); 1067 1068 // Pre-multiply the result 1069 fragBuilder->codeAppendf("\n\t\t%s = half4(%s.rgb * %s.aaa, %s.a);\n", 1070 args.fOutputColor, args.fOutputColor, 1071 args.fOutputColor, args.fOutputColor); 1072} 1073 1074void GrGLPerlinNoise::GenKey(const GrProcessor& processor, const GrShaderCaps&, 1075 GrProcessorKeyBuilder* b) { 1076 const GrPerlinNoise2Effect& turbulence = processor.cast<GrPerlinNoise2Effect>(); 1077 1078 uint32_t key = turbulence.numOctaves(); 1079 1080 key = key << 3; // Make room for next 3 bits 1081 1082 switch (turbulence.type()) { 1083 case SkPerlinNoiseShaderImpl::kFractalNoise_Type: 1084 key |= 0x1; 1085 break; 1086 case SkPerlinNoiseShaderImpl::kTurbulence_Type: 1087 key |= 0x2; 1088 break; 1089 default: 1090 // leave key at 0 1091 break; 1092 } 1093 1094 if (turbulence.stitchTiles()) { 1095 key |= 0x4; // Flip the 3rd bit if tile stitching is on 1096 } 1097 1098 b->add32(key); 1099} 1100 1101void GrGLPerlinNoise::onSetData(const GrGLSLProgramDataManager& pdman, 1102 const GrFragmentProcessor& processor) { 1103 INHERITED::onSetData(pdman, processor); 1104 1105 const GrPerlinNoise2Effect& turbulence = processor.cast<GrPerlinNoise2Effect>(); 1106 1107 const SkVector& baseFrequency = turbulence.baseFrequency(); 1108 pdman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY); 1109 1110 if (turbulence.stitchTiles()) { 1111 const SkPerlinNoiseShaderImpl::StitchData& stitchData = turbulence.stitchData(); 1112 pdman.set2f(fStitchDataUni, SkIntToScalar(stitchData.fWidth), 1113 SkIntToScalar(stitchData.fHeight)); 1114 } 1115} 1116 1117///////////////////////////////////////////////////////////////////// 1118 1119class GrGLImprovedPerlinNoise : public GrGLSLFragmentProcessor { 1120public: 1121 void emitCode(EmitArgs&) override; 1122 1123 static inline void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder*); 1124 1125protected: 1126 void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override; 1127 1128private: 1129 GrGLSLProgramDataManager::UniformHandle fZUni; 1130 GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni; 1131 1132 typedef GrGLSLFragmentProcessor INHERITED; 1133}; 1134 1135///////////////////////////////////////////////////////////////////// 1136 1137class GrImprovedPerlinNoiseEffect : public GrFragmentProcessor { 1138public: 1139 static std::unique_ptr<GrFragmentProcessor> Make( 1140 int octaves, SkScalar z, 1141 std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData, 1142 sk_sp<GrTextureProxy> permutationsProxy, sk_sp<GrTextureProxy> gradientProxy, 1143 const SkMatrix& matrix) { 1144 return std::unique_ptr<GrFragmentProcessor>(new GrImprovedPerlinNoiseEffect( 1145 octaves, z, std::move(paintingData), std::move(permutationsProxy), 1146 std::move(gradientProxy), matrix)); 1147 } 1148 1149 const char* name() const override { return "ImprovedPerlinNoise"; } 1150 1151 std::unique_ptr<GrFragmentProcessor> clone() const override { 1152 return std::unique_ptr<GrFragmentProcessor>(new GrImprovedPerlinNoiseEffect(*this)); 1153 } 1154 1155 const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency; } 1156 SkScalar z() const { return fZ; } 1157 int octaves() const { return fOctaves; } 1158 const SkMatrix& matrix() const { return fCoordTransform.getMatrix(); } 1159 1160private: 1161 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 1162 return new GrGLImprovedPerlinNoise; 1163 } 1164 1165 void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override { 1166 GrGLImprovedPerlinNoise::GenKey(*this, caps, b); 1167 } 1168 1169 bool onIsEqual(const GrFragmentProcessor& sBase) const override { 1170 const GrImprovedPerlinNoiseEffect& s = sBase.cast<GrImprovedPerlinNoiseEffect>(); 1171 return fZ == fZ && 1172 fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency; 1173 } 1174 1175 GrImprovedPerlinNoiseEffect(int octaves, SkScalar z, 1176 std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData, 1177 sk_sp<GrTextureProxy> permutationsProxy, 1178 sk_sp<GrTextureProxy> gradientProxy, 1179 const SkMatrix& matrix) 1180 : INHERITED(kGrImprovedPerlinNoiseEffect_ClassID, kNone_OptimizationFlags) 1181 , fOctaves(octaves) 1182 , fZ(z) 1183 , fPermutationsSampler(std::move(permutationsProxy)) 1184 , fGradientSampler(std::move(gradientProxy)) 1185 , fPaintingData(std::move(paintingData)) { 1186 this->addTextureSampler(&fPermutationsSampler); 1187 this->addTextureSampler(&fGradientSampler); 1188 fCoordTransform.reset(matrix); 1189 this->addCoordTransform(&fCoordTransform); 1190 } 1191 1192 GrImprovedPerlinNoiseEffect(const GrImprovedPerlinNoiseEffect& that) 1193 : INHERITED(kGrImprovedPerlinNoiseEffect_ClassID, kNone_OptimizationFlags) 1194 , fCoordTransform(that.fCoordTransform) 1195 , fOctaves(that.fOctaves) 1196 , fZ(that.fZ) 1197 , fPermutationsSampler(that.fPermutationsSampler) 1198 , fGradientSampler(that.fGradientSampler) 1199 , fPaintingData(new SkPerlinNoiseShaderImpl::PaintingData(*that.fPaintingData)) { 1200 this->addTextureSampler(&fPermutationsSampler); 1201 this->addTextureSampler(&fGradientSampler); 1202 this->addCoordTransform(&fCoordTransform); 1203 } 1204 1205 GR_DECLARE_FRAGMENT_PROCESSOR_TEST 1206 1207 GrCoordTransform fCoordTransform; 1208 int fOctaves; 1209 SkScalar fZ; 1210 TextureSampler fPermutationsSampler; 1211 TextureSampler fGradientSampler; 1212 std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> fPaintingData; 1213 1214 typedef GrFragmentProcessor INHERITED; 1215}; 1216 1217///////////////////////////////////////////////////////////////////// 1218GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrImprovedPerlinNoiseEffect); 1219 1220#if GR_TEST_UTILS 1221std::unique_ptr<GrFragmentProcessor> GrImprovedPerlinNoiseEffect::TestCreate( 1222 GrProcessorTestData* d) { 1223 SkScalar baseFrequencyX = d->fRandom->nextRangeScalar(0.01f, 1224 0.99f); 1225 SkScalar baseFrequencyY = d->fRandom->nextRangeScalar(0.01f, 1226 0.99f); 1227 int numOctaves = d->fRandom->nextRangeU(2, 10); 1228 SkScalar z = SkIntToScalar(d->fRandom->nextU()); 1229 1230 sk_sp<SkShader> shader(SkPerlinNoiseShader::MakeImprovedNoise(baseFrequencyX, 1231 baseFrequencyY, 1232 numOctaves, 1233 z)); 1234 1235 GrTest::TestAsFPArgs asFPArgs(d); 1236 return as_SB(shader)->asFragmentProcessor(asFPArgs.args()); 1237} 1238#endif 1239 1240void GrGLImprovedPerlinNoise::emitCode(EmitArgs& args) { 1241 const GrImprovedPerlinNoiseEffect& pne = args.fFp.cast<GrImprovedPerlinNoiseEffect>(); 1242 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; 1243 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 1244 SkString vCoords = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]); 1245 1246 fBaseFrequencyUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, 1247 "baseFrequency"); 1248 const char* baseFrequencyUni = uniformHandler->getUniformCStr(fBaseFrequencyUni); 1249 1250 fZUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "z"); 1251 const char* zUni = uniformHandler->getUniformCStr(fZUni); 1252 1253 // fade function 1254 static const GrShaderVar fadeArgs[] = { 1255 GrShaderVar("t", kHalf3_GrSLType) 1256 }; 1257 SkString fadeFuncName; 1258 fragBuilder->emitFunction(kHalf3_GrSLType, "fade", SK_ARRAY_COUNT(fadeArgs), 1259 fadeArgs, 1260 "return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);", 1261 &fadeFuncName); 1262 1263 // perm function 1264 static const GrShaderVar permArgs[] = { 1265 GrShaderVar("x", kHalf_GrSLType) 1266 }; 1267 SkString permFuncName; 1268 SkString permCode("return "); 1269 // FIXME even though I'm creating these textures with kRepeat_TileMode, they're clamped. Not 1270 // sure why. Using fract() (here and the next texture lookup) as a workaround. 1271 fragBuilder->appendTextureLookup(&permCode, args.fTexSamplers[0], "float2(fract(x / 256.0), 0.0)", 1272 kHalf2_GrSLType); 1273 permCode.append(".r * 255.0;"); 1274 fragBuilder->emitFunction(kHalf_GrSLType, "perm", SK_ARRAY_COUNT(permArgs), permArgs, 1275 permCode.c_str(), &permFuncName); 1276 1277 // grad function 1278 static const GrShaderVar gradArgs[] = { 1279 GrShaderVar("x", kHalf_GrSLType), 1280 GrShaderVar("p", kHalf3_GrSLType) 1281 }; 1282 SkString gradFuncName; 1283 SkString gradCode("return dot("); 1284 fragBuilder->appendTextureLookup(&gradCode, args.fTexSamplers[1], "float2(fract(x / 16.0), 0.0)", 1285 kHalf2_GrSLType); 1286 gradCode.append(".rgb * 255.0 - float3(1.0), p);"); 1287 fragBuilder->emitFunction(kHalf_GrSLType, "grad", SK_ARRAY_COUNT(gradArgs), gradArgs, 1288 gradCode.c_str(), &gradFuncName); 1289 1290 // lerp function 1291 static const GrShaderVar lerpArgs[] = { 1292 GrShaderVar("a", kHalf_GrSLType), 1293 GrShaderVar("b", kHalf_GrSLType), 1294 GrShaderVar("w", kHalf_GrSLType) 1295 }; 1296 SkString lerpFuncName; 1297 fragBuilder->emitFunction(kHalf_GrSLType, "lerp", SK_ARRAY_COUNT(lerpArgs), lerpArgs, 1298 "return a + w * (b - a);", &lerpFuncName); 1299 1300 // noise function 1301 static const GrShaderVar noiseArgs[] = { 1302 GrShaderVar("p", kHalf3_GrSLType), 1303 }; 1304 SkString noiseFuncName; 1305 SkString noiseCode; 1306 noiseCode.append("half3 P = mod(floor(p), 256.0);"); 1307 noiseCode.append("p -= floor(p);"); 1308 noiseCode.appendf("half3 f = %s(p);", fadeFuncName.c_str()); 1309 noiseCode.appendf("half A = %s(P.x) + P.y;", permFuncName.c_str()); 1310 noiseCode.appendf("half AA = %s(A) + P.z;", permFuncName.c_str()); 1311 noiseCode.appendf("half AB = %s(A + 1.0) + P.z;", permFuncName.c_str()); 1312 noiseCode.appendf("half B = %s(P.x + 1.0) + P.y;", permFuncName.c_str()); 1313 noiseCode.appendf("half BA = %s(B) + P.z;", permFuncName.c_str()); 1314 noiseCode.appendf("half BB = %s(B + 1.0) + P.z;", permFuncName.c_str()); 1315 noiseCode.appendf("half result = %s(", lerpFuncName.c_str()); 1316 noiseCode.appendf("%s(%s(%s(%s(AA), p),", lerpFuncName.c_str(), lerpFuncName.c_str(), 1317 gradFuncName.c_str(), permFuncName.c_str()); 1318 noiseCode.appendf("%s(%s(BA), p + half3(-1.0, 0.0, 0.0)), f.x),", gradFuncName.c_str(), 1319 permFuncName.c_str()); 1320 noiseCode.appendf("%s(%s(%s(AB), p + half3(0.0, -1.0, 0.0)),", lerpFuncName.c_str(), 1321 gradFuncName.c_str(), permFuncName.c_str()); 1322 noiseCode.appendf("%s(%s(BB), p + half3(-1.0, -1.0, 0.0)), f.x), f.y),", 1323 gradFuncName.c_str(), permFuncName.c_str()); 1324 noiseCode.appendf("%s(%s(%s(%s(AA + 1.0), p + half3(0.0, 0.0, -1.0)),", 1325 lerpFuncName.c_str(), lerpFuncName.c_str(), gradFuncName.c_str(), 1326 permFuncName.c_str()); 1327 noiseCode.appendf("%s(%s(BA + 1.0), p + half3(-1.0, 0.0, -1.0)), f.x),", 1328 gradFuncName.c_str(), permFuncName.c_str()); 1329 noiseCode.appendf("%s(%s(%s(AB + 1.0), p + half3(0.0, -1.0, -1.0)),", 1330 lerpFuncName.c_str(), gradFuncName.c_str(), permFuncName.c_str()); 1331 noiseCode.appendf("%s(%s(BB + 1.0), p + half3(-1.0, -1.0, -1.0)), f.x), f.y), f.z);", 1332 gradFuncName.c_str(), permFuncName.c_str()); 1333 noiseCode.append("return result;"); 1334 fragBuilder->emitFunction(kHalf_GrSLType, "noise", SK_ARRAY_COUNT(noiseArgs), noiseArgs, 1335 noiseCode.c_str(), &noiseFuncName); 1336 1337 // noiseOctaves function 1338 static const GrShaderVar noiseOctavesArgs[] = { 1339 GrShaderVar("p", kHalf3_GrSLType) 1340 }; 1341 SkString noiseOctavesFuncName; 1342 SkString noiseOctavesCode; 1343 noiseOctavesCode.append("half result = 0.0;"); 1344 noiseOctavesCode.append("half ratio = 1.0;"); 1345 noiseOctavesCode.appendf("for (half i = 0.0; i < %d; i++) {", pne.octaves()); 1346 noiseOctavesCode.appendf("result += %s(p) / ratio;", noiseFuncName.c_str()); 1347 noiseOctavesCode.append("p *= 2.0;"); 1348 noiseOctavesCode.append("ratio *= 2.0;"); 1349 noiseOctavesCode.append("}"); 1350 noiseOctavesCode.append("return (result + 1.0) / 2.0;"); 1351 fragBuilder->emitFunction(kHalf_GrSLType, "noiseOctaves", SK_ARRAY_COUNT(noiseOctavesArgs), 1352 noiseOctavesArgs, noiseOctavesCode.c_str(), &noiseOctavesFuncName); 1353 1354 fragBuilder->codeAppendf("half2 coords = %s * %s;", vCoords.c_str(), baseFrequencyUni); 1355 fragBuilder->codeAppendf("half r = %s(half3(coords, %s));", noiseOctavesFuncName.c_str(), 1356 zUni); 1357 fragBuilder->codeAppendf("half g = %s(half3(coords, %s + 0000.0));", 1358 noiseOctavesFuncName.c_str(), zUni); 1359 fragBuilder->codeAppendf("half b = %s(half3(coords, %s + 0000.0));", 1360 noiseOctavesFuncName.c_str(), zUni); 1361 fragBuilder->codeAppendf("half a = %s(half3(coords, %s + 0000.0));", 1362 noiseOctavesFuncName.c_str(), zUni); 1363 fragBuilder->codeAppendf("%s = half4(r, g, b, a);", args.fOutputColor); 1364 1365 // Clamp values 1366 fragBuilder->codeAppendf("%s = clamp(%s, 0.0, 1.0);", args.fOutputColor, args.fOutputColor); 1367 1368 // Pre-multiply the result 1369 fragBuilder->codeAppendf("\n\t\t%s = half4(%s.rgb * %s.aaa, %s.a);\n", 1370 args.fOutputColor, args.fOutputColor, 1371 args.fOutputColor, args.fOutputColor); 1372} 1373 1374void GrGLImprovedPerlinNoise::GenKey(const GrProcessor& processor, const GrShaderCaps&, 1375 GrProcessorKeyBuilder* b) { 1376 const GrImprovedPerlinNoiseEffect& pne = processor.cast<GrImprovedPerlinNoiseEffect>(); 1377 b->add32(pne.octaves()); 1378} 1379 1380void GrGLImprovedPerlinNoise::onSetData(const GrGLSLProgramDataManager& pdman, 1381 const GrFragmentProcessor& processor) { 1382 INHERITED::onSetData(pdman, processor); 1383 1384 const GrImprovedPerlinNoiseEffect& noise = processor.cast<GrImprovedPerlinNoiseEffect>(); 1385 1386 const SkVector& baseFrequency = noise.baseFrequency(); 1387 pdman.set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY); 1388 1389 pdman.set1f(fZUni, noise.z()); 1390} 1391 1392///////////////////////////////////////////////////////////////////// 1393std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcessor( 1394 const GrFPArgs& args) const { 1395 SkASSERT(args.fContext); 1396 1397 SkMatrix localMatrix = this->getLocalMatrix(); 1398 if (args.fLocalMatrix) { 1399 localMatrix.preConcat(*args.fLocalMatrix); 1400 } 1401 1402 SkMatrix matrix = *args.fViewMatrix; 1403 matrix.preConcat(localMatrix); 1404 1405 // Either we don't stitch tiles, either we have a valid tile size 1406 SkASSERT(!fStitchTiles || !fTileSize.isEmpty()); 1407 1408 std::unique_ptr<SkPerlinNoiseShaderImpl::PaintingData> paintingData = 1409 skstd::make_unique<SkPerlinNoiseShaderImpl::PaintingData>(fTileSize, 1410 fSeed, 1411 fBaseFrequencyX, 1412 fBaseFrequencyY, 1413 matrix); 1414 1415 SkMatrix m = *args.fViewMatrix; 1416 m.setTranslateX(-localMatrix.getTranslateX() + SK_Scalar1); 1417 m.setTranslateY(-localMatrix.getTranslateY() + SK_Scalar1); 1418 1419 auto proxyProvider = args.fContext->contextPriv().proxyProvider(); 1420 if (fType == kImprovedNoise_Type) { 1421 // Need to assert that the textures we'll create are power of 2 so a copy isn't needed. 1422 // We also know that we will not be using mipmaps. If things things weren't true we should 1423 // go through GrBitmapTextureMaker to handle needed copies. 1424 const sk_sp<SkImage> permutationsImage = paintingData->getImprovedPermutationsImage(); 1425 SkASSERT(SkIsPow2(permutationsImage->width()) && SkIsPow2(permutationsImage->height())); 1426 sk_sp<GrTextureProxy> permutationsTexture( 1427 GrMakeCachedImageProxy(proxyProvider, std::move(permutationsImage))); 1428 1429 const sk_sp<SkImage> gradientImage = paintingData->getGradientImage(); 1430 SkASSERT(SkIsPow2(gradientImage->width()) && SkIsPow2(gradientImage->height())); 1431 sk_sp<GrTextureProxy> gradientTexture( 1432 GrMakeCachedImageProxy(proxyProvider, std::move(gradientImage))); 1433 return GrImprovedPerlinNoiseEffect::Make(fNumOctaves, fSeed, std::move(paintingData), 1434 std::move(permutationsTexture), 1435 std::move(gradientTexture), m); 1436 } 1437 1438 if (0 == fNumOctaves) { 1439 if (kFractalNoise_Type == fType) { 1440 // Extract the incoming alpha and emit rgba = (a/4, a/4, a/4, a/2) 1441 // TODO: Either treat the output of this shader as sRGB or allow client to specify a 1442 // color space of the noise. Either way, this case (and the GLSL) need to convert to 1443 // the destination. 1444 auto inner = 1445 GrConstColorProcessor::Make(GrColor4f::FromGrColor(0x80404040), 1446 GrConstColorProcessor::InputMode::kModulateRGBA); 1447 return GrFragmentProcessor::MulChildByInputAlpha(std::move(inner)); 1448 } 1449 // Emit zero. 1450 return GrConstColorProcessor::Make(GrColor4f::TransparentBlack(), 1451 GrConstColorProcessor::InputMode::kIgnore); 1452 } 1453 1454 // Need to assert that the textures we'll create are power of 2 so that now copy is needed. We 1455 // also know that we will not be using mipmaps. If things things weren't true we should go 1456 // through GrBitmapTextureMaker to handle needed copies. 1457 const sk_sp<SkImage> permutationsImage = paintingData->getPermutationsImage(); 1458 SkASSERT(SkIsPow2(permutationsImage->width()) && SkIsPow2(permutationsImage->height())); 1459 sk_sp<GrTextureProxy> permutationsProxy = GrMakeCachedImageProxy(proxyProvider, 1460 std::move(permutationsImage)); 1461 1462 const sk_sp<SkImage> noiseImage = paintingData->getNoiseImage(); 1463 SkASSERT(SkIsPow2(noiseImage->width()) && SkIsPow2(noiseImage->height())); 1464 sk_sp<GrTextureProxy> noiseProxy = GrMakeCachedImageProxy(proxyProvider, 1465 std::move(noiseImage)); 1466 1467 if (permutationsProxy && noiseProxy) { 1468 auto inner = GrPerlinNoise2Effect::Make(fType, 1469 fNumOctaves, 1470 fStitchTiles, 1471 std::move(paintingData), 1472 std::move(permutationsProxy), 1473 std::move(noiseProxy), 1474 m); 1475 return GrFragmentProcessor::MulChildByInputAlpha(std::move(inner)); 1476 } 1477 return nullptr; 1478} 1479 1480#endif 1481 1482#ifndef SK_IGNORE_TO_STRING 1483void SkPerlinNoiseShaderImpl::toString(SkString* str) const { 1484 str->append("SkPerlinNoiseShaderImpl: ("); 1485 1486 str->append("type: "); 1487 switch (fType) { 1488 case kFractalNoise_Type: 1489 str->append("\"fractal noise\""); 1490 break; 1491 case kTurbulence_Type: 1492 str->append("\"turbulence\""); 1493 break; 1494 default: 1495 str->append("\"unknown\""); 1496 break; 1497 } 1498 str->append(" base frequency: ("); 1499 str->appendScalar(fBaseFrequencyX); 1500 str->append(", "); 1501 str->appendScalar(fBaseFrequencyY); 1502 str->append(") number of octaves: "); 1503 str->appendS32(fNumOctaves); 1504 str->append(" seed: "); 1505 str->appendScalar(fSeed); 1506 str->append(" stitch tiles: "); 1507 str->append(fStitchTiles ? "true " : "false "); 1508 1509 this->INHERITED::toString(str); 1510 1511 str->append(")"); 1512} 1513#endif 1514 1515/////////////////////////////////////////////////////////////////////////////////////////////////// 1516 1517sk_sp<SkShader> SkPerlinNoiseShader::MakeFractalNoise(SkScalar baseFrequencyX, 1518 SkScalar baseFrequencyY, 1519 int numOctaves, SkScalar seed, 1520 const SkISize* tileSize) { 1521 return sk_sp<SkShader>(new SkPerlinNoiseShaderImpl(SkPerlinNoiseShaderImpl::kFractalNoise_Type, 1522 baseFrequencyX, baseFrequencyY, numOctaves, seed, 1523 tileSize)); 1524} 1525 1526sk_sp<SkShader> SkPerlinNoiseShader::MakeTurbulence(SkScalar baseFrequencyX, 1527 SkScalar baseFrequencyY, 1528 int numOctaves, SkScalar seed, 1529 const SkISize* tileSize) { 1530 return sk_sp<SkShader>(new SkPerlinNoiseShaderImpl(SkPerlinNoiseShaderImpl::kTurbulence_Type, 1531 baseFrequencyX, baseFrequencyY, numOctaves, seed, 1532 tileSize)); 1533} 1534 1535sk_sp<SkShader> SkPerlinNoiseShader::MakeImprovedNoise(SkScalar baseFrequencyX, 1536 SkScalar baseFrequencyY, 1537 int numOctaves, SkScalar z) { 1538 return sk_sp<SkShader>(new SkPerlinNoiseShaderImpl(SkPerlinNoiseShaderImpl::kImprovedNoise_Type, 1539 baseFrequencyX, baseFrequencyY, numOctaves, z, 1540 nullptr)); 1541} 1542 1543SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkPerlinNoiseShader) 1544 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShaderImpl) 1545SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1546