Index: src/core/SkShadowShader.cpp |
diff --git a/src/core/SkShadowShader.cpp b/src/core/SkShadowShader.cpp |
index 5fc992acc14dd790ab86e43e6a761ecc7b7db8bc..8c6575e49716f893c2a3b82d194a16d1df0ab914 100644 |
--- a/src/core/SkShadowShader.cpp |
+++ b/src/core/SkShadowShader.cpp |
@@ -541,35 +541,72 @@ void SkShadowShaderImpl::ShadowShaderContext::shadeSpan(int x, int y, |
const SkShadowShaderImpl& lightShader = static_cast<const SkShadowShaderImpl&>(fShader); |
SkPMColor diffuse[BUFFER_MAX]; |
+ SkPMColor povDepth[BUFFER_MAX]; |
do { |
int n = SkTMin(count, BUFFER_MAX); |
- fPovDepthContext->shadeSpan(x, y, diffuse, n); |
fDiffuseContext->shadeSpan(x, y, diffuse, n); |
+ fPovDepthContext->shadeSpan(x, y, povDepth, n); |
for (int i = 0; i < n; ++i) { |
- |
SkColor diffColor = SkUnPreMultiply::PMColorToColor(diffuse[i]); |
+ SkColor povDepthColor = SkUnPreMultiply::PMColorToColor(povDepth[i]); |
- SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f); |
+ SkColor3f totalColor = SkColor3f::Make(0.0f, 0.0f, 0.0f); |
+ SkColor3f totalLight = SkColor3f::Make(0.0f, 0.0f, 0.0f); |
// This is all done in linear unpremul color space (each component 0..255.0f though) |
+ |
for (int l = 0; l < lightShader.fLights->numLights(); ++l) { |
const SkLights::Light& light = lightShader.fLights->light(l); |
- if (SkLights::Light::kAmbient_LightType == light.type()) { |
- accum.fX += light.color().fX * SkColorGetR(diffColor); |
- accum.fY += light.color().fY * SkColorGetG(diffColor); |
- accum.fZ += light.color().fZ * SkColorGetB(diffColor); |
- } else { |
- // scaling by fZ accounts for lighting direction |
- accum.fX += light.color().makeScale(light.dir().fZ).fX * SkColorGetR(diffColor); |
- accum.fY += light.color().makeScale(light.dir().fZ).fY * SkColorGetG(diffColor); |
- accum.fZ += light.color().makeScale(light.dir().fZ).fZ * SkColorGetB(diffColor); |
+ if (light.type() == SkLights::Light::kDirectional_LightType) { |
+ int xOffset = round(light.dir().fX * (SkScalar) SkColorGetB(povDepthColor)); |
jvanverth1
2016/08/16 00:57:18
SkScalarRoundToInt instead of round(), and SkIntTo
vjiaoblack
2016/08/17 13:25:02
Done.
|
+ int yOffset = round(light.dir().fY * (SkScalar) SkColorGetB(povDepthColor)); |
+ |
+ int shX = (x + i + xOffset); |
+ int shY = (y + yOffset); |
+ |
+ if (shX < 0) { shX = 0; } |
jvanverth1
2016/08/16 00:57:18
shX = SkClampPos(shX);
vjiaoblack
2016/08/17 13:25:02
Done.
|
+ if (shY < 0) { shY = 0; } |
+ |
+ if (shX >= light.getShadowMap()->width()) { |
jvanverth1
2016/08/16 00:57:18
Or replace both the bounds checks with SkClampMax(
vjiaoblack
2016/08/17 13:25:02
Done.
|
+ shX = light.getShadowMap()->width() - 1; |
+ } |
+ |
+ if (shY >= light.getShadowMap()->height()) { |
+ shY = light.getShadowMap()->height() - 1; |
+ } |
+ |
+ SkPixmap* shPixels = new SkPixmap(); |
+ int shDepth = 0; |
+ int pvDepth = SkColorGetB(povDepthColor); |
jvanverth1
2016/08/16 00:57:18
Why B?
vjiaoblack
2016/08/17 13:25:02
We stidk the depth into the blue channel. I'll mak
|
+ |
+ if (light.getShadowMap()->peekPixels(shPixels)) { |
jvanverth1
2016/08/16 00:57:18
This seems very inefficient -- instead I suggest b
vjiaoblack
2016/08/17 13:25:02
Done.
|
+ uint32_t pix = *shPixels->addr32(shX, shY); |
jvanverth1
2016/08/16 00:57:18
This looks like it will do nearest neighbor sampli
vjiaoblack
2016/08/17 13:25:02
Well, we want it to alias - interpolation would be
|
+ SkColor shColor(pix); |
+ |
+ shDepth += SkColorGetB(shColor); |
+ } else { |
+ // TODO: handle not being able to read shadow map pixels |
+ } |
+ |
+ if (pvDepth >= shDepth) { |
+ // assume object normals are pointing straight up |
+ totalLight.fX += light.dir().fZ * light.color().fX; |
+ totalLight.fY += light.dir().fZ * light.color().fY; |
+ totalLight.fZ += light.dir().fZ * light.color().fZ; |
+ } |
+ } else if (light.type() == SkLights::Light::kAmbient_LightType) { |
+ totalLight += light.color(); |
} |
} |
- result[i] = convert(accum, SkColorGetA(diffColor)); |
+ totalColor.fX += SkColorGetR(diffColor) * totalLight.fX; |
+ totalColor.fY += SkColorGetG(diffColor) * totalLight.fY; |
+ totalColor.fZ += SkColorGetB(diffColor) * totalLight.fZ; |
+ |
+ result[i] = convert(totalColor, SkColorGetA(diffColor)); |
} |
result += n; |