Ray tracing progress: support for lines, markers and text added


Few months ago, the OCCT ray tracing algorithm was rewritten using GLSL. Apart from better portability and certain performance gain, this step opened the door to some important features that can be added most naturally using close OpenGL and GLSL interoperation - such as visualization of lines and text in a ray-traced scene. Lines and text are examples of scene elements that cannot be visualized using purely the ray tracing algorithm.

The idea behind was to draw these "non-ray-traceable" scene elements with help of OpenGL rasterization and then add the ray-traced (shaded) elements using the frame buffer and depth buffer data prepared at the previous step.

Recently, support for lines, markers and text have been implemented in the frames of OCCT Mantis issue 24819 using the above-mentioned combined approach. Currently, this functionality is available in OCCT Git master.

Most important benefits resulted from this improvement are listed below:

  • Interactive selection now works in a ray-traced scene exactly the same way as in a rasterized scene
  • CAD models can be displayed in a ray-traced scene in both shading and wireframe
  • Auxiliary scene elements such as markers and text labels no longer disappear from a 3D view after switching to ray tracing rendering
  • Text annotations can now be added to a ray-traced scene in a common way - i.e. using the standard 2D over-layer of a V3d_View instance

The few snapshots below should illustrate improved ray tracing algorithm results better than words.

A simple ray-traced scene created by OCCT test case v3d/raytrace/bug24819
Ray-traced scene containing the pump model from the gallery at www.opencascade.org with the axis and bolt shown in wireframe
Ray-traced scene containing the same pump model with one part highlighted by interactive detection
Shing Liu's picture

great job!

Yuriy Sinithin's picture

Good morning, guys !

At last month I make some tests of your GLSL code. It's working cool, but your code must be corrected

1. On some cards GLSL program don't working when we use defined constants in function like max, dot . This problem was found on AMD 760G integrated chipset

For example:

vec3 aTrsfInverse = 1.0f / max (abs (aTrsfRay.Direct), vec3(exp2 (-80.0f)));

this code is working on any video cards, but if you are using #define vec3(exp2 (-80.0f)) then we have a problem

2. It some strange with function vec4 Radiance (in SRay theRay, in vec3 theInverse)

you may try to break your loop , but it's don't working . Don't working return, break, continue. The result is strange and may different on various vendors of GPU

Here we need append Post prefix in GLSL program. For example:

// =======================================================================
// function : Radiance
// purpose : Computes color of specified ray
// =======================================================================
vec4 Radiance (in SRay theRay, in vec3 theInverse)
vec3 aResult = vec3(0.0f);
vec4 aWeight = vec4(1.0f);

if (!ComputeResult(theRay,theInverse,aResult,aWeight)) { return vec4 (aResult,aWeight.w); }
if (!ComputeResult(theRay,theInverse,aResult,aWeight)) { return vec4 (aResult,aWeight.w); } //lines
if (!ComputeResult(theRay,theInverse,aResult,aWeight)) { return vec4 (aResult,aWeight.w); } //that
if (!ComputeResult(theRay,theInverse,aResult,aWeight)) { return vec4 (aResult,aWeight.w); } //added in
if (!ComputeResult(theRay,theInverse,aResult,aWeight)) { return vec4 (aResult,aWeight.w); } //OpenGL_Workspace
if (!ComputeResult(theRay,theInverse,aResult,aWeight)) { return vec4 (aResult,aWeight.w); } //_Raytrace.cxx

return vec4 (aResult,aWeight.w);

3. Textured shapes:

vec3 aAmbient;
vec3 aDiffuse;

if (isTexture)
vec4 aFinal = uModelProj * vec4(aPoint,1.0f);
aFinal.xyz *= 1.f / aFinal.w;

aFinal.xy = 0.5f * (aFinal.xy - 1.0f);

vec3 myColor = texture(uOpenGlColorTexture, aFinal.xy).rgb;

if (myColor.rgb != vec3(0.0f))
aAmbient = myColor;
aDiffuse = myColor*0.25;
isTexture = false;

if (!isTexture)
aAmbient = texelFetch (
uRaytraceMaterialTexture, MATERIAL_AMBN (aTriIndex.w)).rgb;
aDiffuse = texelFetch (
uRaytraceMaterialTexture, MATERIAL_DIFF (aTriIndex.w)).rgb;

4. Environment map:

if (aTriIndex.x == -1)
if (aWeight.w == 0.0f) //Reflection on a shape
if (uEnvironmentReflEnable)
float aTime = IntersectSphere (theRay, uSceneRadius);
aResult += aWeight.xyz *textureLod (uEnvironmentMapTexture,
Latlong (theRay.Direct * aTime + theRay.Origin, uSceneRadius), 0.0f).xyz;
aWeight.w = 0.0f; //Background without transparency

if (uEnvironmentEnable)
{ //Textured background
float aTime = IntersectSphere (theRay, uSceneRadius);
aResult += aWeight.xyz *textureLod (uEnvironmentMapTexture,
Latlong (theRay.Direct * aTime + theRay.Origin, uSceneRadius), 0.0f).xyz;
{ //White background
aResult = vec3(1.0f,1.0f,1.0f);
return false;

Here is return false. In the fact this is working on any vendors. Because we can't break the loop and result be strange.

5. On some video cards like Intel HD 4000 we have overloaded samplers:

//! Texture buffer of vertex coords.
uniform samplerBuffer uGeometryVertexTexture;
//! Texture buffer of vertex normals.
uniform samplerBuffer uGeometryNormalTexture;
//! Texture buffer of triangle indices.
uniform isamplerBuffer uGeometryTriangTexture;

and some shapes is don't displayed on the screen. At this time I think that this buffers may be are divided ...

Sergey Anikin's picture

Hello Yuriy,

Thank you a lot for posting such a detailed test report, it is really a great example to follow!

As a logical continuation of it implied by the standard contribution workflow, could you please proceed to OCCT Mantis and report an issue there, to ensure that your feedback will not be lost?
And of course if you have already made some changes in the GLSL code, why not put them into a dedicated OCCT Git branch?
Like this, your contribution would be integrated into OCCT very quickly.

Thank you a lot in advance - and hope to see your commits in OCCT Git repository soon! :)

Best regards,