93 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			93 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								// DoF with bokeh GLSL shader by Martins Upitis (martinsh) (devlog-martinsh.blogspot.com)
							 | 
						||
| 
								 | 
							
								// Creative Commons Attribution 3.0 Unported License
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "compiled.inc"
							 | 
						||
| 
								 | 
							
								#include "std/math.glsl"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// const float compoDOFDistance = 10.0; // Focal distance value in meters
							 | 
						||
| 
								 | 
							
								// const float compoDOFLength = 160.0; // Focal length in mm 18-200
							 | 
						||
| 
								 | 
							
								// const float compoDOFFstop = 128.0; // F-stop value
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const int samples = 6; // Samples on the first ring
							 | 
						||
| 
								 | 
							
								const int rings = 6; // Ring count
							 | 
						||
| 
								 | 
							
								const vec2 focus = vec2(0.5, 0.5);
							 | 
						||
| 
								 | 
							
								const float coc = 0.11; // Circle of confusion size in mm (35mm film = 0.03mm)
							 | 
						||
| 
								 | 
							
								const float maxblur = 1.0;
							 | 
						||
| 
								 | 
							
								const float threshold = 0.5; // Highlight threshold
							 | 
						||
| 
								 | 
							
								const float gain = 2.0; // Highlight gain
							 | 
						||
| 
								 | 
							
								const float bias = 0.5; // Bokeh edge bias
							 | 
						||
| 
								 | 
							
								const float fringe = 0.7; // Bokeh chromatic aberration/fringing
							 | 
						||
| 
								 | 
							
								const float namount = 0.0001; // Dither amount
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								vec3 color(vec2 coords, const float blur, const sampler2D tex, const vec2 texStep) {
							 | 
						||
| 
								 | 
							
									vec3 col = vec3(0.0);
							 | 
						||
| 
								 | 
							
									col.r = textureLod(tex, coords + vec2(0.0, 1.0) * texStep * fringe * blur, 0.0).r;
							 | 
						||
| 
								 | 
							
									col.g = textureLod(tex, coords + vec2(-0.866, -0.5) * texStep * fringe * blur, 0.0).g;
							 | 
						||
| 
								 | 
							
									col.b = textureLod(tex, coords + vec2(0.866, -0.5) * texStep * fringe * blur, 0.0).b;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									const vec3 lumcoeff = vec3(0.299, 0.587, 0.114);
							 | 
						||
| 
								 | 
							
									float lum = dot(col.rgb, lumcoeff);
							 | 
						||
| 
								 | 
							
									float thresh = max((lum - threshold) * gain, 0.0);
							 | 
						||
| 
								 | 
							
									return col + mix(vec3(0.0), col, thresh * blur);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								vec3 dof(
							 | 
						||
| 
								 | 
							
									const vec2 texCoord, 
							 | 
						||
| 
								 | 
							
									const float gdepth, 
							 | 
						||
| 
								 | 
							
									const sampler2D tex, 
							 | 
						||
| 
								 | 
							
									const sampler2D gbufferD, 
							 | 
						||
| 
								 | 
							
									const vec2 texStep, 
							 | 
						||
| 
								 | 
							
									const vec2 cameraProj, 
							 | 
						||
| 
								 | 
							
									const bool autoFocus, 
							 | 
						||
| 
								 | 
							
									const float DOFDistance, 
							 | 
						||
| 
								 | 
							
									const float DOFLength, 
							 | 
						||
| 
								 | 
							
									const float DOFFStop) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									float depth = linearize(gdepth, cameraProj);
							 | 
						||
| 
								 | 
							
									float fDepth = 0.0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if(autoFocus) {
							 | 
						||
| 
								 | 
							
										fDepth = linearize(textureLod(gbufferD, focus, 0.0).r * 2.0 - 1.0, cameraProj);
							 | 
						||
| 
								 | 
							
									} else {
							 | 
						||
| 
								 | 
							
										fDepth = DOFDistance;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									float f = DOFLength; // Focal length in mm
							 | 
						||
| 
								 | 
							
									float d = fDepth * 1000.0; // Focal plane in mm
							 | 
						||
| 
								 | 
							
									float o = depth * 1000.0; // Depth in mm
							 | 
						||
| 
								 | 
							
									float a = (o * f) / (o - f); 
							 | 
						||
| 
								 | 
							
									float b = (d * f) / (d - f); 
							 | 
						||
| 
								 | 
							
									float c = (d - f) / (d * DOFFStop * coc); 
							 | 
						||
| 
								 | 
							
									float blur = abs(a - b) * c;
							 | 
						||
| 
								 | 
							
									blur = clamp(blur, 0.0, 1.0);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									vec2 noise = rand2(texCoord) * namount * blur;
							 | 
						||
| 
								 | 
							
									float w = (texStep.x) * blur * maxblur + noise.x;
							 | 
						||
| 
								 | 
							
									float h = (texStep.y) * blur * maxblur + noise.y;
							 | 
						||
| 
								 | 
							
									vec3 col = vec3(0.0);
							 | 
						||
| 
								 | 
							
									if (blur < 0.05) {
							 | 
						||
| 
								 | 
							
										col = textureLod(tex, texCoord, 0.0).rgb;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else {
							 | 
						||
| 
								 | 
							
										col = textureLod(tex, texCoord, 0.0).rgb;
							 | 
						||
| 
								 | 
							
										float s = 1.0;
							 | 
						||
| 
								 | 
							
										int ringsamples;
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
										for (int i = 1; i <= rings; ++i) {   
							 | 
						||
| 
								 | 
							
											ringsamples = i * samples;
							 | 
						||
| 
								 | 
							
											for (int j = 0 ; j < ringsamples; ++j) {
							 | 
						||
| 
								 | 
							
												float step = PI2 / float(ringsamples);
							 | 
						||
| 
								 | 
							
												float pw = (cos(float(j) * step) * float(i));
							 | 
						||
| 
								 | 
							
												float ph = (sin(float(j) * step) * float(i));
							 | 
						||
| 
								 | 
							
												float p = 1.0;
							 | 
						||
| 
								 | 
							
												// if (pentagon) p = penta(vec2(pw, ph));
							 | 
						||
| 
								 | 
							
												col += color(texCoord + vec2(pw * w, ph * h), blur, tex, texStep) * mix(1.0, (float(i)) / (float(rings)), bias) * p;  
							 | 
						||
| 
								 | 
							
												s += 1.0 * mix(1.0, (float(i)) / (float(rings)), bias) * p;  
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										col /= s;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return col;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 |