This patch increases ray-tracing performance up to 12% in regular mode, and up to 36% in FSAA mode.
//
}
+// =======================================================================
+// function : Center
+// purpose : Returns centroid position along the given axis
+// =======================================================================
+Standard_ShortReal OpenGl_TriangleSet::Center (
+ const Standard_Integer theIndex, const Standard_Integer theAxis) const
+{
+ // Note: Experiments show that the use of the box centroid (instead
+ // of the triangle centroid) increases render performance up to 12%
+
+ const BVH_Vec4i& aTriangle = Elements[theIndex];
+
+ const Standard_ShortReal aVertex0 =
+ BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.x()], theAxis);
+ const Standard_ShortReal aVertex1 =
+ BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.y()], theAxis);
+ const Standard_ShortReal aVertex2 =
+ BVH::VecComp<Standard_ShortReal, 3>::Get (Vertices[aTriangle.z()], theAxis);
+
+ return (Min (Min (aVertex0, aVertex1), aVertex2) +
+ Max (Max (aVertex0, aVertex1), aVertex2)) * 0.5f;
+}
+
// =======================================================================
// function : Box
// purpose : Returns AABB of primitive set
//! Creates new OpenGL element triangulation.
OpenGl_TriangleSet (const Standard_Size theArrayID)
- : BVH_Triangulation<Standard_ShortReal, 3> (),
+ : BVH_Triangulation<Standard_ShortReal, 3>(),
myArrayID (theArrayID)
{
//
//! Returns AABB of primitive set.
BVH_BoxNt Box() const;
+ //! Returns centroid position along the given axis.
+ Standard_ShortReal Center (const Standard_Integer theIndex, const Standard_Integer theAxis) const;
+
public:
BVH_Array3f Normals; //!< Array of vertex normals.
private:
- Standard_Size myArrayID; //!< Id of associated primitive array.
+ Standard_Size myArrayID; //!< ID of associated primitive array.
};
1, // ID of FSAA program
myPostFSAAProgram);
- const Standard_ShortReal aMaxOffset = 0.559017f;
- const Standard_ShortReal aMinOffset = 0.186339f;
-
myGlContext->core20fwd->glEnableVertexAttribArray (Graphic3d_TOA_POS);
myGlContext->core20fwd->glVertexAttribPointer (Graphic3d_TOA_POS, 3, GL_FLOAT, GL_FALSE, 0, NULL);
- // Perform multi-pass adaptive FSAA using ping-pong technique
- // rotated grid AA always uses 4 samples
- for (Standard_Integer anIt = 0; anIt < 4; ++anIt)
+ // Perform multi-pass adaptive FSAA using ping-pong technique.
+ // We use 'FLIPTRI' sampling pattern changing for every pixel
+ // (3 additional samples per pixel, the 1st sample is already
+ // available from initial ray-traced image).
+ for (Standard_Integer anIt = 1; anIt < 4; ++anIt)
{
GLfloat aOffsetX = 1.f / theSizeX;
GLfloat aOffsetY = 1.f / theSizeY;
- if (anIt < 2)
+ if (anIt == 1)
{
- aOffsetX *= anIt < 1 ? aMinOffset : -aMaxOffset;
- aOffsetY *= anIt < 1 ? aMaxOffset : aMinOffset;
+ aOffsetX *= -0.55f;
+ aOffsetY *= 0.55f;
}
- else
+ else if (anIt == 2)
{
- aOffsetX *= anIt > 2 ? aMaxOffset : -aMinOffset;
- aOffsetY *= anIt > 2 ? -aMinOffset : -aMaxOffset;
+ aOffsetX *= 0.00f;
+ aOffsetY *= -0.55f;
}
-
+ else if (anIt == 3)
+ {
+ aOffsetX *= 0.55f;
+ aOffsetY *= 0.00f;
+ }
+
myPostFSAAProgram->SetUniform (myGlContext,
- myUniformLocations[1][OpenGl_RT_uSamples], anIt + 2);
+ myUniformLocations[1][OpenGl_RT_uSamples], anIt + 1);
myPostFSAAProgram->SetUniform (myGlContext,
myUniformLocations[1][OpenGl_RT_uOffsetX], aOffsetX);
myPostFSAAProgram->SetUniform (myGlContext,
myUniformLocations[1][OpenGl_RT_uOffsetY], aOffsetY);
- Handle(OpenGl_FrameBuffer)& aFramebuffer = anIt % 2 ? myRaytraceFBO1 : myRaytraceFBO2;
+ Handle(OpenGl_FrameBuffer)& aFramebuffer = anIt % 2 ? myRaytraceFBO2 : myRaytraceFBO1;
if (anIt == 3) // disable FBO on last iteration
{
{
aFramebuffer->BindBuffer (myGlContext);
}
-
+
myGlContext->core15fwd->glDrawArrays (GL_TRIANGLES, 0, 6);
if (anIt != 3) // set input for the next pass
//! Normalized pixel coordinates.
in vec2 vPixel;
+//! Sub-pixel offset in X direction for FSAA.
+uniform float uOffsetX = 0.f;
+//! Sub-pixel offset in Y direction for FSAA.
+uniform float uOffsetY = 0.f;
+
//! Origin of viewing ray in left-top corner.
uniform vec3 uOriginLT;
//! Origin of viewing ray in left-bottom corner.
//! Number of accumulated FSAA samples.
uniform int uSamples;
-//! Sub-pixel offset in X direction for FSAA.
-uniform float uOffsetX;
-//! Sub-pixel offset in Y direction for FSAA.
-uniform float uOffsetY;
-
//! Output pixel color.
out vec4 OutColor;
int aPixelX = int (gl_FragCoord.x);
int aPixelY = int (gl_FragCoord.y);
+ // Adjust FLIPTRI pattern used for adaptive FSAA
+ float anOffsetX = mix (uOffsetX, -uOffsetX, float (aPixelX % 2));
+ float anOffsetY = mix (uOffsetY, -uOffsetY, float (aPixelY % 2));
+
vec4 aClr0 = texelFetch (uFSAAInputTexture, ivec2 (aPixelX + 0, aPixelY + 0), 0);
vec4 aClr1 = texelFetch (uFSAAInputTexture, ivec2 (aPixelX + 0, aPixelY - 1), 0);
vec4 aClr2 = texelFetch (uFSAAInputTexture, ivec2 (aPixelX + 0, aPixelY + 1), 0);
abs (aClr6.w - aClr0.w) > LUM_DIFFERENCE ||
abs (aClr7.w - aClr0.w) > LUM_DIFFERENCE ||
abs (aClr8.w - aClr0.w) > LUM_DIFFERENCE;
-
+
if (!aRender)
{
aRender = abs (dot (LUMA, aClr1.xyz) - aLum) > LUM_DIFFERENCE ||
}
vec4 aColor = aClr0;
-
+
if (aRender)
{
- SRay aRay = GenerateRay (vPixel + vec2 (uOffsetX, uOffsetY));
-
+ SRay aRay = GenerateRay (vPixel + vec2 (anOffsetX, anOffsetY));
+
vec3 aInvDirect = 1.f / max (abs (aRay.Direct), SMALL);
-
+
aInvDirect = vec3 (aRay.Direct.x < 0.f ? -aInvDirect.x : aInvDirect.x,
aRay.Direct.y < 0.f ? -aInvDirect.y : aInvDirect.y,
aRay.Direct.z < 0.f ? -aInvDirect.z : aInvDirect.z);
-
+
aColor = mix (aClr0, clamp (Radiance (aRay, aInvDirect), 0.f, 1.f), 1.f / uSamples);
}
-
+
OutColor = aColor;
}
\ No newline at end of file