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