OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 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 "SkCanvas.h" | 8 #include "SkCanvas.h" |
9 #include "SkReadBuffer.h" | 9 #include "SkReadBuffer.h" |
10 #include "SkShadowShader.h" | 10 #include "SkShadowShader.h" |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 scaleVec.appendf("%d", i); | 290 scaleVec.appendf("%d", i); |
291 | 291 |
292 fragBuilder->codeAppendf("vec2 %s;", offset.c_str()); | 292 fragBuilder->codeAppendf("vec2 %s;", offset.c_str()); |
293 | 293 |
294 // note that we flip the y-coord of the offset and then later ad
d | 294 // note that we flip the y-coord of the offset and then later ad
d |
295 // a value just to the y-coord of povCoord. This is to account f
or | 295 // a value just to the y-coord of povCoord. This is to account f
or |
296 // the shifted origins from switching from raster into GPU. | 296 // the shifted origins from switching from raster into GPU. |
297 if (shadowFP.fIsPointLight[i]) { | 297 if (shadowFP.fIsPointLight[i]) { |
298 fragBuilder->codeAppendf("vec3 fragToLight%d = %s - worldCor
;", | 298 fragBuilder->codeAppendf("vec3 fragToLight%d = %s - worldCor
;", |
299 i, lightDirOrPosUniName[i]); | 299 i, lightDirOrPosUniName[i]); |
300 fragBuilder->codeAppendf("float distsq%d = dot(fragToLight%d
, fragToLight%d);" | 300 fragBuilder->codeAppendf("float distsq%d = dot(fragToLight%d
, " |
301 "fragToLight%d = normalize(fragToLi
ght%d);", | 301 "fragToLight%d
);", |
302 i, i, i, i, i); | 302 i, i, i); |
303 fragBuilder->codeAppendf("%s = vec2(worldCor.x - %s.x, %s.y
- worldCor.y) * " | 303 fragBuilder->codeAppendf("%s = vec2(-fragToLight%d) * povDep
th.b;", |
304 "povDepth.b;", | 304 offset.c_str(), i); |
305 offset.c_str(), lightDirOrPosUniNam
e[i], | 305 fragBuilder->codeAppendf("fragToLight%d = normalize(fragToLi
ght%d);", |
306 lightDirOrPosUniName[i]); | 306 i, i); |
| 307 |
| 308 // the 0.375s are precalculated transform values, given that
the depth |
| 309 // maps for pt lights are 4x the size (linearly) as diffuse
maps. |
| 310 // The vec2(0.375, -0.375) is used to transform us to the ce
nter of the map. |
| 311 fragBuilder->codeAppendf("vec2 %s = ((vec2(%s, %s) *" |
| 312 "vMatrixCoord_0_1_Stage0 +" |
| 313 "vec2(0,%s - %s)" |
| 314 "+ %s) / (vec2(%s, %s))) +" |
| 315 "vec2(0.375, -0.375);", |
| 316 povCoord.c_str(), |
| 317 widthUniName, heightUniName, |
| 318 depthMapHeightUniName[i], heightUni
Name, |
| 319 offset.c_str(), |
| 320 depthMapWidthUniName[i], depthMapWi
dthUniName[i]); |
307 } else { | 321 } else { |
308 fragBuilder->codeAppendf("%s = vec2(%s) * povDepth.b * vec2(
255.0, -255.0);", | 322 fragBuilder->codeAppendf("%s = vec2(%s) * povDepth.b * vec2(
255.0, -255.0);", |
309 offset.c_str(), lightDirOrPosUniNam
e[i]); | 323 offset.c_str(), lightDirOrPosUniNam
e[i]); |
| 324 |
| 325 fragBuilder->codeAppendf("vec2 %s = ((vec2(%s, %s) *" |
| 326 "vMatrixCoord_0_1_Stage0 +" |
| 327 "vec2(0,%s - %s)" |
| 328 "+ %s) / vec2(%s, %s));", |
| 329 povCoord.c_str(), |
| 330 widthUniName, heightUniName, |
| 331 depthMapHeightUniName[i], heightUni
Name, |
| 332 offset.c_str(), |
| 333 depthMapWidthUniName[i], depthMapWi
dthUniName[i]); |
310 } | 334 } |
311 fragBuilder->codeAppendf("vec2 %s = (vec2(%s, %s) *" | |
312 "vMatrixCoord_0_1_Stage0 +" | |
313 "vec2(0,%s - %s)" | |
314 " + " | |
315 "%s) / vec2(%s, %s);", | |
316 povCoord.c_str(), | |
317 widthUniName, heightUniName, | |
318 depthMapHeightUniName[i], heightUniName
, | |
319 offset.c_str(), | |
320 depthMapWidthUniName[i], depthMapHeight
UniName[i]); | |
321 | 335 |
322 fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSampler
s[i], | 336 fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSampler
s[i], |
323 povCoord.c_str(), | 337 povCoord.c_str(), |
324 kVec2f_GrSLType); | 338 kVec2f_GrSLType); |
325 | 339 |
326 } | 340 } |
327 | 341 |
328 // helper variables for calculating shadowing | 342 // helper variables for calculating shadowing |
329 | 343 |
330 // variance of depth at this fragment in the context of surrounding
area | 344 // variance of depth at this fragment in the context of surrounding
area |
331 // (area size and weighting dependent on blur size and type) | 345 // (area size and weighting dependent on blur size and type) |
332 fragBuilder->codeAppendf("float variance;"); | 346 fragBuilder->codeAppendf("float variance;"); |
333 | 347 |
334 // the difference in depth between the user POV and light POV. | 348 // the difference in depth between the user POV and light POV. |
335 fragBuilder->codeAppendf("float d;"); | 349 fragBuilder->codeAppendf("float d;"); |
336 | 350 |
337 // add up light contributions from all lights to totalLightColor | 351 // add up light contributions from all lights to totalLightColor |
338 for (int i = 0; i < numLights; i++) { | 352 for (int i = 0; i < numLights; i++) { |
339 if (!shadowFP.isPointLight(i)) { | 353 fragBuilder->codeAppendf("lightProbability = 1;"); |
| 354 |
| 355 // 1/512 == .00195... is less than half a pixel; imperceptible |
| 356 fragBuilder->codeAppendf("if (%s.b <= %s.b + .001953125) {", |
| 357 povDepth.c_str(), depthMaps[i].c_str())
; |
| 358 if (blurAlgorithm == SkShadowParams::kVariance_ShadowType) { |
| 359 // We mess with depth and depth^2 in their given scales. |
| 360 // (i.e. between 0 and 1) |
| 361 fragBuilder->codeAppendf("vec2 moments%d = vec2(%s.b, %s.g);
", |
| 362 i, depthMaps[i].c_str(), depthMaps[
i].c_str()); |
| 363 |
| 364 // variance biasing lessens light bleeding |
| 365 fragBuilder->codeAppendf("variance = max(moments%d.y - " |
| 366 "(moments%d.x * mome
nts%d.x)," |
| 367 "%s);", i, i, i, |
| 368 minVarianceUniName); |
| 369 |
| 370 fragBuilder->codeAppendf("d = (%s.b) - moments%d.x;", |
| 371 povDepth.c_str(), i); |
| 372 fragBuilder->codeAppendf("lightProbability = " |
| 373 "(variance / (variance + d
* d));"); |
| 374 |
| 375 SkString clamp("clamp"); |
| 376 clamp.appendf("%d", i); |
| 377 |
| 378 // choosing between light artifacts or correct shape shadows |
| 379 // linstep |
| 380 fragBuilder->codeAppendf("float %s = clamp((lightProbability
- %s) /" |
| 381 "(1 - %s), 0, 1);"
, |
| 382 clamp.c_str(), shBiasUniName, shBia
sUniName); |
| 383 |
| 384 fragBuilder->codeAppendf("lightProbability = %s;", clamp.c_s
tr()); |
| 385 } else { |
| 386 fragBuilder->codeAppendf("if (%s.b >= %s.b) {", |
| 387 povDepth.c_str(), depthMaps[i].c_st
r()); |
340 fragBuilder->codeAppendf("lightProbability = 1;"); | 388 fragBuilder->codeAppendf("lightProbability = 1;"); |
| 389 fragBuilder->codeAppendf("} else { lightProbability = 0; }")
; |
| 390 } |
341 | 391 |
342 // 1/512 == .00195... is less than half a pixel; imperceptib
le | 392 // VSM: The curved shadows near plane edges are artifacts from b
lurring |
343 fragBuilder->codeAppendf("if (%s.b <= %s.b + .001953125) {", | 393 // lightDir.z is equal to the lightDir dot the surface normal. |
344 povDepth.c_str(), depthMaps[i].c_st
r()); | 394 fragBuilder->codeAppendf("}"); |
345 if (blurAlgorithm == SkShadowParams::kVariance_ShadowType) { | |
346 // We mess with depth and depth^2 in their given scales. | |
347 // (i.e. between 0 and 1) | |
348 fragBuilder->codeAppendf("vec2 moments%d = vec2(%s.b, %s
.g);", | |
349 i, depthMaps[i].c_str(), depthM
aps[i].c_str()); | |
350 | 395 |
351 // variance biasing lessens light bleeding | 396 if (shadowFP.isPointLight(i)) { |
352 fragBuilder->codeAppendf("variance = max(moments%d.y - " | 397 fragBuilder->codeAppendf("totalLightColor += max(fragToLight
%d.z, 0) * %s /" |
353 "(moments%d.x *
moments%d.x)," | 398 "(1 + distsq%d)
*" |
354 "%s);", i, i, i, | |
355 minVarianceUniName); | |
356 | |
357 fragBuilder->codeAppendf("d = (%s.b) - moments%d.x;", | |
358 povDepth.c_str(), i); | |
359 fragBuilder->codeAppendf("lightProbability = " | |
360 "(variance / (variance
+ d * d));"); | |
361 | |
362 SkString clamp("clamp"); | |
363 clamp.appendf("%d", i); | |
364 | |
365 // choosing between light artifacts or correct shape sha
dows | |
366 // linstep | |
367 fragBuilder->codeAppendf("float %s = clamp((lightProbabi
lity - %s) /" | |
368 "(1 - %s), 0,
1);", | |
369 clamp.c_str(), shBiasUniName, s
hBiasUniName); | |
370 | |
371 fragBuilder->codeAppendf("lightProbability = %s;", clamp
.c_str()); | |
372 } else { | |
373 fragBuilder->codeAppendf("if (%s.b >= %s.b) {", | |
374 povDepth.c_str(), depthMaps[i].
c_str()); | |
375 fragBuilder->codeAppendf("lightProbability = 1;"); | |
376 fragBuilder->codeAppendf("} else { lightProbability = 0;
}"); | |
377 } | |
378 | |
379 // VSM: The curved shadows near plane edges are artifacts fr
om blurring | |
380 fragBuilder->codeAppendf("}"); | |
381 fragBuilder->codeAppendf("totalLightColor += %s.z * %s * " | |
382 "lightProbabilit
y;", | 399 "lightProbabilit
y;", |
| 400 i, lightColorUniName[i], i); |
| 401 } else { |
| 402 fragBuilder->codeAppendf("totalLightColor += %s.z * %s * lig
htProbability;", |
383 lightDirOrPosUniName[i], | 403 lightDirOrPosUniName[i], |
384 lightColorUniName[i]); | 404 lightColorUniName[i]); |
385 } else { | |
386 // fragToLight%d.z is equal to the fragToLight dot the surfa
ce normal. | |
387 fragBuilder->codeAppendf("totalLightColor += max(fragToLight
%d.z, 0) * %s /" | |
388 "(1 + distsq%d);
", | |
389 i, lightColorUniName[i], i); | |
390 } | 405 } |
391 } | 406 } |
392 | 407 |
393 fragBuilder->codeAppendf("totalLightColor += %s;", ambientColorUniNa
me); | 408 fragBuilder->codeAppendf("totalLightColor += %s;", ambientColorUniNa
me); |
394 fragBuilder->codeAppendf("%s = resultDiffuseColor * vec4(totalLightC
olor, 1);", | 409 fragBuilder->codeAppendf("%s = resultDiffuseColor * vec4(totalLightC
olor, 1);", |
395 args.fOutputColor); | 410 args.fOutputColor); |
396 } | 411 } |
397 | 412 |
398 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, | 413 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, |
399 GrProcessorKeyBuilder* b) { | 414 GrProcessorKeyBuilder* b) { |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
889 | 904 |
890 /////////////////////////////////////////////////////////////////////////////// | 905 /////////////////////////////////////////////////////////////////////////////// |
891 | 906 |
892 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader) | 907 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader) |
893 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl) | 908 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl) |
894 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 909 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
895 | 910 |
896 /////////////////////////////////////////////////////////////////////////////// | 911 /////////////////////////////////////////////////////////////////////////////// |
897 | 912 |
898 #endif | 913 #endif |
OLD | NEW |