Chromium Code Reviews| Index: src/core/SkShadowShader.cpp |
| diff --git a/src/core/SkShadowShader.cpp b/src/core/SkShadowShader.cpp |
| index 5fc992acc14dd790ab86e43e6a761ecc7b7db8bc..cbe218ba62bd23b141b61ee55d788e054fb962f9 100644 |
| --- a/src/core/SkShadowShader.cpp |
| +++ b/src/core/SkShadowShader.cpp |
| @@ -250,21 +250,21 @@ public: |
| scaleVec.c_str(), |
| widthUniName, heightUniName, |
| depthMapWidthUniName[i], depthMapHeightUniName[i]); |
|
robertphillips
2016/08/10 14:23:18
??
vjiaoblack
2016/08/11 18:28:51
Done.
|
| - |
| +// |
| fragBuilder->codeAppendf("vec2 %s = 1 - %s;\n", |
| scaleOffsetVec.c_str(), scaleVec.c_str()); |
| - |
| fragBuilder->codeAppendf("vec2 %s = (vMatrixCoord_0_1_Stage0 + " |
| - "vec2(%s.x, 0 - %s.y)) " |
| - " * %s + vec2(0,1) * %s;\n", |
| - |
| + "vec2(%s.x, 0 - %s.y)) " |
| + " * %s + vec2(0,1) * %s;\n", |
| povCoord.c_str(), offset.c_str(), offset.c_str(), |
| scaleVec.c_str(), scaleOffsetVec.c_str()); |
| fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSamplers[i], |
| povCoord.c_str(), |
| kVec2f_GrSLType); |
| + |
| + |
| } |
| const char* ambientColorUniName = nullptr; |
| @@ -274,25 +274,45 @@ public: |
| fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseColor.c_str()); |
|
robertphillips
2016/08/10 14:23:18
can we parameterize the shadow generation ?
vjiaoblack
2016/08/11 18:28:51
Done.
|
| - // Essentially, |
| - // diffColor * (ambientLightTot + foreachDirLight(lightColor * (N . L))) |
| + // all the normal vectors point straight up |
| SkString totalLightColor("totalLightColor"); |
| - fragBuilder->codeAppendf("vec3 %s = vec3(0);", totalLightColor.c_str()); |
| + fragBuilder->codeAppendf("vec3 %s = vec3(0,0,0);", totalLightColor.c_str()); |
| + |
| + SkString lightProb("lightProbability"); |
| + fragBuilder->codeAppendf("float %s;", lightProb.c_str()); |
| + fragBuilder->codeAppendf("float variance;"); |
| + fragBuilder->codeAppendf("float d;"); |
| for (int i = 0; i < numLights; i++) { |
| - fragBuilder->codeAppendf("if (%s.b >= %s.b) {", |
| + fragBuilder->codeAppendf("%s = 1;", lightProb.c_str()); |
| + |
| + // 1/512 is less than half a pixel; imperceptible |
| + fragBuilder->codeAppendf("if (%s.b <= %s.b + 1/512) {", |
| povDepth.c_str(), depthMaps[i].c_str()); |
| - // Note that dot(vec3(0,0,1), %s) == %s.z * %s |
| - fragBuilder->codeAppendf("%s += %s.z * %s;", |
| + |
| + fragBuilder->codeAppendf("vec2 moments = vec2(%s.b * 255, %s.g * 255 * 256 );", |
| + depthMaps[i].c_str(), depthMaps[i].c_str()); |
| + |
| + // variance biasing lessens light bleeding |
| + fragBuilder->codeAppendf("variance = max(moments.y - (moments.x * moments.x)," |
| + "1024);"); |
| + |
| + fragBuilder->codeAppendf("d = (%s.b * 255) - moments.x;", povDepth.c_str()); |
| + fragBuilder->codeAppendf("%s = (variance / (variance + d * d));", |
| + lightProb.c_str()); |
| + |
| + // The curved shadows near plane edges are caused by using a non-optimal blurring |
| + // function. Optimally, it'd be a linear blur. |
| + fragBuilder->codeAppendf("}"); |
| + |
| + fragBuilder->codeAppendf("%s += dot(vec3(0,0,1), %s) * %s * %s;", |
| totalLightColor.c_str(), |
| lightDirUniName[i], |
| - lightColorUniName[i]); |
| - fragBuilder->codeAppendf("}"); |
| + lightColorUniName[i], |
| + lightProb.c_str()); |
| } |
| - fragBuilder->codeAppendf("%s += %s;", |
| - totalLightColor.c_str(), |
| - ambientColorUniName); |
| + fragBuilder->codeAppendf("%s += %s;", totalLightColor.c_str(), ambientColorUniName); |
| fragBuilder->codeAppendf("resultDiffuseColor *= vec4(%s, 1);", |
| totalLightColor.c_str()); |