[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