BeginSceneEdit takes ages to execute

Discussion related to the LuxCore functionality, implementations and API.
bartek_zgo
Posts: 116
Joined: Mon Oct 26, 2020 11:42 am

BeginSceneEdit takes ages to execute

Post by bartek_zgo »

Hi Guys,
we are using luxcore for quite long time. We have found, that sometimes luxcore hangs when calling BeginSceneEdit(). Now we have a scene, that makes luxcore block each time.
So we have following situation. The render starts. We are using live session, so we can see that everything looks ok. We want to modify the scene so we call BeginSceneEdit(). At the beginning I thought that luxcore completely hangs executing that command, but it is only slow. The command takes 3 minutes to execute.
I've added some logs to luxcore to investigate.
We are using CPU so luxcore calls:

Code: Select all

void CPURenderEngine::BeginSceneEditLockLess() {
	for (size_t i = 0; i < renderThreads.size(); ++i)
		renderThreads[i]->Interrupt();
	for (size_t i = 0; i < renderThreads.size(); ++i)
		renderThreads[i]->BeginSceneEdit();
}
the first part is ok. But the second loop for ONE thread hangs for 3 minutes. If I edit the same scene for second time, I have to wait for another thread. The thread number looks to be random.

I take a look at void CPURenderThread::StopRenderThread() and found out that the join is waiting 3 minutes.
It is not always 3 minutes. Sometime it is only one minute, but it is still terribly long.

Any idea what could it be? Where should I look?
bartek_zgo
Posts: 116
Joined: Mon Oct 26, 2020 11:42 am

Re: BeginSceneEdit takes ages to execute

Post by bartek_zgo »

currently I'm analyzing bidircputhread.cpp

and it looks that the problem is somewhere here:

Code: Select all

                               if (boost::this_thread::interruption_requested())
                                        SLG_LOG("[BiDirCPURenderThread::" << threadIndex << "] 5b");


                                if (!eyeVertex.bsdf.IsDelta()) {
                                        for (vector<PathVertexVM>::const_iterator lightPathVertex = lightPathVertices.begin();
                                                        lightPathVertex < lightPathVertices.end(); ++lightPathVertex)
                                                ConnectVertices(time, eyeVertex, *lightPathVertex, eyeSampleResult,
                                                                sampler->GetSample(sampleOffset + 6));

                                        assert (eyeSampleResult.IsValid());
                                }

                                //--------------------------------------------------------------
                                // Build the next vertex path ray
                                //--------------------------------------------------------------

                                if (boost::this_thread::interruption_requested())
                                        SLG_LOG("[BiDirCPURenderThread::" << threadIndex << "] 5c");

corresponding output:
[LuxCore][94.593] [BiDirCPURenderThread::12] 5b
[LuxCore][199.949] [BiDirCPURenderThread::12] 5c
daros
Posts: 280
Joined: Thu Dec 12, 2019 3:25 pm
Location: inside human language
Contact:

Re: BeginSceneEdit takes ages to execute

Post by daros »

please help dade!
bartek_zgo
Posts: 116
Joined: Mon Oct 26, 2020 11:42 am

Re: BeginSceneEdit takes ages to execute

Post by bartek_zgo »

I have found that the function Scene::Intersect takes all this time. In our case, CPU use, all this time is taken by EmbreeAccel::Intersect.
This scene has 8000 instances of a tree. So it looks that if the ray hits this tree layer, it stuck for 1-3 minutes.

I'm trying to find out if updating embree lib will help in some way, but I have no idea how to do this.
bartek_zgo
Posts: 116
Joined: Mon Oct 26, 2020 11:42 am

Re: BeginSceneEdit takes ages to execute

Post by bartek_zgo »

I have recompiled luxcore with Embree 4.2 but for some reason render is completely empty. I can see only background image. I think the ray does not hit any geometry.

To compile with Embree 4.2 I've mede following changes:

Code: Select all

diff --git a/src/luxrays/accelerators/embreeaccel.cpp b/src/luxrays/accelerators/embreeaccel.cpp
index 7e6bf39e1..387dd3619 100644
--- a/src/luxrays/accelerators/embreeaccel.cpp
+++ b/src/luxrays/accelerators/embreeaccel.cpp
@@ -226,8 +226,8 @@ bool EmbreeAccel::MeshPtrCompare(const Mesh *p0, const Mesh *p1) {
 }

 bool EmbreeAccel::Intersect(const Ray *ray, RayHit *hit) const {
-       RTCIntersectContext context;
-       rtcInitIntersectContext(&context);
+       RTCRayQueryContext context;
+       rtcInitRayQueryContext(&context);

        RTCRayHit embreeRayHit;

@@ -248,8 +248,14 @@ bool EmbreeAccel::Intersect(const Ray *ray, RayHit *hit) const {
        embreeRayHit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
        embreeRayHit.hit.primID = RTC_INVALID_GEOMETRY_ID;
        embreeRayHit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID;
-
-       rtcIntersect1(embreeScene, &context, &embreeRayHit);
+
+       RTCIntersectArguments intersectArgs;
+       intersectArgs.context = &context;
+
+       rtcIntersect1(embreeScene, &embreeRayHit, &intersectArgs);
+

        if ((embreeRayHit.hit.geomID != RTC_INVALID_GEOMETRY_ID) &&
                        // A safety check in case of not enough numerical precision. Embree

Code: Select all

diff --git a/cmake/Packages/FindEmbree.cmake b/cmake/Packages/FindEmbree.cmake
index 7bcee212b..447592a11 100644
--- a/cmake/Packages/FindEmbree.cmake
+++ b/cmake/Packages/FindEmbree.cmake
@@ -14,22 +14,22 @@
 ## limitations under the License.                                           ##
 ## ======================================================================== ##

-FIND_PATH(EMBREE_INCLUDE_PATH NAMES embree3/rtcore.h PATHS
+FIND_PATH(EMBREE_INCLUDE_PATH NAMES embree4/rtcore.h PATHS
        ${EMBREE_ROOT}/include)
 IF (NOT EMBREE_INCLUDE_PATH)
-       FIND_PATH(EMBREE_INCLUDE_PATH NAMES embree3/rtcore.h PATHS
+       FIND_PATH(EMBREE_INCLUDE_PATH NAMES embree4/rtcore.h PATHS
                /usr/include
                /usr/local/include
                /opt/local/include)
 ENDIF()

-FIND_LIBRARY(EMBREE_LIBRARY NAMES embree3 libembree3.so.3 PATHS
+FIND_LIBRARY(EMBREE_LIBRARY NAMES embree4 libembree4.so.4 PATHS
        ${EMBREE_ROOT}/lib/x64
        ${EMBREE_ROOT}/lib
        ${EMBREE_ROOT}/build
        NO_DEFAULT_PATH)
 IF (NOT EMBREE_LIBRARY)
-       FIND_LIBRARY(EMBREE_LIBRARY NAMES embree3 libembree3.so.3 PATHS
+       FIND_LIBRARY(EMBREE_LIBRARY NAMES embree4 libembree4.so.4 PATHS
                /usr/lib
                /usr/lib64
                /usr/local/lib
[code]
diff --git a/include/luxrays/accelerators/embreeaccel.h b/include/luxrays/accelerators/embreeaccel.h
index b1bc9f5ab..c4f1bccc0 100644
--- a/include/luxrays/accelerators/embreeaccel.h
+++ b/include/luxrays/accelerators/embreeaccel.h
@@ -21,7 +21,7 @@

 #include <boost/thread.hpp>

-#include <embree3/rtcore.h>
+#include <embree4/rtcore.h>

 #include "luxrays/luxrays.h"
 #include "luxrays/core/accelerator.h"

Code: Select all

diff --git a/include/luxrays/core/bvh/bvhbuild.h b/include/luxrays/core/bvh/bvhbuild.h
index bf8b7ab9b..9b762382b 100644
--- a/include/luxrays/core/bvh/bvhbuild.h
+++ b/include/luxrays/core/bvh/bvhbuild.h
@@ -22,8 +22,8 @@
 #include <vector>
 #include <ostream>

-#include <embree3/rtcore.h>
-#include <embree3/rtcore_builder.h>
+#include <embree4/rtcore.h>
+#include <embree4/rtcore_builder.h>

 #include "luxrays/luxrays.h"
 #include "luxrays/core/geometry/bbox.h"

Code: Select all

diff --git a/src/luxrays/core/bvh/bvhembreebuild.cpp b/src/luxrays/core/bvh/bvhembreebuild.cpp
index 9fe9a9e01..8f215edd7 100644
--- a/src/luxrays/core/bvh/bvhembreebuild.cpp
+++ b/src/luxrays/core/bvh/bvhembreebuild.cpp
@@ -20,8 +20,8 @@
 #include <boost/foreach.hpp>
 #include <boost/thread/mutex.hpp>

-#include <embree3/rtcore.h>
-#include <embree3/rtcore_builder.h>
+#include <embree4/rtcore.h>
+#include <embree4/rtcore_builder.h>

 #include "luxrays/core/bvh/bvhbuild.h"
 #include "luxrays/utils/atomic.h"

Code: Select all

diff --git a/src/slg/engines/caches/photongi/pgicbvh.cpp b/src/slg/engines/caches/photongi/pgicbvh.cpp
index 89bb66f03..620c2abbe 100644
--- a/src/slg/engines/caches/photongi/pgicbvh.cpp
+++ b/src/slg/engines/caches/photongi/pgicbvh.cpp
@@ -18,8 +18,8 @@

 #include <algorithm>

-#include <embree3/rtcore.h>
-#include <embree3/rtcore_builder.h>
+#include <embree4/rtcore.h>
+#include <embree4/rtcore_builder.h>

 #include "luxrays/core/bvh/bvhbuild.h"
 #include "slg/engines/caches/photongi/photongicache.h"

Code: Select all

diff --git a/src/slg/lights/strategies/dlscacheimpl/dlscbvh.cpp b/src/slg/lights/strategies/dlscacheimpl/dlscbvh.cpp
index 96944242d..babd2fd19 100644
--- a/src/slg/lights/strategies/dlscacheimpl/dlscbvh.cpp
+++ b/src/slg/lights/strategies/dlscacheimpl/dlscbvh.cpp
@@ -17,8 +17,8 @@
  ***************************************************************************/


-#include <embree3/rtcore.h>
-#include <embree3/rtcore_builder.h>
+#include <embree4/rtcore.h>
+#include <embree4/rtcore_builder.h>

 #include "luxrays/core/bvh/bvhbuild.h"
 #include "slg/lights/strategies/dlscacheimpl/dlscacheimpl.h"

Code: Select all

diff --git a/distfiles/embree-install.sh b/distfiles/embree-install.sh
index 7b56bb2..2cce6c7 100755
--- a/distfiles/embree-install.sh
+++ b/distfiles/embree-install.sh
@@ -6,10 +6,10 @@ LIBRARY_INSTALL_DIR="$1"/lib
 mkdir -p $INCLUDE_INSTALL_DIR
 mkdir -p $LIBRARY_INSTALL_DIR

-cp -av include/embree3 $INCLUDE_INSTALL_DIR
+cp -av include/embree4 $INCLUDE_INSTALL_DIR

 cp -av lib/lib* $LIBRARY_INSTALL_DIR

 rm $LIBRARY_INSTALL_DIR/libtbb.so
 rm $LIBRARY_INSTALL_DIR/libtbb.so.12
-cp $LIBRARY_INSTALL_DIR/libtbb.so.12.1 $LIBRARY_INSTALL_DIR/libtbb.so.12
+cp $LIBRARY_INSTALL_DIR/libtbb.so.12.9 $LIBRARY_INSTALL_DIR/libtbb.so.12

Code: Select all

diff --git a/distfiles/oidn-install.sh b/distfiles/oidn-install.sh
index 07d0fa6..b228998 100755
--- a/distfiles/oidn-install.sh
+++ b/distfiles/oidn-install.sh
@@ -12,4 +12,4 @@ cp -av lib/lib* $LIBRARY_INSTALL_DIR

 rm $LIBRARY_INSTALL_DIR/libtbb.so
 rm $LIBRARY_INSTALL_DIR/libtbb.so.12
-cp $LIBRARY_INSTALL_DIR/libtbb.so.12.1 $LIBRARY_INSTALL_DIR/libtbb.so.12
+cp $LIBRARY_INSTALL_DIR/libtbb.so.12.9 $LIBRARY_INSTALL_DIR/libtbb.so.12

Code: Select all

diff --git a/utils/install b/utils/install
index a1962e2..7c42a5f 100755
--- a/utils/install
+++ b/utils/install
@@ -23,7 +23,7 @@ if echo $LUX_TAG | grep -iq 'sdk' ; then

        mkdir $TARGET/$LUX_TAG/lib
        cp $LUX_TAG/lib/*.so $TARGET/$LUX_TAG/lib
-       cp $TARGET/lib/libOpenImageDenoise.so.1 $TARGET/lib/libembree3.so.3 $TARGET/lib/libtbb.so.12 $TARGET/lib/libtbb.so.2 $TARGET/$LUX_TAG/lib
+       cp $TARGET/lib/libOpenImageDenoise.so.1 $TARGET/lib/libembree4.so.4 $TARGET/lib/libtbb.so.12 $TARGET/lib/libtbb.so.2 $TARGET/$LUX_TAG/lib
        cp -a $TARGET/lib/libnvrtc* $TARGET/$LUX_TAG

        cp $LUX_TAG/README.md $TARGET/$LUX_TAG
@@ -73,7 +73,7 @@ else

        cp $LUX_TAG/bin/luxcoreui $TARGET/$LUX_TAG
        cp $LUX_TAG/lib/*.so $TARGET/$LUX_TAG
-       cp $TARGET/lib/libOpenImageDenoise.so.1 $TARGET/lib/libembree3.so.3 $TARGET/lib/libtbb.so.12 $TARGET/lib/libtbb.so.2 $TARGET/$LUX_TAG
+       cp $TARGET/lib/libOpenImageDenoise.so.1 $TARGET/lib/libembree4.so.4 $TARGET/lib/libtbb.so.12 $TARGET/lib/libtbb.so.2 $TARGET/$LUX_TAG
        cp -a $TARGET/lib/libnvrtc* $TARGET/$LUX_TAG

        cp $LUX_TAG/README.md $TARGET/$LUX_TAG
What more I have made some tricks in build script, to force using https://github.com/embree/embree/releas ... nux.tar.gz
bartek_zgo
Posts: 116
Joined: Mon Oct 26, 2020 11:42 am

Re: BeginSceneEdit takes ages to execute

Post by bartek_zgo »

Hi guys, could anyone help?
I still have an empty render. Embree rtcIntersects1 function returns an empty result (nothing is hit).

I've check all parameters and don't know what to do.
I have found that RTCIntersectsArguments should be initialized so I call:
rtcInitIntersectArguments(&intersectArgs);

This structure has some parameters that changes intersect behavior. I checked them:
feature_mask is initialized by RTC_FEATURE_FLAG_ALL. based on documentation this flag has only effect when using with GPU (not my case)
flags initialized with RTC_RAY_QUERY_FLAG_INCOHERENT. not sure about this, so I kept default value
context -> optional. I've tried to keep NULL or initialize it with context initialized with default values
than we have intersect and filter that are different kind of handler to filter geometry and hits, but if they are NULL they are not executed

than we have ray parameters:
flags should be set to 0
mask - I'm not sure what should it be as I found in documentation: "Further ray masking is enabled by default now as required by most applications and the default ray mask for geometries got changed from 0xFFFFFFFF to 0x1." So I've checked with both values
bartek_zgo
Posts: 116
Joined: Mon Oct 26, 2020 11:42 am

Re: BeginSceneEdit takes ages to execute

Post by bartek_zgo »

First of all I wanted to say that I have recompiled luxcore with embree 4.2. It doesn't change anything with my issue.

I want to show you a short video that shows the problem.

https://we.tl/t-HRjU1pQohr

At the beginning of the video, I move the camera and I can see the result of render in few seconds.
Than I move the camera for the second time and I have to wait about 30s for render.
This is completely random. Sometimes I can move camera 5 times without problems, sometimes it hangs after first move.
In second window you may see what luxcore is doing. The most important part you may find below:

Code: Select all

[LuxCore][2317.428] begin scene edit for each thread i=33
[SDL][2317.428] [18-8-2023 10:49:56] interrupt
[SDL][2317.428] [18-8-2023 10:49:56] join
[SDL][2317.428] [18-8-2023 10:49:56] done
[LuxCore][2317.428] begin scene edit for each thread i=34
[SDL][2317.428] [18-8-2023 10:49:56] interrupt
[SDL][2317.428] [18-8-2023 10:49:56] join
[LuxRays][2350.736] after embre intersect
[SDL][2350.736] [18-8-2023 10:50:30] Intersect 2
[SDL][2350.736] [18-8-2023 10:50:30] Intersect 3
[SDL][2350.736] [18-8-2023 10:50:30] Intersect 4
[SDL][2350.736] [18-8-2023 10:50:30] Intersect exit 2
[LuxCore][2350.736] [BiDirCPURenderThread::34] 5b
[LuxCore][2350.736] [BiDirCPURenderThread::34] 5c
[LuxCore][2350.736] [BiDirCPURenderThread::34] 5d
[LuxCore][2350.736] [BiDirCPURenderThread::34] Next sample
[LuxCore][2350.736] [BiDirCPURenderThread::34] 7
[LuxCore][2350.736] [BiDirCPURenderThread::34] Exited main loop
[LuxCore][2350.736] [BiDirCPURenderThread::34] Rendering thread halted
[SDL][2350.736] [18-8-2023 10:50:30] done
[LuxCore][2350.737] begin scene edit for each thread i=35
[SDL][2350.737] [18-8-2023 10:50:30] interrupt
[SDL][2350.737] [18-8-2023 10:50:30] join
[SDL][2350.737] [18-8-2023 10:50:30] done
[LuxCore][2350.737] begin scene edit for each thread i=36
So when I move camera I call BeginSceneEdit that will stop all threads.
The most important part is in embreeaccel.cpp

Code: Select all

       rtcIntersect1(embreeScene, &embreeRayHit, &intersectArgs);

        if (boost::this_thread::interruption_requested())
                LR_LOG(ctx, "after embre intersect");

So one thread is inside rtcIntersect1. After about 32s you may see in log:
[LuxRays][2350.736] after embre intersect

Any idea?
bartek_zgo
Posts: 116
Joined: Mon Oct 26, 2020 11:42 am

Re: BeginSceneEdit takes ages to execute

Post by bartek_zgo »

Hi guys. Finally I've found the solution.
The ray that is passed to Embree library has Nan in origin and direction. That makes embree library scan all geometry.
So the solution is to add:

Code: Select all

 if (isnan(ray->o.x) || isnan(ray->o.y) || isnan(ray->o.z) || isnan(ray->d.x) || isnan(ray->d.y) || isnan(ray->d.z))
               return false;
in EmbreeAccel::Intersect() function in src/luxrays/accelerators/embreeaccel.cpp file
User avatar
Odilkhan Yakubov
Posts: 209
Joined: Fri Jan 26, 2018 10:07 pm
Location: Tashkent, Uzbekistan

Re: BeginSceneEdit takes ages to execute

Post by Odilkhan Yakubov »

bartek_zgo wrote: Mon Sep 04, 2023 10:19 am Hi guys. Finally I've found the solution.
The ray that is passed to Embree library has Nan in origin and direction. That makes embree library scan all geometry.
So the solution is to add:

Code: Select all

 if (isnan(ray->o.x) || isnan(ray->o.y) || isnan(ray->o.z) || isnan(ray->d.x) || isnan(ray->d.y) || isnan(ray->d.z))
               return false;
in EmbreeAccel::Intersect() function in src/luxrays/accelerators/embreeaccel.cpp file
Hi. Can you fork LuxCore repo and merge into Master source code of LuxCore?
___________________________________________________________________________
LuxCoreRender Developer for Blender
___________________________________________________________________________
juleswilcox
Posts: 3
Joined: Fri Nov 12, 2021 10:19 am
Location: UK
Contact:

Re: BeginSceneEdit takes ages to execute

Post by juleswilcox »

Great work! I have not stumbled on this issue yet but if I managed to solve any other issues then I know how much use it would mean to me. Your persistence has paid off!
Post Reply