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

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

Issue 2246463004: Added distance attenuation and diffuse shading to PointLights (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: made req changes; removed the unused isPointLight uni 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
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 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 8
9 #include "SkLights.h" 9 #include "SkLights.h"
10 #include "SkReadBuffer.h" 10 #include "SkReadBuffer.h"
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 class ShadowFP : public GrFragmentProcessor { 103 class ShadowFP : public GrFragmentProcessor {
104 public: 104 public:
105 ShadowFP(sk_sp<GrFragmentProcessor> povDepth, 105 ShadowFP(sk_sp<GrFragmentProcessor> povDepth,
106 sk_sp<GrFragmentProcessor> diffuse, 106 sk_sp<GrFragmentProcessor> diffuse,
107 sk_sp<SkLights> lights, 107 sk_sp<SkLights> lights,
108 int diffuseWidth, int diffuseHeight, 108 int diffuseWidth, int diffuseHeight,
109 GrContext* context) { 109 GrContext* context) {
110 110
111 // fuse all ambient lights into a single one 111 // fuse all ambient lights into a single one
112 fAmbientColor.set(0.0f, 0.0f, 0.0f); 112 fAmbientColor.set(0.0f, 0.0f, 0.0f);
113 113
robertphillips 2016/08/18 17:12:59 refers to directional lights -> count of direction
vjiaoblack 2016/08/18 18:05:34 Done.
114 fNumDirLights = 0; // refers to directional lights. 114 fNumNonAmbLights = 0; // refers to directional lights.
115 for (int i = 0; i < lights->numLights(); ++i) { 115 for (int i = 0; i < lights->numLights(); ++i) {
116 if (SkLights::Light::kAmbient_LightType == lights->light(i).type()) { 116 if (SkLights::Light::kAmbient_LightType == lights->light(i).type()) {
117 fAmbientColor += lights->light(i).color(); 117 fAmbientColor += lights->light(i).color();
118 } else if (fNumDirLights < SkShadowShader::kMaxNonAmbientLights) { 118 } else if (fNumNonAmbLights < SkShadowShader::kMaxNonAmbientLights) {
119 fLightColor[fNumDirLights] = lights->light(i).color(); 119 fLightColor[fNumNonAmbLights] = lights->light(i).color();
120 fLightDir[fNumDirLights] = lights->light(i).dir(); 120 if (lights->light(i).type() == SkLights::Light::kPoint_LightType ) {
121 fLightDirOrPos[fNumNonAmbLights] = lights->light(i).pos();
122 fLightIntensity[fNumNonAmbLights] = lights->light(i).intensi ty();
123 } else {
124 fLightDirOrPos[fNumNonAmbLights] = lights->light(i).dir();
125 fLightIntensity[fNumNonAmbLights] = 0.0f;
126 }
127 fIsPointLight[fNumNonAmbLights] =
robertphillips 2016/08/18 17:12:59 make the '==' yoda speak
vjiaoblack 2016/08/18 18:05:34 Done.
128 lights->light(i).type() == SkLights::Light::kPoint_Light Type;
129
121 SkImage_Base* shadowMap = ((SkImage_Base*)lights->light(i).getSh adowMap()); 130 SkImage_Base* shadowMap = ((SkImage_Base*)lights->light(i).getSh adowMap());
122 131
123 // gets deleted when the ShadowFP is destroyed, and frees the Gr Texture* 132 // gets deleted when the ShadowFP is destroyed, and frees the Gr Texture*
124 fTexture[fNumDirLights] = sk_sp<GrTexture>(shadowMap->asTextureR ef(context, 133 fTexture[fNumNonAmbLights] = sk_sp<GrTexture>(shadowMap->asTextu reRef(context,
125 GrTextureParams::Clam pNoFilter(), 134 GrTextureParams::Clam pNoFilter(),
126 SkSourceGammaTreatmen t::kIgnore)); 135 SkSourceGammaTreatmen t::kIgnore));
127 fDepthMapAccess[fNumDirLights].reset(fTexture[fNumDirLights].get ()); 136 fDepthMapAccess[fNumNonAmbLights].reset(fTexture[fNumNonAmbLight s].get());
128 this->addTextureAccess(&fDepthMapAccess[fNumDirLights]); 137 this->addTextureAccess(&fDepthMapAccess[fNumNonAmbLights]);
129 138
130 fDepthMapHeight[fNumDirLights] = shadowMap->height(); 139 fDepthMapHeight[fNumNonAmbLights] = shadowMap->height();
131 fDepthMapWidth[fNumDirLights] = shadowMap->width(); 140 fDepthMapWidth[fNumNonAmbLights] = shadowMap->width();
132 141
133 fNumDirLights++; 142 fNumNonAmbLights++;
134 } 143 }
135 } 144 }
136 145
137 fWidth = diffuseWidth; 146 fWidth = diffuseWidth;
138 fHeight = diffuseHeight; 147 fHeight = diffuseHeight;
139 148
140 this->registerChildProcessor(std::move(povDepth)); 149 this->registerChildProcessor(std::move(povDepth));
141 this->registerChildProcessor(std::move(diffuse)); 150 this->registerChildProcessor(std::move(diffuse));
142 this->initClassID<ShadowFP>(); 151 this->initClassID<ShadowFP>();
143 } 152 }
144 153
145 class GLSLShadowFP : public GrGLSLFragmentProcessor { 154 class GLSLShadowFP : public GrGLSLFragmentProcessor {
146 public: 155 public:
147 GLSLShadowFP() { } 156 GLSLShadowFP() { }
148 157
149 void emitCode(EmitArgs& args) override { 158 void emitCode(EmitArgs& args) override {
150 159
151 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; 160 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
152 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 161 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
153 162
154 // add uniforms 163 // add uniforms
155 int32_t numLights = args.fFp.cast<ShadowFP>().fNumDirLights; 164 int32_t numLights = args.fFp.cast<ShadowFP>().fNumNonAmbLights;
156 SkASSERT(numLights <= SkShadowShader::kMaxNonAmbientLights); 165 SkASSERT(numLights <= SkShadowShader::kMaxNonAmbientLights);
157 166
robertphillips 2016/08/18 17:12:59 a) can this be a memcpy ? b) shouldn't it only be
vjiaoblack 2016/08/18 18:05:34 a) ok sure b) no, because we need to use this valu
robertphillips 2016/08/18 18:32:11 okay, do you even need to copy it then?
vjiaoblack 2016/08/18 19:08:16 Yes, because without passing this value in, we wou
robertphillips 2016/08/23 13:52:16 Right, why can't we access the copy in ShadowFP ?
167 bool isPointLight[SkShadowShader::kMaxNonAmbientLights];
168 for (int i = 0; i < SkShadowShader::kMaxNonAmbientLights; i++) {
169 isPointLight[i] = args.fFp.cast<ShadowFP>().fIsPointLight[i];
170 }
171
158 const char* lightDirUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr}; 172 const char* lightDirUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr};
159 const char* lightColorUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr}; 173 const char* lightColorUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr};
174 const char* lightIntensityUniName[SkShadowShader::kMaxNonAmbientLigh ts] = {nullptr};
160 175
161 const char* depthMapWidthUniName[SkShadowShader::kMaxNonAmbientLight s] 176 const char* depthMapWidthUniName[SkShadowShader::kMaxNonAmbientLight s] = {nullptr};
162 = {nullptr}; 177 const char* depthMapHeightUniName[SkShadowShader::kMaxNonAmbientLigh ts] = {nullptr};
163 const char* depthMapHeightUniName[SkShadowShader::kMaxNonAmbientLigh ts]
164 = {nullptr};
165 178
robertphillips 2016/08/18 17:12:59 Are we really getting any mileage out of having th
vjiaoblack 2016/08/18 18:05:34 Yes we are. You'd want to be able to change color
robertphillips 2016/08/18 18:32:11 I meant having lightDirUniNameBase broken out into
vjiaoblack 2016/08/18 19:08:16 Okay, sure.
166 SkString lightDirUniNameBase("lightDir"); 179 SkString lightDirUniNameBase("lightDir");
167 SkString lightColorUniNameBase("lightColor"); 180 SkString lightColorUniNameBase("lightColor");
181 SkString lightIntensityUniNameBase("lightIntensity");
182 SkString isPointLightUniNameBase("isPointLight");
168 183
169 SkString depthMapWidthUniNameBase("dmapWidth"); 184 SkString depthMapWidthUniNameBase("dmapWidth");
170 SkString depthMapHeightUniNameBase("dmapHeight"); 185 SkString depthMapHeightUniNameBase("dmapHeight");
171 186
172 for (int i = 0; i < numLights; i++) { 187 for (int i = 0; i < numLights; i++) {
173 SkString lightDirUniNameStr(lightDirUniNameBase); 188 SkString lightDirUniNameStr(lightDirUniNameBase);
174 lightDirUniNameStr.appendf("%d", i); 189 lightDirUniNameStr.appendf("%d", i);
175 SkString lightColorUniNameStr(lightColorUniNameBase); 190 SkString lightColorUniNameStr(lightColorUniNameBase);
176 lightColorUniNameStr.appendf("%d", i); 191 lightColorUniNameStr.appendf("%d", i);
192 SkString lightIntensityUniNameStr(lightIntensityUniNameBase);
193 lightIntensityUniNameStr.appendf("%d", i);
robertphillips 2016/08/18 17:12:59 We don't seem to use this
vjiaoblack 2016/08/18 18:05:34 Okay, true
194 SkString isPointLightUniNameStr(isPointLightUniNameBase);
195 isPointLightUniNameStr.appendf("%d", i);
177 196
178 SkString depthMapWidthUniNameStr(depthMapWidthUniNameBase); 197 SkString depthMapWidthUniNameStr(depthMapWidthUniNameBase);
179 depthMapWidthUniNameStr.appendf("%d", i); 198 depthMapWidthUniNameStr.appendf("%d", i);
180 SkString depthMapHeightUniNameStr(depthMapHeightUniNameBase); 199 SkString depthMapHeightUniNameStr(depthMapHeightUniNameBase);
181 depthMapHeightUniNameStr.appendf("%d", i); 200 depthMapHeightUniNameStr.appendf("%d", i);
182 201
183 fLightDirUni[i] = uniformHandler->addUniform(kFragment_GrShaderF lag, 202 fLightDirUni[i] = uniformHandler->addUniform(kFragment_GrShaderF lag,
184 kVec3f_GrSLType, 203 kVec3f_GrSLType,
185 kDefault_GrSLPrecis ion, 204 kDefault_GrSLPrecis ion,
186 lightDirUniNameStr. c_str(), 205 lightDirUniNameStr. c_str(),
187 &lightDirUniName[i] ); 206 &lightDirUniName[i] );
188 fLightColorUni[i] = uniformHandler->addUniform(kFragment_GrShade rFlag, 207 fLightColorUni[i] = uniformHandler->addUniform(kFragment_GrShade rFlag,
189 kVec3f_GrSLType, 208 kVec3f_GrSLType,
190 kDefault_GrSLPrec ision, 209 kDefault_GrSLPrec ision,
191 lightColorUniName Str.c_str(), 210 lightColorUniName Str.c_str(),
192 &lightColorUniNam e[i]); 211 &lightColorUniNam e[i]);
212 fLightIntensityUni[i] =
213 uniformHandler->addUniform(kFragment_GrShaderFlag,
214 kFloat_GrSLType,
215 kDefault_GrSLPrecision,
216 lightIntensityUniNameStr.c_st r(),
217 &lightIntensityUniName[i]);
193 218
194 fDepthMapWidthUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag, 219 fDepthMapWidthUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag,
195 kInt_GrSLType, 220 kInt_GrSLType,
196 kDefault_GrSLPrecision, 221 kDefault_GrSLPrecision,
197 depthMapWidthUniNameStr.c_str (), 222 depthMapWidthUniNameStr.c_str (),
198 &depthMapWidthUniName[i]); 223 &depthMapWidthUniName[i]);
199 fDepthMapHeightUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag, 224 fDepthMapHeightUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag,
200 kInt_GrSLType, 225 kInt_GrSLType,
201 kDefault_GrSLPrecision, 226 kDefault_GrSLPrecision,
202 depthMapHeightUniNameStr.c_st r(), 227 depthMapHeightUniNameStr.c_st r(),
203 &depthMapHeightUniName[i]); 228 &depthMapHeightUniName[i]);
204 } 229 }
205 230
206
207 const char* widthUniName = nullptr; 231 const char* widthUniName = nullptr;
208 const char* heightUniName = nullptr; 232 const char* heightUniName = nullptr;
209 233
210 fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 234 fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
211 kInt_GrSLType, 235 kInt_GrSLType,
212 kDefault_GrSLPrecision, 236 kDefault_GrSLPrecision,
213 "width", &widthUniName); 237 "width", &widthUniName);
214 fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 238 fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
215 kInt_GrSLType, 239 kInt_GrSLType,
216 kDefault_GrSLPrecision, 240 kDefault_GrSLPrecision,
217 "height", &heightUniName); 241 "height", &heightUniName);
218 242
219
220 SkString povDepth("povDepth"); 243 SkString povDepth("povDepth");
221 this->emitChild(0, nullptr, &povDepth, args); 244 this->emitChild(0, nullptr, &povDepth, args);
222 245
223 SkString diffuseColor("inDiffuseColor"); 246 SkString diffuseColor("inDiffuseColor");
224 this->emitChild(1, nullptr, &diffuseColor, args); 247 this->emitChild(1, nullptr, &diffuseColor, args);
225 248
226 SkString depthMaps[SkShadowShader::kMaxNonAmbientLights]; 249 SkString depthMaps[SkShadowShader::kMaxNonAmbientLights];
227 250
251 // Multiply by 255 to transform from sampler coordinates to world
252 // coordinates (since 1 channel is 0xFF)
253 fragBuilder->codeAppendf("vec3 worldCor = vec3(vMatrixCoord_0_1_Stag e0 * "
254 "vec2(%s, %s), %s.b * 255); \n",
255 widthUniName, heightUniName, povDepth.c_str ());
256
228 for (int i = 0; i < numLights; i++) { 257 for (int i = 0; i < numLights; i++) {
229 SkString povCoord("povCoord"); 258 SkString povCoord("povCoord");
230 povCoord.appendf("%d", i); 259 povCoord.appendf("%d", i);
231 260
232 // vMatrixCoord_0_1_Stage0 is the texture sampler coordinates. 261 // vMatrixCoord_0_1_Stage0 is the texture sampler coordinates.
233 // povDepth.b * 255 scales it to 0 - 255, bringing it to world s pace, 262 // povDepth.b * 255 scales it to 0 - 255, bringing it to world s pace,
234 // and the / 400 brings it back to a sampler coordinate, 0 - 1 263 // and the / vec2(width, height) brings it back to a sampler coo rdinate
235 // The 400 comes from the shadowmaps GM.
236 // TODO use real shadowmaps size
237 SkString offset("offset"); 264 SkString offset("offset");
238 offset.appendf("%d", i); 265 offset.appendf("%d", i);
239 266
240 SkString scaleVec("scaleVec"); 267 SkString scaleVec("scaleVec");
241 scaleVec.appendf("%d", i); 268 scaleVec.appendf("%d", i);
242 269
243 SkString scaleOffsetVec("scaleOffsetVec"); 270 SkString scaleOffsetVec("scaleOffsetVec");
244 scaleOffsetVec.appendf("%d", i); 271 scaleOffsetVec.appendf("%d", i);
245 272
246 fragBuilder->codeAppendf("vec2 %s = vec2(%s) * povDepth.b * 255 / 400;\n", 273 fragBuilder->codeAppendf("vec2 %s;", offset.c_str());
247 offset.c_str(), lightDirUniName[i]);
248 274
275 if (isPointLight[i]) {
276 fragBuilder->codeAppendf("vec3 fragToLight%d = %s - worldCor ;\n",
277 i, lightDirUniName[i]);
278 fragBuilder->codeAppendf("float distsq%d = dot(fragToLight%d , fragToLight%d);"
279 "fragToLight%d = normalize(fragToLi ght%d);",
280 i, i, i, i, i);
281 fragBuilder->codeAppendf("%s = -vec2(%s.x - worldCor.x, worl dCor.y - %s.y)*"
282 "(povDepth.b) / vec2(%s, %s) ;\n",
283 offset.c_str(), lightDirUniName[i],
284 lightDirUniName[i], widthUniName, h eightUniName);
285 } else {
286 fragBuilder->codeAppendf("%s = vec2(%s) * povDepth.b * 255 / vec2(%s, %s);\n",
287 offset.c_str(), lightDirUniName[i],
288 widthUniName, heightUniName);
289 }
249 fragBuilder->codeAppendf("vec2 %s = (vec2(%s, %s) / vec2(%s, %s) );\n", 290 fragBuilder->codeAppendf("vec2 %s = (vec2(%s, %s) / vec2(%s, %s) );\n",
250 scaleVec.c_str(), 291 scaleVec.c_str(),
251 widthUniName, heightUniName, 292 widthUniName, heightUniName,
252 depthMapWidthUniName[i], depthMapHeight UniName[i]); 293 depthMapWidthUniName[i], depthMapHeight UniName[i]);
253 294
254 fragBuilder->codeAppendf("vec2 %s = 1 - %s;\n", 295 fragBuilder->codeAppendf("vec2 %s = 1 - %s;\n",
255 scaleOffsetVec.c_str(), scaleVec.c_str( )); 296 scaleOffsetVec.c_str(), scaleVec.c_str( ));
256 297
257
258 fragBuilder->codeAppendf("vec2 %s = (vMatrixCoord_0_1_Stage0 + " 298 fragBuilder->codeAppendf("vec2 %s = (vMatrixCoord_0_1_Stage0 + "
259 "vec2(%s.x, 0 - %s.y)) " 299 "vec2(%s.x, 0 - %s.y)) "
260 " * %s + vec2(0,1) * %s;\n", 300 " * %s + vec2(0,1) * %s;\n",
261
262 povCoord.c_str(), offset.c_str(), offse t.c_str(), 301 povCoord.c_str(), offset.c_str(), offse t.c_str(),
263 scaleVec.c_str(), scaleOffsetVec.c_str( )); 302 scaleVec.c_str(), scaleOffsetVec.c_str( ));
264 303
265 fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSampler s[i], 304 fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSampler s[i],
266 povCoord.c_str(), 305 povCoord.c_str(),
267 kVec2f_GrSLType); 306 kVec2f_GrSLType);
268 } 307 }
269 308
270 const char* ambientColorUniName = nullptr; 309 const char* ambientColorUniName = nullptr;
271 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag , 310 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag ,
272 kVec3f_GrSLType, kDefa ult_GrSLPrecision, 311 kVec3f_GrSLType, kDefa ult_GrSLPrecision,
273 "AmbientColor", &ambie ntColorUniName); 312 "AmbientColor", &ambie ntColorUniName);
274 313
275 fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseCol or.c_str()); 314 fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseCol or.c_str());
276 315
277 // Essentially,
278 // diffColor * (ambientLightTot + foreachDirLight(lightColor * (N . L))) 316 // diffColor * (ambientLightTot + foreachDirLight(lightColor * (N . L)))
279 SkString totalLightColor("totalLightColor"); 317 SkString totalLightColor("totalLightColor");
280 fragBuilder->codeAppendf("vec3 %s = vec3(0);", totalLightColor.c_str ()); 318 fragBuilder->codeAppendf("vec3 %s = vec3(0);", totalLightColor.c_str ());
281 319
282 for (int i = 0; i < numLights; i++) { 320 for (int i = 0; i < numLights; i++) {
283 fragBuilder->codeAppendf("if (%s.b >= %s.b) {", 321 if (!isPointLight[i]) {
284 povDepth.c_str(), depthMaps[i].c_str()) ; 322 fragBuilder->codeAppendf("if (%s.b >= %s.b) {",
285 // Note that dot(vec3(0,0,1), %s) == %s.z * %s 323 povDepth.c_str(), depthMaps[i].c_st r());
286 fragBuilder->codeAppendf("%s += %s.z * %s;", 324 // Note that dot(vec3(0,0,1), %s) == %s.z * %s
287 totalLightColor.c_str(), 325 fragBuilder->codeAppendf("%s += %s.z * %s;",
288 lightDirUniName[i], 326 totalLightColor.c_str(),
289 lightColorUniName[i]); 327 lightDirUniName[i],
290 fragBuilder->codeAppendf("}"); 328 lightColorUniName[i]);
329 fragBuilder->codeAppendf("}");
330 } else {
331 // fragToLight%d.z is equal to the fragToLight dot the surfa ce normal.
332 fragBuilder->codeAppendf("%s += fragToLight%d.z * %s / "
333 "(1 + distsq%d / (%s * %s));" ,
334 totalLightColor.c_str(), i,
335 lightColorUniName[i], i,
336 lightIntensityUniName[i],
337 lightIntensityUniName[i]);
338 }
291 } 339 }
292 340
293 fragBuilder->codeAppendf("%s += %s;", 341 fragBuilder->codeAppendf("%s += %s;",
294 totalLightColor.c_str(), 342 totalLightColor.c_str(),
295 ambientColorUniName); 343 ambientColorUniName);
296 344
297 fragBuilder->codeAppendf("resultDiffuseColor *= vec4(%s, 1);", 345 fragBuilder->codeAppendf("resultDiffuseColor *= vec4(%s, 1);",
298 totalLightColor.c_str()); 346 totalLightColor.c_str());
299 347
300 fragBuilder->codeAppendf("%s = resultDiffuseColor;", args.fOutputCol or); 348 fragBuilder->codeAppendf("%s = resultDiffuseColor;", args.fOutputCol or);
301 } 349 }
302 350
303 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, 351 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
304 GrProcessorKeyBuilder* b) { 352 GrProcessorKeyBuilder* b) {
305 const ShadowFP& shadowFP = proc.cast<ShadowFP>(); 353 const ShadowFP& shadowFP = proc.cast<ShadowFP>();
306 b->add32(shadowFP.fNumDirLights); 354 b->add32(shadowFP.fNumNonAmbLights);
355 int isPL = 0;
356 for (int i = 0; i < SkShadowShader::kMaxNonAmbientLights; i++) {
357 isPL = isPL | ((shadowFP.fIsPointLight[i] ? 1 : 0) << i);
358 }
359 b->add32(isPL);
307 } 360 }
308 361
309 protected: 362 protected:
310 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override { 363 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {
311 const ShadowFP &shadowFP = proc.cast<ShadowFP>(); 364 const ShadowFP &shadowFP = proc.cast<ShadowFP>();
312 365
313 fNumDirLights = shadowFP.numLights(); 366 fNumDirLights = shadowFP.numLights();
314 367
315 for (int i = 0; i < fNumDirLights; i++) { 368 for (int i = 0; i < fNumDirLights; i++) {
369 bool isPoint = shadowFP.isPointLight(i);
370 fIsPointLight[i] = isPoint;
371
316 const SkVector3& lightDir = shadowFP.lightDir(i); 372 const SkVector3& lightDir = shadowFP.lightDir(i);
317 if (lightDir != fLightDir[i]) { 373 if (lightDir != fLightDir[i]) {
318 pdman.set3fv(fLightDirUni[i], 1, &lightDir.fX); 374 pdman.set3fv(fLightDirUni[i], 1, &lightDir.fX);
319 fLightDir[i] = lightDir; 375 fLightDir[i] = lightDir;
320 } 376 }
377
321 const SkColor3f& lightColor = shadowFP.lightColor(i); 378 const SkColor3f& lightColor = shadowFP.lightColor(i);
322 if (lightColor != fLightColor[i]) { 379 if (lightColor != fLightColor[i]) {
323 pdman.set3fv(fLightColorUni[i], 1, &lightColor.fX); 380 pdman.set3fv(fLightColorUni[i], 1, &lightColor.fX);
324 fLightColor[i] = lightColor; 381 fLightColor[i] = lightColor;
325 } 382 }
326 383
384 SkScalar lightIntensity = shadowFP.lightIntensity(i);
385 if (lightIntensity != fLightIntensity[i]) {
386 pdman.set1f(fLightIntensityUni[i], lightIntensity);
387 fLightIntensity[i] = lightIntensity;
388 }
389
327 int depthMapWidth = shadowFP.depthMapWidth(i); 390 int depthMapWidth = shadowFP.depthMapWidth(i);
328 if (depthMapWidth != fDepthMapWidth[i]) { 391 if (depthMapWidth != fDepthMapWidth[i]) {
329 pdman.set1i(fDepthMapWidthUni[i], depthMapWidth); 392 pdman.set1i(fDepthMapWidthUni[i], depthMapWidth);
330 fDepthMapWidth[i] = depthMapWidth; 393 fDepthMapWidth[i] = depthMapWidth;
331 } 394 }
332 int depthMapHeight = shadowFP.depthMapHeight(i); 395 int depthMapHeight = shadowFP.depthMapHeight(i);
333 if (depthMapHeight != fDepthMapHeight[i]) { 396 if (depthMapHeight != fDepthMapHeight[i]) {
334 pdman.set1i(fDepthMapHeightUni[i], depthMapHeight); 397 pdman.set1i(fDepthMapHeightUni[i], depthMapHeight);
335 fDepthMapHeight[i] = depthMapHeight; 398 fDepthMapHeight[i] = depthMapHeight;
336 } 399 }
(...skipping 11 matching lines...) Expand all
348 } 411 }
349 412
350 const SkColor3f& ambientColor = shadowFP.ambientColor(); 413 const SkColor3f& ambientColor = shadowFP.ambientColor();
351 if (ambientColor != fAmbientColor) { 414 if (ambientColor != fAmbientColor) {
352 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX); 415 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX);
353 fAmbientColor = ambientColor; 416 fAmbientColor = ambientColor;
354 } 417 }
355 } 418 }
356 419
357 private: 420 private:
421 bool fIsPointLight[SkShadowShader::kMaxNonAmbientLights];
422
358 SkVector3 fLightDir[SkShadowShader::kMaxNonAmbientLights]; 423 SkVector3 fLightDir[SkShadowShader::kMaxNonAmbientLights];
359 GrGLSLProgramDataManager::UniformHandle 424 GrGLSLProgramDataManager::UniformHandle
360 fLightDirUni[SkShadowShader::kMaxNonAmbientLights]; 425 fLightDirUni[SkShadowShader::kMaxNonAmbientLights];
361 426
362 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; 427 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights];
363 GrGLSLProgramDataManager::UniformHandle 428 GrGLSLProgramDataManager::UniformHandle
364 fLightColorUni[SkShadowShader::kMaxNonAmbientLights]; 429 fLightColorUni[SkShadowShader::kMaxNonAmbientLights];
365 430
431 SkScalar fLightIntensity[SkShadowShader::kMaxNonAmbientLights];
432 GrGLSLProgramDataManager::UniformHandle
433 fLightIntensityUni[SkShadowShader::kMaxNonAmbientLights];
434
366 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; 435 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights];
367 GrGLSLProgramDataManager::UniformHandle 436 GrGLSLProgramDataManager::UniformHandle
368 fDepthMapWidthUni[SkShadowShader::kMaxNonAmbientLights]; 437 fDepthMapWidthUni[SkShadowShader::kMaxNonAmbientLights];
369 438
370 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; 439 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights];
371 GrGLSLProgramDataManager::UniformHandle 440 GrGLSLProgramDataManager::UniformHandle
372 fDepthMapHeightUni[SkShadowShader::kMaxNonAmbientLights]; 441 fDepthMapHeightUni[SkShadowShader::kMaxNonAmbientLights];
373 442
374 int fWidth; 443 int fWidth;
375 GrGLSLProgramDataManager::UniformHandle fWidthUni; 444 GrGLSLProgramDataManager::UniformHandle fWidthUni;
376 int fHeight; 445 int fHeight;
377 GrGLSLProgramDataManager::UniformHandle fHeightUni; 446 GrGLSLProgramDataManager::UniformHandle fHeightUni;
378 447
379 SkColor3f fAmbientColor; 448 SkColor3f fAmbientColor;
380 GrGLSLProgramDataManager::UniformHandle fAmbientColorUni; 449 GrGLSLProgramDataManager::UniformHandle fAmbientColorUni;
381 450
382 int fNumDirLights; 451 int fNumDirLights;
383 }; 452 };
384 453
385 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { 454 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
386 GLSLShadowFP::GenKey(*this, caps, b); 455 GLSLShadowFP::GenKey(*this, caps, b);
387 } 456 }
388 457
389 const char* name() const override { return "shadowFP"; } 458 const char* name() const override { return "shadowFP"; }
390 459
391 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { 460 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
392 inout->mulByUnknownFourComponents(); 461 inout->mulByUnknownFourComponents();
393 } 462 }
394 int32_t numLights() const { return fNumDirLights; } 463 int32_t numLights() const { return fNumNonAmbLights; }
395 const SkColor3f& ambientColor() const { return fAmbientColor; } 464 const SkColor3f& ambientColor() const { return fAmbientColor; }
robertphillips 2016/08/18 17:12:59 just return 'bool' - "const bool&" is way overkill
vjiaoblack 2016/08/18 18:05:33 Done.
465 const bool& isPointLight(int i) const {
466 SkASSERT(i < fNumNonAmbLights);
467 return fIsPointLight[i];
468 }
robertphillips 2016/08/18 17:12:59 lightDirOrPos ?
vjiaoblack 2016/08/18 18:05:34 Done.
396 const SkVector3& lightDir(int i) const { 469 const SkVector3& lightDir(int i) const {
397 SkASSERT(i < fNumDirLights); 470 SkASSERT(i < fNumNonAmbLights);
398 return fLightDir[i]; 471 return fLightDirOrPos[i];
399 } 472 }
400 const SkVector3& lightColor(int i) const { 473 const SkVector3& lightColor(int i) const {
401 SkASSERT(i < fNumDirLights); 474 SkASSERT(i < fNumNonAmbLights);
402 return fLightColor[i]; 475 return fLightColor[i];
403 } 476 }
477 SkScalar lightIntensity(int i) const {
478 SkASSERT(i < fNumNonAmbLights);
479 return fLightIntensity[i];
480 }
404 481
405 int depthMapWidth(int i) const { 482 int depthMapWidth(int i) const {
406 SkASSERT(i < fNumDirLights); 483 SkASSERT(i < fNumNonAmbLights);
407 return fDepthMapWidth[i]; 484 return fDepthMapWidth[i];
408 } 485 }
409 int depthMapHeight(int i) const { 486 int depthMapHeight(int i) const {
410 SkASSERT(i < fNumDirLights); 487 SkASSERT(i < fNumNonAmbLights);
411 return fDepthMapHeight[i]; 488 return fDepthMapHeight[i];
412 } 489 }
413 int width() const {return fWidth; } 490 int width() const {return fWidth; }
414 int height() const {return fHeight; } 491 int height() const {return fHeight; }
415 492
416 private: 493 private:
417 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLShadowFP; } 494 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLShadowFP; }
418 495
419 bool onIsEqual(const GrFragmentProcessor& proc) const override { 496 bool onIsEqual(const GrFragmentProcessor& proc) const override {
420 const ShadowFP& shadowFP = proc.cast<ShadowFP>(); 497 const ShadowFP& shadowFP = proc.cast<ShadowFP>();
421 if (fAmbientColor != shadowFP.fAmbientColor || fNumDirLights != shadowFP .fNumDirLights) { 498 if (fAmbientColor != shadowFP.fAmbientColor || fNumNonAmbLights != shado wFP.fNumNonAmbLights) {
422 return false; 499 return false;
423 } 500 }
424 501
425 if (fWidth != shadowFP.fWidth || fHeight != shadowFP.fHeight) { 502 if (fWidth != shadowFP.fWidth || fHeight != shadowFP.fHeight) {
426 return false; 503 return false;
427 } 504 }
428 505
429 for (int i = 0; i < fNumDirLights; i++) { 506 for (int i = 0; i < fNumNonAmbLights; i++) {
430 if (fLightDir[i] != shadowFP.fLightDir[i] || 507 if (fLightDirOrPos[i] != shadowFP.fLightDirOrPos[i] ||
431 fLightColor[i] != shadowFP.fLightColor[i]) { 508 fLightColor[i] != shadowFP.fLightColor[i] ||
509 fLightIntensity[i] != shadowFP.fLightIntensity[i] ||
510 fIsPointLight[i] != shadowFP.fIsPointLight[i]) {
432 return false; 511 return false;
433 } 512 }
434 513
435 if (fDepthMapWidth[i] != shadowFP.fDepthMapWidth[i] || 514 if (fDepthMapWidth[i] != shadowFP.fDepthMapWidth[i] ||
436 fDepthMapHeight[i] != shadowFP.fDepthMapHeight[i]) { 515 fDepthMapHeight[i] != shadowFP.fDepthMapHeight[i]) {
437 return false; 516 return false;
438 } 517 }
439 } 518 }
440 519
441 return true; 520 return true;
442 } 521 }
443 522
444 int fNumDirLights; 523 int fNumNonAmbLights;
445 524
446 SkVector3 fLightDir[SkShadowShader::kMaxNonAmbientLights]; 525 bool fIsPointLight[SkShadowShader::kMaxNonAmbientLights];
526 SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights];
447 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; 527 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights];
528 SkScalar fLightIntensity[SkShadowShader::kMaxNonAmbientLights];
448 GrTextureAccess fDepthMapAccess[SkShadowShader::kMaxNonAmbientLights]; 529 GrTextureAccess fDepthMapAccess[SkShadowShader::kMaxNonAmbientLights];
449 sk_sp<GrTexture> fTexture[SkShadowShader::kMaxNonAmbientLights]; 530 sk_sp<GrTexture> fTexture[SkShadowShader::kMaxNonAmbientLights];
450 531
451 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; 532 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights];
452 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; 533 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights];
453 534
454 int fHeight; 535 int fHeight;
455 int fWidth; 536 int fWidth;
456 537
457 SkColor3f fAmbientColor; 538 SkColor3f fAmbientColor;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 635
555 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f); 636 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f);
556 // This is all done in linear unpremul color space (each component 0 ..255.0f though) 637 // This is all done in linear unpremul color space (each component 0 ..255.0f though)
557 for (int l = 0; l < lightShader.fLights->numLights(); ++l) { 638 for (int l = 0; l < lightShader.fLights->numLights(); ++l) {
558 const SkLights::Light& light = lightShader.fLights->light(l); 639 const SkLights::Light& light = lightShader.fLights->light(l);
559 640
560 if (SkLights::Light::kAmbient_LightType == light.type()) { 641 if (SkLights::Light::kAmbient_LightType == light.type()) {
561 accum.fX += light.color().fX * SkColorGetR(diffColor); 642 accum.fX += light.color().fX * SkColorGetR(diffColor);
562 accum.fY += light.color().fY * SkColorGetG(diffColor); 643 accum.fY += light.color().fY * SkColorGetG(diffColor);
563 accum.fZ += light.color().fZ * SkColorGetB(diffColor); 644 accum.fZ += light.color().fZ * SkColorGetB(diffColor);
645 } else if (SkLights::Light::kDirectional_LightType == light.type ()) {
646 // scaling by fZ accounts for lighting direction
647 accum.fX += light.color().makeScale(light.dir().fZ).fX *
648 SkColorGetR(diffColor);
649 accum.fY += light.color().makeScale(light.dir().fZ).fY *
650 SkColorGetG(diffColor);
651 accum.fZ += light.color().makeScale(light.dir().fZ).fZ *
652 SkColorGetB(diffColor);
564 } else { 653 } else {
565 // scaling by fZ accounts for lighting direction 654 // TODO: do point lights for raster, currently treated like ambient
566 accum.fX += light.color().makeScale(light.dir().fZ).fX * SkC olorGetR(diffColor); 655 accum.fX += light.color().fX * SkColorGetR(diffColor);
567 accum.fY += light.color().makeScale(light.dir().fZ).fY * SkC olorGetG(diffColor); 656 accum.fY += light.color().fY * SkColorGetG(diffColor);
568 accum.fZ += light.color().makeScale(light.dir().fZ).fZ * SkC olorGetB(diffColor); 657 accum.fZ += light.color().fZ * SkColorGetB(diffColor);
569 } 658 }
570 } 659 }
571 660
572 result[i] = convert(accum, SkColorGetA(diffColor)); 661 result[i] = convert(accum, SkColorGetA(diffColor));
573 } 662 }
574 663
575 result += n; 664 result += n;
576 x += n; 665 x += n;
577 count -= n; 666 count -= n;
578 } while (count > 0); 667 } while (count > 0);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 760
672 /////////////////////////////////////////////////////////////////////////////// 761 ///////////////////////////////////////////////////////////////////////////////
673 762
674 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader) 763 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader)
675 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl) 764 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl)
676 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 765 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
677 766
678 /////////////////////////////////////////////////////////////////////////////// 767 ///////////////////////////////////////////////////////////////////////////////
679 768
680 #endif 769 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698