[Bf-blender-cvs] [79b8540] viewport_experiments: First stage of better dof, downsample buffer by half.

Antony Riakiotakis noreply at git.blender.org
Tue Jan 6 17:57:41 CET 2015


Commit: 79b8540e66b86b0f66ddd1edb9bb36867ed86fa1
Author: Antony Riakiotakis
Date:   Tue Jan 6 17:57:25 2015 +0100
Branches: viewport_experiments
https://developer.blender.org/rB79b8540e66b86b0f66ddd1edb9bb36867ed86fa1

First stage of better dof, downsample buffer by half.

===================================================================

M	source/blender/gpu/intern/gpu_compositing.c
M	source/blender/gpu/shaders/gpu_shader_fx_dof_high_frag.glsl
M	source/blender/gpu/shaders/gpu_shader_fx_dof_high_vert.glsl
M	source/blender/gpu/shaders/gpu_shader_fx_lib.glsl

===================================================================

diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c
index d46cff4..13596a2 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -264,7 +264,7 @@ bool GPU_initialize_fx_passes(GPUFX *fx, rcti *rect, rcti *scissor_rect, int fxf
 
 	/* disable effects if no options passed for them */
 	if (!options->dof_options  || (options->dof_options->dof_quality_mode == DOF_QUALITY_HIGH)) {
-		fxflags &= ~GPU_FX_DEPTH_OF_FIELD;
+		//fxflags &= ~GPU_FX_DEPTH_OF_FIELD;
 	}
 	if (!options->ssao_options || options->ssao_options->ssao_num_samples < 1) {
 		fxflags &= ~GPU_FX_SSAO;
@@ -637,7 +637,7 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str
 			dof_shader_pass5 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE, is_persp);
 
 			/* error occured, restore framebuffers and return */
-			if (!dof_shader_pass1 || !dof_shader_pass2 || !dof_shader_pass3 || !dof_shader_pass4 || !dof_shader_pass5) {
+			if (!(dof_shader_pass1 && dof_shader_pass2 && dof_shader_pass3 && dof_shader_pass4 && dof_shader_pass5)) {
 				GPU_framebuffer_texture_unbind(fx->gbuffer, NULL);
 				GPU_framebuffer_restore();
 				return false;
@@ -880,23 +880,119 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, str
 		}
 		/* high quality diffusion solver */
 		else {
-			GPUShader *dof_shader_pass1, *dof_shader_pass2, *dof_shader_pass3, *dof_shader_pass4;
+			GPUShader *dof_shader_pass1, *dof_shader_pass2;//, *dof_shader_pass3, *dof_shader_pass4;
 
-			/* DOF effect has many passes but most of them are performed on a texture whose dimensions are 4 times less than the original
-			 * (16 times lower than original screen resolution). Technique used is not very exact but should be fast enough and is based
-			 * on "Practical Post-Process Depth of Field" see http://http.developer.nvidia.com/GPUGems3/gpugems3_ch28.html */
 			dof_shader_pass1 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_DOWNSAMPLE_HALF, is_persp);
 			dof_shader_pass2 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_DOWNSAMPLE_HALF_COC, is_persp);
-			dof_shader_pass3 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE, is_persp);
-			dof_shader_pass4 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR, is_persp);
+			//dof_shader_pass3 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_BLUR, is_persp);
+			//dof_shader_pass4 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_FINAL_COMBINE, is_persp);
 
 			/* error occured, restore framebuffers and return */
-			if (!dof_shader_pass1) {
+			if (!(dof_shader_pass1 && dof_shader_pass2)) {
 				GPU_framebuffer_texture_unbind(fx->gbuffer, NULL);
 				GPU_framebuffer_restore();
 				return false;
 			}
+			
+			/* downsample pass */
+			{
+				int invrendertargetdim_uniform, color_uniform, depth_uniform, dof_uniform;
+				int viewvecs_uniform;
+
+				float invrendertargetdim[2] = {1.0f / fx->gbuffer_dim[0], 1.0f / fx->gbuffer_dim[1]};
+
+				dof_uniform = GPU_shader_get_uniform(dof_shader_pass1, "dof_params");
+				invrendertargetdim_uniform = GPU_shader_get_uniform(dof_shader_pass1, "invrendertargetdim");
+				color_uniform = GPU_shader_get_uniform(dof_shader_pass1, "colorbuffer");
+				depth_uniform = GPU_shader_get_uniform(dof_shader_pass1, "depthbuffer");
+				viewvecs_uniform = GPU_shader_get_uniform(dof_shader_pass1, "viewvecs");
+
+				GPU_shader_bind(dof_shader_pass1);
+
+				GPU_shader_uniform_vector(dof_shader_pass1, dof_uniform, 4, 1, dof_params);
+				GPU_shader_uniform_vector(dof_shader_pass1, invrendertargetdim_uniform, 2, 1, invrendertargetdim);
+				GPU_shader_uniform_vector(dof_shader_pass1, viewvecs_uniform, 4, 3, viewvecs[0]);
+
+				GPU_texture_bind(src, numslots++);
+				GPU_shader_uniform_texture(dof_shader_pass1, color_uniform, src);
+
+				GPU_texture_bind(fx->depth_buffer, numslots++);
+				GPU_depth_texture_mode(fx->depth_buffer, false, true);
+				GPU_shader_uniform_texture(dof_shader_pass1, depth_uniform, fx->depth_buffer);
+
+				/* target is the downsampled coc buffer */
+				GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_half_downsampled, 0, NULL);
+				/* binding takes care of setting the viewport to the downsampled size */
+				GPU_texture_bind_as_framebuffer(fx->dof_half_downsampled);
+
+				glDisable(GL_DEPTH_TEST);
+				glDrawArrays(GL_QUADS, 0, 4);
+				/* disable bindings */
+				GPU_texture_unbind(src);
+				GPU_depth_texture_mode(fx->depth_buffer, true, false);
+				GPU_texture_unbind(fx->depth_buffer);
+
+				GPU_framebuffer_texture_unbind(fx->gbuffer, fx->dof_half_downsampled);
+				GPU_framebuffer_texture_detach(fx->dof_half_downsampled);
+				numslots = 0;
+				
+			}
+
+			/* final pass, merge blurred layers according to final calculated coc */
+			{
+				int half_downsampled_uniform, nearfar_uniform;
+				
+				GPU_shader_bind(dof_shader_pass2);
 
+				//GPU_shader_uniform_vector(dof_shader_pass2, dof_uniform, 4, 1, dof_params);
+				//GPU_shader_uniform_vector(dof_shader_pass2, invrendertargetdim_uniform, 2, 1, invrendertargetdim);
+				//GPU_shader_uniform_vector(dof_shader_pass2, viewvecs_uniform, 4, 3, viewvecs[0]);
+
+				//GPU_texture_bind(src, numslots++);
+				//GPU_shader_uniform_texture(dof_shader_pass5, original_uniform, src);
+
+				half_downsampled_uniform = GPU_shader_get_uniform(dof_shader_pass2, "colorbuffer");
+				nearfar_uniform = GPU_shader_get_uniform(dof_shader_pass2, "cocbuffer");
+				
+				GPU_texture_bind(fx->dof_half_downsampled, numslots++);
+				GPU_shader_uniform_texture(dof_shader_pass2, half_downsampled_uniform, fx->dof_half_downsampled);
+
+				GPU_texture_bind(fx->dof_nearfar_coc[0], numslots++);
+				GPU_shader_uniform_texture(dof_shader_pass2, nearfar_uniform, fx->dof_nearfar_coc[0]);
+
+				/* if this is the last pass, prepare for rendering on the frambuffer */
+				if (passes_left-- == 1) {
+					GPU_framebuffer_texture_unbind(fx->gbuffer, NULL);
+					if (ofs) {
+						GPU_offscreen_bind(ofs, false);
+					}
+					else
+						GPU_framebuffer_restore();
+				}
+				else {
+					/* bind the ping buffer to the color buffer */
+					GPU_framebuffer_texture_attach(fx->gbuffer, target, 0, NULL);
+				}
+				glDisable(GL_DEPTH_TEST);
+				glDrawArrays(GL_QUADS, 0, 4);
+				/* disable bindings */
+				GPU_texture_unbind(fx->dof_half_downsampled);
+				GPU_texture_unbind(fx->dof_nearfar_coc[0]);
+
+				/* may not be attached, in that case this just returns */
+				if (target) {
+					GPU_framebuffer_texture_detach(target);
+					if (ofs) {
+						GPU_offscreen_bind(ofs, false);
+					}
+					else {
+						GPU_framebuffer_restore();
+					}
+				}
+
+				SWAP(GPUTexture *, target, src);
+				numslots = 0;
+			}
 		}
 	}
 
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_high_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_high_frag.glsl
index 66e2271..277c028 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_high_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_high_frag.glsl
@@ -11,6 +11,8 @@ varying vec2 depth_uv4;
 uniform sampler2D colorbuffer;
 // depth buffer
 uniform sampler2D depthbuffer;
+// circle of confusion buffer
+uniform sampler2D cocbuffer;
 
 // this includes focal distance in x and aperture size in y
 uniform vec4 dof_params;
@@ -24,9 +26,9 @@ float calculate_signed_coc(in float zdepth)
 	return coc * dof_params.z;
 }
 
-void half_downsample_frag()
+void half_downsample_frag(void)
 {
-	vec4 depthv, final_coc;
+	vec4 depthv;
 	depthv.r = calculate_signed_coc(texture2D(depthbuffer, depth_uv1).r);
 	depthv.g = calculate_signed_coc(texture2D(depthbuffer, depth_uv2).r);
 	depthv.b = calculate_signed_coc(texture2D(depthbuffer, depth_uv3).r);
@@ -39,7 +41,13 @@ void half_downsample_frag()
 	gl_FragData[1].b = gl_FragData[1].a = 0.0;
 	
 	/* framebuffer output 1 is bound to half size color. linear filtering should take care of averaging here */
-	gl_FragData[0] = texture2D(colorbuffer, uvcoordsvar);
+	gl_FragData[0] = texture2D(colorbuffer, uvcoordsvar.xy);
+}
+
+void final_combine_frag(void)
+{
+	/* framebuffer output 1 is bound to half size color. linear filtering should take care of averaging here */
+	gl_FragColor = texture2D(colorbuffer, uvcoordsvar.xy);
 }
 
 void main(void)
@@ -47,7 +55,6 @@ void main(void)
 #ifdef HALF_DOWNSAMPLE_PASS
 	half_downsample_frag();
 #elif defined(HALF_DOWNSAMPLE_COC_PASS)
-
+	final_combine_frag();
 #endif
-
 }
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_high_vert.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_high_vert.glsl
index 3231a5c..ffc1733 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_high_vert.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_high_vert.glsl
@@ -13,18 +13,23 @@ void vert_half_downsample(void)
 	uvcoordsvar = gl_MultiTexCoord0;
 	gl_Position = gl_Vertex;
 	
-	depth_uv1 = gl_MultiTexCoord0.xy + vec2(-0.5, -0.5) * invrendertargetdim;
-	depth_uv2 = gl_MultiTexCoord0.xy + vec2(-0.5, 0.5) * invrendertargetdim;
-	depth_uv3 = gl_MultiTexCoord0.xy + vec2(0.5, -0.5) * invrendertargetdim;
-	depth_uv4 = gl_MultiTexCoord0.xy + vec2(0.5, 0.5) * invrendertargetdim;
+	depth_uv1 = gl_MultiTexCoord0.xy + vec2(0.0, 0.0) * invrendertargetdim;
+	depth_uv2 = gl_MultiTexCoord0.xy + vec2(0.0, 1.0) * invrendertargetdim;
+	depth_uv3 = gl_MultiTexCoord0.xy + vec2(1.0, 0.0) * invrendertargetdim;
+	depth_uv4 = gl_MultiTexCoord0.xy + vec2(1.0, 1.0) * invrendertargetdim;
 }
 
+void vert_final_combine(void)
+{
+	uvcoordsvar = gl_MultiTexCoord0;
+	gl_Position = gl_Vertex;
+}
 
 void main(void)
 {
 #ifdef HALF_DOWNSAMPLE_PASS
 	vert_half_downsample();
 #elif defined(HALF_DOWNSAMPLE_COC_PASS)
-	
+	vert_final_combine();
 #endif
 }
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
index a138d2e..6c4bf3b 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_lib.glsl
@@ -44,4 +44,4 @@ vec4 get_view_space_z_from_depth(in vec4 near, in vec4 range, in vec4 depth)
 	return -(near + depth * rang

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list