Depth of field effect


   newCoord = vTexCoord + sampleDist0 * samples11;
   dCheck = texture2D(depth, newCoord);
   if (abs(dCheck.r-d.r)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;

   }
   sum /= additionCount;
  sum.a = d.r*2;
  gl_FragColor =  sum;



This is it, my idea. It works well! :) Both transparent textures plus the 'depth texture check'. :) Still in need of some paramters/cleanup before i'll release the code. (Take note of the near tree trunk/branch/foliage edges - they don't mix together with far away parts - bleeding annihilated.)

Okay, ready to release! :slight_smile: Here is the topic with the source/shaders:



http://www.jmonkeyengine.com/jmeforum/index.php?topic=8985.0

<Removed: wrong topic :smiley: >



Small sidenote on the Crysis screenshot earlier though:



:smiley: Seems the question is not as simple.



The current DoF is implemented on distance. The further the mesh, the higher the blur.

(after a certain distance threshold is reached)



The DoF in Crysis does not seem to be distance implemented. (In that particular screenshot)

(Or it is incorrectly implemented)



The blurring at the base of the gun and the edge of the vision around the treeline suggest a blurring from camera -> small distance from camera, & far treeline to beyond.



Problem is that (in realword measurements), if we look at where the blurring starts on the ground (soldier lying on the ground is blurred), and where it ends on the gun (barrel is not blurred, base is), the guns barrel must start approx where the soldier lies, ie. be more than a couple of meters long.



But if we look at the screenshot starting from the assumption that the blurring is set to a static portion of the screen, (set amount of pixel x/y), the screenshot seems to be correct. (or it could be a combination of distance and set pixels, because the treeline seems to require distance to blur correctly)





To sum up:

  • MrCoder is right, the effect is possible.
  • To set a static part of the screen to be blurred is not possible at the moment, but should not be to hard to implement.
  • The code is currently not setup to blur up to a certain point, not blur, and then blur again from a certain threshold. But again, this is not hard to implement (simpler than the static part).



    To recreate the Crysis screenshot, implement a blurring in reverse: instead of saying from which threshold there should be blurring, specify two thresholds where you do not want any blurring in between. A start & end threshold for a clear view, if you will. (blurring up to and from)


Well, in jcrpg's SVN I've added a week or more ago - more or less what you are talking about although I don't use it for anything.



The trick what I added was to use red and green color of the depth texture to separate blurring of foreground blur / backround blur parts. Between them there's no blurring. You can specify foreground blur end/ background blur start …or something like that :smiley:



http://javacrpg.svn.sourceforge.net/viewvc/javacrpg/trunk/jcrpg/src/org/jcrpg/threed/jme/effects/shader/dof_1_depth_3.frag?view=markup



uniform vec4 dofParams;

varying float depth; // in view space

uniform sampler2D mainTexture;

void main()
{
   float fCloser;
   float fFurther;
   vec4 texCol = texture2D(mainTexture,gl_TexCoord[0].st);
   
   if (depth < dofParams.y)
   {
      // scale depth value between near blur distance and focal distance to
      // [-1, 0] range
      fCloser = ( ((1.0 - depth) + dofParams.y) / (dofParams.y - dofParams.x) );
      fFurther = 0.0;
   }
   else
   {
      fFurther = ( ( ( depth - 1.0) - dofParams.y) / (dofParams.z - dofParams.y) );
      fCloser = 0;
      // scale depth value between focal distance and far blur distance to
      // [0, 1] range
      //f = (depth - dofParams.y) / (dofParams.z - dofParams.y);
      // clamp the far blur to a maximum blurriness
      //f = clamp(f, 0.0, dofParams.w);
   }

   // scale and bias into [0, 1] range
   vec4 sum;  //= vec4(0.5*fCloser + 0.5, 0.5*fFurther + 0.5, 0.0, 0.0);
   sum.r = fCloser;
   sum.g = fFurther;
   sum.a = texCol.a;
   sum.r += 0.001; // setting r a bit higher to let dof_2 shader know this is a rendered spatial pixel, not background
   gl_FragColor = sum;
}



http://javacrpg.svn.sourceforge.net/viewvc/javacrpg/trunk/jcrpg/src/org/jcrpg/threed/jme/effects/shader/dof_3_dof_3.frag?revision=1479


uniform float sampleDist0;
uniform sampler2D scene;            // full resolution image
uniform sampler2D depth;            // full resolution image with depth values

varying vec2 vTexCoord;


void main()
{

   vec2 samples00 = vec2(-0.326212, -0.405805);
   vec2 samples01 = vec2(-0.840144, -0.073580);
   vec2 samples02 = vec2(-0.695914,  0.457137);
   vec2 samples03 = vec2(-0.203345,  0.620716);
   vec2 samples04 = vec2( 0.962340, -0.194983);
   vec2 samples05 = vec2( 0.473434, -0.480026);
   vec2 samples06 = vec2( 0.519456,  0.767022);
   vec2 samples07 = vec2( 0.185461, -0.893124);
   vec2 samples08 = vec2( 0.507431,  0.064425);
   vec2 samples09 = vec2( 0.896420,  0.412458);
   vec2 samples10 = vec2(-0.321940, -0.932615);
   vec2 samples11 = vec2(-0.791559, -0.597705);

   vec2 newCoord;
   vec4 sum = texture2D(scene, vTexCoord);

   
   vec4 d = texture2D(depth, vTexCoord);
 
  if (d.r>0.001) // in the scenario, but not the closest parts which should be kept alpha = 0 (see else)...
  {
 
   sampleDist0 = (d.r)*sampleDist0;
 
   float additionCount = 1;
   
   vec4 dCheck = 0;
   newCoord = vTexCoord + sampleDist0 * samples00;
   dCheck = texture2D(depth, newCoord);
   // if out of rendered spatials pixel (background - r = zero) or near, mix it
   if (dCheck.r==0 || abs(dCheck.r-d.r)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }
  
   newCoord = vTexCoord + sampleDist0 * samples01;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.r==0 || abs(dCheck.r-d.r)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples02;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.r==0 || abs(dCheck.r-d.r)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples03;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.r==0 || abs(dCheck.r-d.r)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples04;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.r==0 || abs(dCheck.r-d.r)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples05;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.r==0 || abs(dCheck.r-d.r)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples06;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.r==0 || abs(dCheck.r-d.r)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples07;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.r==0 || abs(dCheck.r-d.r)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples08;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.r==0 || abs(dCheck.r-d.r)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples09;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.r==0 || abs(dCheck.r-d.r)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples10;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.r==0 || abs(dCheck.r-d.r)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples11;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.r==0 || abs(dCheck.r-d.r)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   sum /= additionCount;
   sum.a = d.r*2;
   gl_FragColor =  sum;
  
   } else
  if (d.g>0.001) // in the scenario, but not the closest parts which should be kept alpha = 0 (see else)...
  {
 
   sampleDist0 = (d.g)*sampleDist0;
 
   float additionCount = 1;
   
   vec4 dCheck = 0;
   newCoord = vTexCoord + sampleDist0 * samples00;
   dCheck = texture2D(depth, newCoord);
   // if out of rendered spatials pixel (background - r = zero) or near, mix it
   if (dCheck.g==0 || abs(dCheck.g-d.g)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }
  
   newCoord = vTexCoord + sampleDist0 * samples01;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.g==0 || abs(dCheck.g-d.g)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples02;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.g==0 || abs(dCheck.g-d.g)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples03;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.g==0 || abs(dCheck.g-d.g)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples04;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.g==0 || abs(dCheck.g-d.g)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples05;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.g==0 || abs(dCheck.g-d.g)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples06;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.g==0 || abs(dCheck.g-d.g)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples07;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.g==0 || abs(dCheck.g-d.g)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples08;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.g==0 || abs(dCheck.g-d.g)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples09;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.g==0 || abs(dCheck.g-d.g)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples10;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.g==0 || abs(dCheck.g-d.g)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   newCoord = vTexCoord + sampleDist0 * samples11;
   dCheck = texture2D(depth, newCoord);
   if (dCheck.g==0 || abs(dCheck.g-d.g)<0.1)
   {
       sum += texture2D(scene, newCoord);
       additionCount = additionCount+1;
   }

   sum /= additionCount;
   sum.a = d.g*2;
   gl_FragColor =  sum;
  
   } else
   {
      sum.a = 0;
    gl_FragColor =  sum;
   }
      
}