diff options
Diffstat (limited to 'src/effects/SkLightingShader.cpp')
-rw-r--r-- | src/effects/SkLightingShader.cpp | 95 |
1 files changed, 45 insertions, 50 deletions
diff --git a/src/effects/SkLightingShader.cpp b/src/effects/SkLightingShader.cpp index 7b55626f55..4dcfa527f9 100644 --- a/src/effects/SkLightingShader.cpp +++ b/src/effects/SkLightingShader.cpp @@ -25,8 +25,6 @@ support multiple lights enforce normal map is 4 channel use SkImages instead if SkBitmaps - vec3 for ambient and light-color - add dox for both lighting equation, and how we compute normal from bitmap To Test: non-opaque diffuse textures @@ -51,7 +49,7 @@ public: */ SkLightingShaderImpl(const SkBitmap& diffuse, const SkBitmap& normal, const SkLightingShader::Light& light, - const SkColor ambient, const SkMatrix* localMatrix) + const SkColor3f& ambient, const SkMatrix* localMatrix) : INHERITED(localMatrix) , fDiffuseMap(diffuse) , fNormalMap(normal) @@ -60,8 +58,6 @@ public: if (!fLight.fDirection.normalize()) { fLight.fDirection = SkPoint3::Make(0.0f, 0.0f, 1.0f); } - SkColorSetA(fLight.fColor, 0xFF); - SkColorSetA(fAmbientColor, 0xFF); } bool isOpaque() const override; @@ -103,7 +99,7 @@ private: SkBitmap fDiffuseMap; SkBitmap fNormalMap; SkLightingShader::Light fLight; - SkColor fAmbientColor; // linear (unpremul) color + SkColor3f fAmbientColor; // linear (unpremul) color. Range is 0..1/channel. friend class SkLightingShader; @@ -124,7 +120,8 @@ private: class LightingFP : public GrFragmentProcessor { public: LightingFP(GrTexture* diffuse, GrTexture* normal, const SkMatrix& matrix, - SkVector3 lightDir, GrColor lightColor, GrColor ambientColor) + const SkVector3& lightDir, const SkColor3f& lightColor, + const SkColor3f& ambientColor) : fDeviceTransform(kDevice_GrCoordSet, matrix) , fDiffuseTextureAccess(diffuse) , fNormalTextureAccess(normal) @@ -140,8 +137,10 @@ public: class LightingGLFP : public GrGLFragmentProcessor { public: - LightingGLFP() : fLightColor(GrColor_ILLEGAL), fAmbientColor(GrColor_ILLEGAL) { + LightingGLFP() { fLightDir.fX = 10000.0f; + fLightColor.fX = 0.0f; + fAmbientColor.fX = 0.0f; } void emitCode(EmitArgs& args) override { @@ -156,12 +155,12 @@ public: const char* lightColorUniName = NULL; fLightColorUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility, - kVec4f_GrSLType, kDefault_GrSLPrecision, + kVec3f_GrSLType, kDefault_GrSLPrecision, "LightColor", &lightColorUniName); const char* ambientColorUniName = NULL; fAmbientColorUni = args.fBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility, - kVec4f_GrSLType, kDefault_GrSLPrecision, + kVec3f_GrSLType, kDefault_GrSLPrecision, "AmbientColor", &ambientColorUniName); fpb->codeAppend("vec4 diffuseColor = "); @@ -180,34 +179,30 @@ public: fpb->codeAppendf("vec3 lightDir = normalize(%s);", lightDirUniName); fpb->codeAppend("float NdotL = dot(normal, lightDir);"); // diffuse light - fpb->codeAppendf("vec3 result = %s.rgb*diffuseColor.rgb*NdotL;", lightColorUniName); + fpb->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;", lightColorUniName); // ambient light - fpb->codeAppendf("result += %s.rgb;", ambientColorUniName); + fpb->codeAppendf("result += %s;", ambientColorUniName); fpb->codeAppendf("%s = vec4(result.rgb, diffuseColor.a);", args.fOutputColor); } void setData(const GrGLProgramDataManager& pdman, const GrProcessor& proc) override { const LightingFP& lightingFP = proc.cast<LightingFP>(); - SkVector3 lightDir = lightingFP.lightDir(); + const SkVector3& lightDir = lightingFP.lightDir(); if (lightDir != fLightDir) { pdman.set3fv(fLightDirUni, 1, &lightDir.fX); fLightDir = lightDir; } - GrColor lightColor = lightingFP.lightColor(); + const SkColor3f& lightColor = lightingFP.lightColor(); if (lightColor != fLightColor) { - GrGLfloat c[4]; - GrColorToRGBAFloat(lightColor, c); - pdman.set4fv(fLightColorUni, 1, c); + pdman.set3fv(fLightColorUni, 1, &lightColor.fX); fLightColor = lightColor; } - GrColor ambientColor = lightingFP.ambientColor(); + const SkColor3f& ambientColor = lightingFP.ambientColor(); if (ambientColor != fAmbientColor) { - GrGLfloat c[4]; - GrColorToRGBAFloat(ambientColor, c); - pdman.set4fv(fAmbientColorUni, 1, c); + pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX); fAmbientColor = ambientColor; } } @@ -223,10 +218,10 @@ public: SkVector3 fLightDir; GrGLProgramDataManager::UniformHandle fLightDirUni; - GrColor fLightColor; + SkColor3f fLightColor; GrGLProgramDataManager::UniformHandle fLightColorUni; - GrColor fAmbientColor; + SkColor3f fAmbientColor; GrGLProgramDataManager::UniformHandle fAmbientColorUni; }; @@ -242,9 +237,9 @@ public: inout->mulByUnknownFourComponents(); } - SkVector3 lightDir() const { return fLightDir; } - GrColor lightColor() const { return fLightColor; } - GrColor ambientColor() const { return fAmbientColor; } + const SkVector3& lightDir() const { return fLightDir; } + const SkColor3f& lightColor() const { return fLightColor; } + const SkColor3f& ambientColor() const { return fAmbientColor; } private: bool onIsEqual(const GrFragmentProcessor& proc) const override { @@ -261,8 +256,8 @@ private: GrTextureAccess fDiffuseTextureAccess; GrTextureAccess fNormalTextureAccess; SkVector3 fLightDir; - GrColor fLightColor; - GrColor fAmbientColor; + SkColor3f fLightColor; + SkColor3f fAmbientColor; }; //////////////////////////////////////////////////////////////////////////// @@ -341,13 +336,8 @@ bool SkLightingShaderImpl::asFragmentProcessor(GrContext* context, const SkPaint return false; } - GrColor lightColor = GrColorPackRGBA(SkColorGetR(fLight.fColor), SkColorGetG(fLight.fColor), - SkColorGetB(fLight.fColor), SkColorGetA(fLight.fColor)); - GrColor ambientColor = GrColorPackRGBA(SkColorGetR(fAmbientColor), SkColorGetG(fAmbientColor), - SkColorGetB(fAmbientColor), SkColorGetA(fAmbientColor)); - *fp = SkNEW_ARGS(LightingFP, (diffuseTexture, normalTexture, matrix, - fLight.fDirection, lightColor, ambientColor)); + fLight.fDirection, fLight.fColor, fAmbientColor)); *color = GrColorPackA4(paint.getAlpha()); return true; } @@ -400,14 +390,14 @@ SkLightingShaderImpl::LightingShaderContext::~LightingShaderContext() { fNormalState->~SkBitmapProcState(); } -static inline int light(int light, int diff, SkScalar NdotL, int ambient) { - int color = int(light * diff * NdotL + 255 * ambient); - if (color <= 0) { +static inline int light(SkScalar light, int diff, SkScalar NdotL, SkScalar ambient) { + SkScalar color = light * diff * NdotL + 255 * ambient; + if (color <= 0.0f) { return 0; - } else if (color >= 255*255) { + } else if (color >= 255.0f) { return 255; } else { - return SkDiv255Round(color); + return (int) color; } } @@ -458,12 +448,12 @@ void SkLightingShaderImpl::LightingShaderContext::shadeSpan(int x, int y, NdotL = norm.dot(lightShader.fLight.fDirection); // This is all done in linear unpremul color space - r = light(SkColorGetR(lightShader.fLight.fColor), SkColorGetR(diffColor), NdotL, - SkColorGetR(lightShader.fAmbientColor)); - g = light(SkColorGetG(lightShader.fLight.fColor), SkColorGetG(diffColor), NdotL, - SkColorGetG(lightShader.fAmbientColor)); - b = light(SkColorGetB(lightShader.fLight.fColor), SkColorGetB(diffColor), NdotL, - SkColorGetB(lightShader.fAmbientColor)); + r = light(lightShader.fLight.fColor.fX, SkColorGetR(diffColor), NdotL, + lightShader.fAmbientColor.fX); + g = light(lightShader.fLight.fColor.fY, SkColorGetG(diffColor), NdotL, + lightShader.fAmbientColor.fY); + b = light(lightShader.fLight.fColor.fZ, SkColorGetB(diffColor), NdotL, + lightShader.fAmbientColor.fZ); result[i] = SkPreMultiplyARGB(SkColorGetA(diffColor), r, g, b); } @@ -502,9 +492,14 @@ SkFlattenable* SkLightingShaderImpl::CreateProc(SkReadBuffer& buf) { if (!buf.readScalarArray(&light.fDirection.fX, 3)) { return NULL; } - light.fColor = buf.readColor(); + if (!buf.readScalarArray(&light.fColor.fX, 3)) { + return NULL; + } - SkColor ambient = buf.readColor(); + SkColor3f ambient; + if (!buf.readScalarArray(&ambient.fX, 3)) { + return NULL; + } return SkNEW_ARGS(SkLightingShaderImpl, (diffuse, normal, light, ambient, &localMatrix)); } @@ -515,8 +510,8 @@ void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { buf.writeBitmap(fDiffuseMap); buf.writeBitmap(fNormalMap); buf.writeScalarArray(&fLight.fDirection.fX, 3); - buf.writeColor(fLight.fColor); - buf.writeColor(fAmbientColor); + buf.writeScalarArray(&fLight.fColor.fX, 3); + buf.writeScalarArray(&fAmbientColor.fX, 3); } SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec, @@ -571,7 +566,7 @@ static bool bitmap_is_too_big(const SkBitmap& bm) { SkShader* SkLightingShader::Create(const SkBitmap& diffuse, const SkBitmap& normal, const SkLightingShader::Light& light, - const SkColor ambient, + const SkColor3f& ambient, const SkMatrix* localMatrix) { if (diffuse.isNull() || bitmap_is_too_big(diffuse) || normal.isNull() || bitmap_is_too_big(normal) || |