| 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 |