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

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: rebased off of master (with variance shadow mapping) 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
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 164
156 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; 165 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
157 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 166 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
167 const ShadowFP& shadowFP = args.fFp.cast<ShadowFP>();
168
169 SkASSERT(shadowFP.fNumNonAmbLights <= SkShadowShader::kMaxNonAmbient Lights);
158 170
159 // add uniforms 171 // add uniforms
160 int32_t numLights = args.fFp.cast<ShadowFP>().fNumDirLights; 172 int32_t numLights = args.fFp.cast<ShadowFP>().fNumNonAmbLights;
161 SkASSERT(numLights <= SkShadowShader::kMaxNonAmbientLights); 173 SkASSERT(numLights <= SkShadowShader::kMaxNonAmbientLights);
162 174
robertphillips 2016/08/25 17:41:43 Didn't you remove this copy once before ?
vjiaoblack 2016/08/26 12:37:22 Done.
175 bool isPointLight[SkShadowShader::kMaxNonAmbientLights];
176 for (int i = 0; i < SkShadowShader::kMaxNonAmbientLights; i++) {
177 isPointLight[i] = args.fFp.cast<ShadowFP>().fIsPointLight[i];
178 }
163 int blurAlgorithm = args.fFp.cast<ShadowFP>().fShadowParams.fType; 179 int blurAlgorithm = args.fFp.cast<ShadowFP>().fShadowParams.fType;
164 180
robertphillips 2016/08/25 17:41:43 what ?
vjiaoblack 2016/08/26 12:37:22 Done.
165 const char* lightDirUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr}; 181 if (isPointLight[0]) {
182 }
183
184 const char* lightDirOrPosUniName[SkShadowShader::kMaxNonAmbientLight s] = {nullptr};
166 const char* lightColorUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr}; 185 const char* lightColorUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr};
186 const char* lightIntensityUniName[SkShadowShader::kMaxNonAmbientLigh ts] = {nullptr};
167 187
168 const char* depthMapWidthUniName[SkShadowShader::kMaxNonAmbientLight s] 188 const char* depthMapWidthUniName[SkShadowShader::kMaxNonAmbientLight s] = {nullptr};
169 = {nullptr}; 189 const char* depthMapHeightUniName[SkShadowShader::kMaxNonAmbientLigh ts] = {nullptr};
170 const char* depthMapHeightUniName[SkShadowShader::kMaxNonAmbientLigh ts]
171 = {nullptr};
172 190
173 SkString lightDirUniNameBase("lightDir"); 191 for (int i = 0; i < shadowFP.fNumNonAmbLights; i++) {
174 SkString lightColorUniNameBase("lightColor"); 192 SkString lightDirOrPosUniNameStr("lightDir");
193 lightDirOrPosUniNameStr.appendf("%d", i);
194 SkString lightColorUniNameStr("lightColor");
195 lightColorUniNameStr.appendf("%d", i);
196 SkString lightIntensityUniNameStr("lightIntensity");
197 lightIntensityUniNameStr.appendf("%d", i);
175 198
176 SkString depthMapWidthUniNameBase("dmapWidth"); 199 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); 200 depthMapWidthUniNameStr.appendf("%d", i);
187 SkString depthMapHeightUniNameStr(depthMapHeightUniNameBase); 201 SkString depthMapHeightUniNameStr("dmapHeight");
188 depthMapHeightUniNameStr.appendf("%d", i); 202 depthMapHeightUniNameStr.appendf("%d", i);
189 203
190 fLightDirUni[i] = uniformHandler->addUniform(kFragment_GrShaderF lag, 204 fLightDirOrPosUni[i] = uniformHandler->addUniform(kFragment_GrSh aderFlag,
191 kVec3f_GrSLType, 205 kVec3f_GrSLType,
192 kDefault_GrSLPrecis ion, 206 kDefault_GrSLPrecis ion,
193 lightDirUniNameStr. c_str(), 207 lightDirOrPosUniNam eStr.c_str(),
194 &lightDirUniName[i] ); 208 &lightDirOrPosUniNa me[i]);
195 fLightColorUni[i] = uniformHandler->addUniform(kFragment_GrShade rFlag, 209 fLightColorUni[i] = uniformHandler->addUniform(kFragment_GrShade rFlag,
196 kVec3f_GrSLType, 210 kVec3f_GrSLType,
197 kDefault_GrSLPrec ision, 211 kDefault_GrSLPrec ision,
198 lightColorUniName Str.c_str(), 212 lightColorUniName Str.c_str(),
199 &lightColorUniNam e[i]); 213 &lightColorUniNam e[i]);
214 fLightIntensityUni[i] =
215 uniformHandler->addUniform(kFragment_GrShaderFlag,
216 kFloat_GrSLType,
217 kDefault_GrSLPrecision,
218 lightIntensityUniNameStr.c_st r(),
219 &lightIntensityUniName[i]);
200 220
201 fDepthMapWidthUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag, 221 fDepthMapWidthUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag,
202 kInt_GrSLType, 222 kInt_GrSLType,
203 kDefault_GrSLPrecision, 223 kDefault_GrSLPrecision,
204 depthMapWidthUniNameStr.c_str (), 224 depthMapWidthUniNameStr.c_str (),
205 &depthMapWidthUniName[i]); 225 &depthMapWidthUniName[i]);
206 fDepthMapHeightUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag, 226 fDepthMapHeightUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag,
207 kInt_GrSLType, 227 kInt_GrSLType,
208 kDefault_GrSLPrecision, 228 kDefault_GrSLPrecision,
209 depthMapHeightUniNameStr.c_st r(), 229 depthMapHeightUniNameStr.c_st r(),
(...skipping 17 matching lines...) Expand all
227 247
228 fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 248 fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
229 kInt_GrSLType, 249 kInt_GrSLType,
230 kDefault_GrSLPrecision, 250 kDefault_GrSLPrecision,
231 "width", &widthUniName); 251 "width", &widthUniName);
232 fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, 252 fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
233 kInt_GrSLType, 253 kInt_GrSLType,
234 kDefault_GrSLPrecision, 254 kDefault_GrSLPrecision,
235 "height", &heightUniName); 255 "height", &heightUniName);
236 256
237
238 SkString povDepth("povDepth"); 257 SkString povDepth("povDepth");
239 this->emitChild(0, nullptr, &povDepth, args); 258 this->emitChild(0, nullptr, &povDepth, args);
240 259
241 SkString diffuseColor("inDiffuseColor"); 260 SkString diffuseColor("inDiffuseColor");
242 this->emitChild(1, nullptr, &diffuseColor, args); 261 this->emitChild(1, nullptr, &diffuseColor, args);
243 262
244 SkString depthMaps[SkShadowShader::kMaxNonAmbientLights]; 263 SkString depthMaps[SkShadowShader::kMaxNonAmbientLights];
245 264
246 for (int i = 0; i < numLights; i++) { 265 // Multiply by 255 to transform from sampler coordinates to world
266 // coordinates (since 1 channel is 0xFF)
267 fragBuilder->codeAppendf("vec3 worldCor = vec3(vMatrixCoord_0_1_Stag e0 * "
268 "vec2(%s, %s), %s.b * 255); \n",
269 widthUniName, heightUniName, povDepth.c_str ());
270
271 // Applies the offset indexing that goes from our view space into th e light's space.
272 for (int i = 0; i < shadowFP.fNumNonAmbLights; i++) {
247 SkString povCoord("povCoord"); 273 SkString povCoord("povCoord");
248 povCoord.appendf("%d", i); 274 povCoord.appendf("%d", i);
249 275
250 // vMatrixCoord_0_1_Stage0 is the texture sampler coordinates. 276 // vMatrixCoord_0_1_Stage0 is the texture sampler coordinates.
251 // povDepth.b * 255 scales it to 0 - 255, bringing it to world s pace, 277 // 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 278 // 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"); 279 SkString offset("offset");
256 offset.appendf("%d", i); 280 offset.appendf("%d", i);
257 281
258 SkString scaleVec("scaleVec"); 282 SkString scaleVec("scaleVec");
259 scaleVec.appendf("%d", i); 283 scaleVec.appendf("%d", i);
260 284
261 SkString scaleOffsetVec("scaleOffsetVec"); 285 SkString scaleOffsetVec("scaleOffsetVec");
262 scaleOffsetVec.appendf("%d", i); 286 scaleOffsetVec.appendf("%d", i);
263 287
264 fragBuilder->codeAppendf("vec2 %s = vec2(%s) * povDepth.b * 255 / 400;\n", 288 fragBuilder->codeAppendf("vec2 %s;", offset.c_str());
265 offset.c_str(), lightDirUniName[i]);
266 289
290 if (shadowFP.fIsPointLight[i]) {
291 fragBuilder->codeAppendf("vec3 fragToLight%d = %s - worldCor ;\n",
292 i, lightDirOrPosUniName[i]);
293 fragBuilder->codeAppendf("float distsq%d = dot(fragToLight%d , fragToLight%d);"
294 "fragToLight%d = normalize(fragToLi ght%d);",
295 i, i, i, i, i);
296 fragBuilder->codeAppendf("%s = -vec2(%s.x - worldCor.x, worl dCor.y - %s.y)*"
297 "(povDepth.b) / vec2(%s, %s) ;\n",
298 offset.c_str(), lightDirOrPosUniNam e[i],
299 lightDirOrPosUniName[i],
300 widthUniName, heightUniName);
301 } else {
302 fragBuilder->codeAppendf("%s = vec2(%s) * povDepth.b * 255 / vec2(%s, %s);\n",
303 offset.c_str(), lightDirOrPosUniNam e[i],
304 widthUniName, heightUniName);
305 }
267 fragBuilder->codeAppendf("vec2 %s = (vec2(%s, %s) / vec2(%s, %s) );\n", 306 fragBuilder->codeAppendf("vec2 %s = (vec2(%s, %s) / vec2(%s, %s) );\n",
268 scaleVec.c_str(), 307 scaleVec.c_str(),
269 widthUniName, heightUniName, 308 widthUniName, heightUniName,
270 depthMapWidthUniName[i], depthMapHeight UniName[i]); 309 depthMapWidthUniName[i], depthMapHeight UniName[i]);
271 310
272 fragBuilder->codeAppendf("vec2 %s = 1 - %s;\n", 311 fragBuilder->codeAppendf("vec2 %s = 1 - %s;\n",
273 scaleOffsetVec.c_str(), scaleVec.c_str( )); 312 scaleOffsetVec.c_str(),
313 scaleVec.c_str());
274 314
275 fragBuilder->codeAppendf("vec2 %s = (vMatrixCoord_0_1_Stage0 + " 315 fragBuilder->codeAppendf("vec2 %s = (vMatrixCoord_0_1_Stage0 + "
276 "vec2(%s.x, 0 - %s.y)) " 316 "vec2(%s.x, 0 - %s.y)) "
277 " * %s + vec2(0,1) * %s;\n", 317 " * %s + vec2(0,1) * %s;\n",
278 povCoord.c_str(), offset.c_str(), offse t.c_str(), 318 povCoord.c_str(), offset.c_str(), offse t.c_str(),
279 scaleVec.c_str(), scaleOffsetVec.c_str( )); 319 scaleVec.c_str(), scaleOffsetVec.c_str( ));
280 320
281 fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSampler s[i], 321 fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSampler s[i],
282 povCoord.c_str(), 322 povCoord.c_str(),
283 kVec2f_GrSLType); 323 kVec2f_GrSLType);
284 324
285
286 } 325 }
287 326
288 const char* ambientColorUniName = nullptr; 327 const char* ambientColorUniName = nullptr;
289 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag , 328 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag ,
290 kVec3f_GrSLType, kDefa ult_GrSLPrecision, 329 kVec3f_GrSLType, kDefa ult_GrSLPrecision,
291 "AmbientColor", &ambie ntColorUniName); 330 "AmbientColor", &ambie ntColorUniName);
292 331
293 fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseCol or.c_str()); 332 fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseCol or.c_str());
294 333
295 SkString totalLightColor("totalLightColor"); 334 SkString totalLightColor("totalLightColor");
296 fragBuilder->codeAppendf("vec3 %s = vec3(0,0,0);", totalLightColor.c _str()); 335 fragBuilder->codeAppendf("vec3 %s = vec3(0,0,0);", totalLightColor.c _str());
297 336
298 fragBuilder->codeAppendf("float lightProbability;"); 337 fragBuilder->codeAppendf("float lightProbability;");
299 fragBuilder->codeAppendf("float variance;"); 338 fragBuilder->codeAppendf("float variance;");
300 fragBuilder->codeAppendf("float d;"); 339 fragBuilder->codeAppendf("float d;");
301 340
302 for (int i = 0; i < numLights; i++) { 341 for (int i = 0; i < numLights; i++) {
303 fragBuilder->codeAppendf("lightProbability = 1;"); 342 if (!isPointLight[i]) {
343 fragBuilder->codeAppendf("lightProbability = 1;");
304 344
305 // 1/512 is less than half a pixel; imperceptible 345 // 1/512 is less than half a pixel; imperceptible
306 fragBuilder->codeAppendf("if (%s.b <= %s.b + 1/512) {", 346 fragBuilder->codeAppendf("if (%s.b <= %s.b + 1/512) {",
307 povDepth.c_str(), depthMaps[i].c_str()) ; 347 povDepth.c_str(), depthMaps[i].c_st r());
308 if (blurAlgorithm == SkShadowParams::kVariance_ShadowType) { 348 if (blurAlgorithm == SkShadowParams::kVariance_ShadowType) {
309 fragBuilder->codeAppendf("vec2 moments = vec2(%s.b * 255, % s.g * 255 * 256 );", 349 fragBuilder->codeAppendf("vec2 moments%d = vec2(%s.b * 2 55,"
310 depthMaps[i].c_str(), depthMaps[i]. c_str()); 350 "%s.g * 2 55 * 256 );",
351 i, depthMaps[i].c_str(), depthM aps[i].c_str());
311 352
312 // variance biasing lessens light bleeding 353 // variance biasing lessens light bleeding
313 fragBuilder->codeAppendf("variance = max(moments.y - (moment s.x * moments.x)," 354 fragBuilder->codeAppendf("variance = max(moments%d.y - "
314 "%s);", minVarianceUniName) ; 355 "(moments%d.x * moments%d.x),"
356 "%s);", i, i, i,
357 minVarianceUniName);
315 358
316 fragBuilder->codeAppendf("d = (%s.b * 255) - moments.x;", po vDepth.c_str()); 359 fragBuilder->codeAppendf("d = (%s.b * 255) - moments%d.x ;",
317 fragBuilder->codeAppendf("lightProbability = " 360 povDepth.c_str(), i);
318 "(variance / (variance + d * d));") ; 361 fragBuilder->codeAppendf("lightProbability = "
362 "(variance / (variance + d * d));");
319 363
320 SkString clamp("clamp"); 364 SkString clamp("clamp");
321 clamp.appendf("%d", i); 365 clamp.appendf("%d", i);
322 366
323 // choosing between light artifacts or correct shape shadows 367 // choosing between light artifacts or correct shape sha dows
324 // linstep 368 // linstep
325 fragBuilder->codeAppendf("float %s = clamp((lightProbability - %s) /" 369 fragBuilder->codeAppendf("float %s = clamp((lightProbabi lity - %s) /"
326 "(1 - %s), 0, 1);" , 370 "(1 - %s), 0, 1);",
327 clamp.c_str(), shBiasUniName, shBia sUniName); 371 clamp.c_str(), shBiasUniName, s hBiasUniName);
328 372
329 fragBuilder->codeAppendf("lightProbability = %s;", clamp.c_s tr()); 373 fragBuilder->codeAppendf("lightProbability = %s;", clamp .c_str());
374 } else {
375 fragBuilder->codeAppendf("if (%s.b >= %s.b) {",
376 povDepth.c_str(), depthMaps[i]. c_str());
377 fragBuilder->codeAppendf("lightProbability = 1;");
378 fragBuilder->codeAppendf("} else { lightProbability = 0; }");
379 }
380
381 // VSM: The curved shadows near plane edges are mostly light bleeding.
382 fragBuilder->codeAppendf("}");
383 fragBuilder->codeAppendf("%s += dot(vec3(0,0,1), %s) * %s * "
384 "lightProbability;",
385 totalLightColor.c_str(),
386 lightDirOrPosUniName[i],
387 lightColorUniName[i]);
330 } else { 388 } else {
331 fragBuilder->codeAppendf("if (%s.b >= %s.b) {", 389 if (!shadowFP.fIsPointLight[i]) {
332 povDepth.c_str(), depthMaps[i].c_st r()); 390 fragBuilder->codeAppendf("if (%s.b >= %s.b) {",
333 fragBuilder->codeAppendf("lightProbability = 1;"); 391 povDepth.c_str(), depthMaps[i]. c_str());
334 fragBuilder->codeAppendf("} else { lightProbability = 0; }") ; 392 // Note that dot(vec3(0,0,1), %s) == %s.z * %s
393 fragBuilder->codeAppendf("%s += %s.z * %s;",
394 totalLightColor.c_str(),
395 lightDirOrPosUniName[i],
396 lightColorUniName[i]);
397 fragBuilder->codeAppendf("}");
398 } else {
399 // fragToLight%d.z is equal to the fragToLight dot the s urface normal.
400 fragBuilder->codeAppendf("%s += max(fragToLight%d.z, 0) * %s /"
401 "(1 + distsq%d / (%s * %s));",
402 totalLightColor.c_str(), i,
403 lightColorUniName[i], i,
404 lightIntensityUniName[i],
405 lightIntensityUniName[i]);
406 }
335 } 407 }
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 } 408 }
345 409
346 fragBuilder->codeAppendf("%s += %s;", totalLightColor.c_str(), ambie ntColorUniName); 410 fragBuilder->codeAppendf("%s += %s;", totalLightColor.c_str(), ambie ntColorUniName);
347 411
348 fragBuilder->codeAppendf("resultDiffuseColor *= vec4(%s, 1);", 412 fragBuilder->codeAppendf("resultDiffuseColor *= vec4(%s, 1);",
349 totalLightColor.c_str()); 413 totalLightColor.c_str());
350 414
351 fragBuilder->codeAppendf("%s = resultDiffuseColor;", args.fOutputCol or); 415 fragBuilder->codeAppendf("%s = resultDiffuseColor;", args.fOutputCol or);
352 } 416 }
353 417
354 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, 418 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&,
355 GrProcessorKeyBuilder* b) { 419 GrProcessorKeyBuilder* b) {
356 const ShadowFP& shadowFP = proc.cast<ShadowFP>(); 420 const ShadowFP& shadowFP = proc.cast<ShadowFP>();
357 b->add32(shadowFP.fNumDirLights); 421 b->add32(shadowFP.fNumNonAmbLights);
422 int isPL = 0;
423 for (int i = 0; i < SkShadowShader::kMaxNonAmbientLights; i++) {
424 isPL = isPL | ((shadowFP.fIsPointLight[i] ? 1 : 0) << i);
425 }
426 b->add32(isPL);
358 b->add32(shadowFP.fShadowParams.fType); 427 b->add32(shadowFP.fShadowParams.fType);
359 } 428 }
360 429
361 protected: 430 protected:
362 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override { 431 void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {
363 const ShadowFP &shadowFP = proc.cast<ShadowFP>(); 432 const ShadowFP &shadowFP = proc.cast<ShadowFP>();
364 433
robertphillips 2016/08/25 17:41:43 Didn't you remove this once before ?
vjiaoblack 2016/08/26 12:37:22 Done.
365 for (int i = 0; i < shadowFP.fNumDirLights; i++) { 434 fNumNonAmbLights = shadowFP.numLights();
366 const SkVector3& lightDir = shadowFP.lightDir(i); 435
367 if (lightDir != fLightDir[i]) { 436 for (int i = 0; i < fNumNonAmbLights; i++) {
368 pdman.set3fv(fLightDirUni[i], 1, &lightDir.fX); 437 bool isPoint = shadowFP.isPointLight(i);
369 fLightDir[i] = lightDir; 438 fIsPointLight[i] = isPoint;
439
440 const SkVector3& lightDirOrPos = shadowFP.lightDirOrPos(i);
441 if (lightDirOrPos != fLightDirOrPos[i]) {
442 pdman.set3fv(fLightDirOrPosUni[i], 1, &lightDirOrPos.fX);
443 fLightDirOrPos[i] = lightDirOrPos;
370 } 444 }
445
371 const SkColor3f& lightColor = shadowFP.lightColor(i); 446 const SkColor3f& lightColor = shadowFP.lightColor(i);
372 if (lightColor != fLightColor[i]) { 447 if (lightColor != fLightColor[i]) {
373 pdman.set3fv(fLightColorUni[i], 1, &lightColor.fX); 448 pdman.set3fv(fLightColorUni[i], 1, &lightColor.fX);
374 fLightColor[i] = lightColor; 449 fLightColor[i] = lightColor;
375 } 450 }
376 451
452 SkScalar lightIntensity = shadowFP.lightIntensity(i);
453 if (lightIntensity != fLightIntensity[i]) {
454 pdman.set1f(fLightIntensityUni[i], lightIntensity);
455 fLightIntensity[i] = lightIntensity;
456 }
457
377 int depthMapWidth = shadowFP.depthMapWidth(i); 458 int depthMapWidth = shadowFP.depthMapWidth(i);
378 if (depthMapWidth != fDepthMapWidth[i]) { 459 if (depthMapWidth != fDepthMapWidth[i]) {
379 pdman.set1i(fDepthMapWidthUni[i], depthMapWidth); 460 pdman.set1i(fDepthMapWidthUni[i], depthMapWidth);
380 fDepthMapWidth[i] = depthMapWidth; 461 fDepthMapWidth[i] = depthMapWidth;
381 } 462 }
382 int depthMapHeight = shadowFP.depthMapHeight(i); 463 int depthMapHeight = shadowFP.depthMapHeight(i);
383 if (depthMapHeight != fDepthMapHeight[i]) { 464 if (depthMapHeight != fDepthMapHeight[i]) {
384 pdman.set1i(fDepthMapHeightUni[i], depthMapHeight); 465 pdman.set1i(fDepthMapHeightUni[i], depthMapHeight);
385 fDepthMapHeight[i] = depthMapHeight; 466 fDepthMapHeight[i] = depthMapHeight;
386 } 467 }
(...skipping 23 matching lines...) Expand all
410 } 491 }
411 492
412 const SkColor3f& ambientColor = shadowFP.ambientColor(); 493 const SkColor3f& ambientColor = shadowFP.ambientColor();
413 if (ambientColor != fAmbientColor) { 494 if (ambientColor != fAmbientColor) {
414 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX); 495 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX);
415 fAmbientColor = ambientColor; 496 fAmbientColor = ambientColor;
416 } 497 }
417 } 498 }
418 499
419 private: 500 private:
420 SkVector3 fLightDir[SkShadowShader::kMaxNonAmbientLights]; 501 bool fIsPointLight[SkShadowShader::kMaxNonAmbientLights];
502
503 SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights];
421 GrGLSLProgramDataManager::UniformHandle 504 GrGLSLProgramDataManager::UniformHandle
422 fLightDirUni[SkShadowShader::kMaxNonAmbientLights]; 505 fLightDirOrPosUni[SkShadowShader::kMaxNonAmbientLights];
423 506
424 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; 507 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights];
425 GrGLSLProgramDataManager::UniformHandle 508 GrGLSLProgramDataManager::UniformHandle
426 fLightColorUni[SkShadowShader::kMaxNonAmbientLights]; 509 fLightColorUni[SkShadowShader::kMaxNonAmbientLights];
427 510
511 SkScalar fLightIntensity[SkShadowShader::kMaxNonAmbientLights];
512 GrGLSLProgramDataManager::UniformHandle
513 fLightIntensityUni[SkShadowShader::kMaxNonAmbientLights];
514
428 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; 515 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights];
429 GrGLSLProgramDataManager::UniformHandle 516 GrGLSLProgramDataManager::UniformHandle
430 fDepthMapWidthUni[SkShadowShader::kMaxNonAmbientLights]; 517 fDepthMapWidthUni[SkShadowShader::kMaxNonAmbientLights];
431 518
432 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; 519 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights];
433 GrGLSLProgramDataManager::UniformHandle 520 GrGLSLProgramDataManager::UniformHandle
434 fDepthMapHeightUni[SkShadowShader::kMaxNonAmbientLights]; 521 fDepthMapHeightUni[SkShadowShader::kMaxNonAmbientLights];
435 522
436 int fWidth; 523 int fWidth;
437 GrGLSLProgramDataManager::UniformHandle fWidthUni; 524 GrGLSLProgramDataManager::UniformHandle fWidthUni;
438 int fHeight; 525 int fHeight;
439 GrGLSLProgramDataManager::UniformHandle fHeightUni; 526 GrGLSLProgramDataManager::UniformHandle fHeightUni;
440 527
441 SkScalar fBiasingConstant; 528 SkScalar fBiasingConstant;
442 GrGLSLProgramDataManager::UniformHandle fBiasingConstantUni; 529 GrGLSLProgramDataManager::UniformHandle fBiasingConstantUni;
443 SkScalar fMinVariance; 530 SkScalar fMinVariance;
444 GrGLSLProgramDataManager::UniformHandle fMinVarianceUni; 531 GrGLSLProgramDataManager::UniformHandle fMinVarianceUni;
445 532
446 SkColor3f fAmbientColor; 533 SkColor3f fAmbientColor;
447 GrGLSLProgramDataManager::UniformHandle fAmbientColorUni; 534 GrGLSLProgramDataManager::UniformHandle fAmbientColorUni;
535
536 int fNumNonAmbLights;
448 }; 537 };
449 538
450 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { 539 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
451 GLSLShadowFP::GenKey(*this, caps, b); 540 GLSLShadowFP::GenKey(*this, caps, b);
452 } 541 }
453 542
454 const char* name() const override { return "shadowFP"; } 543 const char* name() const override { return "shadowFP"; }
455 544
456 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { 545 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
457 inout->mulByUnknownFourComponents(); 546 inout->mulByUnknownFourComponents();
458 } 547 }
459 int32_t numLights() const { return fNumDirLights; } 548 int32_t numLights() const { return fNumNonAmbLights; }
460 const SkColor3f& ambientColor() const { return fAmbientColor; } 549 const SkColor3f& ambientColor() const { return fAmbientColor; }
461 const SkVector3& lightDir(int i) const { 550 bool isPointLight(int i) const {
462 SkASSERT(i < fNumDirLights); 551 SkASSERT(i < fNumNonAmbLights);
463 return fLightDir[i]; 552 return fIsPointLight[i];
553 }
554 const SkVector3& lightDirOrPos(int i) const {
555 SkASSERT(i < fNumNonAmbLights);
556 return fLightDirOrPos[i];
464 } 557 }
465 const SkVector3& lightColor(int i) const { 558 const SkVector3& lightColor(int i) const {
466 SkASSERT(i < fNumDirLights); 559 SkASSERT(i < fNumNonAmbLights);
467 return fLightColor[i]; 560 return fLightColor[i];
468 } 561 }
562 SkScalar lightIntensity(int i) const {
563 SkASSERT(i < fNumNonAmbLights);
564 return fLightIntensity[i];
565 }
469 566
470 int depthMapWidth(int i) const { 567 int depthMapWidth(int i) const {
471 SkASSERT(i < fNumDirLights); 568 SkASSERT(i < fNumNonAmbLights);
472 return fDepthMapWidth[i]; 569 return fDepthMapWidth[i];
473 } 570 }
474 int depthMapHeight(int i) const { 571 int depthMapHeight(int i) const {
475 SkASSERT(i < fNumDirLights); 572 SkASSERT(i < fNumNonAmbLights);
476 return fDepthMapHeight[i]; 573 return fDepthMapHeight[i];
477 } 574 }
478 int width() const {return fWidth; } 575 int width() const {return fWidth; }
479 int height() const {return fHeight; } 576 int height() const {return fHeight; }
480 577
481 const SkShadowParams& shadowParams() const {return fShadowParams; } 578 const SkShadowParams& shadowParams() const {return fShadowParams; }
482 579
483 private: 580 private:
484 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLShadowFP; } 581 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLShadowFP; }
485 582
486 bool onIsEqual(const GrFragmentProcessor& proc) const override { 583 bool onIsEqual(const GrFragmentProcessor& proc) const override {
487 const ShadowFP& shadowFP = proc.cast<ShadowFP>(); 584 const ShadowFP& shadowFP = proc.cast<ShadowFP>();
488 if (fAmbientColor != shadowFP.fAmbientColor || fNumDirLights != shadowFP .fNumDirLights) { 585 if (fAmbientColor != shadowFP.fAmbientColor ||
586 fNumNonAmbLights != shadowFP.fNumNonAmbLights) {
489 return false; 587 return false;
490 } 588 }
491 589
492 if (fWidth != shadowFP.fWidth || fHeight != shadowFP.fHeight) { 590 if (fWidth != shadowFP.fWidth || fHeight != shadowFP.fHeight) {
493 return false; 591 return false;
494 } 592 }
495 593
496 for (int i = 0; i < fNumDirLights; i++) { 594 for (int i = 0; i < fNumNonAmbLights; i++) {
497 if (fLightDir[i] != shadowFP.fLightDir[i] || 595 if (fLightDirOrPos[i] != shadowFP.fLightDirOrPos[i] ||
498 fLightColor[i] != shadowFP.fLightColor[i]) { 596 fLightColor[i] != shadowFP.fLightColor[i] ||
597 fLightIntensity[i] != shadowFP.fLightIntensity[i] ||
598 fIsPointLight[i] != shadowFP.fIsPointLight[i]) {
499 return false; 599 return false;
500 } 600 }
501 601
502 if (fDepthMapWidth[i] != shadowFP.fDepthMapWidth[i] || 602 if (fDepthMapWidth[i] != shadowFP.fDepthMapWidth[i] ||
503 fDepthMapHeight[i] != shadowFP.fDepthMapHeight[i]) { 603 fDepthMapHeight[i] != shadowFP.fDepthMapHeight[i]) {
504 return false; 604 return false;
505 } 605 }
506 } 606 }
507 607
508 return true; 608 return true;
509 } 609 }
510 610
511 int fNumDirLights; 611 int fNumNonAmbLights;
512 612
513 SkVector3 fLightDir[SkShadowShader::kMaxNonAmbientLights]; 613 bool fIsPointLight[SkShadowShader::kMaxNonAmbientLights];
614 SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights];
514 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; 615 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights];
616 SkScalar fLightIntensity[SkShadowShader::kMaxNonAmbientLights];
515 GrTextureAccess fDepthMapAccess[SkShadowShader::kMaxNonAmbientLights]; 617 GrTextureAccess fDepthMapAccess[SkShadowShader::kMaxNonAmbientLights];
516 sk_sp<GrTexture> fTexture[SkShadowShader::kMaxNonAmbientLights]; 618 sk_sp<GrTexture> fTexture[SkShadowShader::kMaxNonAmbientLights];
517 619
518 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; 620 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights];
519 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; 621 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights];
520 622
521 int fHeight; 623 int fHeight;
522 int fWidth; 624 int fWidth;
523 625
524 SkShadowParams fShadowParams; 626 SkShadowParams fShadowParams;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 725
624 SkColor3f accum = SkColor3f::Make(0.0f, 0.0f, 0.0f); 726 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) 727 // 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) { 728 for (int l = 0; l < lightShader.fLights->numLights(); ++l) {
627 const SkLights::Light& light = lightShader.fLights->light(l); 729 const SkLights::Light& light = lightShader.fLights->light(l);
628 730
629 if (SkLights::Light::kAmbient_LightType == light.type()) { 731 if (SkLights::Light::kAmbient_LightType == light.type()) {
630 accum.fX += light.color().fX * SkColorGetR(diffColor); 732 accum.fX += light.color().fX * SkColorGetR(diffColor);
631 accum.fY += light.color().fY * SkColorGetG(diffColor); 733 accum.fY += light.color().fY * SkColorGetG(diffColor);
632 accum.fZ += light.color().fZ * SkColorGetB(diffColor); 734 accum.fZ += light.color().fZ * SkColorGetB(diffColor);
735 } else if (SkLights::Light::kDirectional_LightType == light.type ()) {
736 // scaling by fZ accounts for lighting direction
737 accum.fX += light.color().makeScale(light.dir().fZ).fX *
738 SkColorGetR(diffColor);
739 accum.fY += light.color().makeScale(light.dir().fZ).fY *
740 SkColorGetG(diffColor);
741 accum.fZ += light.color().makeScale(light.dir().fZ).fZ *
742 SkColorGetB(diffColor);
633 } else { 743 } else {
634 // scaling by fZ accounts for lighting direction 744 // TODO: do point lights for raster, currently treated like ambient
635 accum.fX += light.color().makeScale(light.dir().fZ).fX * SkC olorGetR(diffColor); 745 accum.fX += light.color().fX * SkColorGetR(diffColor);
636 accum.fY += light.color().makeScale(light.dir().fZ).fY * SkC olorGetG(diffColor); 746 accum.fY += light.color().fY * SkColorGetG(diffColor);
637 accum.fZ += light.color().makeScale(light.dir().fZ).fZ * SkC olorGetB(diffColor); 747 accum.fZ += light.color().fZ * SkColorGetB(diffColor);
638 } 748 }
639 } 749 }
640 750
641 result[i] = convert(accum, SkColorGetA(diffColor)); 751 result[i] = convert(accum, SkColorGetA(diffColor));
642 } 752 }
643 753
644 result += n; 754 result += n;
645 x += n; 755 x += n;
646 count -= n; 756 count -= n;
647 } while (count > 0); 757 } while (count > 0);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 864
755 /////////////////////////////////////////////////////////////////////////////// 865 ///////////////////////////////////////////////////////////////////////////////
756 866
757 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader) 867 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader)
758 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl) 868 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl)
759 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 869 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
760 870
761 /////////////////////////////////////////////////////////////////////////////// 871 ///////////////////////////////////////////////////////////////////////////////
762 872
763 #endif 873 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698