[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