Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines/basic/shaders/basic_conservative_depth_geom.glsl')
-rw-r--r--source/blender/draw/engines/basic/shaders/basic_conservative_depth_geom.glsl51
1 files changed, 51 insertions, 0 deletions
diff --git a/source/blender/draw/engines/basic/shaders/basic_conservative_depth_geom.glsl b/source/blender/draw/engines/basic/shaders/basic_conservative_depth_geom.glsl
new file mode 100644
index 00000000000..d478f37691e
--- /dev/null
+++ b/source/blender/draw/engines/basic/shaders/basic_conservative_depth_geom.glsl
@@ -0,0 +1,51 @@
+#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+/* Adaptation of Conservative Rasterization
+ * from GPU Gems 2
+ * Using method 2.
+ *
+ * Actual final implementation does not do conservative rasterization and only
+ * avoids triangles producing no fragments.
+ */
+
+void main()
+{
+ /* Compute plane normal in ndc space. */
+ vec3 pos0 = gl_in[0].gl_Position.xyz / gl_in[0].gl_Position.w;
+ vec3 pos1 = gl_in[1].gl_Position.xyz / gl_in[1].gl_Position.w;
+ vec3 pos2 = gl_in[2].gl_Position.xyz / gl_in[2].gl_Position.w;
+ vec3 plane = normalize(cross(pos1 - pos0, pos2 - pos0));
+ /* Compute NDC bound box. */
+ vec4 bbox = vec4(min(min(pos0.xy, pos1.xy), pos2.xy), max(max(pos0.xy, pos1.xy), pos2.xy));
+ /* Convert to pixel space. */
+ bbox = (bbox * 0.5 + 0.5) * drw_view.viewport_size.xyxy;
+ /* Detect failure cases where triangles would produce no fragments. */
+ bvec2 is_subpixel = lessThan(bbox.zw - bbox.xy, vec2(1.0));
+ /* View aligned triangle. */
+ const float threshold = 0.00001;
+ bool is_coplanar = abs(plane.z) < threshold;
+
+ for (int i = 0; i < 3; i++) {
+ gl_Position = gl_in[i].gl_Position;
+ if (all(is_subpixel)) {
+ vec2 ofs = (i == 0) ? vec2(-1.0) : ((i == 1) ? vec2(2.0, -1.0) : vec2(-1.0, 2.0));
+ /* HACK: Fix cases where the triangle is too small make it cover at least one pixel. */
+ gl_Position.xy += drw_view.viewport_size_inverse * gl_Position.w * ofs;
+ }
+ /* Test if the triangle is almost parralele with the view to avoid precision issues. */
+ else if (any(is_subpixel) || is_coplanar) {
+ /* HACK: Fix cases where the triangle is Parallel to the view by deforming it slightly. */
+ vec2 ofs = (i == 0) ? vec2(-1.0) : ((i == 1) ? vec2(1.0, -1.0) : vec2(1.0));
+ gl_Position.xy += drw_view.viewport_size_inverse * gl_Position.w * ofs;
+ }
+ else {
+ /* Triangle expansion should happen here, but we decide to not implement it for
+ * depth precision & performance reasons. */
+ }
+
+ view_clipping_distances_set(gl_in[i]);
+ EmitVertex();
+ }
+ EndPrimitive();
+}