0
$\begingroup$

I need to raycast many points (up to 10k points) in BGE with python, and the performance is poor. Reduce the range and polygon count improves slightly, but still far from ideal. I would get 10 frame per second at most.

I need to know the range accurately for many points at any instance. Imagine a flash bomb in BGE, where I need to ray trace the path in all direction.

I already written the core as a C++ library and import with python module to speed things up. The c++ library calls BGE raycast directly. It's the raycast function that is the bottle neck. I looked into the source code, and there seems to be quite a bit of overhead checking.

Any fast solution to it?

[thoughts: GLSL rendering also need some form of raycast to ray trace shadow and lights. I am imagining someone might have managed to use the rendering engine's ray trace to off-load the raycast to GPU. Any thought?]

$\endgroup$
4
$\begingroup$

First off, what is the actual application? I highly doubt you need to do 10k raycasts. Generally if you invert the problem you can find new ways to solve it. (ie instead of can the camera see the objects, ask can the objects see the camera. You can then apply culling based on if the object is in the view frustrum etc. etc.)


Shadows are done using depth-buffer calculations, not raycasts (the geometry is mathematically projected onto a plane, and for each pixel, the depth is used to decide if it's in front or if if's behind). However, if you can represent your problem such that the answer can be determined by looking at what objects are visible to the pixels of a camera, then there is a solution using the rasterizer.

If each object has a unique color and is shadeless, and you perform a bge.texture.ImageRender() to generate a texture from a particular camera (any but the active camera), you can then sample it using list(texture.source.image), and then, using the color at a specified pixel, you can look up what object has that color. You could also sample the depth buffer by setting the camera into depth or zbuff mode (depth only if you have a floating-point texture that it's loading into).

This process can be automated somewhat. In one system I developed, I had to sample what object was clicked on when there were about 1 million polies. Having them all as physics objects added 5-6 seconds to program startup, and ran very slowly. So I did as described above, with the same auto-assigning unique colors at startup. I also used a shader that could flick between the 'uniqueID' mode and a 'display' mode such that by setting a uniform, the objects could be identified or display nicely.


Now you mention "Imagine a flash bomb in BGE, where I need to ray trace the path in all direction.". This could be represented by six cameras with a 90 degree field of view. Six cameras rendering at 512x512 does run at 60FPS with a million polygons - but it's a near thing. (GTX970, i7-6700)

$\endgroup$
  • $\begingroup$ I need to get the precise distance for 10k points in python under BGE. The distances are streamed elsewhere for physical simulations, so yes getting distances precisely is the only acceptable way to do it. Whether the data should be acquired through raycast, that is the question. Raytraced shadow is part of blender's intrinsic function. As a random thought, I was wondering is it hackable to get distances into python. Your response actually inspired me to look into getting Z-coordinate from Z-buffer, which might be a solution. Let me look at this further. $\endgroup$ – hkhako Jan 25 '17 at 20:23
  • $\begingroup$ "Raytraced shadow is part of blender's intrinsic function" Yes, in render mode. In game mode it's done using the depth buffer. (See twitter.com/simonschreibt/status/806272700469678081 for a bit of an explanation). You can recover the depth buffer information using imageRender.depth: pythonapi.upbge.org/… $\endgroup$ – sdfgeoff Jan 27 '17 at 0:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.