[Bf-blender-cvs] [9e2efd6] viewport_experiments: Framebuffer FX.

Antony Riakiotakis noreply at git.blender.org
Fri Sep 12 18:05:52 CEST 2014


Commit: 9e2efd68e1cf063d5e93890422a3def3c5ecd720
Author: Antony Riakiotakis
Date:   Tue Sep 9 17:05:56 2014 +0200
Branches: viewport_experiments
https://developer.blender.org/rB9e2efd68e1cf063d5e93890422a3def3c5ecd720

Framebuffer FX.

This commit introduces offscreen rendering for the 3D viewport.
There is test code that calculates depth and normal data
in screen space.

Currently just DOF is supported with a few parameters to control the
effect

This code recreates the framebuffer and texture objects every frame
which will make it -slow-. Use at your own risk.

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

M	SConstruct
M	release/scripts/startup/bl_ui/space_view3d.py
M	source/blender/editors/space_view3d/drawobject.c
M	source/blender/editors/space_view3d/view3d_draw.c
M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_buffers.h
M	source/blender/gpu/GPU_extensions.h
M	source/blender/gpu/intern/gpu_buffers.c
M	source/blender/gpu/intern/gpu_extensions.c
A	source/blender/gpu/shaders/gpu_shader_fx_frag.glsl
A	source/blender/gpu/shaders/gpu_shader_fx_vert.glsl
M	source/blender/makesdna/DNA_view3d_types.h
M	source/blender/makesrna/intern/rna_space.c

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

diff --git a/SConstruct b/SConstruct
index d1d0db9..4519026 100644
--- a/SConstruct
+++ b/SConstruct
@@ -701,6 +701,8 @@ if B.targets != ['cudakernels']:
     data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vertex.glsl")
     data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl")
     data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl")
+    data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_frag.glsl")
+    data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_vert.glsl")
     data_to_c_simple("intern/opencolorio/gpu_shader_display_transform.glsl")
 
     # --- blender ---
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 61d359e..b192d24 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -2865,8 +2865,18 @@ class VIEW3D_PT_view3d_shading(Panel):
                 col.prop(view, "show_textured_shadeless")
 
         col.prop(view, "show_backface_culling")
-        if obj and obj.mode == 'EDIT' and view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
-            col.prop(view, "show_occlude_wire")
+
+        if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'}:
+            if obj and obj.mode == 'EDIT':
+                col.prop(view, "show_occlude_wire")
+            #hide ssao for now, will expose again when it's ready
+            #col.prop(view, "ssao")
+            col.prop(view, "depth_of_field")
+            if view.depth_of_field:
+                subcol = col.column(align=True)
+                subcol.prop(view, "dof_focal_distance")
+                subcol.prop(view, "dof_aperture")
+                subcol.prop(view, "dof_fstop")
 
 
 class VIEW3D_PT_view3d_motion_tracking(Panel):
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 75d64e9..bcc826b 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -7255,7 +7255,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
 		if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) {
 			if (ob->type == OB_MESH) {
 				if (dt < OB_SOLID) {
-					zbufoff = 1;
+					zbufoff = true;
 					dt = OB_SOLID;
 				}
 
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 004b3e1..3283069 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -3377,12 +3377,17 @@ static void update_lods(Scene *scene, float camera_pos[3])
 }
 #endif
 
-
 static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3D *v3d,
                                           ARegion *ar, const char **grid_unit)
 {
 	RegionView3D *rv3d = ar->regiondata;
 	unsigned int lay_used = v3d->lay_used;
+	
+	/* post processing */
+	GPUFrameBuffer *first_pass = NULL;
+	GPUTexture *color_buffer = NULL;
+	GPUTexture *depth_buffer = NULL;
+	float screendim[2];
 
 	/* shadow buffers, before we setup matrices */
 	if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype))
@@ -3407,6 +3412,56 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3
 	}
 #endif
 
+	/* framebuffer fx needed, we need to draw offscreen first */
+	if (v3d->shader_fx & V3D_FX_DEPTH_OF_FIELD) {
+		int w = BLI_rcti_size_x(&ar->winrct) + 1, h = BLI_rcti_size_y(&ar->winrct) + 1;
+		
+		char err_out[256];
+		/* overkill to create per frame, but it's just for testing now */
+		first_pass = GPU_framebuffer_create();
+		
+		screendim[0] = w;
+		screendim[1] = h;
+
+		if (first_pass) {
+			if (!(color_buffer = GPU_texture_create_2D(w, h, NULL, err_out))) {
+				printf(".256%s\n", err_out);
+			}
+			
+			if (!(depth_buffer = GPU_texture_create_depth(w, h, err_out))) {
+				printf("%.256s\n", err_out);
+			}
+			
+			/* in case of failure, cleanup */
+			if (!color_buffer || !depth_buffer) {
+				if (color_buffer) {
+					GPU_texture_free(color_buffer);
+					color_buffer = NULL;
+				}
+				if (depth_buffer) {
+					GPU_texture_free(depth_buffer);
+					depth_buffer = NULL;
+				}		
+				GPU_framebuffer_free(first_pass);
+				first_pass = NULL;
+			}
+			else {
+				/* bind the buffers */
+				
+				/* first depth buffer, because system assumes read/write buffers */
+				if(!GPU_framebuffer_texture_attach(first_pass, depth_buffer, err_out))
+					printf("%.256s\n", err_out);
+
+				if(!GPU_framebuffer_texture_attach(first_pass, color_buffer, err_out))
+					printf("%.256s\n", err_out);
+				
+				GPU_framebuffer_texture_bind(first_pass, color_buffer, 
+											 GPU_texture_opengl_width(color_buffer), GPU_texture_opengl_height(color_buffer));
+				//glClearColor(1.0, 0.0, 1.0, 1.0);
+				//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+			}
+		}		
+	}
 	/* clear the background */
 	view3d_main_area_clear(scene, v3d, ar);
 
@@ -3416,8 +3471,88 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3
 	}
 
 	/* main drawing call */
-	view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false);
+	view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, first_pass != NULL);
+
+	/* post process */
+	if (first_pass) {
+		float fullscreencos[4][2] = {{-1.0f, -1.0f}, {1.0f, -1.0f}, {1.0f, 1.0f}, {-1.0f, 1.0f}};
+		float fullscreenuvs[4][2] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}};
+		GPUShader *fx_shader;
+		
+		/* first, unbind the render-to-texture framebuffer */
+		GPU_framebuffer_texture_unbind(first_pass, color_buffer);
+		//GPU_framebuffer_texture_detach(first_pass, color_buffer);
+		//GPU_framebuffer_texture_detach(first_pass, depth_buffer);
+		GPU_framebuffer_restore();
+		
+		/* full screen FX pass */
+		
+		/* first we need to blur the color pass */
+		
+		
+		/* set up the shader */
+		fx_shader = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD);
+		if (fx_shader) {
+			int screendim_uniform, color_uniform, depth_uniform, dof_uniform, blurred_uniform;
+			float fac = v3d->dof_fstop * v3d->dof_aperture;
+			float parameters[2] = {v3d->dof_aperture * fabs(fac / (v3d->dof_focal_distance - fac)), 
+								   v3d->dof_focal_distance};
+
+			dof_uniform = GPU_shader_get_uniform(fx_shader, "dof_params");
+			blurred_uniform = GPU_shader_get_uniform(fx_shader, "blurredcolorbuffer");
+			screendim_uniform = GPU_shader_get_uniform(fx_shader, "screendim");
+			color_uniform = GPU_shader_get_uniform(fx_shader, "colorbuffer");
+			depth_uniform = GPU_shader_get_uniform(fx_shader, "depthbuffer");
+
+			GPU_shader_bind(fx_shader);
+
+			GPU_shader_uniform_vector(fx_shader, screendim_uniform, 2, 1, screendim);
+			GPU_shader_uniform_vector(fx_shader, dof_uniform, 2, 1, parameters);
+
+			GPU_texture_bind(color_buffer, 0);
+			GPU_shader_uniform_texture(fx_shader, blurred_uniform, color_buffer);
+			/* 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(color_buffer, 1);
+			GPU_shader_uniform_texture(fx_shader, color_uniform, color_buffer);
+			
+			GPU_texture_bind(depth_buffer, 2);
+			GPU_depth_texture_mode(depth_buffer, false);
+			GPU_shader_uniform_texture(fx_shader, depth_uniform, depth_buffer);
+		}
+		/* set up quad buffer */
+		glVertexPointer(2, GL_FLOAT, 0, fullscreencos);
+		glTexCoordPointer(2, GL_FLOAT, 0, fullscreenuvs);
+		glEnableClientState(GL_VERTEX_ARRAY);
+		glEnableClientState(GL_TEXTURE_COORD_ARRAY);		
+		
+		/* set invalid color in case shader fails */
+		glColor3f(1.0, 0.0, 1.0);
+
+		/* draw */
+		glDisable(GL_DEPTH_TEST);
+		glDrawArrays(GL_QUADS, 0, 4);
 
+		/* disable bindings */
+		GPU_texture_unbind(color_buffer);
+		GPU_depth_texture_mode(depth_buffer, true);
+		GPU_texture_unbind(depth_buffer);
+		glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0.0);
+		
+		glDisableClientState(GL_VERTEX_ARRAY);
+		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+		
+		GPU_shader_unbind();
+		
+		/* cleanup framebuffer */
+		GPU_framebuffer_free(first_pass);
+		GPU_texture_free(color_buffer);
+		GPU_texture_free(depth_buffer);		
+	}
+	
 	/* Disable back anti-aliasing */
 	if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) {
 		glDisable(GL_MULTISAMPLE_ARB);
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 13e46bc..73edcdc 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -70,6 +70,8 @@ data_to_c_simple(shaders/gpu_shader_simple_vert.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_vertex.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_vsm_store_frag.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_vsm_store_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_fx_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_fx_frag.glsl SRC)
 
 if(WITH_GAMEENGINE)
 	add_definitions(-DWITH_GAMEENGINE)
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index ba461d5..c690b0c 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -85,6 +85,7 @@ typedef struct GPUDrawObject {
 	GPUBuffer *points;
 	GPUBuffer *normals;
 	GPUBuffer *uv;
+	GPUBuffer *uv_tex;	
 	GPUBuffer *colors;
 	GPUBuffer *edges;
 	GPUBuffer *uvedges;
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index 04c4119..dbfc948 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -128,6 +128,8 @@ void GPU_texture_ref(GPUTexture *tex);
 void GPU_texture_bind(GPUTexture *tex, int number);
 void GPU_texture_unbind(GPUTexture *tex);
 
+void GPU_depth_texture_mode(GPUTexture *tex, bool compare);
+
 GPUFrameBuffer *GPU_texture_framebuffer(GPUTexture *tex);
 
 int GPU_texture_target(GPUTexture *tex);
@@ -188,7 +190,17 @@ typedef enum GPUBuiltinShader {
 	GPU_SHADER_SEP_GAUSSIAN_BLUR =	(1<<1),
 } GPUBuiltinShader;
 
+typedef enum GPUFXShaderEffect {
+	GPU_SHADER_FX_SSAO           =	(1

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list