 
 void main(void)
 {
+  phi = random(gl_FragCoord.xy)*TWOPI;
+  
   // Get base fragment color, which will be attenuated based on visible light
   vec4 color = gl_Color * texture2D(osgShadow_baseTexture, gl_TexCoord[0].xy);
   

  float uBlockerDistGuess = Depth2Distance(texture2D(osgShadow_umbraDepthTexture, uTexCoord.xy).r, osgShadow_umbraZNearFarInv);
  uBlockerDistGuess = max(uBlockerDistGuess, uTexCoord.w);
  uBlockerDistGuess = min(uBlockerDistGuess, 1.0/osgShadow_umbraZNearFarInv.y);
  vec3 uCoverageCircle = ShadowCoverageCircle(uTexCoordNDC, uTexCoord.w, uBlockerDistGuess, osgShadow_lightDistance + osgShadow_umbraDistance, 1.0);
  vec2 uBlockers = SearchBlockers(osgShadow_umbraDepthTexture, uTexCoord, uCoverageCircle, osgShadow_umbraZNearFarInv, 1.0, numBlockerSamples);
  
  // Penumbra blocker search (using penumbra near plane and adjusting for z increasing towards light)
  float pBlockerDistGuess = Depth2Distance(texture2D(osgShadow_penumbraDepthTexture, pTexCoord.xy).r, osgShadow_penumbraZNearFarInv);
  pBlockerDistGuess = min(pBlockerDistGuess, pTexCoord.w);
  pBlockerDistGuess = max(pBlockerDistGuess, 1.0/osgShadow_penumbraZNearFarInv.x);
  vec3 pCoverageCircle = ShadowCoverageCircle(pTexCoordNDC, -pTexCoord.w, -pBlockerDistGuess, osgShadow_lightDistance - osgShadow_penumbraDistance, -1.0);
  vec2 pBlockers = SearchBlockers(osgShadow_penumbraDepthTexture, pTexCoord, pCoverageCircle, osgShadow_penumbraZNearFarInv, -1.0, numBlockerSamples);
  
  // Adjust umbra blocker distance based on info from penumbra blocker search

  //uVisibility = pVisibility;
  //pVisibility = uVisibility;
  
  uVisibility = 1.0 - uCoverageCircle.w + uCoverageCircle.w*uVisibility;
  pVisibility = 1.0 - pCoverageCircle.w + pCoverageCircle.w*pVisibility;

  float minVisibility = osgShadow_ambientBias.x;
  float shadowedVisibility = 0.5 * (uVisibility + pVisibility);
  if(shadowedVisibility == 1.0) shadowedVisibility -= 0.5*fwidth(shadowedVisibility);
