[Bf-blender-cvs] [c629291] viewport_experiments: Framebuffer compositing:

Antony Riakiotakis noreply at git.blender.org
Wed Oct 29 12:01:24 CET 2014


Commit: c6292918a36b302ab688cffaf4355e1730fdee08
Author: Antony Riakiotakis
Date:   Wed Oct 29 12:01:13 2014 +0100
Branches: viewport_experiments
https://developer.blender.org/rBc6292918a36b302ab688cffaf4355e1730fdee08

Framebuffer compositing:

* Cleanup compositing buffers better when not needed.

* Support passes for the dof effect through defines in main - easy
solution to allow not having too many files for one shader effect.

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

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

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

diff --git a/source/blender/gpu/GPU_compositing.h b/source/blender/gpu/GPU_compositing.h
index a745801..d6c057e 100644
--- a/source/blender/gpu/GPU_compositing.h
+++ b/source/blender/gpu/GPU_compositing.h
@@ -43,12 +43,18 @@ struct Scene;
 /**** Public API *****/
 
 typedef enum GPUFXShaderEffect {
-	GPU_SHADER_FX_SSAO           =	(1<<0),
-	GPU_SHADER_FX_DEPTH_OF_FIELD =	(1<<1),
-	GPU_SHADER_FX_MAX            =	(1<<2),
+	/* Screen space ambient occlusion shader */
+	GPU_SHADER_FX_SSAO           = 1,
+
+	/* depth of field passes. Yep, quite a complex effect */
+	GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE = 2,
+	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,
 } GPUFXShaderEffect;
 
-#define MAX_FX_SHADERS (GPU_SHADER_FX_MAX - 1)
+/* keep in synch with enum above! */
+#define MAX_FX_SHADERS 6
 
 /* 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 862e332..2c41ff3 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -102,6 +102,21 @@ GPUFX *GPU_create_fx_compositor(void)
 	return fx;
 }
 
+static void cleanup_fx_dof_buffers(GPUFX *fx)
+{
+	if (fx->dof_near_coc_blurred_buffer) {
+		GPU_texture_free(fx->dof_near_coc_blurred_buffer);
+		fx->dof_near_coc_blurred_buffer = NULL;
+	}
+	if (fx->dof_near_coc_buffer) {
+		GPU_texture_free(fx->dof_near_coc_buffer);
+		fx->dof_near_coc_buffer = NULL;
+	}
+	if (fx->dof_near_coc_final_buffer) {
+		GPU_texture_free(fx->dof_near_coc_final_buffer);
+		fx->dof_near_coc_final_buffer = NULL;
+	}
+}
 
 static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo)
 {
@@ -123,18 +138,7 @@ static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo)
 		fx->depth_buffer = NULL;
 	}		
 
-	if (fx->dof_near_coc_blurred_buffer) {
-		GPU_texture_free(fx->dof_near_coc_blurred_buffer);
-		fx->dof_near_coc_blurred_buffer = NULL;
-	}
-	if (fx->dof_near_coc_buffer) {
-		GPU_texture_free(fx->dof_near_coc_buffer);
-		fx->dof_near_coc_buffer = NULL;
-	}
-	if (fx->dof_near_coc_final_buffer) {
-		GPU_texture_free(fx->dof_near_coc_final_buffer);
-		fx->dof_near_coc_final_buffer = NULL;
-	}
+	cleanup_fx_dof_buffers(fx);
 
 	if (fx->jitter_buffer && do_fbo) {
 		GPU_texture_free(fx->jitter_buffer);
@@ -202,6 +206,7 @@ bool GPU_initialize_fx_passes(GPUFX *fx, rcti *rect, rcti *scissor_rect, int fxf
 {
 	int w = BLI_rcti_size_x(rect) + 1, h = BLI_rcti_size_y(rect) + 1;
 	char err_out[256];
+	int num_passes = 0;
 
 	fx->effects = 0;
 
@@ -210,6 +215,14 @@ bool GPU_initialize_fx_passes(GPUFX *fx, rcti *rect, rcti *scissor_rect, int fxf
 		return false;
 	}
 	
+	fx->num_passes = 0;
+	/* dof really needs a ping-pong buffer to work */
+	if (fxflags & V3D_FX_DEPTH_OF_FIELD) {
+		num_passes++;
+	}
+	if (fxflags & V3D_FX_SSAO)
+		num_passes++;
+
 	if (!fx->gbuffer) 
 		fx->gbuffer = GPU_framebuffer_create();
 	
@@ -238,35 +251,51 @@ bool GPU_initialize_fx_passes(GPUFX *fx, rcti *rect, rcti *scissor_rect, int fxf
 	}
 	
 	/* 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;
+	if (fxflags & V3D_FX_DEPTH_OF_FIELD) {
+		if (!fx->dof_near_coc_buffer || !fx->dof_near_coc_blurred_buffer || !fx->dof_near_coc_final_buffer) {
+			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);
+				cleanup_fx_gl_data(fx, true);
+				return false;
+			}
+			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;
+			}
 		}
+	}
+	else {
+		/* cleanup unnecessary buffers */
+		cleanup_fx_dof_buffers(fx);
+	}
 
-		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;
-		}
-		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;
+	/* we need to pass data between shader stages, allocate an extra color buffer */
+	if (num_passes > 1) {
+		if(!fx->color_buffer_sec) {
+			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;
+			}
 		}
-		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;
+	}
+	else {
+		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;
 		}
 	}
+
 	/* bind the buffers */
 	
 	/* first depth buffer, because system assumes read/write buffers */
@@ -289,17 +318,12 @@ 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;
 
+	fx->num_passes = num_passes;
+
 	return true;
 }
 
@@ -462,7 +486,7 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d, struct RegionView3D
 
 	/* 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);
+		fx_shader = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE, rv3d->is_persp);
 		if (fx_shader) {
 			float dof_params[4];
 			int screendim_uniform, color_uniform, depth_uniform, dof_uniform, blurred_uniform;
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 36f9023..46d87a1 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -1564,10 +1564,12 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
 	return retval;
 }
 
+#define MAX_DEFINES 100
+
 GPUShader *GPU_shader_get_builtin_fx_shader(int effects, bool persp)
 {
 	int offset;
-	const char *defines = NULL;
+	char defines[MAX_DEFINES] = "";
 	/* avoid shaders out of range */
 	if (effects >= MAX_FX_SHADERS)
 		return NULL;
@@ -1576,14 +1578,16 @@ GPUShader *GPU_shader_get_builtin_fx_shader(int effects, bool persp)
 
 	if (persp) {
 		offset += 1;
-		defines = "#define PERSP_MATRIX\n";
+		strcat(defines, "#define PERSP_MATRIX\n");
 	}
 
 	if (!GG.shaders.fx_shaders[offset]) {
 		if (effects == GPU_SHADER_FX_SSAO)
 			GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_ssao_frag_glsl, datatoc_gpu_shader_fx_lib_glsl, defines);
-		else if (effects == GPU_SHADER_FX_DEPTH_OF_FIELD)
+		else if (effects == GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE) {
+			strcat(defines, "#define FIRST_PASS\n");
 			GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, datatoc_gpu_shader_fx_lib_glsl, defines);
+		}
 	}
 	
 	return GG.shaders.fx_shaders[offset];
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 d556164..053c165 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl
@@ -24,7 +24,7 @@ float calculate_dof_coc(in vec3 viewposition)
     return coc * dof_params.z;
 }
 
-void main()
+void first_pass()
 {
     float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
     vec4 color = texture2D(colorbuffer, uvcoordsvar.xy);
@@ -34,3 +34,13 @@ void main()
 
     gl_FragColor = vec4(coc * color.rgb, 1.0);
 }
+
+void main()
+{
+#ifdef FIRST_PASS
+    first_pass();
+#elif defined(SECOND_PASS)
+#elif defined(THIRD_PASS)
+#elif defined(FOURTH_PASS)
+#endif
+}




More information about the Bf-blender-cvs mailing list