| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkDither.h" | 8 #include "SkDither.h" |
| 9 #include "SkPerlinNoiseShader.h" | 9 #include "SkPerlinNoiseShader.h" |
| 10 #include "SkColorFilter.h" | 10 #include "SkColorFilter.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 // noiseValue is the color component's value (or color) | 32 // noiseValue is the color component's value (or color) |
| 33 // limitValue is the maximum perlin noise array index value allowed | 33 // limitValue is the maximum perlin noise array index value allowed |
| 34 // newValue is the current noise dimension (either width or height) | 34 // newValue is the current noise dimension (either width or height) |
| 35 inline int checkNoise(int noiseValue, int limitValue, int newValue) { | 35 inline int checkNoise(int noiseValue, int limitValue, int newValue) { |
| 36 // If the noise value would bring us out of bounds of the current noise arra
y while we are | 36 // If the noise value would bring us out of bounds of the current noise arra
y while we are |
| 37 // stiching noise tiles together, wrap the noise around the current dimensio
n of the noise to | 37 // stiching noise tiles together, wrap the noise around the current dimensio
n of the noise to |
| 38 // stay within the array bounds in a continuous fashion (so that tiling line
s are not visible) | 38 // stay within the array bounds in a continuous fashion (so that tiling line
s are not visible) |
| 39 if (noiseValue >= limitValue) { | 39 if (noiseValue >= limitValue) { |
| 40 noiseValue -= newValue; | 40 noiseValue -= newValue; |
| 41 } | 41 } |
| 42 if (noiseValue >= limitValue - 1) { | |
| 43 noiseValue -= newValue - 1; | |
| 44 } | |
| 45 return noiseValue; | 42 return noiseValue; |
| 46 } | 43 } |
| 47 | 44 |
| 48 inline SkScalar smoothCurve(SkScalar t) { | 45 inline SkScalar smoothCurve(SkScalar t) { |
| 49 static const SkScalar SK_Scalar3 = 3.0f; | 46 static const SkScalar SK_Scalar3 = 3.0f; |
| 50 | 47 |
| 51 // returns t * t * (3 - 2 * t) | 48 // returns t * t * (3 - 2 * t) |
| 52 return SkScalarMul(SkScalarSquare(t), SK_Scalar3 - 2 * t); | 49 return SkScalarMul(SkScalarSquare(t), SK_Scalar3 - 2 * t); |
| 53 } | 50 } |
| 54 | 51 |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 buffer.writeBool(fStitchTiles); | 310 buffer.writeBool(fStitchTiles); |
| 314 buffer.writeInt(fTileSize.fWidth); | 311 buffer.writeInt(fTileSize.fWidth); |
| 315 buffer.writeInt(fTileSize.fHeight); | 312 buffer.writeInt(fTileSize.fHeight); |
| 316 } | 313 } |
| 317 | 314 |
| 318 SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::noise2D( | 315 SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::noise2D( |
| 319 int channel, const PaintingData& paintingData, | 316 int channel, const PaintingData& paintingData, |
| 320 const StitchData& stitchData, const SkPoint& noiseVector) const { | 317 const StitchData& stitchData, const SkPoint& noiseVector) const { |
| 321 struct Noise { | 318 struct Noise { |
| 322 int noisePositionIntegerValue; | 319 int noisePositionIntegerValue; |
| 320 int nextNoisePositionIntegerValue; |
| 323 SkScalar noisePositionFractionValue; | 321 SkScalar noisePositionFractionValue; |
| 324 Noise(SkScalar component) | 322 Noise(SkScalar component) |
| 325 { | 323 { |
| 326 SkScalar position = component + kPerlinNoise; | 324 SkScalar position = component + kPerlinNoise; |
| 327 noisePositionIntegerValue = SkScalarFloorToInt(position); | 325 noisePositionIntegerValue = SkScalarFloorToInt(position); |
| 328 noisePositionFractionValue = position - SkIntToScalar(noisePositionI
ntegerValue); | 326 noisePositionFractionValue = position - SkIntToScalar(noisePositionI
ntegerValue); |
| 327 nextNoisePositionIntegerValue = noisePositionIntegerValue + 1; |
| 329 } | 328 } |
| 330 }; | 329 }; |
| 331 Noise noiseX(noiseVector.x()); | 330 Noise noiseX(noiseVector.x()); |
| 332 Noise noiseY(noiseVector.y()); | 331 Noise noiseY(noiseVector.y()); |
| 333 SkScalar u, v; | 332 SkScalar u, v; |
| 334 const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoi
seShader&>(fShader); | 333 const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoi
seShader&>(fShader); |
| 335 // If stitching, adjust lattice points accordingly. | 334 // If stitching, adjust lattice points accordingly. |
| 336 if (perlinNoiseShader.fStitchTiles) { | 335 if (perlinNoiseShader.fStitchTiles) { |
| 337 noiseX.noisePositionIntegerValue = | 336 noiseX.noisePositionIntegerValue = |
| 338 checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stit
chData.fWidth); | 337 checkNoise(noiseX.noisePositionIntegerValue, stitchData.fWrapX, stit
chData.fWidth); |
| 339 noiseY.noisePositionIntegerValue = | 338 noiseY.noisePositionIntegerValue = |
| 340 checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stit
chData.fHeight); | 339 checkNoise(noiseY.noisePositionIntegerValue, stitchData.fWrapY, stit
chData.fHeight); |
| 340 noiseX.nextNoisePositionIntegerValue = |
| 341 checkNoise(noiseX.nextNoisePositionIntegerValue, stitchData.fWrapX,
stitchData.fWidth); |
| 342 noiseY.nextNoisePositionIntegerValue = |
| 343 checkNoise(noiseY.nextNoisePositionIntegerValue, stitchData.fWrapY,
stitchData.fHeight); |
| 341 } | 344 } |
| 342 noiseX.noisePositionIntegerValue &= kBlockMask; | 345 noiseX.noisePositionIntegerValue &= kBlockMask; |
| 343 noiseY.noisePositionIntegerValue &= kBlockMask; | 346 noiseY.noisePositionIntegerValue &= kBlockMask; |
| 344 int latticeIndex = | 347 noiseX.nextNoisePositionIntegerValue &= kBlockMask; |
| 345 paintingData.fLatticeSelector[noiseX.noisePositionIntegerValue] + | 348 noiseY.nextNoisePositionIntegerValue &= kBlockMask; |
| 346 noiseY.noisePositionIntegerValue; | 349 int i = |
| 347 int nextLatticeIndex = | 350 paintingData.fLatticeSelector[noiseX.noisePositionIntegerValue]; |
| 348 paintingData.fLatticeSelector[(noiseX.noisePositionIntegerValue + 1) & k
BlockMask] + | 351 int j = |
| 349 noiseY.noisePositionIntegerValue; | 352 paintingData.fLatticeSelector[noiseX.nextNoisePositionIntegerValue]; |
| 353 int b00 = (i + noiseY.noisePositionIntegerValue) & kBlockMask; |
| 354 int b10 = (j + noiseY.noisePositionIntegerValue) & kBlockMask; |
| 355 int b01 = (i + noiseY.nextNoisePositionIntegerValue) & kBlockMask; |
| 356 int b11 = (j + noiseY.nextNoisePositionIntegerValue) & kBlockMask; |
| 350 SkScalar sx = smoothCurve(noiseX.noisePositionFractionValue); | 357 SkScalar sx = smoothCurve(noiseX.noisePositionFractionValue); |
| 351 SkScalar sy = smoothCurve(noiseY.noisePositionFractionValue); | 358 SkScalar sy = smoothCurve(noiseY.noisePositionFractionValue); |
| 352 // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#
feTurbulenceElement | 359 // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#
feTurbulenceElement |
| 353 SkPoint fractionValue = SkPoint::Make(noiseX.noisePositionFractionValue, | 360 SkPoint fractionValue = SkPoint::Make(noiseX.noisePositionFractionValue, |
| 354 noiseY.noisePositionFractionValue); //
Offset (0,0) | 361 noiseY.noisePositionFractionValue); //
Offset (0,0) |
| 355 u = paintingData.fGradient[channel][latticeIndex & kBlockMask].dot(fractionV
alue); | 362 u = paintingData.fGradient[channel][b00].dot(fractionValue); |
| 356 fractionValue.fX -= SK_Scalar1; // Offset (-1,0) | 363 fractionValue.fX -= SK_Scalar1; // Offset (-1,0) |
| 357 v = paintingData.fGradient[channel][nextLatticeIndex & kBlockMask].dot(fract
ionValue); | 364 v = paintingData.fGradient[channel][b10].dot(fractionValue); |
| 358 SkScalar a = SkScalarInterp(u, v, sx); | 365 SkScalar a = SkScalarInterp(u, v, sx); |
| 359 fractionValue.fY -= SK_Scalar1; // Offset (-1,-1) | 366 fractionValue.fY -= SK_Scalar1; // Offset (-1,-1) |
| 360 v = paintingData.fGradient[channel][(nextLatticeIndex + 1) & kBlockMask].dot
(fractionValue); | 367 v = paintingData.fGradient[channel][b11].dot(fractionValue); |
| 361 fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1) | 368 fractionValue.fX = noiseX.noisePositionFractionValue; // Offset (0,-1) |
| 362 u = paintingData.fGradient[channel][(latticeIndex + 1) & kBlockMask].dot(fra
ctionValue); | 369 u = paintingData.fGradient[channel][b01].dot(fractionValue); |
| 363 SkScalar b = SkScalarInterp(u, v, sx); | 370 SkScalar b = SkScalarInterp(u, v, sx); |
| 364 return SkScalarInterp(a, b, sy); | 371 return SkScalarInterp(a, b, sy); |
| 365 } | 372 } |
| 366 | 373 |
| 367 SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::calculateTurbulenceValue
ForPoint( | 374 SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::calculateTurbulenceValue
ForPoint( |
| 368 int channel, const PaintingData& paintingData, | 375 int channel, const PaintingData& paintingData, |
| 369 StitchData& stitchData, const SkPoint& point) const { | 376 StitchData& stitchData, const SkPoint& point) const { |
| 370 const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoi
seShader&>(fShader); | 377 const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoi
seShader&>(fShader); |
| 371 if (perlinNoiseShader.fStitchTiles) { | 378 if (perlinNoiseShader.fStitchTiles) { |
| 372 // Set up TurbulenceInitial stitch values. | 379 // Set up TurbulenceInitial stitch values. |
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 } | 989 } |
| 983 | 990 |
| 984 // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8 | 991 // There are 4 lines, so the center of each line is 1/8, 3/8, 5/8 and 7/8 |
| 985 const char* chanCoordR = "0.125"; | 992 const char* chanCoordR = "0.125"; |
| 986 const char* chanCoordG = "0.375"; | 993 const char* chanCoordG = "0.375"; |
| 987 const char* chanCoordB = "0.625"; | 994 const char* chanCoordB = "0.625"; |
| 988 const char* chanCoordA = "0.875"; | 995 const char* chanCoordA = "0.875"; |
| 989 const char* chanCoord = "chanCoord"; | 996 const char* chanCoord = "chanCoord"; |
| 990 const char* stitchData = "stitchData"; | 997 const char* stitchData = "stitchData"; |
| 991 const char* ratio = "ratio"; | 998 const char* ratio = "ratio"; |
| 992 const char* noiseXY = "noiseXY"; | |
| 993 const char* noiseVec = "noiseVec"; | 999 const char* noiseVec = "noiseVec"; |
| 994 const char* noiseSmooth = "noiseSmooth"; | 1000 const char* noiseSmooth = "noiseSmooth"; |
| 1001 const char* floorVal = "floorVal"; |
| 995 const char* fractVal = "fractVal"; | 1002 const char* fractVal = "fractVal"; |
| 996 const char* uv = "uv"; | 1003 const char* uv = "uv"; |
| 997 const char* ab = "ab"; | 1004 const char* ab = "ab"; |
| 998 const char* latticeIdx = "latticeIdx"; | 1005 const char* latticeIdx = "latticeIdx"; |
| 1006 const char* bcoords = "bcoords"; |
| 999 const char* lattice = "lattice"; | 1007 const char* lattice = "lattice"; |
| 1000 const char* inc8bit = "0.00390625"; // 1.0 / 256.0 | 1008 const char* inc8bit = "0.00390625"; // 1.0 / 256.0 |
| 1001 // This is the math to convert the two 16bit integer packed into rgba 8 bit
input into a | 1009 // This is the math to convert the two 16bit integer packed into rgba 8 bit
input into a |
| 1002 // [-1,1] vector and perform a dot product between that vector and the provi
ded vector. | 1010 // [-1,1] vector and perform a dot product between that vector and the provi
ded vector. |
| 1003 const char* dotLattice = "dot(((%s.ga + %s.rb * vec2(%s)) * vec2(2.0) - vec
2(1.0)), %s);"; | 1011 const char* dotLattice = "dot(((%s.ga + %s.rb * vec2(%s)) * vec2(2.0) - vec
2(1.0)), %s);"; |
| 1004 | 1012 |
| 1005 // Add noise function | 1013 // Add noise function |
| 1006 static const GrGLShaderVar gPerlinNoiseArgs[] = { | 1014 static const GrGLShaderVar gPerlinNoiseArgs[] = { |
| 1007 GrGLShaderVar(chanCoord, kFloat_GrSLType), | 1015 GrGLShaderVar(chanCoord, kFloat_GrSLType), |
| 1008 GrGLShaderVar(noiseVec, kVec2f_GrSLType) | 1016 GrGLShaderVar(noiseVec, kVec2f_GrSLType) |
| 1009 }; | 1017 }; |
| 1010 | 1018 |
| 1011 static const GrGLShaderVar gPerlinNoiseStitchArgs[] = { | 1019 static const GrGLShaderVar gPerlinNoiseStitchArgs[] = { |
| 1012 GrGLShaderVar(chanCoord, kFloat_GrSLType), | 1020 GrGLShaderVar(chanCoord, kFloat_GrSLType), |
| 1013 GrGLShaderVar(noiseVec, kVec2f_GrSLType), | 1021 GrGLShaderVar(noiseVec, kVec2f_GrSLType), |
| 1014 GrGLShaderVar(stitchData, kVec2f_GrSLType) | 1022 GrGLShaderVar(stitchData, kVec2f_GrSLType) |
| 1015 }; | 1023 }; |
| 1016 | 1024 |
| 1017 SkString noiseCode; | 1025 SkString noiseCode; |
| 1018 | 1026 |
| 1019 noiseCode.appendf("\tvec4 %s = vec4(floor(%s), fract(%s));", noiseXY, noiseV
ec, noiseVec); | 1027 noiseCode.appendf("\tvec4 %s;\n", floorVal); |
| 1028 noiseCode.appendf("\t%s.xy = floor(%s);\n", floorVal, noiseVec); |
| 1029 noiseCode.appendf("\t%s.zw = %s.xy + vec2(1.0);\n", floorVal, floorVal); |
| 1030 noiseCode.appendf("\tvec2 %s = fract(%s);\n", fractVal, noiseVec); |
| 1020 | 1031 |
| 1021 // smooth curve : t * t * (3 - 2 * t) | 1032 // smooth curve : t * t * (3 - 2 * t) |
| 1022 noiseCode.appendf("\n\tvec2 %s = %s.zw * %s.zw * (vec2(3.0) - vec2(2.0) * %s
.zw);", | 1033 noiseCode.appendf("\n\tvec2 %s = %s * %s * (vec2(3.0) - vec2(2.0) * %s);", |
| 1023 noiseSmooth, noiseXY, noiseXY, noiseXY); | 1034 noiseSmooth, fractVal, fractVal, fractVal); |
| 1024 | 1035 |
| 1025 // Adjust frequencies if we're stitching tiles | 1036 // Adjust frequencies if we're stitching tiles |
| 1026 if (fStitchTiles) { | 1037 if (fStitchTiles) { |
| 1027 noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }", | 1038 noiseCode.appendf("\n\tif(%s.x >= %s.x) { %s.x -= %s.x; }", |
| 1028 noiseXY, stitchData, noiseXY, stitchData); | 1039 floorVal, stitchData, floorVal, stitchData); |
| 1029 noiseCode.appendf("\n\tif(%s.x >= (%s.x - 1.0)) { %s.x -= (%s.x - 1.0);
}", | |
| 1030 noiseXY, stitchData, noiseXY, stitchData); | |
| 1031 noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }", | 1040 noiseCode.appendf("\n\tif(%s.y >= %s.y) { %s.y -= %s.y; }", |
| 1032 noiseXY, stitchData, noiseXY, stitchData); | 1041 floorVal, stitchData, floorVal, stitchData); |
| 1033 noiseCode.appendf("\n\tif(%s.y >= (%s.y - 1.0)) { %s.y -= (%s.y - 1.0);
}", | 1042 noiseCode.appendf("\n\tif(%s.z >= %s.x) { %s.z -= %s.x; }", |
| 1034 noiseXY, stitchData, noiseXY, stitchData); | 1043 floorVal, stitchData, floorVal, stitchData); |
| 1044 noiseCode.appendf("\n\tif(%s.w >= %s.y) { %s.w -= %s.y; }", |
| 1045 floorVal, stitchData, floorVal, stitchData); |
| 1035 } | 1046 } |
| 1036 | 1047 |
| 1037 // Get texture coordinates and normalize | 1048 // Get texture coordinates and normalize |
| 1038 noiseCode.appendf("\n\t%s.xy = fract(floor(mod(%s.xy, 256.0)) / vec2(256.0))
;\n", | 1049 noiseCode.appendf("\n\t%s = fract(floor(mod(%s, 256.0)) / vec4(256.0));\n", |
| 1039 noiseXY, noiseXY); | 1050 floorVal, floorVal); |
| 1040 | 1051 |
| 1041 // Get permutation for x | 1052 // Get permutation for x |
| 1042 { | 1053 { |
| 1043 SkString xCoords(""); | 1054 SkString xCoords(""); |
| 1044 xCoords.appendf("vec2(%s.x, 0.5)", noiseXY); | 1055 xCoords.appendf("vec2(%s.x, 0.5)", floorVal); |
| 1045 | 1056 |
| 1046 noiseCode.appendf("\n\tvec2 %s;\n\t%s.x = ", latticeIdx, latticeIdx); | 1057 noiseCode.appendf("\n\tvec2 %s;\n\t%s.x = ", latticeIdx, latticeIdx); |
| 1047 builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), k
Vec2f_GrSLType); | 1058 builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), k
Vec2f_GrSLType); |
| 1048 noiseCode.append(".r;"); | 1059 noiseCode.append(".r;"); |
| 1049 } | 1060 } |
| 1050 | 1061 |
| 1051 // Get permutation for x + 1 | 1062 // Get permutation for x + 1 |
| 1052 { | 1063 { |
| 1053 SkString xCoords(""); | 1064 SkString xCoords(""); |
| 1054 xCoords.appendf("vec2(fract(%s.x + %s), 0.5)", noiseXY, inc8bit); | 1065 xCoords.appendf("vec2(%s.z, 0.5)", floorVal); |
| 1055 | 1066 |
| 1056 noiseCode.appendf("\n\t%s.y = ", latticeIdx); | 1067 noiseCode.appendf("\n\t%s.y = ", latticeIdx); |
| 1057 builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), k
Vec2f_GrSLType); | 1068 builder->appendTextureLookup(&noiseCode, samplers[0], xCoords.c_str(), k
Vec2f_GrSLType); |
| 1058 noiseCode.append(".r;"); | 1069 noiseCode.append(".r;"); |
| 1059 } | 1070 } |
| 1060 | 1071 |
| 1061 #if defined(SK_BUILD_FOR_ANDROID) | 1072 #if defined(SK_BUILD_FOR_ANDROID) |
| 1062 // Android rounding for Tegra devices, like, for example: Xoom (Tegra 2), Ne
xus 7 (Tegra 3). | 1073 // Android rounding for Tegra devices, like, for example: Xoom (Tegra 2), Ne
xus 7 (Tegra 3). |
| 1063 // The issue is that colors aren't accurate enough on Tegra devices. For exa
mple, if an 8 bit | 1074 // The issue is that colors aren't accurate enough on Tegra devices. For exa
mple, if an 8 bit |
| 1064 // value of 124 (or 0.486275 here) is entered, we can get a texture value of
123.513725 | 1075 // value of 124 (or 0.486275 here) is entered, we can get a texture value of
123.513725 |
| 1065 // (or 0.484368 here). The following rounding operation prevents these preci
sion issues from | 1076 // (or 0.484368 here). The following rounding operation prevents these preci
sion issues from |
| 1066 // affecting the result of the noise by making sure that we only have multip
les of 1/255. | 1077 // affecting the result of the noise by making sure that we only have multip
les of 1/255. |
| 1067 // (Note that 1/255 is about 0.003921569, which is the value used here). | 1078 // (Note that 1/255 is about 0.003921569, which is the value used here). |
| 1068 noiseCode.appendf("\n\t%s = floor(%s * vec2(255.0) + vec2(0.5)) * vec2(0.003
921569);", | 1079 noiseCode.appendf("\n\t%s = floor(%s * vec2(255.0) + vec2(0.5)) * vec2(0.003
921569);", |
| 1069 latticeIdx, latticeIdx); | 1080 latticeIdx, latticeIdx); |
| 1070 #endif | 1081 #endif |
| 1071 | 1082 |
| 1072 // Get (x,y) coordinates with the permutated x | 1083 // Get (x,y) coordinates with the permutated x |
| 1073 noiseCode.appendf("\n\t%s = fract(%s + %s.yy);", latticeIdx, latticeIdx, noi
seXY); | 1084 noiseCode.appendf("\n\tvec4 %s = fract(%s.xyxy + %s.yyww);", bcoords, lattic
eIdx, floorVal); |
| 1074 | |
| 1075 noiseCode.appendf("\n\tvec2 %s = %s.zw;", fractVal, noiseXY); | |
| 1076 | 1085 |
| 1077 noiseCode.appendf("\n\n\tvec2 %s;", uv); | 1086 noiseCode.appendf("\n\n\tvec2 %s;", uv); |
| 1078 // Compute u, at offset (0,0) | 1087 // Compute u, at offset (0,0) |
| 1079 { | 1088 { |
| 1080 SkString latticeCoords(""); | 1089 SkString latticeCoords(""); |
| 1081 latticeCoords.appendf("vec2(%s.x, %s)", latticeIdx, chanCoord); | 1090 latticeCoords.appendf("vec2(%s.x, %s)", bcoords, chanCoord); |
| 1082 noiseCode.appendf("\n\tvec4 %s = ", lattice); | 1091 noiseCode.appendf("\n\tvec4 %s = ", lattice); |
| 1083 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), | 1092 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), |
| 1084 kVec2f_GrSLType); | 1093 kVec2f_GrSLType); |
| 1085 noiseCode.appendf(".bgra;\n\t%s.x = ", uv); | 1094 noiseCode.appendf(".bgra;\n\t%s.x = ", uv); |
| 1086 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); | 1095 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); |
| 1087 } | 1096 } |
| 1088 | 1097 |
| 1089 noiseCode.appendf("\n\t%s.x -= 1.0;", fractVal); | 1098 noiseCode.appendf("\n\t%s.x -= 1.0;", fractVal); |
| 1090 // Compute v, at offset (-1,0) | 1099 // Compute v, at offset (-1,0) |
| 1091 { | 1100 { |
| 1092 SkString latticeCoords(""); | 1101 SkString latticeCoords(""); |
| 1093 latticeCoords.appendf("vec2(%s.y, %s)", latticeIdx, chanCoord); | 1102 latticeCoords.appendf("vec2(%s.y, %s)", bcoords, chanCoord); |
| 1094 noiseCode.append("\n\tlattice = "); | 1103 noiseCode.append("\n\tlattice = "); |
| 1095 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), | 1104 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), |
| 1096 kVec2f_GrSLType); | 1105 kVec2f_GrSLType); |
| 1097 noiseCode.appendf(".bgra;\n\t%s.y = ", uv); | 1106 noiseCode.appendf(".bgra;\n\t%s.y = ", uv); |
| 1098 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); | 1107 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); |
| 1099 } | 1108 } |
| 1100 | 1109 |
| 1101 // Compute 'a' as a linear interpolation of 'u' and 'v' | 1110 // Compute 'a' as a linear interpolation of 'u' and 'v' |
| 1102 noiseCode.appendf("\n\tvec2 %s;", ab); | 1111 noiseCode.appendf("\n\tvec2 %s;", ab); |
| 1103 noiseCode.appendf("\n\t%s.x = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmoo
th); | 1112 noiseCode.appendf("\n\t%s.x = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmoo
th); |
| 1104 | 1113 |
| 1105 noiseCode.appendf("\n\t%s.y -= 1.0;", fractVal); | 1114 noiseCode.appendf("\n\t%s.y -= 1.0;", fractVal); |
| 1106 // Compute v, at offset (-1,-1) | 1115 // Compute v, at offset (-1,-1) |
| 1107 { | 1116 { |
| 1108 SkString latticeCoords(""); | 1117 SkString latticeCoords(""); |
| 1109 latticeCoords.appendf("vec2(fract(%s.y + %s), %s)", latticeIdx, inc8bit,
chanCoord); | 1118 latticeCoords.appendf("vec2(%s.w, %s)", bcoords, chanCoord); |
| 1110 noiseCode.append("\n\tlattice = "); | 1119 noiseCode.append("\n\tlattice = "); |
| 1111 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), | 1120 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), |
| 1112 kVec2f_GrSLType); | 1121 kVec2f_GrSLType); |
| 1113 noiseCode.appendf(".bgra;\n\t%s.y = ", uv); | 1122 noiseCode.appendf(".bgra;\n\t%s.y = ", uv); |
| 1114 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); | 1123 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); |
| 1115 } | 1124 } |
| 1116 | 1125 |
| 1117 noiseCode.appendf("\n\t%s.x += 1.0;", fractVal); | 1126 noiseCode.appendf("\n\t%s.x += 1.0;", fractVal); |
| 1118 // Compute u, at offset (0,-1) | 1127 // Compute u, at offset (0,-1) |
| 1119 { | 1128 { |
| 1120 SkString latticeCoords(""); | 1129 SkString latticeCoords(""); |
| 1121 latticeCoords.appendf("vec2(fract(%s.x + %s), %s)", latticeIdx, inc8bit,
chanCoord); | 1130 latticeCoords.appendf("vec2(%s.z, %s)", bcoords, chanCoord); |
| 1122 noiseCode.append("\n\tlattice = "); | 1131 noiseCode.append("\n\tlattice = "); |
| 1123 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), | 1132 builder->appendTextureLookup(&noiseCode, samplers[1], latticeCoords.c_st
r(), |
| 1124 kVec2f_GrSLType); | 1133 kVec2f_GrSLType); |
| 1125 noiseCode.appendf(".bgra;\n\t%s.x = ", uv); | 1134 noiseCode.appendf(".bgra;\n\t%s.x = ", uv); |
| 1126 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); | 1135 noiseCode.appendf(dotLattice, lattice, lattice, inc8bit, fractVal); |
| 1127 } | 1136 } |
| 1128 | 1137 |
| 1129 // Compute 'b' as a linear interpolation of 'u' and 'v' | 1138 // Compute 'b' as a linear interpolation of 'u' and 'v' |
| 1130 noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmoo
th); | 1139 noiseCode.appendf("\n\t%s.y = mix(%s.x, %s.y, %s.x);", ab, uv, uv, noiseSmoo
th); |
| 1131 // Compute the noise as a linear interpolation of 'a' and 'b' | 1140 // Compute the noise as a linear interpolation of 'a' and 'b' |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1377 str->append(" seed: "); | 1386 str->append(" seed: "); |
| 1378 str->appendScalar(fSeed); | 1387 str->appendScalar(fSeed); |
| 1379 str->append(" stitch tiles: "); | 1388 str->append(" stitch tiles: "); |
| 1380 str->append(fStitchTiles ? "true " : "false "); | 1389 str->append(fStitchTiles ? "true " : "false "); |
| 1381 | 1390 |
| 1382 this->INHERITED::toString(str); | 1391 this->INHERITED::toString(str); |
| 1383 | 1392 |
| 1384 str->append(")"); | 1393 str->append(")"); |
| 1385 } | 1394 } |
| 1386 #endif | 1395 #endif |
| OLD | NEW |