0025221: Visualization - Depth test errors in ray-tracing scene containing face outlines
authorduv <duv@opencascade.com>
Tue, 25 Oct 2016 08:21:17 +0000 (11:21 +0300)
committerapn <apn@opencascade.com>
Thu, 27 Oct 2016 14:29:00 +0000 (17:29 +0300)
Calculation of polygon offset for ray tracing has been changed.
Issues with wrong data in FBO depth buffer has been resolved.

src/Shaders/PathtraceBase.fs
src/Shaders/RaytraceBase.fs
src/Shaders/RaytraceRender.fs
tests/v3d/raytrace/bug25221 [new file with mode: 0644]

index bf778ad..09db692 100644 (file)
@@ -652,17 +652,10 @@ vec4 PathTrace (in SRay theRay, in vec3 theInverse)
     // Evaluate depth on first hit
     if (aDepth == 0)
     {
-      // For polygons that are parallel to the screen plane, the depth slope
-      // is equal to 1, resulting in small polygon offset. For polygons that
-      // that are at a large angle to the screen, the depth slope tends to 1,
-      // resulting in a larger polygon offset
-      float aPolygonOffset = uSceneEpsilon * EPS_SCALE /
-        max (abs (dot (theRay.Direct, aHit.Normal)), MIN_SLOPE);
+      vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin, 1.f);
 
-      // Hit point in NDC-space [-1,1] (the polygon offset is applied in the world space)
-      vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin + theRay.Direct * aPolygonOffset, 1.f);
-
-      aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w) * 0.5f + 0.5f;
+      float aPolygonOffset = PolygonOffset (aHit.Normal, theRay.Origin);
+      aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE) * 0.5f + 0.5f;
     }
 
     // fetch material (BSDF)
index 6c5f5e4..d5f9a80 100644 (file)
@@ -787,6 +787,31 @@ vec3 SmoothNormal (in vec2 theUV, in ivec4 theTriangle)
                     aNormal0 * (1.0f - theUV.x - theUV.y));
 }
 
+#define POLYGON_OFFSET_UNIT 0.f
+#define POLYGON_OFFSET_FACTOR 1.f
+#define POLYGON_OFFSET_SCALE 0.006f
+
+// =======================================================================
+// function : PolygonOffset
+// purpose  : Computes OpenGL polygon offset
+// =======================================================================
+float PolygonOffset (in vec3 theNormal, in vec3 thePoint)
+{
+  vec4 aProjectedNorm = vec4 (theNormal, -dot (theNormal, thePoint)) * uUnviewMat;
+
+  float aPolygonOffset = POLYGON_OFFSET_UNIT;
+
+  if (aProjectedNorm.z * aProjectedNorm.z > 1e-20f)
+  {
+    aProjectedNorm.xy *= 1.f / aProjectedNorm.z;
+
+    aPolygonOffset += POLYGON_OFFSET_FACTOR * max (abs (aProjectedNorm.x),
+                                                   abs (aProjectedNorm.y));
+  }
+
+  return aPolygonOffset;
+}
+
 // =======================================================================
 // function : SmoothUV
 // purpose  : Interpolates UV coordinates across the triangle
@@ -908,17 +933,10 @@ vec4 Radiance (in SRay theRay, in vec3 theInverse)
     // Evaluate depth on first hit
     if (aDepth == 0)
     {
-      // For polygons that are parallel to the screen plane, the depth slope
-      // is equal to 1, resulting in small polygon offset. For polygons that
-      // that are at a large angle to the screen, the depth slope tends to 1,
-      // resulting in a larger polygon offset
-      float aPolygonOffset = uSceneEpsilon * EPS_SCALE /
-        max (abs (dot (theRay.Direct, aHit.Normal)), MIN_SLOPE);
-
-      // Hit point in NDC-space [-1,1] (the polygon offset is applied in the world space)
-      vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin + theRay.Direct * aPolygonOffset, 1.f);
+      vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin, 1.f);
 
-      aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w) * 0.5f + 0.5f;
+      float aPolygonOffset = PolygonOffset (aHit.Normal, theRay.Origin);
+      aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE) * 0.5f + 0.5f;
     }
 
     vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);
index ae25d4e..e2e493f 100644 (file)
@@ -95,7 +95,14 @@ void main (void)
 
 #else
 
-  OutColor = mix (texture2D (uAccumTexture, vPixel), aColor, uSampleWeight);
+  if (uSampleWeight >= 1.f)
+  {
+    OutColor = aColor;
+  }
+  else
+  {
+    OutColor = mix (texture2D (uAccumTexture, vPixel), aColor, uSampleWeight);
+  }
 
 #endif // ADAPTIVE_SAMPLING
 
diff --git a/tests/v3d/raytrace/bug25221 b/tests/v3d/raytrace/bug25221
new file mode 100644 (file)
index 0000000..279cb22
--- /dev/null
@@ -0,0 +1,72 @@
+puts "========"
+puts "OCC25221"
+puts "========"
+##########################################
+## Visualization - Depth test errors in ray-tracing scene containing face outlines
+##########################################
+
+# custom shapes
+set aShape [locate_data_file occ/Bottom.brep]
+
+# setup 3D viewer content
+vinit name=View1 w=512 h=512
+
+vsetdispmode 1
+restore $aShape s
+vdisplay s
+vfit
+
+# activate ray-tracing
+vrenderparams -raytrace
+
+# highlight the shape
+vmoveto 200 200
+
+vdump $imagedir/${casename}_lines_closeup.png
+
+vzoom 0.5
+
+vdump $imagedir/${casename}_lines_far.png
+
+vfit
+
+# change camera to perspective
+vcamera -persp
+
+# change highlight display mode
+vdisplay s -highMode 1
+
+# highlight the shape again
+vmoveto 0 0
+vmoveto 200 200
+
+vdump $imagedir/${casename}_faces_closeup.png
+
+# apply transformation
+vlocrotate s 0 0 0 0 0 1 10
+vloctranslate s -30 0 0
+vmoveto 0 0
+vmoveto 200 200
+
+vdump $imagedir/${casename}_faces_closeup_rotated.png
+
+vlocreset s
+vmoveto 0 0
+vmoveto 200 200
+
+vzoom 0.5
+
+vdump $imagedir/${casename}_faces_far.png
+
+# enable Path tracing
+vrenderparams -gi
+vfit
+vfps 100
+
+vdump $imagedir/${casename}_faces_pt.png
+
+# rotate camera
+vrotate 0 0.2 0
+vfps 100
+
+vdump $imagedir/${casename}_faces_pt_rot.png