[Bf-blender-cvs] [eb8a09d] viewport_experiments: DOF effect works :)

Antony Riakiotakis noreply at git.blender.org
Fri Oct 31 21:24:53 CET 2014


Commit: eb8a09d567e1a4712a0e85bfc1b610f5f5f3af5a
Author: Antony Riakiotakis
Date:   Fri Oct 31 15:41:53 2014 +0100
Branches: viewport_experiments
https://developer.blender.org/rBeb8a09d567e1a4712a0e85bfc1b610f5f5f3af5a

DOF effect works :)

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

M	source/blender/gpu/GPU_compositing.h
M	source/blender/gpu/intern/gpu_compositing.c
M	source/blender/gpu/intern/gpu_extensions.c
M	source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
M	source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl

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

diff --git a/source/blender/gpu/GPU_compositing.h b/source/blender/gpu/GPU_compositing.h
index d6c057e..ab39a6d 100644
--- a/source/blender/gpu/GPU_compositing.h
+++ b/source/blender/gpu/GPU_compositing.h
@@ -51,10 +51,11 @@ typedef enum GPUFXShaderEffect {
 	GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO = 3,
 	GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE = 4,
 	GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR = 5,
+	GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE = 6,
 } GPUFXShaderEffect;
 
 /* keep in synch with enum above! */
-#define MAX_FX_SHADERS 6
+#define MAX_FX_SHADERS 7
 
 /* generate a new FX compositor */
 GPUFX *GPU_create_fx_compositor(void);
diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c
index 27cdfdd..41acfc2 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -478,18 +478,28 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d, struct RegionView3D
 
 	/* second pass, dof */
 	if (fx->effects & V3D_FX_DEPTH_OF_FIELD) {
-		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_shader_pass5;
+		float dof_params[4];
+		float scale = scene->unit.system ? scene->unit.scale_length : 1.0f;
+		float scale_camera = 0.001f / scale;
+		float aperture = 2.0f * scale_camera * v3d->dof_focal_length / v3d->dof_fstop; // * v3d->dof_aperture;
+
+		dof_params[0] = aperture * fabs(scale_camera * v3d->dof_focal_length / (v3d->dof_focus_distance - scale_camera * v3d->dof_focal_length));
+		dof_params[1] = v3d->dof_focus_distance;
+		dof_params[2] = fx->gbuffer_dim[0] / (scale_camera * v3d->dof_sensor);
+		dof_params[3] = 0.0f;
 
 		/* 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_PASS_ONE, rv3d->is_persp);
 		dof_shader_pass2 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO, rv3d->is_persp);
 		dof_shader_pass3 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE, rv3d->is_persp);
+		dof_shader_pass4 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR, rv3d->is_persp);
+		dof_shader_pass5 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE, rv3d->is_persp);
 
 		/* error occured, restore framebuffers and return */
-		if (!dof_shader_pass1 || !(dof_shader_pass2)) {
+		if (!dof_shader_pass1 || !(dof_shader_pass2) || (!dof_shader_pass3) || (!dof_shader_pass4)) {
 			GPU_framebuffer_texture_unbind(fx->gbuffer, NULL);
 			GPU_framebuffer_restore();
 			return false;
@@ -497,21 +507,11 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d, struct RegionView3D
 
 		/* pass first, first level of blur in low res buffer */
 		{
-			float dof_params[4];
 			int invrendertargetdim_uniform, color_uniform, depth_uniform, dof_uniform;
 			int viewvecs_uniform;
 
-			float scale = scene->unit.system ? scene->unit.scale_length : 1.0f;
-			float scale_camera = 0.001f / scale;
-			float aperture = 2.0f * scale_camera * v3d->dof_focal_length / v3d->dof_fstop; // * v3d->dof_aperture;
-
 			float invrendertargetdim[2] = {1.0f / fx->gbuffer_dim[0], 1.0f / fx->gbuffer_dim[1]};
 
-			dof_params[0] = aperture * fabs(scale_camera * v3d->dof_focal_length / (v3d->dof_focus_distance - scale_camera * v3d->dof_focal_length));
-			dof_params[1] = v3d->dof_focus_distance;
-			dof_params[2] = fx->gbuffer_dim[0] / (scale_camera * v3d->dof_sensor);
-			dof_params[3] = 0.0f;
-
 			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");
@@ -533,6 +533,7 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d, struct RegionView3D
 
 			/* target is the downsampled coc buffer */
 			GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, NULL);
+			/* binding takes care of setting the viewport to the downsampled size */
 			GPU_framebuffer_texture_bind(fx->gbuffer, fx->dof_near_coc_buffer,
 			                             GPU_texture_opengl_width(fx->dof_near_coc_buffer), GPU_texture_opengl_height(fx->dof_near_coc_buffer));
 
@@ -543,56 +544,165 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d, struct RegionView3D
 			GPU_depth_texture_mode(fx->depth_buffer, true, false);
 			GPU_texture_unbind(fx->depth_buffer);
 
-			GPU_framebuffer_texture_unbind(fx->gbuffer, fx->dof_near_coc_buffer);
 			GPU_framebuffer_texture_detach(fx->gbuffer, fx->dof_near_coc_buffer);
 			numslots = 0;
 		}
 
-		/* second pass */
+		/* second pass, gaussian blur the downsampled image */
 		{
-			int near_coc_downsampled;
-			int invrendertargetdim_uniform;
+			int invrendertargetdim_uniform, color_uniform, depth_uniform, dof_uniform;
+			int viewvecs_uniform;
 			float invrendertargetdim[2] = {1.0f / GPU_texture_opengl_width(fx->dof_near_coc_blurred_buffer),
 			                               1.0f / GPU_texture_opengl_height(fx->dof_near_coc_blurred_buffer)};
+			float tmp = invrendertargetdim[0];
+			invrendertargetdim[0] = 0.0f;
+
+			dof_params[2] = GPU_texture_opengl_width(fx->dof_near_coc_blurred_buffer) / (scale_camera * v3d->dof_sensor);
 
-			near_coc_downsampled = GPU_shader_get_uniform(dof_shader_pass2, "colorbuffer");
+			dof_uniform = GPU_shader_get_uniform(dof_shader_pass2, "dof_params");
 			invrendertargetdim_uniform = GPU_shader_get_uniform(dof_shader_pass2, "invrendertargetdim");
+			color_uniform = GPU_shader_get_uniform(dof_shader_pass2, "colorbuffer");
+			depth_uniform = GPU_shader_get_uniform(dof_shader_pass2, "depthbuffer");
+			viewvecs_uniform = GPU_shader_get_uniform(dof_shader_pass2, "viewvecs");
 
+			/* Blurring vertically */
 			GPU_shader_bind(dof_shader_pass2);
 
-			GPU_texture_bind(fx->dof_near_coc_buffer, numslots++);
-			GPU_shader_uniform_texture(dof_shader_pass2, near_coc_downsampled, fx->dof_near_coc_buffer);
+			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]);
 
-			/* if this is the last pass, prepare for rendering on the frambuffer */
-			GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_blurred_buffer, NULL);
-			GPU_framebuffer_texture_bind(fx->gbuffer, fx->dof_near_coc_blurred_buffer,
-			                             GPU_texture_opengl_width(fx->dof_near_coc_blurred_buffer), GPU_texture_opengl_height(fx->dof_near_coc_blurred_buffer));
+			GPU_texture_bind(fx->depth_buffer, numslots++);
+			GPU_depth_texture_mode(fx->depth_buffer, false, true);
+			GPU_shader_uniform_texture(dof_shader_pass2, depth_uniform, fx->depth_buffer);
 
-			glDisable(GL_DEPTH_TEST);
+			GPU_texture_bind(fx->dof_near_coc_buffer, numslots++);
+			GPU_shader_uniform_texture(dof_shader_pass2, color_uniform, fx->dof_near_coc_buffer);
+
+			/* use final buffer as a temp here */
+			GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, NULL);
+
+			/* Drawing quad */
 			glDrawArrays(GL_QUADS, 0, 4);
-			/* disable bindings */
+
+			/* *unbind/detach */
 			GPU_texture_unbind(fx->dof_near_coc_buffer);
+			GPU_framebuffer_texture_detach(fx->gbuffer, fx->dof_near_coc_final_buffer);
+
+			/* Blurring horizontally */
+			invrendertargetdim[0] = tmp;
+			invrendertargetdim[1] = 0.0f;
+			GPU_shader_uniform_vector(dof_shader_pass2, invrendertargetdim_uniform, 2, 1, invrendertargetdim);
+
+			GPU_texture_bind(fx->dof_near_coc_final_buffer, numslots++);
+			GPU_shader_uniform_texture(dof_shader_pass2, color_uniform, fx->dof_near_coc_final_buffer);
+
+			GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_blurred_buffer, NULL);
+			glDrawArrays(GL_QUADS, 0, 4);
+
+			/* *unbind/detach */
 			GPU_depth_texture_mode(fx->depth_buffer, true, false);
 			GPU_texture_unbind(fx->depth_buffer);
 
-			GPU_framebuffer_texture_unbind(fx->gbuffer, fx->dof_near_coc_blurred_buffer);
+			GPU_texture_unbind(fx->dof_near_coc_final_buffer);
 			GPU_framebuffer_texture_detach(fx->gbuffer, fx->dof_near_coc_blurred_buffer);
 
-			SWAP(GPUTexture *, target, src);
+			dof_params[2] = fx->gbuffer_dim[0] / (scale_camera * v3d->dof_sensor);
+
 			numslots = 0;
 		}
 
-		/* third pass */
+		/* third pass, calculate near coc */
 		{
-			int near_coc_downsampled;
+			int near_coc_downsampled, near_coc_blurred;
 
 			near_coc_downsampled = GPU_shader_get_uniform(dof_shader_pass3, "colorbuffer");
+			near_coc_blurred = GPU_shader_get_uniform(dof_shader_pass3, "blurredcolorbuffer");
 
 			GPU_shader_bind(dof_shader_pass3);
 
+			GPU_texture_bind(fx->dof_near_coc_buffer, numslots++);
+			GPU_shader_uniform_texture(dof_shader_pass3, near_coc_downsampled, fx->dof_near_coc_buffer);
+
+			GPU_texture_bind(fx->dof_near_coc_blurred_buffer, numslots++);
+			GPU_shader_uniform_texture(dof_shader_pass3, near_coc_blurred, fx->dof_near_coc_blurred_buffer);
+
+			GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, NULL);
+
+			glDisable(GL_DEPTH_TEST);
+			glDrawArrays(GL_QUADS, 0, 4);
+			/* disable bindings */
+			GPU_texture_unbind(fx->dof_near_coc_buffer);
+			GPU_texture_unbind(fx->dof_near_coc_blurred_buffer);
+
+			/* unbinding here restores the size to the original */
+			GPU_framebuffer_texture_detach(fx->gbuffer, fx->dof_near_coc_final_buffer);
+
+			numslots = 0;
+		}
+
+		/* fourth pass blur final coc once to eliminate discontinuities */
+		{
+			int near_coc_downsampled;
+			int invrendertargetdim_uniform;
+			float invrendertargetdim[2] = {1.0f / GPU_texture_opengl_width(fx->dof_near_coc_blurred_buffer),
+			                               

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list