[Bf-blender-cvs] [f1fd5ed74fb] blender2.8: T55333 Workbench: Cavity Shader

Jeroen Bakker noreply at git.blender.org
Wed Jun 6 15:06:56 CEST 2018


Commit: f1fd5ed74fb0afd602f53860d0b2db46189c218a
Author: Jeroen Bakker
Date:   Wed Jun 6 14:47:54 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBf1fd5ed74fb0afd602f53860d0b2db46189c218a

T55333 Workbench: Cavity Shader

A cavity shader based on SSAO. Works on all workbench deferred passes.

Per 3d viewport the cavity shader options can be set as different
shading needed different options. Some global options are in the
Viewport Display of the scene like num samples and distance.

Experimental: Naming of Ridges and Valleys

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

M	release/scripts/startup/bl_ui/properties_scene.py
M	release/scripts/startup/bl_ui/space_view3d.py
M	source/blender/blenloader/intern/versioning_280.c
M	source/blender/draw/CMakeLists.txt
A	source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl
A	source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl
M	source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl
M	source/blender/draw/engines/workbench/workbench_data.c
M	source/blender/draw/engines/workbench/workbench_deferred.c
M	source/blender/draw/engines/workbench/workbench_materials.c
M	source/blender/draw/engines/workbench/workbench_private.h
M	source/blender/editors/space_view3d/space_view3d.c
M	source/blender/makesdna/DNA_view3d_types.h
M	source/blender/makesrna/intern/rna_scene.c
M	source/blender/makesrna/intern/rna_space.c

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

diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py
index 1b9c7b5eacb..33e89014538 100644
--- a/release/scripts/startup/bl_ui/properties_scene.py
+++ b/release/scripts/startup/bl_ui/properties_scene.py
@@ -476,6 +476,24 @@ class SCENE_PT_viewport_display(SceneButtonsPanel, Panel):
         col.prop(scene.display, "shadow_shift")
 
 
+class SCENE_PT_viewport_display_ssao(SceneButtonsPanel, Panel):
+    bl_label = "Viewport Display SSAO"
+    bl_parent_id = "SCENE_PT_viewport_display"
+
+    @classmethod
+    def poll(cls, context):
+        return True
+
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+        scene = context.scene
+        col = layout.column()
+        col.prop(scene.display, "matcap_ssao_samples")
+        col.prop(scene.display, "matcap_ssao_distance")
+        col.prop(scene.display, "matcap_ssao_attenuation")
+
+
 class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel):
     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY', 'BLENDER_EEVEE'}
     _context_path = "scene"
@@ -492,6 +510,7 @@ classes = (
     SCENE_PT_color_management,
     SCENE_PT_color_management_curves,
     SCENE_PT_viewport_display,
+    SCENE_PT_viewport_display_ssao,
     SCENE_PT_audio,
     SCENE_PT_physics,
     SCENE_PT_rigid_body_world,
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 1a70092eb21..149f93245df 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -3527,6 +3527,14 @@ class VIEW3D_PT_shading(Panel):
             sub.active = shading.show_shadows and not shading.show_xray
             sub.prop(shading, "shadow_intensity", text="")
 
+            row = col.row()
+            row.active = not shading.show_xray
+            row.prop(shading, "show_cavity")
+            sub = row.column()
+            sub.active = not shading.show_xray and shading.show_cavity
+            sub.prop(shading, "cavity_ridge_factor")
+            sub.prop(shading, "cavity_valley_factor")
+
             row = col.row()
             row.prop(shading, "show_object_outline")
             sub = row.row()
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index f4c61e424ae..83a0f21002a 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -1568,5 +1568,18 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
 				}
 			}
 		}
+		if (!DNA_struct_elem_find(fd->filesdna, "View3DShading", "float", "cavity_valley_factor")) {
+			for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
+				for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
+					for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
+						if (sl->spacetype == SPACE_VIEW3D) {
+							View3D *v3d = (View3D *)sl;
+							v3d->shading.cavity_valley_factor = 1.0f;
+							v3d->shading.cavity_ridge_factor = 1.0f;
+						}
+					}
+				}
+			}
+		}
 	}
 }
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 40fd8762821..9c3aa34b5d8 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -219,6 +219,8 @@ data_to_c_simple(engines/eevee/shaders/volumetric_scatter_frag.glsl SRC)
 data_to_c_simple(engines/eevee/shaders/volumetric_integration_frag.glsl SRC)
 
 data_to_c_simple(engines/workbench/shaders/workbench_background_lib.glsl SRC)
+data_to_c_simple(engines/workbench/shaders/workbench_cavity_lib.glsl SRC)
+data_to_c_simple(engines/workbench/shaders/workbench_cavity_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_checkerboard_depth_frag.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_common_lib.glsl SRC)
 data_to_c_simple(engines/workbench/shaders/workbench_data_lib.glsl SRC)
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl
new file mode 100644
index 00000000000..f6ddd54b7f7
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl
@@ -0,0 +1,71 @@
+out vec4 fragColor;
+
+uniform sampler2D depthBuffer;
+uniform sampler2D colorBuffer;
+uniform sampler2D normalBuffer;
+uniform sampler2D positionBuffer;
+
+uniform vec2 invertedViewportSize;
+uniform mat4 WinMatrix; /* inverse WinMatrix */
+
+uniform vec4 viewvecs[3];
+uniform vec4 ssao_params;
+uniform vec4 ssao_settings;
+uniform sampler2D ssao_jitter;
+
+layout(std140) uniform samples_block {
+	vec4 ssao_samples[500];
+};
+
+#define ssao_samples_num	ssao_params.x
+#define jitter_tilling		ssao_params.yz
+#define dfdy_sign			ssao_params.w
+
+#define ssao_distance		ssao_settings.x
+#define ssao_factor_cavity	ssao_settings.y
+#define ssao_factor_edge	ssao_settings.z
+#define ssao_attenuation	ssao_settings.a
+
+vec3 get_view_space_from_depth(in vec2 uvcoords, in float depth)
+{
+	if (WinMatrix[3][3] == 0.0) {
+		/* Perspective */
+		float d = 2.0 * depth - 1.0;
+
+		float zview = -WinMatrix[3][2] / (d + WinMatrix[2][2]);
+
+		return zview * (viewvecs[0].xyz + vec3(uvcoords, 0.0) * viewvecs[1].xyz);
+	}
+	else {
+		/* Orthographic */
+		vec3 offset = vec3(uvcoords, depth);
+
+		return viewvecs[0].xyz + offset * viewvecs[1].xyz;
+	}
+}
+
+/* forward declartion */
+void ssao_factors(
+        in float depth, in vec3 normal, in vec3 position, in vec2 screenco,
+        out float cavities, out float edges);
+
+
+void main()
+{
+	vec2 screenco = vec2(gl_FragCoord.xy) * invertedViewportSize;
+	ivec2 texel = ivec2(gl_FragCoord.xy);
+
+	float depth = texelFetch(depthBuffer, texel, 0).x;
+	vec3 position = get_view_space_from_depth(screenco, depth);
+
+	vec4 diffuse_color = texelFetch(colorBuffer, texel, 0);
+	vec3 normal_viewport = normal_decode(texelFetch(normalBuffer, texel, 0).rg);
+	if (diffuse_color.a == 0.0) {
+		normal_viewport = -normal_viewport;
+	}
+
+	float cavity = 0.0, edges = 0.0;
+	ssao_factors(depth, normal_viewport, position, screenco, cavity, edges);
+
+	fragColor = vec4(cavity, edges, 0.0, 1.0);
+}
\ No newline at end of file
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
new file mode 100644
index 00000000000..da0198ab2e7
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
@@ -0,0 +1,79 @@
+
+
+/*  from The Alchemy screen-space ambient obscurance algorithm
+ * http://graphics.cs.williams.edu/papers/AlchemyHPG11/VV11AlchemyAO.pdf */
+
+void ssao_factors(
+        in float depth, in vec3 normal, in vec3 position, in vec2 screenco,
+        out float cavities, out float edges)
+{
+	cavities = edges = 0.0;
+	/* early out if there is no need for SSAO */
+	if (ssao_factor_cavity == 0.0 && ssao_factor_edge == 0.0)
+		return;
+
+	/* take the normalized ray direction here */
+	vec3 noise = texture(ssao_jitter, screenco.xy * jitter_tilling).rgb;
+
+	/* find the offset in screen space by multiplying a point
+	 * in camera space at the depth of the point by the projection matrix. */
+	vec2 offset;
+	float homcoord = WinMatrix[2][3] * position.z + WinMatrix[3][3];
+	offset.x = WinMatrix[0][0] * ssao_distance / homcoord;
+	offset.y = WinMatrix[1][1] * ssao_distance / homcoord;
+	/* convert from -1.0...1.0 range to 0.0..1.0 for easy use with texture coordinates */
+	offset *= 0.5;
+
+	int num_samples = int(ssao_samples_num);
+
+	/* Note. Putting noise usage here to put some ALU after texture fetch. */
+	vec2 rotX = noise.rg;
+	vec2 rotY = vec2(-rotX.y, rotX.x);
+
+	for (int x = 0; x < num_samples && x < 500; x++) {
+		/* ssao_samples[x].xy is sample direction (normalized).
+		 * ssao_samples[x].z is sample distance from disk center. */
+
+		/* Rotate with random direction to get jittered result. */
+		vec2 dir_jittered = vec2(dot(ssao_samples[x].xy, rotX), dot(ssao_samples[x].xy, rotY));
+		dir_jittered.xy *= ssao_samples[x].z + noise.b;
+
+		vec2 uvcoords = screenco.xy + dir_jittered * offset;
+
+		if (uvcoords.x > 1.0 || uvcoords.x < 0.0 || uvcoords.y > 1.0 || uvcoords.y < 0.0)
+			continue;
+
+		float depth_new = texture(depthBuffer, uvcoords).r;
+
+		/* Handle Background case */
+		bool is_background = (depth_new == 1.0);
+
+		/* This trick provide good edge effect even if no neighboor is found. */
+		vec3 pos_new = get_view_space_from_depth(uvcoords, (is_background) ? depth : depth_new);
+
+		if (is_background)
+			pos_new.z -= ssao_distance;
+
+		vec3 dir = pos_new - position;
+		float len = length(dir);
+		float f_cavities = dot(dir, normal);
+		float f_edge = -f_cavities;
+		float f_bias = 0.05 * len + 0.0001;
+
+		float attenuation = 1.0 / (len * (1.0 + len * len * ssao_attenuation));
+
+		/* use minor bias here to avoid self shadowing */
+		if (f_cavities > -f_bias)
+			cavities += f_cavities * attenuation;
+
+		if (f_edge > f_bias)
+			edges += f_edge * attenuation;
+	}
+
+	cavities /= ssao_samples_num;
+	edges /= ssao_samples_num;
+
+	/* don't let cavity wash out the surface appearance */
+	cavities = clamp(cavities * ssao_factor_cavity, 0.0, 1.0);
+	edges = edges * ssao_factor_edge;
+}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl
index 326837bc69f..9116e2e7ef5 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_deferred_composite_frag.glsl
@@ -5,6 +5,8 @@ uniform sampler2D colorBuffer;
 uniform sampler2D specularBuffer;
 uniform sampler2D normalBuffer;
 /* normalBuffer contains viewport normals */
+uniform sampler2D cavityBuffer;
+
 uniform vec2 invertedViewportSize;
 uniform float shadowMultiplier;
 uniform float lightMultiplier;
@@ -77,7 +79,6 @@ void main()
 #endif
 
 #ifdef V3D_LIGHTING_MATCAP
-	/* TODO: if pixel data is matcap. then */
 	vec3 diffuse_light = texel

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list