[Bf-blender-cvs] [30be0f0] viewport_experiments: Refactoring of SSAO code. Uses some optimizations but result is different still test file here to help with debugging.

Antony Riakiotakis noreply at git.blender.org
Tue Oct 21 20:33:53 CEST 2014


Commit: 30be0f097714fff2ab17888d455fdbdb281cf533
Author: Antony Riakiotakis
Date:   Tue Oct 21 17:57:35 2014 +0200
Branches: viewport_experiments
https://developer.blender.org/rB30be0f097714fff2ab17888d455fdbdb281cf533

Refactoring of SSAO code. Uses some optimizations but result is different
still test file here to help with debugging.

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

M	release/scripts/startup/bl_ui/space_view3d.py
M	source/blender/editors/space_view3d/view3d_draw.c
M	source/blender/gpu/GPU_compositing.h
M	source/blender/gpu/intern/gpu_compositing.c
M	source/blender/gpu/shaders/gpu_shader_fx_frag.glsl
M	source/blender/makesdna/DNA_view3d_types.h
M	source/blender/makesrna/intern/rna_space.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 6fdeb78..2c9533a 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -2900,9 +2900,8 @@ class VIEW3D_PT_view3d_shading(Panel):
             col.prop(view, "ssao")
             if view.ssao:
                 subcol = col.column(align=True)
-                subcol.prop(view, "ssao_scale")
                 subcol.prop(view, "ssao_darkening")
-                subcol.prop(view, "ssao_distance_atten")
+                subcol.prop(view, "ssao_distance_max")
                 subcol.prop(view, "ssao_color")
 
 
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 5a1b320..bc2cf04 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -3449,7 +3449,7 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3
 
 	/* post process */
 	if (do_compositing) {
-		GPU_fx_do_composite_pass(rv3d->compositor, v3d);
+		GPU_fx_do_composite_pass(rv3d->compositor, v3d, rv3d);
 	}
 	
 	/* Disable back anti-aliasing */
diff --git a/source/blender/gpu/GPU_compositing.h b/source/blender/gpu/GPU_compositing.h
index b186c0c..a669508 100644
--- a/source/blender/gpu/GPU_compositing.h
+++ b/source/blender/gpu/GPU_compositing.h
@@ -35,6 +35,7 @@
 /* opaque handle for framebuffer compositing effects (defined in gpu_compositing.c )*/
 typedef struct GPUFX GPUFX;
 
+struct RegionView3D;
 struct View3D;
 struct rcti;
 
@@ -58,6 +59,6 @@ void GPU_destroy_fx_compositor(GPUFX *fx);
 bool GPU_initialize_fx_passes(GPUFX *fx, struct rcti *rect, rcti *scissor_rect, int fxflags);
 
 /* do compositing on the fx passes that have been initialized */
-bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d);
+bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d, struct RegionView3D *rv3d);
 
 #endif // __GPU_COMPOSITING_H__
diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c
index cf3c9e9..90089da 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -167,7 +167,7 @@ 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) {
+bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d, struct RegionView3D *rv3d) {
 	GPUShader *fx_shader;
 	int numslots = 0, i;
 	
@@ -187,14 +187,38 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d) {
 	/* 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; 
-		int ssao_uniform, ssao_color_uniform;
+		/* view vectors for the corners of the view frustum. Can be used to recreate the world space position easily */
+		float ssao_viewvecs[3][4] = {
+		    {-1.0f, -1.0f, -1.0f, 1.0f},
+		    {1.0f, -1.0f, -1.0f, 1.0f},
+		    {-1.0f, 1.0f, -1.0f, 1.0f}
+		};
+		int i;
+		int screendim_uniform, color_uniform, depth_uniform, dof_uniform, blurred_uniform;
+		int ssao_uniform, ssao_color_uniform, ssao_viewvecs_uniform;
 		float fac = v3d->dof_fstop * v3d->dof_aperture;
 		float dof_params[2] = {v3d->dof_aperture * fabs(fac / (v3d->dof_focal_distance - fac)), 
 							   v3d->dof_focal_distance};
-		float ssao_params[4] = {v3d->ssao_scale, v3d->ssao_darkening, v3d->ssao_distance_atten, 0.0};
+		float ssao_params[4] = {v3d->ssao_distance_max, v3d->ssao_darkening, 0.0f, 0.0f};
 		float screen_dim[2] = {fx->gbuffer_dim[0], fx->gbuffer_dim[1]};
 		
+		float invproj[4][4];
+
+		/* invert the view matrix */
+		invert_m4_m4(invproj, rv3d->winmat);
+
+		/* convert the view vectors to view space */
+		for (i = 0; i < 3; i++) {
+			mul_m4_v4(invproj, ssao_viewvecs[i]);
+			/* normalized trick see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
+			mul_v3_fl(ssao_viewvecs[i], 1.0f / ssao_viewvecs[i][3]);
+			mul_v3_fl(ssao_viewvecs[i], 1.0f / ssao_viewvecs[i][2]);
+		}
+
+		/* we need to store the differences */
+		ssao_viewvecs[1][0] -= ssao_viewvecs[0][0];
+		ssao_viewvecs[1][1] = ssao_viewvecs[2][1] - ssao_viewvecs[0][1];
+
 		dof_uniform = GPU_shader_get_uniform(fx_shader, "dof_params");
 		ssao_uniform = GPU_shader_get_uniform(fx_shader, "ssao_params");
 		ssao_color_uniform = GPU_shader_get_uniform(fx_shader, "ssao_color");
@@ -202,6 +226,7 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d) {
 		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");
+		ssao_viewvecs_uniform = GPU_shader_get_uniform(fx_shader, "ssao_viewvecs");
 		
 		GPU_shader_bind(fx_shader);
 		
@@ -209,7 +234,8 @@ bool GPU_fx_do_composite_pass(GPUFX *fx, struct View3D *v3d) {
 		GPU_shader_uniform_vector(fx_shader, dof_uniform, 2, 1, dof_params);
 		GPU_shader_uniform_vector(fx_shader, ssao_uniform, 4, 1, ssao_params);
 		GPU_shader_uniform_vector(fx_shader, ssao_color_uniform, 4, 1, v3d->ssao_color);
-		
+		GPU_shader_uniform_vector(fx_shader, ssao_viewvecs_uniform, 4, 3, ssao_viewvecs[0]);
+
 		GPU_texture_bind(fx->color_buffer, numslots++);
 		GPU_shader_uniform_texture(fx_shader, blurred_uniform, fx->color_buffer);
 		/* generate mipmaps for the color buffer */
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_frag.glsl
index d373350..7b5cabf 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_frag.glsl
@@ -18,17 +18,21 @@ uniform vec2 dof_params;
 uniform vec4 ssao_params;
 uniform vec4 ssao_color;
 
+/* store the view space vectors for the corners of the view frustum here. It helps to quickly reconstruct view space vectors
+ * by using uv coordinates, see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
+uniform vec4 ssao_viewvecs[3];
+
 #define NUM_SAMPLES 8
 
-vec3 calculate_view_space_normal(in vec4 viewposition)
+vec3 calculate_view_space_normal(in vec3 viewposition)
 {
-    vec3 normal = cross(normalize(dFdx(viewposition.xyz)), 
-                        normalize(dFdy(viewposition.xyz)));
+    vec3 normal = cross(normalize(dFdx(viewposition)),
+                        normalize(dFdy(viewposition)));
     normalize(normal);
     return normal;
 }
 
-vec4 calculate_view_space_position(in vec2 uvcoords, float depth)
+vec3 calculate_view_space_position(in vec2 uvcoords, float depth)
 {	
     //First we need to calculate the view space distance from the shader inputs
     //This will unfortunately depend on the precision of the depth buffer which is not linear
@@ -39,7 +43,20 @@ vec4 calculate_view_space_position(in vec2 uvcoords, float depth)
     viewposition = gl_ProjectionMatrixInverse * viewposition;
     viewposition = viewposition / viewposition.w;
     
-    return viewposition;
+    return viewposition.xyz;
+}
+
+vec3 get_view_space_from_depth(in vec2 uvcoords, float depth)
+{
+    /* convert depth to non-normalized range */
+    float d = 2.0 * depth - 1.0;
+
+    /* simple depth reconstruction, see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
+    float zview = gl_ProjectionMatrix[2][3] / (d - gl_ProjectionMatrix[2][2]);
+
+    vec3 pos = vec3(zview * (ssao_viewvecs[0].xy + uvcoords * ssao_viewvecs[1].xy), zview);
+
+    return pos;
 }
 
 float calculate_dof_coc(in vec4 viewposition, inout vec3 normal)
@@ -59,24 +76,27 @@ float calculate_ssao_factor(float depth)
     if (depth == 1.0)
         return 0.0;
 
-    vec4 position = calculate_view_space_position(framecoords.xy, depth);
+    vec3 position = get_view_space_from_depth(framecoords.xy, depth);
     vec3 normal = calculate_view_space_normal(position);
 
-    // divide by distance to camera to make the effect independent
-    vec2 offset = (ssao_params.x / position.z) * vec2(1.0/screendim.x, 1.0/screendim.y);
+    // find the offset in screen space by multiplying a point in camera space at the depth of the point by the projection matrix.
+    vec4 offset = (gl_ProjectionMatrix * vec4(ssao_params.x, ssao_params.x, position.z, 1.0));
     float factor = 0.0;
     int x, y;
     
+    /* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */
+    offset = (offset / offset.w) * 0.5 + vec4(0.5);
+
     for (x = 0; x < NUM_SAMPLES; x++) {
         for (y = 0; y < NUM_SAMPLES; y++) {
-            vec2 uvcoords = framecoords.xy + (vec2(x,y) - vec2(4.0)) * offset;
+            vec2 uvcoords = framecoords.xy + (vec2(x,y) - vec2(4.0)) * offset.xy;
 	
             float depth = texture2D(depthbuffer, uvcoords).r;
             if (depth != 1.0) {
-                vec4 pos_new = calculate_view_space_position(uvcoords, depth);
-                vec3 dir = vec3(pos_new.xyz) - vec3(position.xyz);
+                vec3 pos_new = get_view_space_from_depth(uvcoords, depth);
+                vec3 dir = pos_new - position;
                 float len = length(dir);
-                factor += max(dot(dir, normal) * (1.0/(1.0 + len * len * ssao_params.z)), 0.0);
+                factor += max(dot(dir, normal) * max(1.0 - len / ssao_params.x, 0.0), 0.0);
             }
         }
     }
@@ -95,7 +115,12 @@ void main()
     // blend between blurred-non blurred images based on coc	
     //vec4 color = coc * texture2D(blurredcolorbuffer, framecoords.xy) +
     //       (1.0 - coc) * texture2D(colorbuffer, framecoords.xy);
-    
-    vec4 color = mix(texture2D(colorbuffer, framecoords.xy), ssao_color, calculate_ssao_factor(depth)); 
-    gl_FragColor = vec4(color.xyz, 1.0);
+
+    vec3 position = get_view_space_from_depth(framecoords.xy, depth);
+    vec3 normal = calculate_view_space_normal(position);
+
+//    vec4 color = mix(texture2D(colorbuffer, framecoords.xy), ssao_color, calculate_ssao_factor(depth));
+//    gl_FragColor = vec4(color.xyz, 1.

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list