Guest User

Untitled

a guest
Jan 28th, 2016
111
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //#version 330
  2. /*
  3. DoF with bokeh GLSL shader v2.4
  4. by Martins Upitis (martinsh) (devlog-martinsh.blogspot.com)
  5. ----------------------
  6. The shader is Blender Game Engine ready, but it should be quite simple to adapt for your engine.
  7. This work is licensed under a Creative Commons Attribution 3.0 Unported License.
  8. So you are free to share, modify and adapt it for your needs, and even use it for commercial use.
  9. I would also love to hear about a project you are using it.
  10. Have fun,
  11. Martins
  12. ----------------------
  13. changelog:
  14.  
  15. 2.4:
  16. - physically accurate DoF simulation calculated from "focalDepth" ,"focalLength", "f-stop" and "CoC" parameters.
  17. - option for artist controlled DoF simulation calculated only from "focalDepth" and individual controls for near and far blur
  18. - added "circe of confusion" (CoC) parameter in mm to accurately simulate DoF with different camera sensor or film sizes
  19. - cleaned up the code
  20. - some optimization
  21. 2.3:
  22. - new and physically little more accurate DoF
  23. - two extra input variables - focal length and aperture iris diameter
  24. - added a debug visualization of focus point and focal range
  25. 2.1:
  26. - added an option for pentagonal bokeh shape
  27. - minor fixes
  28. 2.0:
  29. - variable sample count to increase quality/performance
  30. - option to blur depth buffer to reduce hard edges
  31. - option to dither the samples with noise or pattern
  32. - bokeh chromatic aberration/fringing
  33. - bokeh bias to bring out bokeh edges
  34. - image thresholding to bring out highlights when image is out of focus
  35. */
  36.  
  37. uniform sampler2D Render;
  38. uniform sampler2D Tex0;
  39.  
  40. uniform vec2 PixelSize;
  41. uniform float width;
  42. uniform float height;
  43.  
  44. #define PI 3.14159265
  45.  
  46. //uniform variables from external script
  47.  
  48. /*
  49. uniform float focalDepth; //focal distance value in meters, but you may use autofocus option below
  50. uniform float focalLength; //focal length in mm
  51. uniform float fstop; //f-stop value
  52. uniform bool showFocus; //show debug focus point and focal range (red = focal point, green = focal range)
  53. */
  54. float focalDepth = 1.5;
  55. float focalLength = 12.0;
  56. float fstop = 2.0;
  57. bool showFocus = false;
  58.  
  59. /*
  60. make sure that these two values are the same for your camera, otherwise distances will be wrong.
  61. */
  62.  
  63. float znear = 0.1; //camera clipping start
  64. float zfar = 24000.0; //camera clipping end
  65.  
  66. //------------------------------------------
  67. //user variables
  68.  
  69. int samples = 4; //samples on the first ring
  70. int rings = 4; //ring count
  71.  
  72. bool manualdof = false; //manual dof calculation
  73. float ndofstart = 1.0; //near dof blur start
  74. float ndofdist = 2.0; //near dof blur falloff distance
  75. float fdofstart = 1.0; //far dof blur start
  76. float fdofdist = 3.0; //far dof blur falloff distance
  77.  
  78. float CoC = 0.03;//circle of confusion size in mm (35mm film = 0.03mm)
  79.  
  80. bool vignetting = false; //use optical lens vignetting?
  81. float vignout = 1.3; //vignetting outer border
  82. float vignin = 0.0; //vignetting inner border
  83. float vignfade = 22.0; //f-stops till vignete fades
  84.  
  85. bool autofocus = true; //use autofocus in shader? disable if you use external focalDepth value
  86. vec2 focus = vec2(0.5,0.5); // autofocus point on screen (0.0,0.0 - left lower corner, 1.0,1.0 - upper right)
  87. float maxblur = 1.0; //clamp value of max blur (0.0 = no blur,1.0 default)
  88.  
  89. float threshold = 1.1; //highlight threshold;
  90. float gain = 0.0; //highlight gain;
  91.  
  92. float bias = 0.5; //bokeh edge bias
  93. float fringe = 0.7; //bokeh chromatic aberration/fringing
  94.  
  95. bool noise = true; //use noise instead of pattern for sample dithering
  96. float namount = 0.0001; //dither amount
  97.  
  98. bool depthblur = false; //blur the depth buffer?
  99. float dbsize = 1.25; //depthblursize
  100.  
  101. /*
  102. next part is experimental
  103. not looking good with small sample and ring count
  104. looks okay starting from samples = 4, rings = 4
  105. */
  106.  
  107. bool pentagon = false; //use pentagon as bokeh shape?
  108. float feather = 0.4; //pentagon shape feather
  109.  
  110. //------------------------------------------
  111.  
  112.  
  113. float penta(vec2 coords) //pentagonal shape
  114. {
  115. float scale = float(rings) - 1.3;
  116. vec4 HS0 = vec4( 1.0, 0.0, 0.0, 1.0);
  117. vec4 HS1 = vec4( 0.309016994, 0.951056516, 0.0, 1.0);
  118. vec4 HS2 = vec4(-0.809016994, 0.587785252, 0.0, 1.0);
  119. vec4 HS3 = vec4(-0.809016994,-0.587785252, 0.0, 1.0);
  120. vec4 HS4 = vec4( 0.309016994,-0.951056516, 0.0, 1.0);
  121. vec4 HS5 = vec4( 0.0 ,0.0 , 1.0, 1.0);
  122.  
  123. vec4 one = vec4( 1.0 );
  124.  
  125. vec4 P = vec4((coords),vec2(scale, scale));
  126.  
  127. vec4 dist = vec4(0.0);
  128. float inorout = -4.0;
  129.  
  130. dist.x = dot( P, HS0 );
  131. dist.y = dot( P, HS1 );
  132. dist.z = dot( P, HS2 );
  133. dist.w = dot( P, HS3 );
  134.  
  135. dist = smoothstep( -feather, feather, dist );
  136.  
  137. inorout += dot( dist, one );
  138.  
  139. dist.x = dot( P, HS4 );
  140. dist.y = HS5.w - abs( P.z );
  141.  
  142. dist = smoothstep( -feather, feather, dist );
  143. inorout += dist.x;
  144.  
  145. return clamp( inorout, 0.0, 1.0 );
  146. }
  147.  
  148. float bdepth(vec2 coords) //blurring depth
  149. {
  150. float d = 0.0;
  151. float kernel[9];
  152. vec2 offset[9];
  153.  
  154. vec2 wh = PixelSize * dbsize;
  155.  
  156. offset[0] = vec2(-wh.x,-wh.y);
  157. offset[1] = vec2( 0.0, -wh.y);
  158. offset[2] = vec2( wh.x -wh.y);
  159.  
  160. offset[3] = vec2(-wh.x, 0.0);
  161. offset[4] = vec2( 0.0, 0.0);
  162. offset[5] = vec2( wh.x, 0.0);
  163.  
  164. offset[6] = vec2(-wh.x, wh.y);
  165. offset[7] = vec2( 0.0, wh.y);
  166. offset[8] = vec2( wh.x, wh.y);
  167.  
  168. kernel[0] = 1.0/16.0; kernel[1] = 2.0/16.0; kernel[2] = 1.0/16.0;
  169. kernel[3] = 2.0/16.0; kernel[4] = 4.0/16.0; kernel[5] = 2.0/16.0;
  170. kernel[6] = 1.0/16.0; kernel[7] = 2.0/16.0; kernel[8] = 1.0/16.0;
  171.  
  172.  
  173. for( int i=0; i<9; i++ )
  174. {
  175. float tmp = texture2D(Tex0, coords + offset[i]).r;
  176. d += tmp * kernel[i];
  177. }
  178.  
  179. return d;
  180. }
  181.  
  182.  
  183. vec3 color(vec2 coords,float blur) //processing the sample
  184. {
  185. vec3 col = vec3(0.0);
  186.  
  187. col.r = texture2D(Render,coords + vec2(0.0,1.0)*PixelSize*fringe*blur).r;
  188. col.g = texture2D(Render,coords + vec2(-0.866,-0.5)*PixelSize*fringe*blur).g;
  189. col.b = texture2D(Render,coords + vec2(0.866,-0.5)*PixelSize*fringe*blur).b;
  190.  
  191. vec3 lumcoeff = vec3(0.299,0.587,0.114);
  192. float lum = dot(col.rgb, lumcoeff);
  193. float thresh = max((lum-threshold)*gain, 0.0);
  194. return col+mix(vec3(0.0),col,thresh*blur);
  195. }
  196.  
  197. vec2 rand(vec2 coord) //generating noise/pattern texture for dithering
  198. {
  199. float noiseX = ((fract(1.0-coord.s*(width/2.0))*0.25)+(fract(coord.t*(height/2.0))*0.75))*2.0-1.0;
  200. float noiseY = ((fract(1.0-coord.s*(width/2.0))*0.75)+(fract(coord.t*(height/2.0))*0.25))*2.0-1.0;
  201.  
  202. if (noise)
  203. {
  204. noiseX = clamp(fract(sin(dot(coord ,vec2(12.9898,78.233))) * 43758.5453),0.0,1.0)*2.0-1.0;
  205. noiseY = clamp(fract(sin(dot(coord ,vec2(12.9898,78.233)*2.0)) * 43758.5453),0.0,1.0)*2.0-1.0;
  206. }
  207. return vec2(noiseX,noiseY);
  208. }
  209.  
  210. vec3 debugFocus(vec3 col, float blur, float depth)
  211. {
  212. float edge = 0.002*depth; //distance based edge smoothing
  213. float m = clamp(smoothstep(0.0,edge,blur),0.0,1.0);
  214. float e = clamp(smoothstep(1.0-edge,1.0,blur),0.0,1.0);
  215.  
  216. col = mix(col,vec3(1.0,0.5,0.0),(1.0-m)*0.6);
  217. col = mix(col,vec3(0.0,0.5,1.0),((1.0-e)-(1.0-m))*0.2);
  218.  
  219. return col;
  220. }
  221.  
  222. float linearize(float depth)
  223. {
  224. return -zfar * znear / (depth * (zfar - znear) - zfar);
  225. }
  226.  
  227. float vignette()
  228. {
  229. float dist = distance(gl_TexCoord[3].xy, vec2(0.5,0.5));
  230. dist = smoothstep(vignout+(fstop/vignfade), vignin+(fstop/vignfade), dist);
  231. return clamp(dist,0.0,1.0);
  232. }
  233.  
  234. void main()
  235. {
  236. //scene depth calculation
  237. vec2 texcoord = gl_TexCoord[0].xy;
  238. float depth = linearize(texture2D(Tex0,texcoord.xy).x);
  239.  
  240. if (depthblur)
  241. {
  242. depth = linearize(bdepth(texcoord.xy));
  243. }
  244.  
  245. //focal plane calculation
  246.  
  247. float fDepth = focalDepth;
  248.  
  249. if (autofocus)
  250. {
  251. fDepth = linearize(texture2D(Tex0,focus).x);
  252. }
  253.  
  254. //dof blur factor calculation
  255.  
  256. float blur = 0.0;
  257.  
  258. if (manualdof)
  259. {
  260. float a = depth-fDepth; //focal plane
  261. float b = (a-fdofstart)/fdofdist; //far DoF
  262. float c = (-a-ndofstart)/ndofdist; //near Dof
  263. blur = (a>0.0)?b:c;
  264. }
  265.  
  266. else
  267. {
  268. float f = focalLength; //focal length in mm
  269. float d = fDepth*1000.0; //focal plane in mm
  270. float o = depth*1000.0; //depth in mm
  271.  
  272. float a = (o*f)/(o-f);
  273. float b = (d*f)/(d-f);
  274. float c = (d-f)/(d*fstop*CoC);
  275.  
  276. blur = abs(a-b)*c;
  277. }
  278.  
  279. blur = clamp(blur,0.0,1.0);
  280.  
  281. // calculation of pattern for ditering
  282.  
  283. vec2 noise = rand(texcoord.xy)*namount*blur;
  284.  
  285. // getting blur x and y step factor
  286.  
  287. float w = PixelSize.x*blur*maxblur+noise.x;
  288. float h = PixelSize.y*blur*maxblur+noise.y;
  289.  
  290. // calculation of final color
  291.  
  292. vec3 col = vec3(0.0);
  293.  
  294. if(blur < 0.05) //some optimization thingy
  295. {
  296. col = texture2D(Render, texcoord.xy).rgb;
  297. }
  298.  
  299. else
  300. {
  301. col = texture2D(Render, texcoord.xy).rgb;
  302. float s = 1.0;
  303. int ringsamples;
  304.  
  305. for (int i = 1; i <= rings; i += 1)
  306. {
  307. ringsamples = i * samples;
  308.  
  309. for (int j = 0 ; j < ringsamples ; j += 1)
  310. {
  311. float step = PI*2.0 / float(ringsamples);
  312. float pw = (cos(float(j)*step)*float(i));
  313. float ph = (sin(float(j)*step)*float(i));
  314. float p = 1.0;
  315. if (pentagon)
  316. {
  317. p = penta(vec2(pw,ph));
  318. }
  319. col += color(texcoord.xy + vec2(pw*w,ph*h),blur)*mix(1.0,(float(i))/(float(rings)),bias)*p;
  320. s += 1.0*mix(1.0,(float(i))/(float(rings)),bias)*p;
  321. }
  322. }
  323. col /= s; //divide by sample count
  324. }
  325.  
  326. if (showFocus)
  327. {
  328. col = debugFocus(col, blur, depth);
  329. }
  330.  
  331. if (vignetting)
  332. {
  333. col *= vignette();
  334. }
  335.  
  336. //gl_FragColor.rgb = texture(Render, texcoord);
  337. gl_FragColor.rgb = col;
  338. gl_FragColor.a = 1.0;
  339. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×