diff --git a/src/Shaders/PathtraceBase.fs b/src/Shaders/PathtraceBase.fs index bf778ad5f2..09db692e99 100644 --- a/src/Shaders/PathtraceBase.fs +++ b/src/Shaders/PathtraceBase.fs @@ -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) diff --git a/src/Shaders/RaytraceBase.fs b/src/Shaders/RaytraceBase.fs index 6c5f5e4692..d5f9a80063 100644 --- a/src/Shaders/RaytraceBase.fs +++ b/src/Shaders/RaytraceBase.fs @@ -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); + 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; } vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex); diff --git a/src/Shaders/RaytraceRender.fs b/src/Shaders/RaytraceRender.fs index ae25d4ef95..e2e493ffce 100644 --- a/src/Shaders/RaytraceRender.fs +++ b/src/Shaders/RaytraceRender.fs @@ -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 index 0000000000..279cb22f97 --- /dev/null +++ b/tests/v3d/raytrace/bug25221 @@ -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