| Index: src/effects/SkLightingShader.cpp
|
| diff --git a/src/effects/SkLightingShader.cpp b/src/effects/SkLightingShader.cpp
|
| index 7b55626f55a3d5ae5e6b287b5fe74c17be40b65d..4dcfa527f90f7c2dc92458262647808f6dddd09a 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) ||
|
|
|