37#if defined(GR_TEST_UTILS)
38std::unique_ptr<GrFragmentProcessor> GrPerlinNoise2Effect::TestCreate(GrProcessorTestData*
d) {
43 tileSize.
fWidth =
d->fRandom->nextRangeU(4, 4096);
44 tileSize.
fHeight =
d->fRandom->nextRangeU(4, 4096);
45 SkScalar baseFrequencyX =
d->fRandom->nextRangeScalar(0.01f, 0.99f);
46 SkScalar baseFrequencyY =
d->fRandom->nextRangeScalar(0.01f, 0.99f);
60 GrTest::TestAsFPArgs asFPArgs(
d);
62 shader.get(), asFPArgs.args(), GrTest::TestMatrix(
d->fRandom));
66SkString GrPerlinNoise2Effect::Impl::emitHelper(EmitArgs&
args) {
83 "floorVal.xy = floor(noiseVec);"
84 "floorVal.zw = floorVal.xy + half2(1);"
85 "half2 fractVal = fract(noiseVec);"
88 "half2 noiseSmooth = smoothstep(0, 1, fractVal);"
93 noiseCode.
append(
"floorVal -= step(stitchData.xyxy, floorVal) * stitchData.xyxy;");
98 SkString sampleX = this->invokeChild(0,
"half4(1)",
args,
"half2(floorVal.x + 0.5, 0.5)");
99 SkString sampleY = this->invokeChild(0,
"half4(1)",
args,
"half2(floorVal.z + 0.5, 0.5)");
100 noiseCode.
appendf(
"half2 latticeIdx = half2(%s.a, %s.a);", sampleX.
c_str(), sampleY.
c_str());
102 if (
args.fShaderCaps->fPerlinNoiseRoundingFix) {
110 "latticeIdx = floor(latticeIdx * half2(255.0) + half2(0.5)) * half2(0.003921569);");
114 noiseCode.
append(
"half4 bcoords = 256*latticeIdx.xyxy + floorVal.yyww;");
119 static constexpr const char* inc8bit =
"0.00390625";
121 SkStringPrintf(
"dot((lattice.ga + lattice.rb*%s)*2 - half2(1), fractVal)", inc8bit);
123 SkString sampleA = this->invokeChild(1,
"half4(1)",
args,
"half2(bcoords.x, chanCoord)");
124 SkString sampleB = this->invokeChild(1,
"half4(1)",
args,
"half2(bcoords.y, chanCoord)");
125 SkString sampleC = this->invokeChild(1,
"half4(1)",
args,
"half2(bcoords.w, chanCoord)");
126 SkString sampleD = this->invokeChild(1,
"half4(1)",
args,
"half2(bcoords.z, chanCoord)");
129 noiseCode.
appendf(
"half4 lattice = %s;", sampleA.
c_str());
133 noiseCode.
append(
"fractVal.x -= 1.0;");
138 noiseCode.
append(
"half a = mix(u, v, noiseSmooth.x);");
141 noiseCode.
append(
"fractVal.y -= 1.0;");
146 noiseCode.
append(
"fractVal.x += 1.0;");
151 noiseCode.
append(
"half b = mix(u, v, noiseSmooth.x);");
154 noiseCode.
append(
"return mix(a, b, noiseSmooth.y);");
156 SkString noiseFuncName = fragBuilder->getMangledFunctionName(
"noiseFuncName");
159 noiseFuncName.
c_str(),
160 {gPerlinNoiseStitchArgs, std::size(gPerlinNoiseStitchArgs)},
164 noiseFuncName.
c_str(),
165 {gPerlinNoiseArgs, std::size(gPerlinNoiseArgs)},
169 return noiseFuncName;
172void GrPerlinNoise2Effect::Impl::emitCode(EmitArgs&
args) {
180 fBaseFrequencyUni = uniformHandler->
addUniform(
182 const char* baseFrequencyUni = uniformHandler->
getUniformCStr(fBaseFrequencyUni);
184 const char* stitchDataUni =
nullptr;
199 fragBuilder->codeAppendf(
200 "half2 noiseVec = half2((%s + 0.5) * %s);",
args.fSampleCoord, baseFrequencyUni);
203 fragBuilder->codeAppendf(
"half4 color = half4(0);");
206 fragBuilder->codeAppendf(
"half2 stitchData = %s;", stitchDataUni);
209 fragBuilder->codeAppendf(
"half ratio = 1.0;");
212 fragBuilder->codeAppendf(
"for (int octave = 0; octave < %d; ++octave) {", pne.
numOctaves());
213 fragBuilder->codeAppendf(
"color += ");
215 fragBuilder->codeAppend(
"abs(");
219 static constexpr const char* chanCoordR =
"0.5";
220 static constexpr const char* chanCoordG =
"1.5";
221 static constexpr const char* chanCoordB =
"2.5";
222 static constexpr const char* chanCoordA =
"3.5";
224 fragBuilder->codeAppendf(
225 "half4(%s(%s, noiseVec, stitchData), %s(%s, noiseVec, stitchData),"
226 "%s(%s, noiseVec, stitchData), %s(%s, noiseVec, stitchData))",
227 noiseFuncName.
c_str(),
229 noiseFuncName.
c_str(),
231 noiseFuncName.
c_str(),
233 noiseFuncName.
c_str(),
236 fragBuilder->codeAppendf(
237 "half4(%s(%s, noiseVec), %s(%s, noiseVec),"
238 "%s(%s, noiseVec), %s(%s, noiseVec))",
239 noiseFuncName.
c_str(),
241 noiseFuncName.
c_str(),
243 noiseFuncName.
c_str(),
245 noiseFuncName.
c_str(),
249 fragBuilder->codeAppend(
")");
251 fragBuilder->codeAppend(
" * ratio;");
253 fragBuilder->codeAppend(
254 "noiseVec *= half2(2.0);"
258 fragBuilder->codeAppend(
"stitchData *= half2(2.0);");
260 fragBuilder->codeAppend(
"}");
265 fragBuilder->codeAppendf(
"color = color * half4(0.5) + half4(0.5);");
269 fragBuilder->codeAppendf(
"color = saturate(color);");
272 fragBuilder->codeAppendf(
"return half4(color.rgb * color.aaa, color.a);");
280 pdman.
set2f(fBaseFrequencyUni, baseFrequency.fX, baseFrequency.fY);
284 pdman.
set2f(fStitchDataUni,
291 uint32_t
key = fNumOctaves;
#define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(...)
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
virtual void set2f(UniformHandle, float, float) const =0
const SkVector & baseFrequency() const
const SkPerlinNoiseShader::StitchData & stitchData() const
SkPerlinNoiseShaderType type() const
void append(const char text[])
const char * c_str() const
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
std::unique_ptr< GrFragmentProcessor > Make(const SkMaskFilter *maskfilter, const GrFPArgs &args, const SkMatrix &ctm)
SK_API sk_sp< SkShader > MakeTurbulence(SkScalar baseFrequencyX, SkScalar baseFrequencyY, int numOctaves, SkScalar seed, const SkISize *tileSize=nullptr)
SK_API sk_sp< SkShader > MakeFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY, int numOctaves, SkScalar seed, const SkISize *tileSize=nullptr)