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

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