[Bf-blender-cvs] [dc22a50] viewport_experiments: Code that enables simultaneous DOF-SSAO effect. There's some sort of texture coordinate offset still.

Antony Riakiotakis noreply at git.blender.org
Tue Oct 28 21:24:57 CET 2014


Commit: dc22a504889e28e71b39c64f20833e4f577f2bad
Author: Antony Riakiotakis
Date:   Tue Oct 28 21:07:49 2014 +0100
Branches: viewport_experiments
https://developer.blender.org/rBdc22a504889e28e71b39c64f20833e4f577f2bad

Code that enables simultaneous DOF-SSAO effect. There's some sort of
texture coordinate offset still.

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

M	source/blender/gpu/intern/gpu_compositing.c
M	source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl

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

diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c
index dfd7105..5777f2d 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -63,8 +63,10 @@ struct GPUFX {
 	/* texture bound to the first color attachment of the gbuffer */
 	GPUTexture *color_buffer;
 
-	/* all those buffers below have to coexist. Fortunately they are all quarter sized (1/16th of memory) of original framebuffer */
+	/* second texture used for ping-pong compositing */
+	GPUTexture *color_buffer_sec;
 
+	/* all those buffers below have to coexist. Fortunately they are all quarter sized (1/16th of memory) of original framebuffer */
 	float dof_near_w;
 	float dof_near_h;
 
@@ -86,6 +88,9 @@ struct GPUFX {
 	
 	/* or-ed flags of enabled effects */
 	int effects;
+
+	/* number of passes, needed to detect if ping pong buffer allocation is needed */
+	int num_passes;
 };
 
 
@@ -105,6 +110,13 @@ static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo)
 		GPU_texture_free(fx->color_buffer);
 		fx->color_buffer = NULL;
 	}
+
+	if (fx->color_buffer_sec) {
+		GPU_framebuffer_texture_detach(fx->gbuffer, fx->color_buffer_sec);
+		GPU_texture_free(fx->color_buffer_sec);
+		fx->color_buffer_sec = NULL;
+	}
+
 	if (fx->depth_buffer) {
 		GPU_framebuffer_texture_detach(fx->gbuffer, fx->depth_buffer);
 		GPU_texture_free(fx->depth_buffer);
@@ -214,38 +226,47 @@ bool GPU_initialize_fx_passes(GPUFX *fx, rcti *rect, rcti *scissor_rect, int fxf
 		
 		if (!(fx->color_buffer = GPU_texture_create_2D(w, h, NULL, err_out))) {
 			printf(".256%s\n", err_out);
+			cleanup_fx_gl_data(fx, true);
+			return false;
 		}
 		
 		if (!(fx->depth_buffer = GPU_texture_create_depth(w, h, err_out))) {
 			printf("%.256s\n", err_out);
+			cleanup_fx_gl_data(fx, true);
+			return false;
+		}
+	}
+	
+	/* create textures for dof effect */
+	if ((fxflags & V3D_FX_DEPTH_OF_FIELD) &&
+	     (!fx->color_buffer_sec || !fx->dof_near_coc_buffer || !fx->dof_near_coc_blurred_buffer || !fx->dof_near_coc_final_buffer ||
+	      w != fx->gbuffer_dim[0] || h != fx->gbuffer_dim[1]))
+	{
+		fx->dof_near_w = w / 4;
+		fx->dof_near_h = h / 4;
+
+		if (!(fx->color_buffer_sec = GPU_texture_create_2D(w, h, NULL, err_out))) {
+			printf(".256%s\n", err_out);
+			cleanup_fx_gl_data(fx, true);
+			return false;
 		}
 
-		/* create textures for dof effect */
-		if (fxflags & V3D_FX_DEPTH_OF_FIELD) {
-			fx->dof_near_w = w / 4;
-			fx->dof_near_h = h / 4;
-
-			if (!(fx->dof_near_coc_buffer = GPU_texture_create_2D(fx->dof_near_w, fx->dof_near_h, NULL, err_out))) {
-				printf("%.256s\n", err_out);
-			}
-			if (!(fx->dof_near_coc_blurred_buffer = GPU_texture_create_2D(fx->dof_near_w, fx->dof_near_h, NULL, err_out))) {
-				printf("%.256s\n", err_out);
-			}
-			if (!(fx->dof_near_coc_final_buffer = GPU_texture_create_2D(fx->dof_near_w, fx->dof_near_h, NULL, err_out))) {
-				printf("%.256s\n", err_out);
-			}
+		if (!(fx->dof_near_coc_buffer = GPU_texture_create_2D(fx->dof_near_w, fx->dof_near_h, NULL, err_out))) {
+			printf("%.256s\n", err_out);
+			cleanup_fx_gl_data(fx, true);
+			return false;
 		}
-		
-		/* in case of failure, cleanup */
-		if (!fx->color_buffer || !fx->depth_buffer) {
+		if (!(fx->dof_near_coc_blurred_buffer = GPU_texture_create_2D(fx->dof_near_w, fx->dof_near_h, NULL, err_out))) {
+			printf("%.256s\n", err_out);
+			cleanup_fx_gl_data(fx, true);
+			return false;
+		}
+		if (!(fx->dof_near_coc_final_buffer = GPU_texture_create_2D(fx->dof_near_w, fx->dof_near_h, NULL, err_out))) {
+			printf("%.256s\n", err_out);
 			cleanup_fx_gl_data(fx, true);
 			return false;
 		}
-		
-		fx->gbuffer_dim[0] = w;
-		fx->gbuffer_dim[1] = h;		
 	}
-	
 	/* bind the buffers */
 	
 	/* first depth buffer, because system assumes read/write buffers */
@@ -268,6 +289,16 @@ bool GPU_initialize_fx_passes(GPUFX *fx, rcti *rect, rcti *scissor_rect, int fxf
 				  w_sc, h_sc);
 	}
 	fx->effects = fxflags;
+	fx->num_passes = 0;
+	/* dof really needs a ping-pong buffer to work */
+	if (fxflags & V3D_FX_DEPTH_OF_FIELD) {
+		fx->num_passes++;
+	}
+	if (fxflags & V3D_FX_SSAO)
+		fx->num_passes++;
+
+	fx->gbuffer_dim[0] = w;
+	fx->gbuffer_dim[1] = h;
 
 	return true;
 }
@@ -275,11 +306,12 @@ bool GPU_initialize_fx_passes(GPUFX *fx, rcti *rect, rcti *scissor_rect, int fxf
 
 bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d, struct RegionView3D *rv3d, struct Scene *scene) {
 	GPUShader *fx_shader;
+	GPUTexture *src, *target;
 	int numslots = 0;
 	float invproj[4][4];
 	int i;
 	/* number of passes left. when there are no more passes, the result is passed to the frambuffer */
-	int passes_left;
+	int passes_left = fx->num_passes;
 	/* dimensions of screen (used in many shaders)*/
 	float screen_dim[2] = {fx->gbuffer_dim[0], fx->gbuffer_dim[1]};
 	/* view vectors for the corners of the view frustum. Can be used to recreate the world space position easily */
@@ -293,10 +325,12 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d, struct RegionView3D
 		return false;
 	
 	/* first, unbind the render-to-texture framebuffer */
-	GPU_framebuffer_texture_unbind(fx->gbuffer, fx->color_buffer);
+	GPU_framebuffer_texture_detach(fx->gbuffer, fx->color_buffer);
 	glPopAttrib();
-	GPU_framebuffer_restore();
-	
+
+	src = fx->color_buffer;
+	target = fx->color_buffer_sec;
+
 	/* set up quad buffer */
 	glVertexPointer(2, GL_FLOAT, 0, fullscreencos);
 	glTexCoordPointer(2, GL_FLOAT, 0, fullscreenuvs);
@@ -381,8 +415,8 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d, struct RegionView3D
 			GPU_shader_uniform_vector(fx_shader, ssao_sample_params_uniform, 4, 1, sample_params);
 			GPU_shader_uniform_vector(fx_shader, ssao_direction_uniform, 2, 16, ssao_sample_directions[0]);
 
-			GPU_texture_bind(fx->color_buffer, numslots++);
-			GPU_shader_uniform_texture(fx_shader, color_uniform, fx->color_buffer);
+			GPU_texture_bind(src, numslots++);
+			GPU_shader_uniform_texture(fx_shader, color_uniform, src);
 
 			GPU_texture_bind(fx->depth_buffer, numslots++);
 			GPU_depth_texture_mode(fx->depth_buffer, false, true);
@@ -395,13 +429,23 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d, struct RegionView3D
 			glColor3f(1.0, 0.0, 1.0);
 
 			/* draw */
+			if (passes_left-- == 1)
+				GPU_framebuffer_restore();
+			else {
+				/* bind the ping buffer to the color buffer */
+				GPU_framebuffer_texture_attach(fx->gbuffer, target, NULL);
+			}
 			glDisable(GL_DEPTH_TEST);
 			glDrawArrays(GL_QUADS, 0, 4);
+
 			/* disable bindings */
-			GPU_texture_unbind(fx->color_buffer);
+			GPU_texture_unbind(src);
 			GPU_depth_texture_mode(fx->depth_buffer, true, false);
 			GPU_texture_unbind(fx->depth_buffer);
 
+			/* swap here, after src/target have been unbound */
+			SWAP(GPUTexture *, target, src);
+
 			/* same texture may be bound to more than one slot. Use this to explicitly disable texturing everywhere */
 			for (i = numslots; i > 0; i--) {
 				glActiveTexture(GL_TEXTURE0 + i - 1);
@@ -409,10 +453,10 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d, struct RegionView3D
 				glDisable(GL_TEXTURE_2D);
 			}
 			numslots = 0;
+
 		}
 	}
 
-
 	/* second pass, dof */
 	if (fx->effects & V3D_FX_DEPTH_OF_FIELD) {
 		fx_shader = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD, rv3d->is_persp);
@@ -443,27 +487,36 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d, struct RegionView3D
 			GPU_shader_uniform_vector(fx_shader, screendim_uniform, 2, 1, screen_dim);
 			GPU_shader_uniform_vector(fx_shader, viewvecs_uniform, 4, 3, viewvecs[0]);
 
-			GPU_texture_bind(fx->color_buffer, numslots++);
-			GPU_shader_uniform_texture(fx_shader, blurred_uniform, fx->color_buffer);
+			GPU_texture_bind(src, numslots++);
+			GPU_shader_uniform_texture(fx_shader, blurred_uniform, src);
 			/* generate mipmaps for the color buffer */
 			//		glGenerateMipmapEXT(GL_TEXTURE_2D);
 			//		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
 			//		glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 2.0);
 
-			GPU_texture_bind(fx->color_buffer, numslots++);
-			GPU_shader_uniform_texture(fx_shader, color_uniform, fx->color_buffer);
+			GPU_texture_bind(src, numslots++);
+			GPU_shader_uniform_texture(fx_shader, color_uniform, src);
 
 			GPU_texture_bind(fx->depth_buffer, numslots++);
 			GPU_depth_texture_mode(fx->depth_buffer, false, true);
 			GPU_shader_uniform_texture(fx_shader, depth_uniform, fx->depth_buffer);
 
+			/* if this is the last pass, prepare for rendering on the frambuffer */
+			if (passes_left-- == 1)
+				GPU_framebuffer_restore();
+			else {
+				/* bind the ping buffer to the color buffer */
+				GPU_framebuffer_texture_attach(fx->gbuffer, target, NULL);
+			}
 			glDisable(GL_DEPTH_TEST);
 			glDrawArrays(GL_QUADS, 0, 4);
 			/* disable bindings */
-			GPU_texture_unbind(fx->color_buffer);
+			GPU_texture_unbind(src);
 			GPU_depth_texture_mode(fx->depth_buffer, true, false);
 			GPU_texture_unbind(fx->depth_buffer);
 
+			SWAP(GPUTexture *, target, src);
+
 			/* same texture may be bound to more than one slot. Use this to explicitly disable texturing everywhere */
 			for (i = numslots; i > 0; i--) {
 				glActiveTexture(GL_TEXTURE0 + i - 1);
@@ -478,6 +531,7 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d, struct RegionView3D
 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 	
 	GPU_shader_unbind();
-	
+	GPU_framebuffer_texture_unbind(fx->gbuffer, NULL);
+
 	return true;
 }
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
index c12b27d..d556164 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
@@ -27,9 +27,10 @@ float calculate_dof_coc(in vec3 viewposition)
 void main()
 {
     float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
+    vec4 color = texture2D(colorbuffer, uvcoordsvar.xy);
 
     vec3 position = get_view_space_from_depth(uvcoordsvar.xy, viewvecs[0].xyz, viewvecs[1].xyz, depth);
     float coc = calculate_dof_coc(position);
 
-    gl_FragColor = vec4(coc, coc, coc, 1.0)

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list