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 |