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

Side by Side Diff: src/core/SkLightingShader.cpp

Issue 2239933004: LightingFP now supports multiple directional lights (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: Resolved rebase conflicts 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 unified diff | Download patch
« no previous file with comments | « include/core/SkLights.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 ///////////////////////////////////////////////////////////////////////////////
OLDNEW
« no previous file with comments | « include/core/SkLights.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698