OLD | NEW |
---|---|
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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
111 const SkShadowParams& params, | 111 const SkShadowParams& params, |
112 GrContext* context) { | 112 GrContext* context) { |
113 | 113 |
114 fAmbientColor = lights->ambientLightColor(); | 114 fAmbientColor = lights->ambientLightColor(); |
115 | 115 |
116 fNumNonAmbLights = 0; // count of non-ambient lights | 116 fNumNonAmbLights = 0; // count of non-ambient lights |
117 for (int i = 0; i < lights->numLights(); ++i) { | 117 for (int i = 0; i < lights->numLights(); ++i) { |
118 if (fNumNonAmbLights < SkShadowShader::kMaxNonAmbientLights) { | 118 if (fNumNonAmbLights < SkShadowShader::kMaxNonAmbientLights) { |
119 fLightColor[fNumNonAmbLights] = lights->light(i).color(); | 119 fLightColor[fNumNonAmbLights] = lights->light(i).color(); |
120 | 120 |
121 if (SkLights::Light::kDirectional_LightType == lights->light(i). type()) { | 121 if (SkLights::Light::kPoint_LightType == lights->light(i).type() ) { |
122 fLightDirOrPos[fNumNonAmbLights] = lights->light(i).pos(); | |
123 fInvSqLightIntensity[fNumNonAmbLights] = 1.0f / | |
jvanverth1
2016/08/29 18:30:14
The standard formula for a point light is L = I *
vjiaoblack
2016/08/29 19:45:21
Okay, i'll simplify the model!
Done.
| |
124 (lights->light(i).intensity() * lights->light(i).int ensity()); | |
125 } else { | |
122 fLightDirOrPos[fNumNonAmbLights] = lights->light(i).dir(); | 126 fLightDirOrPos[fNumNonAmbLights] = lights->light(i).dir(); |
123 fLightIntensity[fNumNonAmbLights] = 0.0f; | 127 fInvSqLightIntensity[fNumNonAmbLights] = 0.0f; |
124 } else if (SkLights::Light::kPoint_LightType == lights->light(i) .type()) { | |
125 fLightDirOrPos[fNumNonAmbLights] = lights->light(i).pos(); | |
126 fLightIntensity[fNumNonAmbLights] = lights->light(i).intensi ty(); | |
127 } | 128 } |
128 | 129 |
129 fIsPointLight[fNumNonAmbLights] = | 130 fIsPointLight[fNumNonAmbLights] = |
130 SkLights::Light::kPoint_LightType == lights->light(i).ty pe(); | 131 SkLights::Light::kPoint_LightType == lights->light(i).ty pe(); |
131 | 132 |
132 SkImage_Base* shadowMap = ((SkImage_Base*)lights->light(i).getSh adowMap()); | 133 SkImage_Base* shadowMap = ((SkImage_Base*)lights->light(i).getSh adowMap()); |
133 | 134 |
134 // 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* |
135 fTexture[fNumNonAmbLights] = sk_sp<GrTexture>(shadowMap->asTextu reRef(context, | 136 fTexture[fNumNonAmbLights] = sk_sp<GrTexture>(shadowMap->asTextu reRef(context, |
136 GrTextureParams::Clam pNoFilter(), | 137 GrTextureParams::Clam pNoFilter(), |
(...skipping 30 matching lines...) Expand all Loading... | |
167 SkASSERT(shadowFP.fNumNonAmbLights <= SkShadowShader::kMaxNonAmbient Lights); | 168 SkASSERT(shadowFP.fNumNonAmbLights <= SkShadowShader::kMaxNonAmbient Lights); |
168 | 169 |
169 // add uniforms | 170 // add uniforms |
170 int32_t numLights = shadowFP.fNumNonAmbLights; | 171 int32_t numLights = shadowFP.fNumNonAmbLights; |
171 SkASSERT(numLights <= SkShadowShader::kMaxNonAmbientLights); | 172 SkASSERT(numLights <= SkShadowShader::kMaxNonAmbientLights); |
172 | 173 |
173 int blurAlgorithm = shadowFP.fShadowParams.fType; | 174 int blurAlgorithm = shadowFP.fShadowParams.fType; |
174 | 175 |
175 const char* lightDirOrPosUniName[SkShadowShader::kMaxNonAmbientLight s] = {nullptr}; | 176 const char* lightDirOrPosUniName[SkShadowShader::kMaxNonAmbientLight s] = {nullptr}; |
176 const char* lightColorUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr}; | 177 const char* lightColorUniName[SkShadowShader::kMaxNonAmbientLights] = {nullptr}; |
177 const char* lightIntensityUniName[SkShadowShader::kMaxNonAmbientLigh ts] = {nullptr}; | 178 const char* invLightIntensitySqUniName[SkShadowShader::kMaxNonAmbien tLights] = |
179 {nullptr}; | |
180 | |
181 const char* ambientColorUniName = nullptr; | |
178 | 182 |
179 const char* depthMapWidthUniName[SkShadowShader::kMaxNonAmbientLight s] = {nullptr}; | 183 const char* depthMapWidthUniName[SkShadowShader::kMaxNonAmbientLight s] = {nullptr}; |
180 const char* depthMapHeightUniName[SkShadowShader::kMaxNonAmbientLigh ts] = {nullptr}; | 184 const char* depthMapHeightUniName[SkShadowShader::kMaxNonAmbientLigh ts] = {nullptr}; |
185 const char* widthUniName = nullptr; // dimensions of povDepth | |
186 const char* heightUniName = nullptr; | |
181 | 187 |
188 const char* shBiasUniName = nullptr; | |
189 const char* minVarianceUniName = nullptr; | |
190 | |
191 // setting uniforms | |
182 for (int i = 0; i < shadowFP.fNumNonAmbLights; i++) { | 192 for (int i = 0; i < shadowFP.fNumNonAmbLights; i++) { |
183 SkString lightDirOrPosUniNameStr("lightDir"); | 193 SkString lightDirOrPosUniNameStr("lightDir"); |
184 lightDirOrPosUniNameStr.appendf("%d", i); | 194 lightDirOrPosUniNameStr.appendf("%d", i); |
185 SkString lightColorUniNameStr("lightColor"); | 195 SkString lightColorUniNameStr("lightColor"); |
186 lightColorUniNameStr.appendf("%d", i); | 196 lightColorUniNameStr.appendf("%d", i); |
187 SkString lightIntensityUniNameStr("lightIntensity"); | 197 SkString lightIntensityUniNameStr("lightIntensity"); |
188 lightIntensityUniNameStr.appendf("%d", i); | 198 lightIntensityUniNameStr.appendf("%d", i); |
189 | 199 |
190 SkString depthMapWidthUniNameStr("dmapWidth"); | 200 SkString depthMapWidthUniNameStr("dmapWidth"); |
191 depthMapWidthUniNameStr.appendf("%d", i); | 201 depthMapWidthUniNameStr.appendf("%d", i); |
192 SkString depthMapHeightUniNameStr("dmapHeight"); | 202 SkString depthMapHeightUniNameStr("dmapHeight"); |
193 depthMapHeightUniNameStr.appendf("%d", i); | 203 depthMapHeightUniNameStr.appendf("%d", i); |
194 | 204 |
195 fLightDirOrPosUni[i] = uniformHandler->addUniform(kFragment_GrSh aderFlag, | 205 fLightDirOrPosUni[i] = uniformHandler->addUniform(kFragment_GrSh aderFlag, |
196 kVec3f_GrSLType, | 206 kVec3f_GrSLType, |
197 kDefault_GrSLPrecis ion, | 207 kDefault_GrSLPrecis ion, |
198 lightDirOrPosUniNam eStr.c_str(), | 208 lightDirOrPosUniNam eStr.c_str(), |
199 &lightDirOrPosUniNa me[i]); | 209 &lightDirOrPosUniNa me[i]); |
200 fLightColorUni[i] = uniformHandler->addUniform(kFragment_GrShade rFlag, | 210 fLightColorUni[i] = uniformHandler->addUniform(kFragment_GrShade rFlag, |
201 kVec3f_GrSLType, | 211 kVec3f_GrSLType, |
202 kDefault_GrSLPrec ision, | 212 kDefault_GrSLPrec ision, |
203 lightColorUniName Str.c_str(), | 213 lightColorUniName Str.c_str(), |
204 &lightColorUniNam e[i]); | 214 &lightColorUniNam e[i]); |
205 fLightIntensityUni[i] = | 215 fInvSqLightIntensityUni[i] = |
206 uniformHandler->addUniform(kFragment_GrShaderFlag, | 216 uniformHandler->addUniform(kFragment_GrShaderFlag, |
207 kFloat_GrSLType, | 217 kFloat_GrSLType, |
208 kDefault_GrSLPrecision, | 218 kDefault_GrSLPrecision, |
209 lightIntensityUniNameStr.c_st r(), | 219 lightIntensityUniNameStr.c_st r(), |
210 &lightIntensityUniName[i]); | 220 &invLightIntensitySqUniName[i ]); |
211 | 221 |
212 fDepthMapWidthUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag, | 222 fDepthMapWidthUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag, |
213 kInt_GrSLType, | 223 kInt_GrSLType, |
214 kDefault_GrSLPrecision, | 224 kDefault_GrSLPrecision, |
215 depthMapWidthUniNameStr.c_str (), | 225 depthMapWidthUniNameStr.c_str (), |
216 &depthMapWidthUniName[i]); | 226 &depthMapWidthUniName[i]); |
217 fDepthMapHeightUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag, | 227 fDepthMapHeightUni[i] = uniformHandler->addUniform(kFragment_GrS haderFlag, |
218 kInt_GrSLType, | 228 kInt_GrSLType, |
219 kDefault_GrSLPrecision, | 229 kDefault_GrSLPrecision, |
220 depthMapHeightUniNameStr.c_st r(), | 230 depthMapHeightUniNameStr.c_st r(), |
221 &depthMapHeightUniName[i]); | 231 &depthMapHeightUniName[i]); |
222 } | 232 } |
223 | 233 |
224 const char* shBiasUniName = nullptr; | |
225 const char* minVarianceUniName = nullptr; | |
226 | |
227 fBiasingConstantUni = uniformHandler->addUniform(kFragment_GrShaderF lag, | 234 fBiasingConstantUni = uniformHandler->addUniform(kFragment_GrShaderF lag, |
228 kFloat_GrSLType, | 235 kFloat_GrSLType, |
229 kDefault_GrSLPrecis ion, | 236 kDefault_GrSLPrecis ion, |
230 "shadowBias", &shBi asUniName); | 237 "shadowBias", &shBi asUniName); |
231 fMinVarianceUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 238 fMinVarianceUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
232 kFloat_GrSLType, | 239 kFloat_GrSLType, |
233 kDefault_GrSLPrecision, | 240 kDefault_GrSLPrecision, |
234 "minVariance", &minVari anceUniName); | 241 "minVariance", &minVari anceUniName); |
235 | 242 |
236 const char* widthUniName = nullptr; | |
237 const char* heightUniName = nullptr; | |
238 | |
239 fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 243 fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
240 kInt_GrSLType, | 244 kInt_GrSLType, |
241 kDefault_GrSLPrecision, | 245 kDefault_GrSLPrecision, |
242 "width", &widthUniName); | 246 "width", &widthUniName); |
243 fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 247 fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
244 kInt_GrSLType, | 248 kInt_GrSLType, |
245 kDefault_GrSLPrecision, | 249 kDefault_GrSLPrecision, |
246 "height", &heightUniName); | 250 "height", &heightUniName); |
247 | 251 |
252 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag , | |
253 kVec3f_GrSLType, kDefa ult_GrSLPrecision, | |
254 "AmbientColor", &ambie ntColorUniName); | |
255 | |
256 SkString povDepthSampler("_povDepth"); | |
248 SkString povDepth("povDepth"); | 257 SkString povDepth("povDepth"); |
249 this->emitChild(0, nullptr, &povDepth, args); | 258 this->emitChild(0, nullptr, &povDepthSampler, args); |
259 fragBuilder->codeAppendf("vec4 %s = %s;", povDepth.c_str(), povDepth Sampler.c_str()); | |
250 | 260 |
261 SkString diffuseColorSampler("_inDiffuseColor"); | |
251 SkString diffuseColor("inDiffuseColor"); | 262 SkString diffuseColor("inDiffuseColor"); |
252 this->emitChild(1, nullptr, &diffuseColor, args); | 263 this->emitChild(1, nullptr, &diffuseColorSampler, args); |
264 fragBuilder->codeAppendf("vec4 %s = %s;", diffuseColor.c_str(), | |
265 diffuseColorSampler.c_str()); | |
253 | 266 |
254 SkString depthMaps[SkShadowShader::kMaxNonAmbientLights]; | 267 SkString depthMaps[SkShadowShader::kMaxNonAmbientLights]; |
255 | 268 |
269 fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseCol or.c_str()); | |
270 fragBuilder->codeAppendf("vec3 totalLightColor = vec3(0,0,0);"); | |
jvanverth1
2016/08/29 18:30:14
You can just do vec3(0);
Don't need appendf.
vjiaoblack
2016/08/29 19:45:21
Done.
| |
271 | |
272 // probability that a fragment is lit. For each light, we multiply t his by the | |
273 // light's color to get its contribution to totalLightColor. | |
274 fragBuilder->codeAppendf("float lightProbability;"); | |
275 | |
276 // coordinates of current fragment in world space | |
277 fragBuilder->codeAppendf("vec3 worldCor;"); | |
jvanverth1
2016/08/29 18:30:14
Don't need appendf here, can use append. Same for
vjiaoblack
2016/08/29 19:45:22
Done.
| |
278 | |
256 // Multiply by 255 to transform from sampler coordinates to world | 279 // Multiply by 255 to transform from sampler coordinates to world |
257 // coordinates (since 1 channel is 0xFF) | 280 // coordinates (since 1 channel is 0xFF) |
258 fragBuilder->codeAppendf("vec3 worldCor = vec3(vMatrixCoord_0_1_Stag e0 * " | 281 fragBuilder->codeAppendf("worldCor = vec3(vMatrixCoord_0_1_Stage0 * " |
259 "vec2(%s, %s), %s.b * 255); ", | 282 "vec2(%s, %s), %s.b * 255);", |
260 widthUniName, heightUniName, povDepth.c_str ()); | 283 widthUniName, heightUniName, povDepth.c_str ()); |
261 | 284 |
262 // Applies the offset indexing that goes from our view space into th e light's space. | 285 // Applies the offset indexing that goes from our view space into th e light's space. |
263 for (int i = 0; i < shadowFP.fNumNonAmbLights; i++) { | 286 for (int i = 0; i < shadowFP.fNumNonAmbLights; i++) { |
264 SkString povCoord("povCoord"); | 287 SkString povCoord("povCoord"); |
265 povCoord.appendf("%d", i); | 288 povCoord.appendf("%d", i); |
266 | 289 |
267 // vMatrixCoord_0_1_Stage0 is the texture sampler coordinates. | 290 // vMatrixCoord_0_1_Stage0 is the texture sampler coordinates. |
268 // povDepth.b * 255 scales it to 0 - 255, bringing it to world s pace, | 291 // povDepth.b * 255 scales it to 0 - 255, bringing it to world s pace, |
269 // and the / vec2(width, height) brings it back to a sampler coo rdinate | 292 // and the / vec2(width, height) brings it back to a sampler coo rdinate |
270 SkString offset("offset"); | 293 SkString offset("offset"); |
271 offset.appendf("%d", i); | 294 offset.appendf("%d", i); |
272 | 295 |
273 SkString scaleVec("scaleVec"); | 296 SkString scaleVec("scaleVec"); |
274 scaleVec.appendf("%d", i); | 297 scaleVec.appendf("%d", i); |
275 | 298 |
276 SkString scaleOffsetVec("scaleOffsetVec"); | |
277 scaleOffsetVec.appendf("%d", i); | |
278 | |
279 fragBuilder->codeAppendf("vec2 %s;", offset.c_str()); | 299 fragBuilder->codeAppendf("vec2 %s;", offset.c_str()); |
280 | 300 |
281 if (shadowFP.fIsPointLight[i]) { | 301 if (shadowFP.fIsPointLight[i]) { |
282 fragBuilder->codeAppendf("vec3 fragToLight%d = %s - worldCor ;", | 302 fragBuilder->codeAppendf("vec3 fragToLight%d = %s - worldCor ;", |
283 i, lightDirOrPosUniName[i]); | 303 i, lightDirOrPosUniName[i]); |
284 fragBuilder->codeAppendf("float distsq%d = dot(fragToLight%d , fragToLight%d);" | 304 fragBuilder->codeAppendf("float distsq%d = dot(fragToLight%d , fragToLight%d);" |
285 "fragToLight%d = normalize(fragToLi ght%d);", | 305 "fragToLight%d = normalize(fragToLi ght%d);", |
286 i, i, i, i, i); | 306 i, i, i, i, i); |
287 fragBuilder->codeAppendf("%s = -vec2(%s.x - worldCor.x, worl dCor.y - %s.y)*" | 307 fragBuilder->codeAppendf("%s = vec2(worldCor - %s) * povDept h.b;", |
288 "(povDepth.b) / vec2(%s, %s) ;", | 308 offset.c_str(), lightDirOrPosUniNam e[i]); |
289 offset.c_str(), lightDirOrPosUniNam e[i], | |
290 lightDirOrPosUniName[i], | |
291 widthUniName, heightUniName); | |
292 } else { | 309 } else { |
293 fragBuilder->codeAppendf("%s = vec2(%s) * povDepth.b * 255 / vec2(%s, %s);", | 310 fragBuilder->codeAppendf("%s = vec2(%s) * povDepth.b * 255 * " |
294 offset.c_str(), lightDirOrPosUniNam e[i], | 311 "vec2(1.0, -1.0);", |
jvanverth1
2016/08/29 18:30:14
Replace 255*vec2(1, -1) with vec2(255, -255)? And
vjiaoblack
2016/08/29 19:45:22
Done.
| |
295 widthUniName, heightUniName); | 312 offset.c_str(), lightDirOrPosUniNam e[i]); |
296 } | 313 } |
297 fragBuilder->codeAppendf("vec2 %s = (vec2(%s, %s) / vec2(%s, %s) );", | 314 fragBuilder->codeAppendf("vec2 %s = (vec2(%s, %s) *" |
298 scaleVec.c_str(), | 315 "vMatrixCoord_0_1_Stage0 +" |
316 "vec2(0,%s - %s) + " | |
317 "%s) / vec2(%s, %s);", | |
318 povCoord.c_str(), | |
299 widthUniName, heightUniName, | 319 widthUniName, heightUniName, |
320 depthMapHeightUniName[i], heightUniName , | |
321 offset.c_str(), | |
300 depthMapWidthUniName[i], depthMapHeight UniName[i]); | 322 depthMapWidthUniName[i], depthMapHeight UniName[i]); |
301 | 323 |
302 fragBuilder->codeAppendf("vec2 %s = 1 - %s;\n", | |
303 scaleOffsetVec.c_str(), | |
304 scaleVec.c_str()); | |
305 | |
306 fragBuilder->codeAppendf("vec2 %s = (vMatrixCoord_0_1_Stage0 + " | |
307 "vec2(%s.x, 0 - %s.y)) " | |
308 " * %s + vec2(0,1) * %s;", | |
309 povCoord.c_str(), offset.c_str(), offse t.c_str(), | |
310 scaleVec.c_str(), scaleOffsetVec.c_str( )); | |
311 | |
312 fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSampler s[i], | 324 fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSampler s[i], |
313 povCoord.c_str(), | 325 povCoord.c_str(), |
314 kVec2f_GrSLType); | 326 kVec2f_GrSLType); |
315 | 327 |
316 } | 328 } |
317 | 329 |
318 const char* ambientColorUniName = nullptr; | 330 // helper variables for calculating shadowing |
319 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag , | |
320 kVec3f_GrSLType, kDefa ult_GrSLPrecision, | |
321 "AmbientColor", &ambie ntColorUniName); | |
322 | 331 |
323 fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseCol or.c_str()); | 332 // variance of depth at this fragment in the context of surrounding area |
333 // (area size and weighting dependent on blur size and type) | |
334 fragBuilder->codeAppendf("float variance;"); | |
324 | 335 |
325 SkString totalLightColor("totalLightColor"); | 336 // the difference in depth between the user POV and light POV. |
326 fragBuilder->codeAppendf("vec3 %s = vec3(0,0,0);", totalLightColor.c _str()); | |
327 | |
328 fragBuilder->codeAppendf("float lightProbability;"); | |
329 fragBuilder->codeAppendf("float variance;"); | |
330 fragBuilder->codeAppendf("float d;"); | 337 fragBuilder->codeAppendf("float d;"); |
331 | 338 |
339 // add up light contributions from all lights to totalLightColor | |
332 for (int i = 0; i < numLights; i++) { | 340 for (int i = 0; i < numLights; i++) { |
333 if (!shadowFP.isPointLight(i)) { | 341 if (!shadowFP.isPointLight(i)) { |
334 fragBuilder->codeAppendf("lightProbability = 1;"); | 342 fragBuilder->codeAppendf("lightProbability = 1;"); |
335 | 343 |
336 // 1/512 is less than half a pixel; imperceptible | 344 // 1/512 == .00195... is less than half a pixel; imperceptib le |
337 fragBuilder->codeAppendf("if (%s.b <= %s.b + 1/512) {", | 345 fragBuilder->codeAppendf("if (%s.b <= %s.b + .001953125) {", |
jvanverth1
2016/08/29 18:30:14
Good catch.
vjiaoblack
2016/08/29 19:45:22
Done.
| |
338 povDepth.c_str(), depthMaps[i].c_st r()); | 346 povDepth.c_str(), depthMaps[i].c_st r()); |
339 if (blurAlgorithm == SkShadowParams::kVariance_ShadowType) { | 347 if (blurAlgorithm == SkShadowParams::kVariance_ShadowType) { |
340 fragBuilder->codeAppendf("vec2 moments%d = vec2(%s.b * 2 55," | 348 // we stored depth^2 in the SPFCanvas after dividing it by 256, |
341 "%s.g * 2 55 * 256 );", | 349 // so here we multiply it by 256. |
jvanverth1
2016/08/29 18:30:14
Where are we multiplying by 256?
vjiaoblack
2016/08/29 19:45:21
Acknowledged.
| |
350 fragBuilder->codeAppendf("vec2 moments%d = vec2(%s.b, %s .g);", | |
342 i, depthMaps[i].c_str(), depthM aps[i].c_str()); | 351 i, depthMaps[i].c_str(), depthM aps[i].c_str()); |
343 | 352 |
344 // variance biasing lessens light bleeding | 353 // variance biasing lessens light bleeding |
345 fragBuilder->codeAppendf("variance = max(moments%d.y - " | 354 fragBuilder->codeAppendf("variance = max(moments%d.y - " |
346 "(moments%d.x * moments%d.x)," | 355 "(moments%d.x * moments%d.x)," |
347 "%s);", i, i, i, | 356 "%s);", i, i, i, |
348 minVarianceUniName); | 357 minVarianceUniName); |
349 | 358 |
350 fragBuilder->codeAppendf("d = (%s.b * 255) - moments%d.x ;", | 359 fragBuilder->codeAppendf("d = (%s.b) - moments%d.x;", |
351 povDepth.c_str(), i); | 360 povDepth.c_str(), i); |
352 fragBuilder->codeAppendf("lightProbability = " | 361 fragBuilder->codeAppendf("lightProbability = " |
353 "(variance / (variance + d * d));"); | 362 "(variance / (variance + d * d));"); |
354 | 363 |
355 SkString clamp("clamp"); | 364 SkString clamp("clamp"); |
356 clamp.appendf("%d", i); | 365 clamp.appendf("%d", i); |
357 | 366 |
358 // choosing between light artifacts or correct shape sha dows | 367 // choosing between light artifacts or correct shape sha dows |
359 // linstep | 368 // linstep |
360 fragBuilder->codeAppendf("float %s = clamp((lightProbabi lity - %s) /" | 369 fragBuilder->codeAppendf("float %s = clamp((lightProbabi lity - %s) /" |
361 "(1 - %s), 0, 1);", | 370 "(1 - %s), 0, 1);", |
jvanverth1
2016/08/29 18:30:14
Nit: Indent to parenthesis.
vjiaoblack
2016/08/29 19:45:22
Done.
| |
362 clamp.c_str(), shBiasUniName, s hBiasUniName); | 371 clamp.c_str(), shBiasUniName, s hBiasUniName); |
363 | 372 |
364 fragBuilder->codeAppendf("lightProbability = %s;", clamp .c_str()); | 373 fragBuilder->codeAppendf("lightProbability = %s;", clamp .c_str()); |
365 } else { | 374 } else { |
366 fragBuilder->codeAppendf("if (%s.b >= %s.b) {", | 375 fragBuilder->codeAppendf("if (%s.b >= %s.b) {", |
367 povDepth.c_str(), depthMaps[i]. c_str()); | 376 povDepth.c_str(), depthMaps[i]. c_str()); |
368 fragBuilder->codeAppendf("lightProbability = 1;"); | 377 fragBuilder->codeAppendf("lightProbability = 1;"); |
369 fragBuilder->codeAppendf("} else { lightProbability = 0; }"); | 378 fragBuilder->codeAppendf("} else { lightProbability = 0; }"); |
370 } | 379 } |
371 | 380 |
372 // VSM: The curved shadows near plane edges are artifacts fr om blurring | 381 // VSM: The curved shadows near plane edges are artifacts fr om blurring |
373 fragBuilder->codeAppendf("}"); | 382 fragBuilder->codeAppendf("}"); |
374 fragBuilder->codeAppendf("%s += dot(vec3(0,0,1), %s) * %s * " | 383 fragBuilder->codeAppendf("totalLightColor += %s.z * %s * " |
375 "lightProbability;", | 384 "lightProbabilit y;", |
376 totalLightColor.c_str(), | |
377 lightDirOrPosUniName[i], | 385 lightDirOrPosUniName[i], |
378 lightColorUniName[i]); | 386 lightColorUniName[i]); |
379 } else { | 387 } else { |
380 // fragToLight%d.z is equal to the fragToLight dot the surfa ce normal. | 388 // fragToLight%d.z is equal to the fragToLight dot the surfa ce normal. |
381 fragBuilder->codeAppendf("%s += max(fragToLight%d.z, 0) * %s /" | 389 fragBuilder->codeAppendf("totalLightColor += max(fragToLight %d.z, 0) * %s /" |
382 "(1 + distsq%d / (%s * %s));" , | 390 "(1 + distsq%d * %s);", |
383 totalLightColor.c_str(), i, | 391 i, lightColorUniName[i], i, |
384 lightColorUniName[i], i, | 392 invLightIntensitySqUniName[i]); |
385 lightIntensityUniName[i], | |
386 lightIntensityUniName[i]); | |
387 } | 393 } |
388 } | 394 } |
389 | 395 |
390 fragBuilder->codeAppendf("%s += %s;", totalLightColor.c_str(), ambie ntColorUniName); | 396 fragBuilder->codeAppendf("totalLightColor += %s;", ambientColorUniNa me); |
391 | 397 fragBuilder->codeAppendf("%s = resultDiffuseColor * vec4(totalLightC olor, 1);", |
392 fragBuilder->codeAppendf("resultDiffuseColor *= vec4(%s, 1);", | 398 args.fOutputColor); |
393 totalLightColor.c_str()); | |
394 | |
395 fragBuilder->codeAppendf("%s = resultDiffuseColor;", args.fOutputCol or); | |
396 } | 399 } |
397 | 400 |
398 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, | 401 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, |
399 GrProcessorKeyBuilder* b) { | 402 GrProcessorKeyBuilder* b) { |
400 const ShadowFP& shadowFP = proc.cast<ShadowFP>(); | 403 const ShadowFP& shadowFP = proc.cast<ShadowFP>(); |
401 b->add32(shadowFP.fNumNonAmbLights); | 404 b->add32(shadowFP.fNumNonAmbLights); |
402 int isPL = 0; | 405 int isPL = 0; |
403 for (int i = 0; i < SkShadowShader::kMaxNonAmbientLights; i++) { | 406 for (int i = 0; i < SkShadowShader::kMaxNonAmbientLights; i++) { |
404 isPL = isPL | ((shadowFP.fIsPointLight[i] ? 1 : 0) << i); | 407 isPL = isPL | ((shadowFP.fIsPointLight[i] ? 1 : 0) << i); |
405 } | 408 } |
(...skipping 12 matching lines...) Expand all Loading... | |
418 fLightDirOrPos[i] = lightDirOrPos; | 421 fLightDirOrPos[i] = lightDirOrPos; |
419 } | 422 } |
420 | 423 |
421 const SkColor3f& lightColor = shadowFP.lightColor(i); | 424 const SkColor3f& lightColor = shadowFP.lightColor(i); |
422 if (lightColor != fLightColor[i]) { | 425 if (lightColor != fLightColor[i]) { |
423 pdman.set3fv(fLightColorUni[i], 1, &lightColor.fX); | 426 pdman.set3fv(fLightColorUni[i], 1, &lightColor.fX); |
424 fLightColor[i] = lightColor; | 427 fLightColor[i] = lightColor; |
425 } | 428 } |
426 | 429 |
427 SkScalar lightIntensity = shadowFP.lightIntensity(i); | 430 SkScalar lightIntensity = shadowFP.lightIntensity(i); |
428 if (lightIntensity != fLightIntensity[i]) { | 431 if (lightIntensity != fInvSqLightIntensity[i]) { |
429 pdman.set1f(fLightIntensityUni[i], lightIntensity); | 432 pdman.set1f(fInvSqLightIntensityUni[i], lightIntensity); |
430 fLightIntensity[i] = lightIntensity; | 433 fInvSqLightIntensity[i] = lightIntensity; |
431 } | 434 } |
432 | 435 |
433 int depthMapWidth = shadowFP.depthMapWidth(i); | 436 int depthMapWidth = shadowFP.depthMapWidth(i); |
434 if (depthMapWidth != fDepthMapWidth[i]) { | 437 if (depthMapWidth != fDepthMapWidth[i]) { |
435 pdman.set1i(fDepthMapWidthUni[i], depthMapWidth); | 438 pdman.set1i(fDepthMapWidthUni[i], depthMapWidth); |
436 fDepthMapWidth[i] = depthMapWidth; | 439 fDepthMapWidth[i] = depthMapWidth; |
437 } | 440 } |
438 int depthMapHeight = shadowFP.depthMapHeight(i); | 441 int depthMapHeight = shadowFP.depthMapHeight(i); |
439 if (depthMapHeight != fDepthMapHeight[i]) { | 442 if (depthMapHeight != fDepthMapHeight[i]) { |
440 pdman.set1i(fDepthMapHeightUni[i], depthMapHeight); | 443 pdman.set1i(fDepthMapHeightUni[i], depthMapHeight); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
474 | 477 |
475 private: | 478 private: |
476 SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights]; | 479 SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights]; |
477 GrGLSLProgramDataManager::UniformHandle | 480 GrGLSLProgramDataManager::UniformHandle |
478 fLightDirOrPosUni[SkShadowShader::kMaxNonAmbientLights]; | 481 fLightDirOrPosUni[SkShadowShader::kMaxNonAmbientLights]; |
479 | 482 |
480 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; | 483 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; |
481 GrGLSLProgramDataManager::UniformHandle | 484 GrGLSLProgramDataManager::UniformHandle |
482 fLightColorUni[SkShadowShader::kMaxNonAmbientLights]; | 485 fLightColorUni[SkShadowShader::kMaxNonAmbientLights]; |
483 | 486 |
484 SkScalar fLightIntensity[SkShadowShader::kMaxNonAmbientLights]; | 487 SkScalar fInvSqLightIntensity[SkShadowShader::kMaxNonAmbientLights]; |
485 GrGLSLProgramDataManager::UniformHandle | 488 GrGLSLProgramDataManager::UniformHandle |
486 fLightIntensityUni[SkShadowShader::kMaxNonAmbientLights]; | 489 fInvSqLightIntensityUni[SkShadowShader::kMaxNonAmbientLights]; |
487 | 490 |
488 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; | 491 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; |
489 GrGLSLProgramDataManager::UniformHandle | 492 GrGLSLProgramDataManager::UniformHandle |
490 fDepthMapWidthUni[SkShadowShader::kMaxNonAmbientLights]; | 493 fDepthMapWidthUni[SkShadowShader::kMaxNonAmbientLights]; |
491 | 494 |
492 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; | 495 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; |
493 GrGLSLProgramDataManager::UniformHandle | 496 GrGLSLProgramDataManager::UniformHandle |
494 fDepthMapHeightUni[SkShadowShader::kMaxNonAmbientLights]; | 497 fDepthMapHeightUni[SkShadowShader::kMaxNonAmbientLights]; |
495 | 498 |
496 int fWidth; | 499 int fWidth; |
(...skipping 28 matching lines...) Expand all Loading... | |
525 const SkVector3& lightDirOrPos(int i) const { | 528 const SkVector3& lightDirOrPos(int i) const { |
526 SkASSERT(i < fNumNonAmbLights); | 529 SkASSERT(i < fNumNonAmbLights); |
527 return fLightDirOrPos[i]; | 530 return fLightDirOrPos[i]; |
528 } | 531 } |
529 const SkVector3& lightColor(int i) const { | 532 const SkVector3& lightColor(int i) const { |
530 SkASSERT(i < fNumNonAmbLights); | 533 SkASSERT(i < fNumNonAmbLights); |
531 return fLightColor[i]; | 534 return fLightColor[i]; |
532 } | 535 } |
533 SkScalar lightIntensity(int i) const { | 536 SkScalar lightIntensity(int i) const { |
534 SkASSERT(i < fNumNonAmbLights); | 537 SkASSERT(i < fNumNonAmbLights); |
535 return fLightIntensity[i]; | 538 return fInvSqLightIntensity[i]; |
536 } | 539 } |
537 | 540 |
538 int depthMapWidth(int i) const { | 541 int depthMapWidth(int i) const { |
539 SkASSERT(i < fNumNonAmbLights); | 542 SkASSERT(i < fNumNonAmbLights); |
540 return fDepthMapWidth[i]; | 543 return fDepthMapWidth[i]; |
541 } | 544 } |
542 int depthMapHeight(int i) const { | 545 int depthMapHeight(int i) const { |
543 SkASSERT(i < fNumNonAmbLights); | 546 SkASSERT(i < fNumNonAmbLights); |
544 return fDepthMapHeight[i]; | 547 return fDepthMapHeight[i]; |
545 } | 548 } |
(...skipping 12 matching lines...) Expand all Loading... | |
558 return false; | 561 return false; |
559 } | 562 } |
560 | 563 |
561 if (fWidth != shadowFP.fWidth || fHeight != shadowFP.fHeight) { | 564 if (fWidth != shadowFP.fWidth || fHeight != shadowFP.fHeight) { |
562 return false; | 565 return false; |
563 } | 566 } |
564 | 567 |
565 for (int i = 0; i < fNumNonAmbLights; i++) { | 568 for (int i = 0; i < fNumNonAmbLights; i++) { |
566 if (fLightDirOrPos[i] != shadowFP.fLightDirOrPos[i] || | 569 if (fLightDirOrPos[i] != shadowFP.fLightDirOrPos[i] || |
567 fLightColor[i] != shadowFP.fLightColor[i] || | 570 fLightColor[i] != shadowFP.fLightColor[i] || |
568 fLightIntensity[i] != shadowFP.fLightIntensity[i] || | 571 fInvSqLightIntensity[i] != shadowFP.fInvSqLightIntensity[i] || |
569 fIsPointLight[i] != shadowFP.fIsPointLight[i]) { | 572 fIsPointLight[i] != shadowFP.fIsPointLight[i]) { |
570 return false; | 573 return false; |
571 } | 574 } |
572 | 575 |
573 if (fDepthMapWidth[i] != shadowFP.fDepthMapWidth[i] || | 576 if (fDepthMapWidth[i] != shadowFP.fDepthMapWidth[i] || |
574 fDepthMapHeight[i] != shadowFP.fDepthMapHeight[i]) { | 577 fDepthMapHeight[i] != shadowFP.fDepthMapHeight[i]) { |
575 return false; | 578 return false; |
576 } | 579 } |
577 } | 580 } |
578 | 581 |
579 return true; | 582 return true; |
580 } | 583 } |
581 | 584 |
582 int fNumNonAmbLights; | 585 int fNumNonAmbLights; |
583 | 586 |
584 bool fIsPointLight[SkShadowShader::kMaxNonAmbientLights]; | 587 bool fIsPointLight[SkShadowShader::kMaxNonAmbientLights]; |
585 SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights]; | 588 SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights]; |
586 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; | 589 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; |
587 SkScalar fLightIntensity[SkShadowShader::kMaxNonAmbientLights]; | 590 SkScalar fInvSqLightIntensity[SkShadowShader::kMaxNonAmbientLights]; |
588 GrTextureAccess fDepthMapAccess[SkShadowShader::kMaxNonAmbientLights]; | 591 GrTextureAccess fDepthMapAccess[SkShadowShader::kMaxNonAmbientLights]; |
589 sk_sp<GrTexture> fTexture[SkShadowShader::kMaxNonAmbientLights]; | 592 sk_sp<GrTexture> fTexture[SkShadowShader::kMaxNonAmbientLights]; |
590 | 593 |
591 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; | 594 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; |
592 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; | 595 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; |
593 | 596 |
594 int fHeight; | 597 int fHeight; |
595 int fWidth; | 598 int fWidth; |
596 | 599 |
597 SkShadowParams fShadowParams; | 600 SkShadowParams fShadowParams; |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
836 | 839 |
837 /////////////////////////////////////////////////////////////////////////////// | 840 /////////////////////////////////////////////////////////////////////////////// |
838 | 841 |
839 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader) | 842 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader) |
840 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl) | 843 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl) |
841 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 844 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
842 | 845 |
843 /////////////////////////////////////////////////////////////////////////////// | 846 /////////////////////////////////////////////////////////////////////////////// |
844 | 847 |
845 #endif | 848 #endif |
OLD | NEW |