| 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 fLightColor[fNumNonAmbLights].scale(lights->light(i).intensi
ty()); |
| 124 } else { |
| 122 fLightDirOrPos[fNumNonAmbLights] = lights->light(i).dir(); | 125 fLightDirOrPos[fNumNonAmbLights] = lights->light(i).dir(); |
| 123 fLightIntensity[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 } | 126 } |
| 128 | 127 |
| 129 fIsPointLight[fNumNonAmbLights] = | 128 fIsPointLight[fNumNonAmbLights] = |
| 130 SkLights::Light::kPoint_LightType == lights->light(i).ty
pe(); | 129 SkLights::Light::kPoint_LightType == lights->light(i).ty
pe(); |
| 131 | 130 |
| 132 SkImage_Base* shadowMap = ((SkImage_Base*)lights->light(i).getSh
adowMap()); | 131 SkImage_Base* shadowMap = ((SkImage_Base*)lights->light(i).getSh
adowMap()); |
| 133 | 132 |
| 134 // gets deleted when the ShadowFP is destroyed, and frees the Gr
Texture* | 133 // gets deleted when the ShadowFP is destroyed, and frees the Gr
Texture* |
| 135 fTexture[fNumNonAmbLights] = sk_sp<GrTexture>(shadowMap->asTextu
reRef(context, | 134 fTexture[fNumNonAmbLights] = sk_sp<GrTexture>(shadowMap->asTextu
reRef(context, |
| 136 GrTextureParams::Clam
pNoFilter(), | 135 GrTextureParams::Clam
pNoFilter(), |
| (...skipping 30 matching lines...) Expand all Loading... |
| 167 SkASSERT(shadowFP.fNumNonAmbLights <= SkShadowShader::kMaxNonAmbient
Lights); | 166 SkASSERT(shadowFP.fNumNonAmbLights <= SkShadowShader::kMaxNonAmbient
Lights); |
| 168 | 167 |
| 169 // add uniforms | 168 // add uniforms |
| 170 int32_t numLights = shadowFP.fNumNonAmbLights; | 169 int32_t numLights = shadowFP.fNumNonAmbLights; |
| 171 SkASSERT(numLights <= SkShadowShader::kMaxNonAmbientLights); | 170 SkASSERT(numLights <= SkShadowShader::kMaxNonAmbientLights); |
| 172 | 171 |
| 173 int blurAlgorithm = shadowFP.fShadowParams.fType; | 172 int blurAlgorithm = shadowFP.fShadowParams.fType; |
| 174 | 173 |
| 175 const char* lightDirOrPosUniName[SkShadowShader::kMaxNonAmbientLight
s] = {nullptr}; | 174 const char* lightDirOrPosUniName[SkShadowShader::kMaxNonAmbientLight
s] = {nullptr}; |
| 176 const char* lightColorUniName[SkShadowShader::kMaxNonAmbientLights]
= {nullptr}; | 175 const char* lightColorUniName[SkShadowShader::kMaxNonAmbientLights]
= {nullptr}; |
| 177 const char* lightIntensityUniName[SkShadowShader::kMaxNonAmbientLigh
ts] = {nullptr}; | 176 const char* ambientColorUniName = nullptr; |
| 178 | 177 |
| 179 const char* depthMapWidthUniName[SkShadowShader::kMaxNonAmbientLight
s] = {nullptr}; | 178 const char* depthMapWidthUniName[SkShadowShader::kMaxNonAmbientLight
s] = {nullptr}; |
| 180 const char* depthMapHeightUniName[SkShadowShader::kMaxNonAmbientLigh
ts] = {nullptr}; | 179 const char* depthMapHeightUniName[SkShadowShader::kMaxNonAmbientLigh
ts] = {nullptr}; |
| 180 const char* widthUniName = nullptr; // dimensions of povDepth |
| 181 const char* heightUniName = nullptr; |
| 181 | 182 |
| 183 const char* shBiasUniName = nullptr; |
| 184 const char* minVarianceUniName = nullptr; |
| 185 |
| 186 // setting uniforms |
| 182 for (int i = 0; i < shadowFP.fNumNonAmbLights; i++) { | 187 for (int i = 0; i < shadowFP.fNumNonAmbLights; i++) { |
| 183 SkString lightDirOrPosUniNameStr("lightDir"); | 188 SkString lightDirOrPosUniNameStr("lightDir"); |
| 184 lightDirOrPosUniNameStr.appendf("%d", i); | 189 lightDirOrPosUniNameStr.appendf("%d", i); |
| 185 SkString lightColorUniNameStr("lightColor"); | 190 SkString lightColorUniNameStr("lightColor"); |
| 186 lightColorUniNameStr.appendf("%d", i); | 191 lightColorUniNameStr.appendf("%d", i); |
| 187 SkString lightIntensityUniNameStr("lightIntensity"); | 192 SkString lightIntensityUniNameStr("lightIntensity"); |
| 188 lightIntensityUniNameStr.appendf("%d", i); | 193 lightIntensityUniNameStr.appendf("%d", i); |
| 189 | 194 |
| 190 SkString depthMapWidthUniNameStr("dmapWidth"); | 195 SkString depthMapWidthUniNameStr("dmapWidth"); |
| 191 depthMapWidthUniNameStr.appendf("%d", i); | 196 depthMapWidthUniNameStr.appendf("%d", i); |
| 192 SkString depthMapHeightUniNameStr("dmapHeight"); | 197 SkString depthMapHeightUniNameStr("dmapHeight"); |
| 193 depthMapHeightUniNameStr.appendf("%d", i); | 198 depthMapHeightUniNameStr.appendf("%d", i); |
| 194 | 199 |
| 195 fLightDirOrPosUni[i] = uniformHandler->addUniform(kFragment_GrSh
aderFlag, | 200 fLightDirOrPosUni[i] = uniformHandler->addUniform(kFragment_GrSh
aderFlag, |
| 196 kVec3f_GrSLType, | 201 kVec3f_GrSLType, |
| 197 kDefault_GrSLPrecis
ion, | 202 kDefault_GrSLPrecis
ion, |
| 198 lightDirOrPosUniNam
eStr.c_str(), | 203 lightDirOrPosUniNam
eStr.c_str(), |
| 199 &lightDirOrPosUniNa
me[i]); | 204 &lightDirOrPosUniNa
me[i]); |
| 200 fLightColorUni[i] = uniformHandler->addUniform(kFragment_GrShade
rFlag, | 205 fLightColorUni[i] = uniformHandler->addUniform(kFragment_GrShade
rFlag, |
| 201 kVec3f_GrSLType, | 206 kVec3f_GrSLType, |
| 202 kDefault_GrSLPrec
ision, | 207 kDefault_GrSLPrec
ision, |
| 203 lightColorUniName
Str.c_str(), | 208 lightColorUniName
Str.c_str(), |
| 204 &lightColorUniNam
e[i]); | 209 &lightColorUniNam
e[i]); |
| 205 fLightIntensityUni[i] = | |
| 206 uniformHandler->addUniform(kFragment_GrShaderFlag, | |
| 207 kFloat_GrSLType, | |
| 208 kDefault_GrSLPrecision, | |
| 209 lightIntensityUniNameStr.c_st
r(), | |
| 210 &lightIntensityUniName[i]); | |
| 211 | 210 |
| 212 fDepthMapWidthUni[i] = uniformHandler->addUniform(kFragment_GrS
haderFlag, | 211 fDepthMapWidthUni[i] = uniformHandler->addUniform(kFragment_GrS
haderFlag, |
| 213 kInt_GrSLType, | 212 kInt_GrSLType, |
| 214 kDefault_GrSLPrecision, | 213 kDefault_GrSLPrecision, |
| 215 depthMapWidthUniNameStr.c_str
(), | 214 depthMapWidthUniNameStr.c_str
(), |
| 216 &depthMapWidthUniName[i]); | 215 &depthMapWidthUniName[i]); |
| 217 fDepthMapHeightUni[i] = uniformHandler->addUniform(kFragment_GrS
haderFlag, | 216 fDepthMapHeightUni[i] = uniformHandler->addUniform(kFragment_GrS
haderFlag, |
| 218 kInt_GrSLType, | 217 kInt_GrSLType, |
| 219 kDefault_GrSLPrecision, | 218 kDefault_GrSLPrecision, |
| 220 depthMapHeightUniNameStr.c_st
r(), | 219 depthMapHeightUniNameStr.c_st
r(), |
| 221 &depthMapHeightUniName[i]); | 220 &depthMapHeightUniName[i]); |
| 222 } | 221 } |
| 223 | 222 |
| 224 const char* shBiasUniName = nullptr; | |
| 225 const char* minVarianceUniName = nullptr; | |
| 226 | |
| 227 fBiasingConstantUni = uniformHandler->addUniform(kFragment_GrShaderF
lag, | 223 fBiasingConstantUni = uniformHandler->addUniform(kFragment_GrShaderF
lag, |
| 228 kFloat_GrSLType, | 224 kFloat_GrSLType, |
| 229 kDefault_GrSLPrecis
ion, | 225 kDefault_GrSLPrecis
ion, |
| 230 "shadowBias", &shBi
asUniName); | 226 "shadowBias", &shBi
asUniName); |
| 231 fMinVarianceUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 227 fMinVarianceUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
| 232 kFloat_GrSLType, | 228 kFloat_GrSLType, |
| 233 kDefault_GrSLPrecision, | 229 kDefault_GrSLPrecision, |
| 234 "minVariance", &minVari
anceUniName); | 230 "minVariance", &minVari
anceUniName); |
| 235 | 231 |
| 236 const char* widthUniName = nullptr; | |
| 237 const char* heightUniName = nullptr; | |
| 238 | |
| 239 fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 232 fWidthUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
| 240 kInt_GrSLType, | 233 kInt_GrSLType, |
| 241 kDefault_GrSLPrecision, | 234 kDefault_GrSLPrecision, |
| 242 "width", &widthUniName); | 235 "width", &widthUniName); |
| 243 fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 236 fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
| 244 kInt_GrSLType, | 237 kInt_GrSLType, |
| 245 kDefault_GrSLPrecision, | 238 kDefault_GrSLPrecision, |
| 246 "height", &heightUniName); | 239 "height", &heightUniName); |
| 247 | 240 |
| 241 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag
, |
| 242 kVec3f_GrSLType, kDefa
ult_GrSLPrecision, |
| 243 "AmbientColor", &ambie
ntColorUniName); |
| 244 |
| 245 SkString povDepthSampler("_povDepth"); |
| 248 SkString povDepth("povDepth"); | 246 SkString povDepth("povDepth"); |
| 249 this->emitChild(0, nullptr, &povDepth, args); | 247 this->emitChild(0, nullptr, &povDepthSampler, args); |
| 248 fragBuilder->codeAppendf("vec4 %s = %s;", povDepth.c_str(), povDepth
Sampler.c_str()); |
| 250 | 249 |
| 250 SkString diffuseColorSampler("_inDiffuseColor"); |
| 251 SkString diffuseColor("inDiffuseColor"); | 251 SkString diffuseColor("inDiffuseColor"); |
| 252 this->emitChild(1, nullptr, &diffuseColor, args); | 252 this->emitChild(1, nullptr, &diffuseColorSampler, args); |
| 253 fragBuilder->codeAppendf("vec4 %s = %s;", diffuseColor.c_str(), |
| 254 diffuseColorSampler.c_str()); |
| 253 | 255 |
| 254 SkString depthMaps[SkShadowShader::kMaxNonAmbientLights]; | 256 SkString depthMaps[SkShadowShader::kMaxNonAmbientLights]; |
| 255 | 257 |
| 258 fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseCol
or.c_str()); |
| 259 fragBuilder->codeAppend ("vec3 totalLightColor = vec3(0);"); |
| 260 |
| 261 // probability that a fragment is lit. For each light, we multiply t
his by the |
| 262 // light's color to get its contribution to totalLightColor. |
| 263 fragBuilder->codeAppend ("float lightProbability;"); |
| 264 |
| 265 // coordinates of current fragment in world space |
| 266 fragBuilder->codeAppend ("vec3 worldCor;"); |
| 267 |
| 256 // Multiply by 255 to transform from sampler coordinates to world | 268 // Multiply by 255 to transform from sampler coordinates to world |
| 257 // coordinates (since 1 channel is 0xFF) | 269 // coordinates (since 1 channel is 0xFF) |
| 258 fragBuilder->codeAppendf("vec3 worldCor = vec3(vMatrixCoord_0_1_Stag
e0 * " | 270 // Note: vMatrixCoord_0_1_Stage0 is the texture sampler coordinates. |
| 259 "vec2(%s, %s), %s.b * 255);
", | 271 fragBuilder->codeAppendf("worldCor = vec3(vMatrixCoord_0_1_Stage0 *
" |
| 272 "vec2(%s, %s), %s.b * 255);", |
| 260 widthUniName, heightUniName, povDepth.c_str
()); | 273 widthUniName, heightUniName, povDepth.c_str
()); |
| 261 | 274 |
| 262 // Applies the offset indexing that goes from our view space into th
e light's space. | 275 // 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++) { | 276 for (int i = 0; i < shadowFP.fNumNonAmbLights; i++) { |
| 264 SkString povCoord("povCoord"); | 277 SkString povCoord("povCoord"); |
| 265 povCoord.appendf("%d", i); | 278 povCoord.appendf("%d", i); |
| 266 | 279 |
| 267 // vMatrixCoord_0_1_Stage0 is the texture sampler coordinates. | |
| 268 // povDepth.b * 255 scales it to 0 - 255, bringing it to world s
pace, | 280 // 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 | 281 // and the / vec2(width, height) brings it back to a sampler coo
rdinate |
| 270 SkString offset("offset"); | 282 SkString offset("offset"); |
| 271 offset.appendf("%d", i); | 283 offset.appendf("%d", i); |
| 272 | 284 |
| 273 SkString scaleVec("scaleVec"); | 285 SkString scaleVec("scaleVec"); |
| 274 scaleVec.appendf("%d", i); | 286 scaleVec.appendf("%d", i); |
| 275 | 287 |
| 276 SkString scaleOffsetVec("scaleOffsetVec"); | |
| 277 scaleOffsetVec.appendf("%d", i); | |
| 278 | |
| 279 fragBuilder->codeAppendf("vec2 %s;", offset.c_str()); | 288 fragBuilder->codeAppendf("vec2 %s;", offset.c_str()); |
| 280 | 289 |
| 290 // note that we flip the y-coord of the offset and then later ad
d |
| 291 // a value just to the y-coord of povCoord. This is to account f
or |
| 292 // the shifted origins from switching from raster into GPU. |
| 281 if (shadowFP.fIsPointLight[i]) { | 293 if (shadowFP.fIsPointLight[i]) { |
| 282 fragBuilder->codeAppendf("vec3 fragToLight%d = %s - worldCor
;", | 294 fragBuilder->codeAppendf("vec3 fragToLight%d = %s - worldCor
;", |
| 283 i, lightDirOrPosUniName[i]); | 295 i, lightDirOrPosUniName[i]); |
| 284 fragBuilder->codeAppendf("float distsq%d = dot(fragToLight%d
, fragToLight%d);" | 296 fragBuilder->codeAppendf("float distsq%d = dot(fragToLight%d
, fragToLight%d);" |
| 285 "fragToLight%d = normalize(fragToLi
ght%d);", | 297 "fragToLight%d = normalize(fragToLi
ght%d);", |
| 286 i, i, i, i, i); | 298 i, i, i, i, i); |
| 287 fragBuilder->codeAppendf("%s = -vec2(%s.x - worldCor.x, worl
dCor.y - %s.y)*" | 299 fragBuilder->codeAppendf("%s = vec2(worldCor.x - %s.x, %s.y
- worldCor.y) * " |
| 288 "(povDepth.b) / vec2(%s, %s)
;", | 300 "povDepth.b;", |
| 289 offset.c_str(), lightDirOrPosUniNam
e[i], | 301 offset.c_str(), lightDirOrPosUniNam
e[i], |
| 290 lightDirOrPosUniName[i], | 302 lightDirOrPosUniName[i]); |
| 291 widthUniName, heightUniName); | |
| 292 } else { | 303 } else { |
| 293 fragBuilder->codeAppendf("%s = vec2(%s) * povDepth.b * 255 /
vec2(%s, %s);", | 304 fragBuilder->codeAppendf("%s = vec2(%s) * povDepth.b * vec2(
255.0, -255.0);", |
| 294 offset.c_str(), lightDirOrPosUniNam
e[i], | 305 offset.c_str(), lightDirOrPosUniNam
e[i]); |
| 295 widthUniName, heightUniName); | |
| 296 } | 306 } |
| 297 fragBuilder->codeAppendf("vec2 %s = (vec2(%s, %s) / vec2(%s, %s)
);", | 307 fragBuilder->codeAppendf("vec2 %s = (vec2(%s, %s) *" |
| 298 scaleVec.c_str(), | 308 "vMatrixCoord_0_1_Stage0 +" |
| 309 "vec2(0,%s - %s)" |
| 310 " + " |
| 311 "%s) / vec2(%s, %s);", |
| 312 povCoord.c_str(), |
| 299 widthUniName, heightUniName, | 313 widthUniName, heightUniName, |
| 314 depthMapHeightUniName[i], heightUniName
, |
| 315 offset.c_str(), |
| 300 depthMapWidthUniName[i], depthMapHeight
UniName[i]); | 316 depthMapWidthUniName[i], depthMapHeight
UniName[i]); |
| 301 | 317 |
| 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], | 318 fragBuilder->appendTextureLookup(&depthMaps[i], args.fTexSampler
s[i], |
| 313 povCoord.c_str(), | 319 povCoord.c_str(), |
| 314 kVec2f_GrSLType); | 320 kVec2f_GrSLType); |
| 315 | 321 |
| 316 } | 322 } |
| 317 | 323 |
| 318 const char* ambientColorUniName = nullptr; | 324 // helper variables for calculating shadowing |
| 319 fAmbientColorUni = uniformHandler->addUniform(kFragment_GrShaderFlag
, | |
| 320 kVec3f_GrSLType, kDefa
ult_GrSLPrecision, | |
| 321 "AmbientColor", &ambie
ntColorUniName); | |
| 322 | 325 |
| 323 fragBuilder->codeAppendf("vec4 resultDiffuseColor = %s;", diffuseCol
or.c_str()); | 326 // variance of depth at this fragment in the context of surrounding
area |
| 327 // (area size and weighting dependent on blur size and type) |
| 328 fragBuilder->codeAppendf("float variance;"); |
| 324 | 329 |
| 325 SkString totalLightColor("totalLightColor"); | 330 // 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;"); | 331 fragBuilder->codeAppendf("float d;"); |
| 331 | 332 |
| 333 // add up light contributions from all lights to totalLightColor |
| 332 for (int i = 0; i < numLights; i++) { | 334 for (int i = 0; i < numLights; i++) { |
| 333 if (!shadowFP.isPointLight(i)) { | 335 if (!shadowFP.isPointLight(i)) { |
| 334 fragBuilder->codeAppendf("lightProbability = 1;"); | 336 fragBuilder->codeAppendf("lightProbability = 1;"); |
| 335 | 337 |
| 336 // 1/512 is less than half a pixel; imperceptible | 338 // 1/512 == .00195... is less than half a pixel; imperceptib
le |
| 337 fragBuilder->codeAppendf("if (%s.b <= %s.b + 1/512) {", | 339 fragBuilder->codeAppendf("if (%s.b <= %s.b + .001953125) {", |
| 338 povDepth.c_str(), depthMaps[i].c_st
r()); | 340 povDepth.c_str(), depthMaps[i].c_st
r()); |
| 339 if (blurAlgorithm == SkShadowParams::kVariance_ShadowType) { | 341 if (blurAlgorithm == SkShadowParams::kVariance_ShadowType) { |
| 340 fragBuilder->codeAppendf("vec2 moments%d = vec2(%s.b * 2
55," | 342 // We mess with depth and depth^2 in their given scales. |
| 341 "%s.g * 2
55 * 256 );", | 343 // (i.e. between 0 and 1) |
| 344 fragBuilder->codeAppendf("vec2 moments%d = vec2(%s.b, %s
.g);", |
| 342 i, depthMaps[i].c_str(), depthM
aps[i].c_str()); | 345 i, depthMaps[i].c_str(), depthM
aps[i].c_str()); |
| 343 | 346 |
| 344 // variance biasing lessens light bleeding | 347 // variance biasing lessens light bleeding |
| 345 fragBuilder->codeAppendf("variance = max(moments%d.y - " | 348 fragBuilder->codeAppendf("variance = max(moments%d.y - " |
| 346 "(moments%d.x *
moments%d.x)," | 349 "(moments%d.x *
moments%d.x)," |
| 347 "%s);", i, i, i, | 350 "%s);", i, i, i, |
| 348 minVarianceUniName); | 351 minVarianceUniName); |
| 349 | 352 |
| 350 fragBuilder->codeAppendf("d = (%s.b * 255) - moments%d.x
;", | 353 fragBuilder->codeAppendf("d = (%s.b) - moments%d.x;", |
| 351 povDepth.c_str(), i); | 354 povDepth.c_str(), i); |
| 352 fragBuilder->codeAppendf("lightProbability = " | 355 fragBuilder->codeAppendf("lightProbability = " |
| 353 "(variance / (variance
+ d * d));"); | 356 "(variance / (variance
+ d * d));"); |
| 354 | 357 |
| 355 SkString clamp("clamp"); | 358 SkString clamp("clamp"); |
| 356 clamp.appendf("%d", i); | 359 clamp.appendf("%d", i); |
| 357 | 360 |
| 358 // choosing between light artifacts or correct shape sha
dows | 361 // choosing between light artifacts or correct shape sha
dows |
| 359 // linstep | 362 // linstep |
| 360 fragBuilder->codeAppendf("float %s = clamp((lightProbabi
lity - %s) /" | 363 fragBuilder->codeAppendf("float %s = clamp((lightProbabi
lity - %s) /" |
| 361 "(1 - %s), 0, 1);", | 364 "(1 - %s), 0,
1);", |
| 362 clamp.c_str(), shBiasUniName, s
hBiasUniName); | 365 clamp.c_str(), shBiasUniName, s
hBiasUniName); |
| 363 | 366 |
| 364 fragBuilder->codeAppendf("lightProbability = %s;", clamp
.c_str()); | 367 fragBuilder->codeAppendf("lightProbability = %s;", clamp
.c_str()); |
| 365 } else { | 368 } else { |
| 366 fragBuilder->codeAppendf("if (%s.b >= %s.b) {", | 369 fragBuilder->codeAppendf("if (%s.b >= %s.b) {", |
| 367 povDepth.c_str(), depthMaps[i].
c_str()); | 370 povDepth.c_str(), depthMaps[i].
c_str()); |
| 368 fragBuilder->codeAppendf("lightProbability = 1;"); | 371 fragBuilder->codeAppendf("lightProbability = 1;"); |
| 369 fragBuilder->codeAppendf("} else { lightProbability = 0;
}"); | 372 fragBuilder->codeAppendf("} else { lightProbability = 0;
}"); |
| 370 } | 373 } |
| 371 | 374 |
| 372 // VSM: The curved shadows near plane edges are artifacts fr
om blurring | 375 // VSM: The curved shadows near plane edges are artifacts fr
om blurring |
| 373 fragBuilder->codeAppendf("}"); | 376 fragBuilder->codeAppendf("}"); |
| 374 fragBuilder->codeAppendf("%s += dot(vec3(0,0,1), %s) * %s *
" | 377 fragBuilder->codeAppendf("totalLightColor += %s.z * %s * " |
| 375 "lightProbability;", | 378 "lightProbabilit
y;", |
| 376 totalLightColor.c_str(), | |
| 377 lightDirOrPosUniName[i], | 379 lightDirOrPosUniName[i], |
| 378 lightColorUniName[i]); | 380 lightColorUniName[i]); |
| 379 } else { | 381 } else { |
| 380 // fragToLight%d.z is equal to the fragToLight dot the surfa
ce normal. | 382 // fragToLight%d.z is equal to the fragToLight dot the surfa
ce normal. |
| 381 fragBuilder->codeAppendf("%s += max(fragToLight%d.z, 0) * %s
/" | 383 fragBuilder->codeAppendf("totalLightColor += max(fragToLight
%d.z, 0) * %s /" |
| 382 "(1 + distsq%d / (%s * %s));"
, | 384 "(1 + distsq%d);
", |
| 383 totalLightColor.c_str(), i, | 385 i, lightColorUniName[i], i); |
| 384 lightColorUniName[i], i, | |
| 385 lightIntensityUniName[i], | |
| 386 lightIntensityUniName[i]); | |
| 387 } | 386 } |
| 388 } | 387 } |
| 389 | 388 |
| 390 fragBuilder->codeAppendf("%s += %s;", totalLightColor.c_str(), ambie
ntColorUniName); | 389 fragBuilder->codeAppendf("totalLightColor += %s;", ambientColorUniNa
me); |
| 391 | 390 fragBuilder->codeAppendf("%s = resultDiffuseColor * vec4(totalLightC
olor, 1);", |
| 392 fragBuilder->codeAppendf("resultDiffuseColor *= vec4(%s, 1);", | 391 args.fOutputColor); |
| 393 totalLightColor.c_str()); | |
| 394 | |
| 395 fragBuilder->codeAppendf("%s = resultDiffuseColor;", args.fOutputCol
or); | |
| 396 } | 392 } |
| 397 | 393 |
| 398 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, | 394 static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, |
| 399 GrProcessorKeyBuilder* b) { | 395 GrProcessorKeyBuilder* b) { |
| 400 const ShadowFP& shadowFP = proc.cast<ShadowFP>(); | 396 const ShadowFP& shadowFP = proc.cast<ShadowFP>(); |
| 401 b->add32(shadowFP.fNumNonAmbLights); | 397 b->add32(shadowFP.fNumNonAmbLights); |
| 402 int isPL = 0; | 398 int isPL = 0; |
| 403 for (int i = 0; i < SkShadowShader::kMaxNonAmbientLights; i++) { | 399 for (int i = 0; i < SkShadowShader::kMaxNonAmbientLights; i++) { |
| 404 isPL = isPL | ((shadowFP.fIsPointLight[i] ? 1 : 0) << i); | 400 isPL = isPL | ((shadowFP.fIsPointLight[i] ? 1 : 0) << i); |
| 405 } | 401 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 417 pdman.set3fv(fLightDirOrPosUni[i], 1, &lightDirOrPos.fX); | 413 pdman.set3fv(fLightDirOrPosUni[i], 1, &lightDirOrPos.fX); |
| 418 fLightDirOrPos[i] = lightDirOrPos; | 414 fLightDirOrPos[i] = lightDirOrPos; |
| 419 } | 415 } |
| 420 | 416 |
| 421 const SkColor3f& lightColor = shadowFP.lightColor(i); | 417 const SkColor3f& lightColor = shadowFP.lightColor(i); |
| 422 if (lightColor != fLightColor[i]) { | 418 if (lightColor != fLightColor[i]) { |
| 423 pdman.set3fv(fLightColorUni[i], 1, &lightColor.fX); | 419 pdman.set3fv(fLightColorUni[i], 1, &lightColor.fX); |
| 424 fLightColor[i] = lightColor; | 420 fLightColor[i] = lightColor; |
| 425 } | 421 } |
| 426 | 422 |
| 427 SkScalar lightIntensity = shadowFP.lightIntensity(i); | |
| 428 if (lightIntensity != fLightIntensity[i]) { | |
| 429 pdman.set1f(fLightIntensityUni[i], lightIntensity); | |
| 430 fLightIntensity[i] = lightIntensity; | |
| 431 } | |
| 432 | |
| 433 int depthMapWidth = shadowFP.depthMapWidth(i); | 423 int depthMapWidth = shadowFP.depthMapWidth(i); |
| 434 if (depthMapWidth != fDepthMapWidth[i]) { | 424 if (depthMapWidth != fDepthMapWidth[i]) { |
| 435 pdman.set1i(fDepthMapWidthUni[i], depthMapWidth); | 425 pdman.set1i(fDepthMapWidthUni[i], depthMapWidth); |
| 436 fDepthMapWidth[i] = depthMapWidth; | 426 fDepthMapWidth[i] = depthMapWidth; |
| 437 } | 427 } |
| 438 int depthMapHeight = shadowFP.depthMapHeight(i); | 428 int depthMapHeight = shadowFP.depthMapHeight(i); |
| 439 if (depthMapHeight != fDepthMapHeight[i]) { | 429 if (depthMapHeight != fDepthMapHeight[i]) { |
| 440 pdman.set1i(fDepthMapHeightUni[i], depthMapHeight); | 430 pdman.set1i(fDepthMapHeightUni[i], depthMapHeight); |
| 441 fDepthMapHeight[i] = depthMapHeight; | 431 fDepthMapHeight[i] = depthMapHeight; |
| 442 } | 432 } |
| 443 } | 433 } |
| 444 | 434 |
| 445 SkScalar biasingConstant = shadowFP.shadowParams().fBiasingConstant; | 435 SkScalar biasingConstant = shadowFP.shadowParams().fBiasingConstant; |
| 446 if (biasingConstant != fBiasingConstant) { | 436 if (biasingConstant != fBiasingConstant) { |
| 447 pdman.set1f(fBiasingConstantUni, biasingConstant); | 437 pdman.set1f(fBiasingConstantUni, biasingConstant); |
| 448 fBiasingConstant = biasingConstant; | 438 fBiasingConstant = biasingConstant; |
| 449 } | 439 } |
| 450 | 440 |
| 451 SkScalar minVariance = shadowFP.shadowParams().fMinVariance; | 441 SkScalar minVariance = shadowFP.shadowParams().fMinVariance; |
| 452 if (minVariance != fMinVariance) { | 442 if (minVariance != fMinVariance) { |
| 453 pdman.set1f(fMinVarianceUni, minVariance); | 443 // transform variance from pixel-scale to normalized scale |
| 454 fMinVariance = minVariance; | 444 pdman.set1f(fMinVarianceUni, minVariance / 65536.0f); |
| 445 fMinVariance = minVariance / 65536.0f; |
| 455 } | 446 } |
| 456 | 447 |
| 457 int width = shadowFP.width(); | 448 int width = shadowFP.width(); |
| 458 if (width != fWidth) { | 449 if (width != fWidth) { |
| 459 pdman.set1i(fWidthUni, width); | 450 pdman.set1i(fWidthUni, width); |
| 460 fWidth = width; | 451 fWidth = width; |
| 461 } | 452 } |
| 462 int height = shadowFP.height(); | 453 int height = shadowFP.height(); |
| 463 if (height != fHeight) { | 454 if (height != fHeight) { |
| 464 pdman.set1i(fHeightUni, height); | 455 pdman.set1i(fHeightUni, height); |
| 465 fHeight = height; | 456 fHeight = height; |
| 466 } | 457 } |
| 467 | 458 |
| 468 const SkColor3f& ambientColor = shadowFP.ambientColor(); | 459 const SkColor3f& ambientColor = shadowFP.ambientColor(); |
| 469 if (ambientColor != fAmbientColor) { | 460 if (ambientColor != fAmbientColor) { |
| 470 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX); | 461 pdman.set3fv(fAmbientColorUni, 1, &ambientColor.fX); |
| 471 fAmbientColor = ambientColor; | 462 fAmbientColor = ambientColor; |
| 472 } | 463 } |
| 473 } | 464 } |
| 474 | 465 |
| 475 private: | 466 private: |
| 476 SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights]; | 467 SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights]; |
| 477 GrGLSLProgramDataManager::UniformHandle | 468 GrGLSLProgramDataManager::UniformHandle |
| 478 fLightDirOrPosUni[SkShadowShader::kMaxNonAmbientLights]; | 469 fLightDirOrPosUni[SkShadowShader::kMaxNonAmbientLights]; |
| 479 | 470 |
| 480 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; | 471 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; |
| 481 GrGLSLProgramDataManager::UniformHandle | 472 GrGLSLProgramDataManager::UniformHandle |
| 482 fLightColorUni[SkShadowShader::kMaxNonAmbientLights]; | 473 fLightColorUni[SkShadowShader::kMaxNonAmbientLights]; |
| 483 | 474 |
| 484 SkScalar fLightIntensity[SkShadowShader::kMaxNonAmbientLights]; | |
| 485 GrGLSLProgramDataManager::UniformHandle | |
| 486 fLightIntensityUni[SkShadowShader::kMaxNonAmbientLights]; | |
| 487 | |
| 488 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; | 475 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; |
| 489 GrGLSLProgramDataManager::UniformHandle | 476 GrGLSLProgramDataManager::UniformHandle |
| 490 fDepthMapWidthUni[SkShadowShader::kMaxNonAmbientLights]; | 477 fDepthMapWidthUni[SkShadowShader::kMaxNonAmbientLights]; |
| 491 | 478 |
| 492 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; | 479 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; |
| 493 GrGLSLProgramDataManager::UniformHandle | 480 GrGLSLProgramDataManager::UniformHandle |
| 494 fDepthMapHeightUni[SkShadowShader::kMaxNonAmbientLights]; | 481 fDepthMapHeightUni[SkShadowShader::kMaxNonAmbientLights]; |
| 495 | 482 |
| 496 int fWidth; | 483 int fWidth; |
| 497 GrGLSLProgramDataManager::UniformHandle fWidthUni; | 484 GrGLSLProgramDataManager::UniformHandle fWidthUni; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 523 return fIsPointLight[i]; | 510 return fIsPointLight[i]; |
| 524 } | 511 } |
| 525 const SkVector3& lightDirOrPos(int i) const { | 512 const SkVector3& lightDirOrPos(int i) const { |
| 526 SkASSERT(i < fNumNonAmbLights); | 513 SkASSERT(i < fNumNonAmbLights); |
| 527 return fLightDirOrPos[i]; | 514 return fLightDirOrPos[i]; |
| 528 } | 515 } |
| 529 const SkVector3& lightColor(int i) const { | 516 const SkVector3& lightColor(int i) const { |
| 530 SkASSERT(i < fNumNonAmbLights); | 517 SkASSERT(i < fNumNonAmbLights); |
| 531 return fLightColor[i]; | 518 return fLightColor[i]; |
| 532 } | 519 } |
| 533 SkScalar lightIntensity(int i) const { | |
| 534 SkASSERT(i < fNumNonAmbLights); | |
| 535 return fLightIntensity[i]; | |
| 536 } | |
| 537 | |
| 538 int depthMapWidth(int i) const { | 520 int depthMapWidth(int i) const { |
| 539 SkASSERT(i < fNumNonAmbLights); | 521 SkASSERT(i < fNumNonAmbLights); |
| 540 return fDepthMapWidth[i]; | 522 return fDepthMapWidth[i]; |
| 541 } | 523 } |
| 542 int depthMapHeight(int i) const { | 524 int depthMapHeight(int i) const { |
| 543 SkASSERT(i < fNumNonAmbLights); | 525 SkASSERT(i < fNumNonAmbLights); |
| 544 return fDepthMapHeight[i]; | 526 return fDepthMapHeight[i]; |
| 545 } | 527 } |
| 546 int width() const {return fWidth; } | 528 int width() const {return fWidth; } |
| 547 int height() const {return fHeight; } | 529 int height() const {return fHeight; } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 558 return false; | 540 return false; |
| 559 } | 541 } |
| 560 | 542 |
| 561 if (fWidth != shadowFP.fWidth || fHeight != shadowFP.fHeight) { | 543 if (fWidth != shadowFP.fWidth || fHeight != shadowFP.fHeight) { |
| 562 return false; | 544 return false; |
| 563 } | 545 } |
| 564 | 546 |
| 565 for (int i = 0; i < fNumNonAmbLights; i++) { | 547 for (int i = 0; i < fNumNonAmbLights; i++) { |
| 566 if (fLightDirOrPos[i] != shadowFP.fLightDirOrPos[i] || | 548 if (fLightDirOrPos[i] != shadowFP.fLightDirOrPos[i] || |
| 567 fLightColor[i] != shadowFP.fLightColor[i] || | 549 fLightColor[i] != shadowFP.fLightColor[i] || |
| 568 fLightIntensity[i] != shadowFP.fLightIntensity[i] || | |
| 569 fIsPointLight[i] != shadowFP.fIsPointLight[i]) { | 550 fIsPointLight[i] != shadowFP.fIsPointLight[i]) { |
| 570 return false; | 551 return false; |
| 571 } | 552 } |
| 572 | 553 |
| 573 if (fDepthMapWidth[i] != shadowFP.fDepthMapWidth[i] || | 554 if (fDepthMapWidth[i] != shadowFP.fDepthMapWidth[i] || |
| 574 fDepthMapHeight[i] != shadowFP.fDepthMapHeight[i]) { | 555 fDepthMapHeight[i] != shadowFP.fDepthMapHeight[i]) { |
| 575 return false; | 556 return false; |
| 576 } | 557 } |
| 577 } | 558 } |
| 578 | 559 |
| 579 return true; | 560 return true; |
| 580 } | 561 } |
| 581 | 562 |
| 582 int fNumNonAmbLights; | 563 int fNumNonAmbLights; |
| 583 | 564 |
| 584 bool fIsPointLight[SkShadowShader::kMaxNonAmbientLights]; | 565 bool fIsPointLight[SkShadowShader::kMaxNonAmbientLights]; |
| 585 SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights]; | 566 SkVector3 fLightDirOrPos[SkShadowShader::kMaxNonAmbientLights]; |
| 586 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; | 567 SkColor3f fLightColor[SkShadowShader::kMaxNonAmbientLights]; |
| 587 SkScalar fLightIntensity[SkShadowShader::kMaxNonAmbientLights]; | |
| 588 GrTextureAccess fDepthMapAccess[SkShadowShader::kMaxNonAmbientLights]; | 568 GrTextureAccess fDepthMapAccess[SkShadowShader::kMaxNonAmbientLights]; |
| 589 sk_sp<GrTexture> fTexture[SkShadowShader::kMaxNonAmbientLights]; | 569 sk_sp<GrTexture> fTexture[SkShadowShader::kMaxNonAmbientLights]; |
| 590 | 570 |
| 591 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; | 571 int fDepthMapWidth[SkShadowShader::kMaxNonAmbientLights]; |
| 592 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; | 572 int fDepthMapHeight[SkShadowShader::kMaxNonAmbientLights]; |
| 593 | 573 |
| 594 int fHeight; | 574 int fHeight; |
| 595 int fWidth; | 575 int fWidth; |
| 596 | 576 |
| 597 SkShadowParams fShadowParams; | 577 SkShadowParams fShadowParams; |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 | 816 |
| 837 /////////////////////////////////////////////////////////////////////////////// | 817 /////////////////////////////////////////////////////////////////////////////// |
| 838 | 818 |
| 839 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader) | 819 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowShader) |
| 840 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl) | 820 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowShaderImpl) |
| 841 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 821 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| 842 | 822 |
| 843 /////////////////////////////////////////////////////////////////////////////// | 823 /////////////////////////////////////////////////////////////////////////////// |
| 844 | 824 |
| 845 #endif | 825 #endif |
| OLD | NEW |