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

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: disabled shadows: Created 4 years, 3 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 | « src/core/SkLights.cpp ('k') | src/utils/SkShadowPaintFilterCanvas.cpp » ('j') | 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 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 #include "SkCanvas.h" 8 #include "SkCanvas.h"
9 #include "SkReadBuffer.h" 9 #include "SkReadBuffer.h"
10 #include "SkShadowShader.h" 10 #include "SkShadowShader.h"
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 ShadowFP(sk_sp<GrFragmentProcessor> povDepth, 107 ShadowFP(sk_sp<GrFragmentProcessor> povDepth,
108 sk_sp<GrFragmentProcessor> diffuse, 108 sk_sp<GrFragmentProcessor> diffuse,
109 sk_sp<SkLights> lights, 109 sk_sp<SkLights> lights,
110 int diffuseWidth, int diffuseHeight, 110 int diffuseWidth, int diffuseHeight,
111 const SkShadowParams& params, 111 const SkShadowParams& params,
112 GrContext* context) { 112 GrContext* context) {
113 113
114 // fuse all ambient lights into a single one 114 // fuse all ambient lights into a single one
115 fAmbientColor.set(0.0f, 0.0f, 0.0f); 115 fAmbientColor.set(0.0f, 0.0f, 0.0f);
116 116
117 fNumDirLights = 0; // refers to directional lights. 117 fNumNonAmbLights = 0; // count of non-ambient lights
118 for (int i = 0; i < lights->numLights(); ++i) { 118 for (int i = 0; i < lights->numLights(); ++i) {
119 if (SkLights::Light::kAmbient_LightType == lights->light(i).type()) { 119 if (SkLights::Light::kAmbient_LightType == lights->light(i).type()) {
120 fAmbientColor += lights->light(i).color(); 120 fAmbientColor += lights->light(i).color();
121 } else if (fNumDirLights < SkShadowShader::kMaxNonAmbientLights) { 121 } else if (fNumNonAmbLights < SkShadowShader::kMaxNonAmbientLights) {
122 fLightColor[fNumDirLights] = lights->light(i).color(); 122 fLightColor[fNumNonAmbLights] = lights->light(i).color();
123 fLightDir[fNumDirLights] = lights->light(i).dir(); 123 if (lights->light(i).type() == SkLights::Light::kPoint_LightType ) {
124 fLightDirOrPos[fNumNonAmbLights] = lights->light(i).pos();
125 fLightIntensity[fNumNonAmbLights] = lights->light(i).intensi ty();
126 } else {
127 fLightDirOrPos[fNumNonAmbLights] = lights->light(i).dir();
128 fLightIntensity[fNumNonAmbLights] = 0.0f;
129 }
130 fIsPointLight[fNumNonAmbLights] =
131 SkLights::Light::kPoint_LightType == lights->light(i).t ype();
132
124 SkImage_Base* shadowMap = ((SkImage_Base*)lights->light(i).getSh adowMap()); 133 SkImage_Base* shadowMap = ((SkImage_Base*)lights->light(i).getSh adowMap());
125 134
126 // gets deleted when the ShadowFP is destroyed, and frees the Gr Texture* 135 // gets deleted when the ShadowFP is destroyed, and frees the Gr Texture*
127 fTexture[fNumDirLights] = sk_sp<GrTexture>(shadowMap->asTextureR ef(context, 136 fTexture[fNumNonAmbLights] = sk_sp<GrTexture>(shadowMap->asTextu reRef(context,
128 GrTextureParams::Clam pNoFilter(), 137 GrTextureParams::Clam pNoFilter(),
129 SkSourceGammaTreatmen t::kIgnore)); 138 SkSourceGammaTreatmen t::kIgnore));
130 fDepthMapAccess[fNumDirLights].reset(fTexture[fNumDirLights].get ()); 139 fDepthMapAccess[fNumNonAmbLights].reset(fTexture[fNumNonAmbLight s].get());
131 this->addTextureAccess(&fDepthMapAccess[fNumDirLights]); 140 this->addTextureAccess(&fDepthMapAccess[fNumNonAmbLights]);
132 141
133 fDepthMapHeight[fNumDirLights] = shadowMap->height(); 142 fDepthMapHeight[fNumNonAmbLights] = shadowMap->height();
134 fDepthMapWidth[fNumDirLights] = shadowMap->width(); 143 fDepthMapWidth[fNumNonAmbLights] = shadowMap->width();
135 144
136 fNumDirLights++; 145 fNumNonAmbLights++;
137 } 146 }
138 } 147 }
139 148
140 fWidth = diffuseWidth; 149 fWidth = diffuseWidth;
141 fHeight = diffuseHeight; 150 fHeight = diffuseHeight;
142 151
143 fShadowParams = params; 152 fShadowParams = params;
144 153
145 this->registerChildProcessor(std::move(povDepth)); 154 this->registerChildProcessor(std::move(povDepth));
146 this->registerChildProcessor(std::move(diffuse)); 155 this->registerChildProcessor(std::move(diffuse));
147 this->initClassID<ShadowFP>(); 156 this->initClassID<ShadowFP>();
148 } 157 }
149 158
150 class GLSLShadowFP : public GrGLSLFragmentProcessor { 159 class GLSLShadowFP : public GrGLSLFragmentProcessor {
151 public: 160 public:
152 GLSLShadowFP() { } 161 GLSLShadowFP() { }
153 162
154 void emitCode(EmitArgs& args) override { 163 void emitCode(EmitArgs& args) override {
155
156 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; 164 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
157 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 165 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
166 const ShadowFP& shadowFP = args.fFp.cast<ShadowFP>();
167
168 SkASSERT(shadowFP.fNumNonAmbLights <= SkShadowShader::kMaxNonAmbient Lights);
158 169
159 // add uniforms 170 // add uniforms
160 int32_t numLights = args.fFp.cast<ShadowFP>().fNumDirLights; 171 int32_t numLights = shadowFP.fNumNonAmbLights;
161 SkASSERT(numLights <= SkShadowShader::kMaxNonAmbientLights); 172 SkASSERT(numLights <= SkShadowShader::kMaxNonAmbientLights);
162 173
163 int blurAlgorithm = args.fFp.cast<ShadowFP>().fShadowParams.fType; 174 int blurAlgorithm = shadowFP.fShadowParams.fType;
164 175
165 const char* lightDirUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr}; 176 const char* lightDirOrPosUniName[SkShadowShader::kMaxNonAmbientLight s] = {nullptr};
166 const char* lightColorUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr}; 177 const char* lightColorUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr};
178 const char* lightIntensityUniName[SkShadowShader::kMaxNonAmbientLigh ts] = {nullptr};
167 179
168 const char* depthMapWidthUniName[SkShadowShader::kMaxNonAmbientLight s] 180 const char* depthMapWidthUniName[SkShadowShader::kMaxNonAmbientLight s] = {nullptr};
169 = {nullptr}; 181 const char* depthMapHeightUniName[SkShadowShader::kMaxNonAmbientLigh ts] = {nullptr};
170 const char* depthMapHeightUniName[SkShadowShader::kMaxNonAmbientLigh ts]
171 = {nullptr};
172 182
173 SkString lightDirUniNameBase("lightDir"); 183 for (int i = 0; i < shadowFP.fNumNonAmbLights; i++) {
174 SkString lightColorUniNameBase("lightColor"); 184 SkString lightDirOrPosUniNameStr("lightDir");
185 lightDirOrPosUniNameStr.appendf("%d", i);
186 SkString lightColorUniNameStr("lightColor");
187 lightColorUniNameStr.appendf("%d", i);
188 SkString lightIntensityUniNameStr("lightIntensity");
189 lightIntensityUniNameStr.appendf("%d", i);
175 190
176 SkString depthMapWidthUniNameBase("dmapWidth"); 191 SkString depthMapWidthUniNameStr("dmapWidth");
177 SkString depthMapHeightUniNameBase("dmapHeight");
178
179 for (int i = 0; i < numLights; i++) {
180 SkString lightDirUniNameStr(lightDirUniNameBase);
181 lightDirUniNameStr.appendf("%d", i);
182 SkString lightColorUniNameStr(lightColorUniNameBase);
183 lightColorUniNameStr.appendf("%d", i);
184
185 SkString depthMapWidthUniNameStr(depthMapWidthUniNameBase);
186 depthMapWidthUniNameStr.appendf("%d", i); 192 depthMapWidthUniNameStr.appendf("%d", i);
187 SkString depthMapHeightUniNameStr(depthMapHeightUniNameBase); 193 SkString depthMapHeightUniNameStr("dmapHeight");
188 depthMapHeightUniNameStr.appendf("%d", i); 194 depthMapHeightUniNameStr.appendf("%d", i);
189 195
190 fLightDirUni[i] = uniformHandler->addUniform(kFragment_GrShaderF lag, 196 fLightDirOrPosUni[i] = uniformHandler->addUniform(kFragment_GrSh aderFlag,
191 kVec3f_GrSLType, 197 kVec3f_GrSLType,
192 kDefault_GrSLPrecis ion, 198 kDefault_GrSLPrecis ion,
193 lightDirUniNameStr. c_str(), 199 lightDirOrPosUniNam eStr.c_str(),
194 &lightDirUniName[i] ); 200 &lightDirOrPosUniNa me[i]);
195 fLightColorUni[i] = uniformHandler->addUniform(kFragment_GrShade rFlag, 201 fLightColorUni[i] = uniformHandler->addUniform(kFragment_GrShade rFlag,
196 kVec3f_GrSLType, 202 kVec3f_GrSLType,
197 kDefault_GrSLPrec ision, 203 kDefault_GrSLPrec ision,
198 lightColorUniName Str.c_str(), 204 lightColorUniName Str.c_str(),
199 &lightColorUniNam e[i]); 205 &lightColorUniNam e[i]);
206 fLightIntensityUni[i] =
207 uniformHandler->addUniform(kFragment_GrShaderFlag,
208 kFloat_GrSLType,
209 kDefault_GrSLPrecision,
210 lightIntensityUniNameStr.c_st r(),
211 &lightIntensityUniName[i]);
200 212
201 fDepthMapWidthUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag, 213 fDepthMapWidthUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag,
202 kInt_GrSLType, 214 kInt_GrSLType,
203 kDefault_GrSLPrecision, 215 kDefault_GrSLPrecision,
204 depthMapWidthUniNameStr.c_str (), 216 depthMapWidthUniNameStr.c_str (),
205 &depthMapWidthUniName[i]); 217 &depthMapWidthUniName[i]);
206 fDepthMapHeightUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag, 218 fDepthMapHeightUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag,
207 kInt_GrSLType, 219 kInt_GrSLType,
208 kDefault_GrSLPrecision, 220 kDefault_GrSLPrecision,
209 depthMapHeightUniNameStr.c_st r(), 221 depthMapHeightUniNameStr.c_st r(),
(...skipping 17 matching lines...) Expand all
227 239
228 fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 240 fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
229 kInt_GrSLType, 241 kInt_GrSLType,
230 kDefault_GrSLPrecision, 242 kDefault_GrSLPrecision,
231 "width", &widthUniName); 243 "width", &widthUniName);
232 fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 244 fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
233 kInt_GrSLType, 245 kInt_GrSLType,
234 kDefault_GrSLPrecision, 246 kDefault_GrSLPrecision,
235 "height", &heightUniName); 247 "height", &heightUniName);
236 248
237
238 SkString povDepth("povDepth"); 249 SkString povDepth("povDepth");
239 this->emitChild(0, nullptr, &povDepth, args); 250 this->emitChild(0, nullptr, &povDepth, args);
240 251
241 SkString diffuseColor("inDiffuseColor"); 252 SkString diffuseColor("inDiffuseColor");
242 this->emitChild(1, nullptr, &diffuseColor, args); 253 this->emitChild(1, nullptr, &diffuseColor, args);
243 254
244 SkString depthMaps[SkShadowShader::kMaxNonAmbientLights]; 255 SkString depthMaps[SkShadowShader::kMaxNonAmbientLights];
245 256
246 for (int i = 0; i < numLights; i++) { 257 // Multiply by 255 to transform from sampler coordinates to world
258 // coordinates (since 1 channel is 0xFF)
259 fragBuilder->codeAppendf("vec3 worldCor = vec3(vMatrixCoord_0_1_Stag e0 * "
260 "vec2(%s, %s), %s.b * 255); ",
261 widthUniName, heightUniName, povDepth.c_str ());
262
263 // Applies the offset indexing that goes from our view space into th e light's space.
264 for (int i = 0; i < shadowFP.fNumNonAmbLights; i++) {
247 SkString povCoord("povCoord"); 265 SkString povCoord("povCoord");
248 povCoord.appendf("%d", i); 266 povCoord.appendf("%d", i);
249 267
250 // vMatrixCoord_0_1_Stage0 is the texture sampler coordinates. 268 // vMatrixCoord_0_1_Stage0 is the texture sampler coordinates.
251 // povDepth.b * 255 scales it to 0 - 255, bringing it to world s pace, 269 // povDepth.b * 255 scales it to 0 - 255, bringing it to world s pace,
252 // and the / 400 brings it back to a sampler coordinate, 0 - 1 270 // and the / vec2(width, height) brings it back to a sampler coo rdinate
253 // The 400 comes from the shadowmaps GM.
254 // TODO use real shadowmaps size
255 SkString offset("offset"); 271 SkString offset("offset");
256 offset.appendf("%d", i); 272 offset.appendf("%d", i);
257 273
258 SkString scaleVec("scaleVec"); 274 SkString scaleVec("scaleVec");
259 scaleVec.appendf("%d", i); 275 scaleVec.appendf("%d", i);
260 276
261 SkString scaleOffsetVec("scaleOffsetVec"); 277 SkString scaleOffsetVec("scaleOffsetVec");
262 scaleOffsetVec.appendf("%d", i); 278 scaleOffsetVec.appendf("%d", i);
263 279
264 fragBuilder->codeAppendf("vec2 %s = vec2(%s) * povDepth.b * 255 / 400;\n", 280 fragBuilder->codeAppendf("vec2 %s;", offset.c_str());
265 offset.c_str(), lightDirUniName[i]);
266 281
267 fragBuilder->codeAppendf("vec2 %s = (vec2(%s, %s) / vec2(%s, %s) );\n", 282 if (shadowFP.fIsPointLight[i]) {
283 fragBuilder->codeAppendf("vec3 fragToLight%d = %s - worldCor ;",
284 i, lightDirOrPosUniName[i]);
285 fragBuilder->codeAppendf("float distsq%d = dot(fragToLight%d , fragToLight%d);"
286 "fragToLight%d = normalize(fragToLi ght%d);",
287 i, i, i, i, i);
288 fragBuilder->codeAppendf("%s = -vec2(%s.x - worldCor.x, worl dCor.y - %s.y)*"
289 "(povDepth.b) / vec2(%s, %s) ;",
290 offset.c_str(), lightDirOrPosUniNam e[i],
291 lightDirOrPosUniName[i],
292 widthUniName, heightUniName);
293 } else {
294 fragBuilder->codeAppendf("%s = vec2(%s) * povDepth.b * 255 / vec2(%s, %s);",
295 offset.c_str(), lightDirOrPosUniNam e[i],
296 widthUniName, heightUniName);
297 }
298 fragBuilder->codeAppendf("vec2 %s = (vec2(%s, %s) / vec2(%s, %s) );",
268 scaleVec.c_str(), 299 scaleVec.c_str(),
269 widthUniName, heightUniName, 300 widthUniName, heightUniName,
270 depthMapWidthUniName[i], depthMapHeight UniName[i]); 301 depthMapWidthUniName[i], depthMapHeight UniName[i]);
271 302
272 fragBuilder->codeAppendf("vec2 %s = 1 - %s;\n", 303 fragBuilder->codeAppendf("vec2 %s = 1 - %s;\n",
273 scaleOffsetVec.c_str(), scaleVec.c_str( )); 304 scaleOffsetVec.c_str(),
305 scaleVec.c_str());
274 306
275 fragBuilder->codeAppendf("vec2 %s = (vMatrixCoord_0_1_Stage0 + " 307 fragBuilder->codeAppendf("vec2 %s = (vMatrixCoord_0_1_Stage0 + "
276 "vec2(%s.x, 0 - %s.y)) " 308 "vec2(%s.x, 0 - %s.y)) "
277 " * %s + vec2(0,1) * %s;\n", 309 " * %s + vec2(0,1) * %s;",
278 povCoord.c_str(), offset.c_str(), offse t.c_str(), 310 povCoord.c_str(), offset.c_str(), offse t.c_str(),
279 scaleVec.c_str(), scaleOffsetVec.c_str( )); 311 scaleVec.c_str(), scaleOffsetVec.c_str( ));
280 312
281 fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSampler s[i], 313 fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSampler s[i],
282 povCoord.c_str(), 314 povCoord.c_str(),
283 kVec2f_GrSLType); 315 kVec2f_GrSLType);
284 316
285
286 } 317 }
287 318
288 const char* ambientColorUniName = nullptr; 319 const char* ambientColorUniName = nullptr;
289 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag , 320 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag ,
290 kVec3f_GrSLType, kDefa ult_GrSLPrecision, 321 kVec3f_GrSLType, kDefa ult_GrSLPrecision,
291 "AmbientColor", &ambie ntColorUniName); 322 "AmbientColor", &ambie ntColorUniName);
292 323
293 fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseCol or.c_str()); 324 fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseCol or.c_str());
294 325
295 SkString totalLightColor("totalLightColor"); 326 SkString totalLightColor("totalLightColor");
296 fragBuilder->codeAppendf("vec3 %s = vec3(0,0,0);", totalLightColor.c _str()); 327 fragBuilder->codeAppendf("vec3 %s = vec3(0,0,0);", totalLightColor.c _str());
297 328
298 fragBuilder->codeAppendf("float lightProbability;"); 329 fragBuilder->codeAppendf("float lightProbability;");
299 fragBuilder->codeAppendf("float variance;"); 330 fragBuilder->codeAppendf("float variance;");
300 fragBuilder->codeAppendf("float d;"); 331 fragBuilder->codeAppendf("float d;");
301 332
302 for (int i = 0; i < numLights; i++) { 333 for (int i = 0; i < numLights; i++) {
303 fragBuilder->codeAppendf("lightProbability = 1;"); 334 if (!shadowFP.isPointLight(i)) {
335 fragBuilder->codeAppendf("lightProbability = 1;");
304 336
305 // 1/512 is less than half a pixel; imperceptible 337 // 1/512 is less than half a pixel; imperceptible
306 fragBuilder->codeAppendf("if (%s.b <= %s.b + 1/512) {", 338 fragBuilder->codeAppendf("if (%s.b <= %s.b + 1/512) {",
307 povDepth.c_str(), depthMaps[i].c_str()) ; 339 povDepth.c_str(), depthMaps[i].c_st r());
308 if (blurAlgorithm == SkShadowParams::kVariance_ShadowType) { 340 if (blurAlgorithm == SkShadowParams::kVariance_ShadowType) {
309 fragBuilder->codeAppendf("vec2 moments = vec2(%s.b * 255, % s.g * 255 * 256 );", 341 fragBuilder->codeAppendf("vec2 moments%d = vec2(%s.b * 2 55,"
310 depthMaps[i].c_str(), depthMaps[i]. c_str()); 342 "%s.g * 2 55 * 256 );",
343 i, depthMaps[i].c_str(), depthM aps[i].c_str());
311 344
312 // variance biasing lessens light bleeding 345 // variance biasing lessens light bleeding
313 fragBuilder->codeAppendf("variance = max(moments.y - (moment s.x * moments.x)," 346 fragBuilder->codeAppendf("variance = max(moments%d.y - "
314 "%s);", minVarianceUniName) ; 347 "(moments%d.x * moments%d.x),"
348 "%s);", i, i, i,
349 minVarianceUniName);
315 350
316 fragBuilder->codeAppendf("d = (%s.b * 255) - moments.x;", po vDepth.c_str()); 351 fragBuilder->codeAppendf("d = (%s.b * 255) - moments%d.x ;",
317 fragBuilder->codeAppendf("lightProbability = " 352 povDepth.c_str(), i);
318 "(variance / (variance + d * d));") ; 353 fragBuilder->codeAppendf("lightProbability = "
354 "(variance / (variance + d * d));");
319 355
320 SkString clamp("clamp"); 356 SkString clamp("clamp");
321 clamp.appendf("%d", i); 357 clamp.appendf("%d", i);
322 358
323 // choosing between light artifacts or correct shape shadows 359 // choosing between light artifacts or correct shape sha dows
324 // linstep 360 // linstep
325 fragBuilder->codeAppendf("float %s = clamp((lightProbability - %s) /" 361 fragBuilder->codeAppendf("float %s = clamp((lightProbabi lity - %s) /"
326 "(1 - %s), 0, 1);" , 362 "(1 - %s), 0, 1);",
327 clamp.c_str(), shBiasUniName, shBia sUniName); 363 clamp.c_str(), shBiasUniName, s hBiasUniName);
328 364
329 fragBuilder->codeAppendf("lightProbability = %s;", clamp.c_s tr()); 365 fragBuilder->codeAppendf("lightProbability = %s;", clamp .c_str());
366 } else {
367 fragBuilder->codeAppendf("if (%s.b >= %s.b) {",
368 povDepth.c_str(), depthMaps[i]. c_str());
369 fragBuilder->codeAppendf("lightProbability = 1;");
370 fragBuilder->codeAppendf("} else { lightProbability = 0; }");
371 }
372
373 // VSM: The curved shadows near plane edges are artifacts fr om blurring
374 fragBuilder->codeAppendf("}");
375 fragBuilder->codeAppendf("%s += dot(vec3(0,0,1), %s) * %s * "
376 "lightProbability;",
377 totalLightColor.c_str(),
378 lightDirOrPosUniName[i],
379 lightColorUniName[i]);
330 } else { 380 } else {
331 fragBuilder->codeAppendf("if (%s.b >= %s.b) {", 381 // fragToLight%d.z is equal to the fragToLight dot the surfa ce normal.
332 povDepth.c_str(), depthMaps[i].c_st r()); 382 fragBuilder->codeAppendf("%s += max(fragToLight%d.z, 0) * %s /"
333 fragBuilder->codeAppendf("lightProbability = 1;"); 383 "(1 + distsq%d / (%s * %s));" ,
334 fragBuilder->codeAppendf("} else { lightProbability = 0; }") ; 384 totalLightColor.c_str(), i,
385 lightColorUniName[i], i,
386 lightIntensityUniName[i],
387 lightIntensityUniName[i]);
335 } 388 }
336
337 // VSM: The curved shadows near plane edges are mostly light ble eding.
338 fragBuilder->codeAppendf("}");
339
340 fragBuilder->codeAppendf("%s += dot(vec3(0,0,1), %s) * %s * ligh tProbability;",
341 totalLightColor.c_str(),
342 lightDirUniName[i],
343 lightColorUniName[i]);
344 } 389 }
345 390
346 fragBuilder->codeAppendf("%s += %s;", totalLightColor.c_str(), ambie ntColorUniName); 391 fragBuilder->codeAppendf("%s += %s;", totalLightColor.c_str(), ambie ntColorUniName);
347 392
348 fragBuilder->codeAppendf("resultDiffuseColor *= vec4(%s, 1);", 393 fragBuilder->codeAppendf("resultDiffuseColor *= vec4(%s, 1);",
349 totalLightColor.c_str()); 394 totalLightColor.c_str());
350 395
351 fragBuilder->codeAppendf("%s = resultDiffuseColor;", args.fOutputCol or); 396 fragBuilder->codeAppendf("%s = resultDiffuseColor;", args.fOutputCol or);
352 } 397 }
353 398
354 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, 399 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
355 GrProcessorKeyBuilder* b) { 400 GrProcessorKeyBuilder* b) {
356 const ShadowFP& shadowFP = proc.cast<ShadowFP>(); 401 const ShadowFP& shadowFP = proc.cast<ShadowFP>();
357 b->add32(shadowFP.fNumDirLights); 402 b->add32(shadowFP.fNumNonAmbLights);
403 int isPL = 0;
404 for (int i = 0; i < SkShadowShader::kMaxNonAmbientLights; i++) {
405 isPL = isPL | ((shadowFP.fIsPointLight[i] ? 1 : 0) << i);
406 }
407 b->add32(isPL);
358 b->add32(shadowFP.fShadowParams.fType); 408 b->add32(shadowFP.fShadowParams.fType);
359 } 409 }
360 410
361 protected: 411 protected:
362 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override { 412 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {
363 const ShadowFP &shadowFP = proc.cast<ShadowFP>(); 413 const ShadowFP &shadowFP = proc.cast<ShadowFP>();
364 414
365 for (int i = 0; i < shadowFP.fNumDirLights; i++) { 415 for (int i = 0; i < shadowFP.numLights(); i++) {
366 const SkVector3& lightDir = shadowFP.lightDir(i); 416 const SkVector3& lightDirOrPos = shadowFP.lightDirOrPos(i);
367 if (lightDir != fLightDir[i]) { 417 if (lightDirOrPos != fLightDirOrPos[i]) {
368 pdman.set3fv(fLightDirUni[i], 1, &lightDir.fX); 418 pdman.set3fv(fLightDirOrPosUni[i], 1, &lightDirOrPos.fX);
369 fLightDir[i] = lightDir; 419 fLightDirOrPos[i] = lightDirOrPos;
370 } 420 }
421
371 const SkColor3f& lightColor = shadowFP.lightColor(i); 422 const SkColor3f& lightColor = shadowFP.lightColor(i);
372 if (lightColor != fLightColor[i]) { 423 if (lightColor != fLightColor[i]) {
373 pdman.set3fv(fLightColorUni[i], 1, &lightColor.fX); 424 pdman.set3fv(fLightColorUni[i], 1, &lightColor.fX);
374 fLightColor[i] = lightColor; 425 fLightColor[i] = lightColor;
375 } 426 }
376 427
428 SkScalar lightIntensity = shadowFP.lightIntensity(i);
429 if (lightIntensity != fLightIntensity[i]) {
430 pdman.set1f(fLightIntensityUni[i], lightIntensity);
431 fLightIntensity[i] = lightIntensity;
432 }
433
377 int depthMapWidth = shadowFP.depthMapWidth(i); 434 int depthMapWidth = shadowFP.depthMapWidth(i);
378 if (depthMapWidth != fDepthMapWidth[i]) { 435 if (depthMapWidth != fDepthMapWidth[i]) {
379 pdman.set1i(fDepthMapWidthUni[i], depthMapWidth); 436 pdman.set1i(fDepthMapWidthUni[i], depthMapWidth);
380 fDepthMapWidth[i] = depthMapWidth; 437 fDepthMapWidth[i] = depthMapWidth;
381 } 438 }
382 int depthMapHeight = shadowFP.depthMapHeight(i); 439 int depthMapHeight = shadowFP.depthMapHeight(i);
383 if (depthMapHeight != fDepthMapHeight[i]) { 440 if (depthMapHeight != fDepthMapHeight[i]) {
384 pdman.set1i(fDepthMapHeightUni[i], depthMapHeight); 441 pdman.set1i(fDepthMapHeightUni[i], depthMapHeight);
385 fDepthMapHeight[i] = depthMapHeight; 442 fDepthMapHeight[i] = depthMapHeight;
386 } 443 }
(...skipping 23 matching lines...) Expand all
410 } 467 }
411 468
412 const SkColor3f& ambientColor = shadowFP.ambientColor(); 469 const SkColor3f& ambientColor = shadowFP.ambientColor();
413 if (ambientColor != fAmbientColor) { 470 if (ambientColor != fAmbientColor) {
414 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX); 471 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX);
415 fAmbientColor = ambientColor; 472 fAmbientColor = ambientColor;
416 } 473 }
417 } 474 }
418 475
419 private: 476 private:
420 SkVector3 fLightDir[SkShadowShader::kMaxNonAmbientLights]; 477 SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights];
421 GrGLSLProgramDataManager::UniformHandle 478 GrGLSLProgramDataManager::UniformHandle
422 fLightDirUni[SkShadowShader::kMaxNonAmbientLights]; 479 fLightDirOrPosUni[SkShadowShader::kMaxNonAmbientLights];
423 480
424 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; 481 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights];
425 GrGLSLProgramDataManager::UniformHandle 482 GrGLSLProgramDataManager::UniformHandle
426 fLightColorUni[SkShadowShader::kMaxNonAmbientLights]; 483 fLightColorUni[SkShadowShader::kMaxNonAmbientLights];
427 484
485 SkScalar fLightIntensity[SkShadowShader::kMaxNonAmbientLights];
486 GrGLSLProgramDataManager::UniformHandle
487 fLightIntensityUni[SkShadowShader::kMaxNonAmbientLights];
488
428 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; 489 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights];
429 GrGLSLProgramDataManager::UniformHandle 490 GrGLSLProgramDataManager::UniformHandle
430 fDepthMapWidthUni[SkShadowShader::kMaxNonAmbientLights]; 491 fDepthMapWidthUni[SkShadowShader::kMaxNonAmbientLights];
431 492
432 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; 493 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights];
433 GrGLSLProgramDataManager::UniformHandle 494 GrGLSLProgramDataManager::UniformHandle
434 fDepthMapHeightUni[SkShadowShader::kMaxNonAmbientLights]; 495 fDepthMapHeightUni[SkShadowShader::kMaxNonAmbientLights];
435 496
436 int fWidth; 497 int fWidth;
437 GrGLSLProgramDataManager::UniformHandle fWidthUni; 498 GrGLSLProgramDataManager::UniformHandle fWidthUni;
(...skipping 11 matching lines...) Expand all
449 510
450 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { 511 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
451 GLSLShadowFP::GenKey(*this, caps, b); 512 GLSLShadowFP::GenKey(*this, caps, b);
452 } 513 }
453 514
454 const char* name() const override { return "shadowFP"; } 515 const char* name() const override { return "shadowFP"; }
455 516
456 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { 517 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
457 inout->mulByUnknownFourComponents(); 518 inout->mulByUnknownFourComponents();
458 } 519 }
459 int32_t numLights() const { return fNumDirLights; } 520 int32_t numLights() const { return fNumNonAmbLights; }
460 const SkColor3f& ambientColor() const { return fAmbientColor; } 521 const SkColor3f& ambientColor() const { return fAmbientColor; }
461 const SkVector3& lightDir(int i) const { 522 bool isPointLight(int i) const {
462 SkASSERT(i < fNumDirLights); 523 SkASSERT(i < fNumNonAmbLights);
463 return fLightDir[i]; 524 return fIsPointLight[i];
525 }
526 const SkVector3& lightDirOrPos(int i) const {
527 SkASSERT(i < fNumNonAmbLights);
528 return fLightDirOrPos[i];
464 } 529 }
465 const SkVector3& lightColor(int i) const { 530 const SkVector3& lightColor(int i) const {
466 SkASSERT(i < fNumDirLights); 531 SkASSERT(i < fNumNonAmbLights);
467 return fLightColor[i]; 532 return fLightColor[i];
468 } 533 }
534 SkScalar lightIntensity(int i) const {
535 SkASSERT(i < fNumNonAmbLights);
536 return fLightIntensity[i];
537 }
469 538
470 int depthMapWidth(int i) const { 539 int depthMapWidth(int i) const {
471 SkASSERT(i < fNumDirLights); 540 SkASSERT(i < fNumNonAmbLights);
472 return fDepthMapWidth[i]; 541 return fDepthMapWidth[i];
473 } 542 }
474 int depthMapHeight(int i) const { 543 int depthMapHeight(int i) const {
475 SkASSERT(i < fNumDirLights); 544 SkASSERT(i < fNumNonAmbLights);
476 return fDepthMapHeight[i]; 545 return fDepthMapHeight[i];
477 } 546 }
478 int width() const {return fWidth; } 547 int width() const {return fWidth; }
479 int height() const {return fHeight; } 548 int height() const {return fHeight; }
480 549
481 const SkShadowParams& shadowParams() const {return fShadowParams; } 550 const SkShadowParams& shadowParams() const {return fShadowParams; }
482 551
483 private: 552 private:
484 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLShadowFP; } 553 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLShadowFP; }
485 554
486 bool onIsEqual(const GrFragmentProcessor& proc) const override { 555 bool onIsEqual(const GrFragmentProcessor& proc) const override {
487 const ShadowFP& shadowFP = proc.cast<ShadowFP>(); 556 const ShadowFP& shadowFP = proc.cast<ShadowFP>();
488 if (fAmbientColor != shadowFP.fAmbientColor || fNumDirLights != shadowFP .fNumDirLights) { 557 if (fAmbientColor != shadowFP.fAmbientColor ||
558 fNumNonAmbLights != shadowFP.fNumNonAmbLights) {
489 return false; 559 return false;
490 } 560 }
491 561
492 if (fWidth != shadowFP.fWidth || fHeight != shadowFP.fHeight) { 562 if (fWidth != shadowFP.fWidth || fHeight != shadowFP.fHeight) {
493 return false; 563 return false;
494 } 564 }
495 565
496 for (int i = 0; i < fNumDirLights; i++) { 566 for (int i = 0; i < fNumNonAmbLights; i++) {
497 if (fLightDir[i] != shadowFP.fLightDir[i] || 567 if (fLightDirOrPos[i] != shadowFP.fLightDirOrPos[i] ||
498 fLightColor[i] != shadowFP.fLightColor[i]) { 568 fLightColor[i] != shadowFP.fLightColor[i] ||
569 fLightIntensity[i] != shadowFP.fLightIntensity[i] ||
570 fIsPointLight[i] != shadowFP.fIsPointLight[i]) {
499 return false; 571 return false;
500 } 572 }
501 573
502 if (fDepthMapWidth[i] != shadowFP.fDepthMapWidth[i] || 574 if (fDepthMapWidth[i] != shadowFP.fDepthMapWidth[i] ||
503 fDepthMapHeight[i] != shadowFP.fDepthMapHeight[i]) { 575 fDepthMapHeight[i] != shadowFP.fDepthMapHeight[i]) {
504 return false; 576 return false;
505 } 577 }
506 } 578 }
507 579
508 return true; 580 return true;
509 } 581 }
510 582
511 int fNumDirLights; 583 int fNumNonAmbLights;
512 584
513 SkVector3 fLightDir[SkShadowShader::kMaxNonAmbientLights]; 585 bool fIsPointLight[SkShadowShader::kMaxNonAmbientLights];
586 SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights];
514 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; 587 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights];
588 SkScalar fLightIntensity[SkShadowShader::kMaxNonAmbientLights];
515 GrTextureAccess fDepthMapAccess[SkShadowShader::kMaxNonAmbientLights]; 589 GrTextureAccess fDepthMapAccess[SkShadowShader::kMaxNonAmbientLights];
516 sk_sp<GrTexture> fTexture[SkShadowShader::kMaxNonAmbientLights]; 590 sk_sp<GrTexture> fTexture[SkShadowShader::kMaxNonAmbientLights];
517 591
518 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; 592 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights];
519 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; 593 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights];
520 594
521 int fHeight; 595 int fHeight;
522 int fWidth; 596 int fWidth;
523 597
524 SkShadowParams fShadowParams; 598 SkShadowParams fShadowParams;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 697
624 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f); 698 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f);
625 // This is all done in linear unpremul color space (each component 0 ..255.0f though) 699 // This is all done in linear unpremul color space (each component 0 ..255.0f though)
626 for (int l = 0; l < lightShader.fLights->numLights(); ++l) { 700 for (int l = 0; l < lightShader.fLights->numLights(); ++l) {
627 const SkLights::Light& light = lightShader.fLights->light(l); 701 const SkLights::Light& light = lightShader.fLights->light(l);
628 702
629 if (SkLights::Light::kAmbient_LightType == light.type()) { 703 if (SkLights::Light::kAmbient_LightType == light.type()) {
630 accum.fX += light.color().fX * SkColorGetR(diffColor); 704 accum.fX += light.color().fX * SkColorGetR(diffColor);
631 accum.fY += light.color().fY * SkColorGetG(diffColor); 705 accum.fY += light.color().fY * SkColorGetG(diffColor);
632 accum.fZ += light.color().fZ * SkColorGetB(diffColor); 706 accum.fZ += light.color().fZ * SkColorGetB(diffColor);
707 } else if (SkLights::Light::kDirectional_LightType == light.type ()) {
708 // scaling by fZ accounts for lighting direction
709 accum.fX += light.color().makeScale(light.dir().fZ).fX *
710 SkColorGetR(diffColor);
711 accum.fY += light.color().makeScale(light.dir().fZ).fY *
712 SkColorGetG(diffColor);
713 accum.fZ += light.color().makeScale(light.dir().fZ).fZ *
714 SkColorGetB(diffColor);
633 } else { 715 } else {
634 // scaling by fZ accounts for lighting direction 716 // TODO: do point lights for raster, currently treated like ambient
635 accum.fX += light.color().makeScale(light.dir().fZ).fX * SkC olorGetR(diffColor); 717 accum.fX += light.color().fX * SkColorGetR(diffColor);
636 accum.fY += light.color().makeScale(light.dir().fZ).fY * SkC olorGetG(diffColor); 718 accum.fY += light.color().fY * SkColorGetG(diffColor);
637 accum.fZ += light.color().makeScale(light.dir().fZ).fZ * SkC olorGetB(diffColor); 719 accum.fZ += light.color().fZ * SkColorGetB(diffColor);
638 } 720 }
639 } 721 }
640 722
641 result[i] = convert(accum, SkColorGetA(diffColor)); 723 result[i] = convert(accum, SkColorGetA(diffColor));
642 } 724 }
643 725
644 result += n; 726 result += n;
645 x += n; 727 x += n;
646 count -= n; 728 count -= n;
647 } while (count > 0); 729 } while (count > 0);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 836
755 /////////////////////////////////////////////////////////////////////////////// 837 ///////////////////////////////////////////////////////////////////////////////
756 838
757 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader) 839 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader)
758 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl) 840 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl)
759 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 841 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
760 842
761 /////////////////////////////////////////////////////////////////////////////// 843 ///////////////////////////////////////////////////////////////////////////////
762 844
763 #endif 845 #endif
OLDNEW
« no previous file with comments | « src/core/SkLights.cpp ('k') | src/utils/SkShadowPaintFilterCanvas.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698