Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Unified Diff: src/core/SkShadowShader.cpp

Issue 2248493002: raster shadows (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: compressed shadow-map indexing code Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkShadowShader.cpp
diff --git a/src/core/SkShadowShader.cpp b/src/core/SkShadowShader.cpp
index b1f49b851d775877d6c711db3089a5456abf44a6..6ca82fb65d8431509e635324af81aa1e5167055f 100644
--- a/src/core/SkShadowShader.cpp
+++ b/src/core/SkShadowShader.cpp
@@ -61,6 +61,10 @@ public:
void* fHeapAllocated;
+ int fNonAmbLightCnt;
+ SkPixmap* fShadowMapPixels;
+
+
typedef SkShader::Context INHERITED;
};
@@ -642,9 +646,23 @@ SkShadowShaderImpl::ShadowShaderContext::ShadowShaderContext(
}
fFlags = flags;
+
+ const SkShadowShaderImpl& lightShader = static_cast<const SkShadowShaderImpl&>(fShader);
+
+ fNonAmbLightCnt = lightShader.fLights->numLights();
+ fShadowMapPixels = new SkPixmap[fNonAmbLightCnt];
+
+ for (int i = 0; i < fNonAmbLightCnt; i++) {
+ if (lightShader.fLights->light(i).type() == SkLights::Light::kDirectional_LightType) {
+ lightShader.fLights->light(i).getShadowMap()->
+ peekPixels(&fShadowMapPixels[i]);
+ }
+ }
}
SkShadowShaderImpl::ShadowShaderContext::~ShadowShaderContext() {
+ delete[] fShadowMapPixels;
+
// The dependencies have been created outside of the context on memory that was allocated by
// the onCreateContext() method. Call the destructors and free the memory.
fPovDepthContext->~Context();
@@ -683,44 +701,62 @@ 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 = povDepth[i];
- SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f);
+ SkColor3f totalLight = lightShader.fLights->ambientLightColor();
// This is all done in linear unpremul color space (each component 0..255.0f though)
- accum.fX += lightShader.fLights->ambientLightColor().fX * SkColorGetR(diffColor);
- accum.fY += lightShader.fLights->ambientLightColor().fY * SkColorGetG(diffColor);
- accum.fZ += lightShader.fLights->ambientLightColor().fZ * SkColorGetB(diffColor);
-
for (int l = 0; l < lightShader.fLights->numLights(); ++l) {
const SkLights::Light& light = lightShader.fLights->light(l);
- if (SkLights::Light::kDirectional_LightType == light.type()) {
- // 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 pvDepth = SkColorGetB(povDepthColor); // depth stored in blue channel
+
+ int xOffset = SkScalarRoundToInt(light.dir().fX * pvDepth);
+ int yOffset = SkScalarRoundToInt(light.dir().fY * pvDepth);
+
+ int shX = SkClampMax(x + i + xOffset, light.getShadowMap()->width() - 1);
+ int shY = SkClampMax(y + yOffset, light.getShadowMap()->height() - 1);
+
+ int shDepth = 0;
+
+ // pixmaps that point to things have nonzero heights
+ if (fShadowMapPixels[l].height() > 0) {
+ uint32_t pix = *fShadowMapPixels[l].addr32(shX, shY);
+ SkColor shColor(pix);
+
+ shDepth = SkColorGetB(shColor);
+ } else {
+ // Make lights w/o a shadow map receive the full light contribution
+ shDepth = pvDepth;
+ }
+
+ 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 {
- accum.fX += light.color().fX * SkColorGetR(diffColor);
- accum.fY += light.color().fY * SkColorGetG(diffColor);
- accum.fZ += light.color().fZ * SkColorGetB(diffColor);
+ totalLight += light.color();
}
-
}
- result[i] = convert(accum, SkColorGetA(diffColor));
+ SkColor3f totalColor = SkColor3f::Make(SkColorGetR(diffColor) * totalLight.fX,
+ SkColorGetG(diffColor) * totalLight.fY,
+ SkColorGetB(diffColor) * totalLight.fZ);
+
+ result[i] = convert(totalColor, SkColorGetA(diffColor));
}
result += n;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698