[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