Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkBitmapProcShader.h" | 8 #include "SkBitmapProcShader.h" |
| 9 #include "SkBitmapProcState.h" | 9 #include "SkBitmapProcState.h" |
| 10 #include "SkColor.h" | 10 #include "SkColor.h" |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 // premul'd. | 119 // premul'd. |
| 120 class LightingFP : public GrFragmentProcessor { | 120 class LightingFP : public GrFragmentProcessor { |
| 121 public: | 121 public: |
| 122 LightingFP(sk_sp<GrFragmentProcessor> normalFP, sk_sp<SkLights> lights) { | 122 LightingFP(sk_sp<GrFragmentProcessor> normalFP, sk_sp<SkLights> lights) { |
| 123 | 123 |
| 124 // fuse all ambient lights into a single one | 124 // fuse all ambient lights into a single one |
| 125 fAmbientColor.set(0.0f, 0.0f, 0.0f); | 125 fAmbientColor.set(0.0f, 0.0f, 0.0f); |
| 126 for (int i = 0; i < lights->numLights(); ++i) { | 126 for (int i = 0; i < lights->numLights(); ++i) { |
| 127 if (SkLights::Light::kAmbient_LightType == lights->light(i).type()) { | 127 if (SkLights::Light::kAmbient_LightType == lights->light(i).type()) { |
| 128 fAmbientColor += lights->light(i).color(); | 128 fAmbientColor += lights->light(i).color(); |
| 129 } else if (SkLights::Light::kDirectional_LightType == lights->light( i).type()) { | |
| 130 fDirectionalLights.push_back(lights->light(i)); | |
| 131 // TODO get the handle to the shadow map if there is one | |
| 129 } else { | 132 } else { |
| 130 // TODO: handle more than one of these | 133 SkDEBUGFAIL("Unimplemented Light Type passed to LightingFP"); |
| 131 fLightColor = lights->light(i).color(); | |
| 132 fLightDir = lights->light(i).dir(); | |
| 133 // TODO get the handle to the shadow map if there is one | |
| 134 } | 134 } |
| 135 } | 135 } |
| 136 | 136 |
| 137 this->registerChildProcessor(std::move(normalFP)); | 137 this->registerChildProcessor(std::move(normalFP)); |
| 138 this->initClassID<LightingFP>(); | 138 this->initClassID<LightingFP>(); |
| 139 } | 139 } |
| 140 | 140 |
| 141 class GLSLLightingFP : public GrGLSLFragmentProcessor { | 141 class GLSLLightingFP : public GrGLSLFragmentProcessor { |
| 142 public: | 142 public: |
| 143 GLSLLightingFP() { | 143 GLSLLightingFP() { |
| 144 fLightDir.fX = 10000.0f; | |
| 145 fLightColor.fX = 0.0f; | |
| 146 fAmbientColor.fX = 0.0f; | 144 fAmbientColor.fX = 0.0f; |
| 147 } | 145 } |
| 148 | 146 |
| 149 void emitCode(EmitArgs& args) override { | 147 void emitCode(EmitArgs& args) override { |
| 150 | 148 |
| 151 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; | 149 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
| 152 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; | 150 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; |
| 151 const LightingFP& lightingFP = args.fFp.cast<LightingFP>(); | |
| 153 | 152 |
| 154 // add uniforms | 153 const char *lightDirsUniName = nullptr; |
| 155 const char* lightDirUniName = nullptr; | 154 const char *lightColorsUniName = nullptr; |
| 156 fLightDirUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 155 if (lightingFP.fDirectionalLights.count() != 0) { |
| 157 kVec3f_GrSLType, kDefault_ GrSLPrecision, | 156 fLightDirsUni = uniformHandler->addUniformArray( |
| 158 "LightDir", &lightDirUniNa me); | 157 kFragment_GrShaderFlag, |
| 159 | 158 kVec3f_GrSLType, |
| 160 const char* lightColorUniName = nullptr; | 159 kDefault_GrSLPrecision, |
| 161 fLightColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 160 "LightDir", |
| 162 kVec3f_GrSLType, kDefaul t_GrSLPrecision, | 161 lightingFP.fDirectionalLights.count(), |
| 163 "LightColor", &lightColo rUniName); | 162 &lightDirsUniName); |
| 163 fLightColorsUni = uniformHandler->addUniformArray( | |
| 164 kFragment_GrShaderFlag, | |
| 165 kVec3f_GrSLType, | |
| 166 kDefault_GrSLPrecision, | |
| 167 "LightColor", | |
| 168 lightingFP.fDirectionalLights.count(), | |
| 169 &lightColorsUniName); | |
| 170 } | |
| 164 | 171 |
| 165 const char* ambientColorUniName = nullptr; | 172 const char* ambientColorUniName = nullptr; |
| 166 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag , | 173 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag , |
| 167 kVec3f_GrSLType, kDefa ult_GrSLPrecision, | 174 kVec3f_GrSLType, kDefa ult_GrSLPrecision, |
| 168 "AmbientColor", &ambie ntColorUniName); | 175 "AmbientColor", &ambie ntColorUniName); |
| 169 | 176 |
| 170 fragBuilder->codeAppendf("vec4 diffuseColor = %s;", args.fInputColor ); | 177 fragBuilder->codeAppendf("vec4 diffuseColor = %s;", args.fInputColor ); |
| 171 | 178 |
| 172 SkString dstNormalName("dstNormal"); | 179 SkString dstNormalName("dstNormal"); |
| 173 this->emitChild(0, nullptr, &dstNormalName, args); | 180 this->emitChild(0, nullptr, &dstNormalName, args); |
| 174 | 181 |
| 175 fragBuilder->codeAppendf("vec3 normal = %s.xyz;", dstNormalName.c_st r()); | 182 fragBuilder->codeAppendf("vec3 normal = %s.xyz;", dstNormalName.c_st r()); |
| 176 | 183 |
| 177 // TODO: make this a loop and modulate the contribution from each li ght | 184 fragBuilder->codeAppend( "vec3 result = vec3(0.0);"); |
| 178 // based on the shadow map | 185 |
| 179 fragBuilder->codeAppendf("float NdotL = clamp(dot(normal, %s), 0.0, 1.0);", | |
| 180 lightDirUniName); | |
| 181 // diffuse light | 186 // diffuse light |
| 182 fragBuilder->codeAppendf("vec3 result = %s*diffuseColor.rgb*NdotL;", lightColorUniName); | 187 if (lightingFP.fDirectionalLights.count() != 0) { |
| 188 fragBuilder->codeAppendf("for (int i = 0; i < %d; i++) {", | |
| 189 lightingFP.fDirectionalLights.count()); | |
| 190 // TODO: modulate the contribution from each light based on the shadow map | |
| 191 fragBuilder->codeAppendf(" float NdotL = clamp(dot(normal, %s [i]), 0.0, 1.0);", | |
| 192 lightDirsUniName); | |
| 193 fragBuilder->codeAppendf(" result += %s[i]*diffuseColor.rgb*N dotL;", | |
| 194 lightColorsUniName); | |
| 195 fragBuilder->codeAppend("}"); | |
| 196 } | |
| 197 | |
| 183 // ambient light | 198 // ambient light |
| 184 fragBuilder->codeAppendf("result += %s * diffuseColor.rgb;", ambient ColorUniName); | 199 fragBuilder->codeAppendf("result += %s * diffuseColor.rgb;", ambient ColorUniName); |
| 185 | 200 |
| 186 // Clamping to alpha (equivalent to an unpremul'd clamp to 1.0) | 201 // Clamping to alpha (equivalent to an unpremul'd clamp to 1.0) |
| 187 fragBuilder->codeAppendf("%s = vec4(clamp(result.rgb, 0.0, diffuseCo lor.a), " | 202 fragBuilder->codeAppendf("%s = vec4(clamp(result.rgb, 0.0, diffuseCo lor.a), " |
| 188 "diffuseColor.a);", args.fOutputC olor); | 203 "diffuseColor.a);", args.fOutputC olor); |
| 189 } | 204 } |
| 190 | 205 |
| 191 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, | 206 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, |
| 192 GrProcessorKeyBuilder* b) { | 207 GrProcessorKeyBuilder* b) { |
| 193 // const LightingFP& lightingFP = proc.cast<LightingFP>(); | 208 const LightingFP& lightingFP = proc.cast<LightingFP>(); |
| 194 // only one shader generated currently | 209 b->add32(lightingFP.fDirectionalLights.count()); |
| 195 b->add32(0x0); | |
| 196 } | 210 } |
| 197 | 211 |
| 198 protected: | 212 protected: |
| 199 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override { | 213 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override { |
| 200 const LightingFP& lightingFP = proc.cast<LightingFP>(); | 214 const LightingFP& lightingFP = proc.cast<LightingFP>(); |
| 201 | 215 |
| 202 const SkVector3& lightDir = lightingFP.lightDir(); | 216 const SkTArray<SkLights::Light>& directionalLights = lightingFP.dire ctionalLights(); |
| 203 if (lightDir != fLightDir) { | 217 if (directionalLights != fDirectionalLights) { |
| 204 pdman.set3fv(fLightDirUni, 1, &lightDir.fX); | 218 SkTArray<SkColor3f> lightDirs(directionalLights.count()); |
|
egdaniel
2016/08/15 15:13:09
I current don't have a good suggestion how, but it
dvonbeck
2016/08/15 15:25:09
Based on what we talked, I will leave this as-is f
| |
| 205 fLightDir = lightDir; | 219 SkTArray<SkVector3> lightColors(directionalLights.count()); |
| 206 } | 220 for (const SkLights::Light& light : directionalLights) { |
| 221 lightDirs.push_back(light.dir()); | |
| 222 lightColors.push_back(light.color()); | |
| 223 } | |
| 207 | 224 |
| 208 const SkColor3f& lightColor = lightingFP.lightColor(); | 225 pdman.set3fv(fLightDirsUni, directionalLights.count(), &(lightDi rs[0].fX)); |
| 209 if (lightColor != fLightColor) { | 226 pdman.set3fv(fLightColorsUni, directionalLights.count(), &(light Colors[0].fX)); |
| 210 pdman.set3fv(fLightColorUni, 1, &lightColor.fX); | 227 |
| 211 fLightColor = lightColor; | 228 fDirectionalLights = directionalLights; |
| 212 } | 229 } |
| 213 | 230 |
| 214 const SkColor3f& ambientColor = lightingFP.ambientColor(); | 231 const SkColor3f& ambientColor = lightingFP.ambientColor(); |
| 215 if (ambientColor != fAmbientColor) { | 232 if (ambientColor != fAmbientColor) { |
| 216 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX); | 233 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX); |
| 217 fAmbientColor = ambientColor; | 234 fAmbientColor = ambientColor; |
| 218 } | 235 } |
| 219 } | 236 } |
| 220 | 237 |
| 221 private: | 238 private: |
| 222 SkVector3 fLightDir; | 239 SkTArray<SkLights::Light> fDirectionalLights; |
| 223 GrGLSLProgramDataManager::UniformHandle fLightDirUni; | 240 GrGLSLProgramDataManager::UniformHandle fLightDirsUni; |
| 224 | 241 GrGLSLProgramDataManager::UniformHandle fLightColorsUni; |
| 225 SkColor3f fLightColor; | |
| 226 GrGLSLProgramDataManager::UniformHandle fLightColorUni; | |
| 227 | 242 |
| 228 SkColor3f fAmbientColor; | 243 SkColor3f fAmbientColor; |
| 229 GrGLSLProgramDataManager::UniformHandle fAmbientColorUni; | 244 GrGLSLProgramDataManager::UniformHandle fAmbientColorUni; |
| 230 }; | 245 }; |
| 231 | 246 |
| 232 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { | 247 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { |
| 233 GLSLLightingFP::GenKey(*this, caps, b); | 248 GLSLLightingFP::GenKey(*this, caps, b); |
| 234 } | 249 } |
| 235 | 250 |
| 236 const char* name() const override { return "LightingFP"; } | 251 const char* name() const override { return "LightingFP"; } |
| 237 | 252 |
| 238 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { | 253 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
| 239 inout->mulByUnknownFourComponents(); | 254 inout->mulByUnknownFourComponents(); |
| 240 } | 255 } |
| 241 | 256 |
| 242 const SkVector3& lightDir() const { return fLightDir; } | 257 const SkTArray<SkLights::Light>& directionalLights() const { return fDirecti onalLights; } |
| 243 const SkColor3f& lightColor() const { return fLightColor; } | |
| 244 const SkColor3f& ambientColor() const { return fAmbientColor; } | 258 const SkColor3f& ambientColor() const { return fAmbientColor; } |
| 245 | 259 |
| 246 private: | 260 private: |
| 247 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLLightingFP; } | 261 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLLightingFP; } |
| 248 | 262 |
| 249 bool onIsEqual(const GrFragmentProcessor& proc) const override { | 263 bool onIsEqual(const GrFragmentProcessor& proc) const override { |
| 250 const LightingFP& lightingFP = proc.cast<LightingFP>(); | 264 const LightingFP& lightingFP = proc.cast<LightingFP>(); |
| 251 return fLightDir == lightingFP.fLightDir && | 265 return fDirectionalLights == lightingFP.fDirectionalLights && |
| 252 fLightColor == lightingFP.fLightColor && | |
| 253 fAmbientColor == lightingFP.fAmbientColor; | 266 fAmbientColor == lightingFP.fAmbientColor; |
| 254 } | 267 } |
| 255 | 268 |
| 256 SkVector3 fLightDir; | 269 SkTArray<SkLights::Light> fDirectionalLights; |
| 257 SkColor3f fLightColor; | 270 SkColor3f fAmbientColor; |
| 258 SkColor3f fAmbientColor; | |
| 259 }; | 271 }; |
| 260 | 272 |
| 261 //////////////////////////////////////////////////////////////////////////// | 273 //////////////////////////////////////////////////////////////////////////// |
| 262 | 274 |
| 263 sk_sp<GrFragmentProcessor> SkLightingShaderImpl::asFragmentProcessor(const AsFPA rgs& args) const { | 275 sk_sp<GrFragmentProcessor> SkLightingShaderImpl::asFragmentProcessor(const AsFPA rgs& args) const { |
| 264 sk_sp<GrFragmentProcessor> normalFP(fNormalSource->asFragmentProcessor(args) ); | 276 sk_sp<GrFragmentProcessor> normalFP(fNormalSource->asFragmentProcessor(args) ); |
| 265 if (!normalFP) { | 277 if (!normalFP) { |
| 266 return nullptr; | 278 return nullptr; |
| 267 } | 279 } |
| 268 | 280 |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 475 | 487 |
| 476 return new (storage) LightingShaderContext(*this, rec, diffuseContext, norma lProvider, | 488 return new (storage) LightingShaderContext(*this, rec, diffuseContext, norma lProvider, |
| 477 heapAllocated); | 489 heapAllocated); |
| 478 } | 490 } |
| 479 | 491 |
| 480 /////////////////////////////////////////////////////////////////////////////// | 492 /////////////////////////////////////////////////////////////////////////////// |
| 481 | 493 |
| 482 sk_sp<SkShader> SkLightingShader::Make(sk_sp<SkShader> diffuseShader, | 494 sk_sp<SkShader> SkLightingShader::Make(sk_sp<SkShader> diffuseShader, |
| 483 sk_sp<SkNormalSource> normalSource, | 495 sk_sp<SkNormalSource> normalSource, |
| 484 sk_sp<SkLights> lights) { | 496 sk_sp<SkLights> lights) { |
| 497 SkASSERT(lights); | |
| 485 if (!normalSource) { | 498 if (!normalSource) { |
| 486 normalSource = SkNormalSource::MakeFlat(); | 499 normalSource = SkNormalSource::MakeFlat(); |
| 487 } | 500 } |
| 488 | 501 |
| 489 return sk_make_sp<SkLightingShaderImpl>(std::move(diffuseShader), std::move( normalSource), | 502 return sk_make_sp<SkLightingShaderImpl>(std::move(diffuseShader), std::move( normalSource), |
| 490 std::move(lights)); | 503 std::move(lights)); |
| 491 } | 504 } |
| 492 | 505 |
| 493 /////////////////////////////////////////////////////////////////////////////// | 506 /////////////////////////////////////////////////////////////////////////////// |
| 494 | 507 |
| 495 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader) | 508 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingShader) |
| 496 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl) | 509 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingShaderImpl) |
| 497 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 510 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| 498 | 511 |
| 499 /////////////////////////////////////////////////////////////////////////////// | 512 /////////////////////////////////////////////////////////////////////////////// |
| OLD | NEW |