POV-Ray : Newsgroups : povray.general : Speeding up rendering many spheres Server Time
26 Apr 2024 18:42:56 EDT (-0400)
  Speeding up rendering many spheres (Message 4 to 13 of 13)  
<<< Previous 3 Messages Goto Initial 10 Messages
From: Nicolas George
Subject: Re: Speeding up rendering many spheres
Date: 6 May 2020 14:05:59
Message: <5eb2fc87$1@news.povray.org>
William F Pokorny , dans le message <5eb2e4cd$1@news.povray.org>, a

> Have you looked at bounding mode 2 (+bm2)? If not that's worth a shot.

I just tried with 20k spheres, it did not make a visible difference.

> Related: There are issues in v37 and the official v38 branch - mitigated 
> 'somewhat' in my povr solver branch - with tiny sphere intersections 
> getting dropped when they should not be. Applies to a few other objects 
> too a situations too. Depends on exactly how the rays approach.
> 
> This can affect Anti-Aliasing time somewhat substantially because the 
> spheres are basically blinking in and out of existence...  There is, 
> IIRC, some related discussion buried in the github pull req #358 comments.
> 
> https://github.com/POV-Ray/povray/pull/358

I am using the version packages by Debian, they say it is a 3.7.0.8. Anyway,
you tell me there is a problem with sphere intersections, but my scene only
has merges, so I should be safe?

What I am really asking is:

merge {
  A
  B
}

merge {
  merge { A }
  merge { B }
}

where A and B are small and made of many tiny objects close together, but
they are far apart from each other.

Will the second version be faster because POV-Ray will compute a bounding
box for the two sub-merges, or shall I write:

merge {
  merge { A bounded_by box_A }
  merge { B bounded_by box_B }
}

?

I shall test, but it would be helpful to know what is supposed to be the
result.

Thanks for your help.


Post a reply to this message

From: Nicolas George
Subject: Re: Speeding up rendering many spheres
Date: 6 May 2020 14:08:54
Message: <5eb2fd36@news.povray.org>
"Bald Eagle" , dans le message

> For bounding, blobs are apparently the way to go.

I doubt it. The principle of bounding box is that they need to be as fast as
possible, while blobs are vey slow.

> For pseudo-sphere-sweeps, I always use a sphere followed by checking if it's the
> first sphere or not.
> If not, then I draw a cylinder from the last sphere to this sphere.
> Save this sphere in a variable for the next loop.
> In your case with varying radii, you can use cones instead of cylinders.
> 
> Perhaps if that works well enough to fill in the space, then you can even
> decrease the number of spheres you use drastically.

I think I was not clear enough in my first question: the scene is done, it
is made of sphere, they are already computed, I am satisfied with it. I only
need help to get POV-Ray to render it before the end of the century.

> Alternately, and I have no idea if this has any advantage - you could
> model a sphere as a mesh or mesh 2 unit sphere base object and just scale
> and translate it.  But that might only save memory, not speed up the
> rendering.

I doubt that a mesh will take less memory than a sphere.

Thanks for your help.


Post a reply to this message

From: Nicolas George
Subject: Re: Speeding up rendering many spheres
Date: 6 May 2020 14:44:15
Message: <5eb3057f$1@news.povray.org>

> I shall test, but it would be helpful to know what is supposed to be the
> result.

I ran the test, with the scene below.

My conclusion is that POV-Ray does not try to compute bounding boxes for
components of a CSG object.

Can somebody confirm it is the expected behavior?

Well, that means I should gain a significant speed improvement by computing
intermediate bounding boxes before rendering.

As a side note: maybe a directive auto_bounding_box would be a good idea to
let the scene author hint POV-Ray: "this is a very complex CSG object, but
this part is small, it deserves its own bounding box".

Thanks for your help.


My test scene:

camera { 
  location <0, 0, -2>
  look_at <0, 0, 0>
}

#macro many_spheres(x0, y0, z0)
  #local i = -10;
  #while (i <= 10)
    #local j = -10;
    #while (j <= 10)
      #local k = -10;
      #while (k <= 10)
        sphere { <x0 + 0.001 * i, y0 + 0.001 * j, z0 + 0.001 * k>, 0.0008 }
        #local k = k + 1;
      #end
      #local j = j + 1; 
    #end
    #local i = i + 1;
  #end
#end
    
merge {
  //merge {
    many_spheres(-0.5, 0.5, 0)
    //bounded_by { box { <-0.52, 0.48, -0.02>, <-0.48, 0.52, 0.02> } }
  //}
  //merge {
    many_spheres(0.5, -0.5, 0)
    //bounded_by { box { <0.48, -0.52, -0.02>, <0.52, -0.48, 0.02> } }
  //}
  pigment { rgb <1, 1, 0> }
  finish { ambient 1 }
}   

// with bounded_by:  using 8 thread(s) with 3.698 CPU-seconds total
// without:          using 8 thread(s) with 137.005 CPU-seconds total
// without submerge: using 8 thread(s) with 136.182 CPU-seconds total


Post a reply to this message

From: Alain Martel
Subject: Re: Speeding up rendering many spheres
Date: 6 May 2020 14:46:04
Message: <5eb305ec$1@news.povray.org>
Le 2020-05-06 à 11:47, Nicolas George a écrit :
> Hi.
> 
> I have a scene made of 200k spheres merged on a path (like a sphere_sweep,
> but with changing pigment and a ringed look), few are big, many are tiny and
> barely visible. Unsurprisingly, it is taking forever to render.
> 
> I am looking for ways to speed it up.
> 
> My attempt was to group the spheres in sub-merges, and let POV-Ray compute
> bounding boxes for these groups. It helps, a little, but not much. Not
> enough to make the scene possible.
> 
> My next attempt would probably be to try to add explicit bounded_by on the
> groups.
> 
> I could experiment by myself, but people here probably have insight: do you
> have advice on the most efficient way to speed this up?
> 
> Thanks in advance.
> 

If those spheres are not transparent, then, you need to replace that 
merge with an union.

Maybe only have the big one in merge and the small and tiny in unions.
That way, your bounding will get much more efficient.
As the tiny are barely visible, changing from merge to union won't make 
any visible difference. Also, having those opaque instead of transparent 
should have only minimal effect.

I don't think that manual bounding could help.


Post a reply to this message

From: Alain Martel
Subject: Re: Speeding up rendering many spheres
Date: 6 May 2020 14:54:38
Message: <5eb307ee$1@news.povray.org>
Le 2020-05-06 à 14:05, Nicolas George a écrit :
> William F Pokorny , dans le message <5eb2e4cd$1@news.povray.org>, a
>   écrit :
>> Have you looked at bounding mode 2 (+bm2)? If not that's worth a shot.
> 
> I just tried with 20k spheres, it did not make a visible difference.
> 
>> Related: There are issues in v37 and the official v38 branch - mitigated
>> 'somewhat' in my povr solver branch - with tiny sphere intersections
>> getting dropped when they should not be. Applies to a few other objects
>> too a situations too. Depends on exactly how the rays approach.
>>
>> This can affect Anti-Aliasing time somewhat substantially because the
>> spheres are basically blinking in and out of existence...  There is,
>> IIRC, some related discussion buried in the github pull req #358 comments.
>>
>> https://github.com/POV-Ray/povray/pull/358
> 
> I am using the version packages by Debian, they say it is a 3.7.0.8. Anyway,
> you tell me there is a problem with sphere intersections, but my scene only
> has merges, so I should be safe?
> 
> What I am really asking is:
> 
> merge {
>    A
>    B
> }
> 
> merge {
>    merge { A }
>    merge { B }
> }
> 
> where A and B are small and made of many tiny objects close together, but
> they are far apart from each other.

In that case, use:
union{
   merge{ A }
   merge{ B }
}

> 
> Will the second version be faster because POV-Ray will compute a bounding
> box for the two sub-merges, or shall I write:
> 
> merge {
>    merge { A bounded_by box_A }
>    merge { B bounded_by box_B }
> }

This will NOT help in any way.

> 
> ?
> 
> I shall test, but it would be helpful to know what is supposed to be the
> result.
> 
> Thanks for your help.
> 

Whenever you merge several primitives, they always share a single 
bounding box. Any ray entering that bounding box must test for 
everything it contains. ANY internal and manual bounding within that 
merge is totally ignored. That's why merge is so slow.

The purpose of merge is to suppress the internal surfaces when you have 
a transparent object.

So, if you don't use transparency, always use union, never merge.
If you have disconnected transparent components, use an union for them.



Alain


Post a reply to this message

From: Alain Martel
Subject: Re: Speeding up rendering many spheres
Date: 6 May 2020 14:58:43
Message: <5eb308e3$1@news.povray.org>
Le 2020-05-06 à 14:08, Nicolas George a écrit :
> "Bald Eagle" , dans le message
> <web.5eb2f40cddc05618fb0b41570@news.povray.org>, a écrit :
>> For bounding, blobs are apparently the way to go.
> 
> I doubt it. The principle of bounding box is that they need to be as fast as
> possible, while blobs are vey slow.

Slow, yes, but not as slow as a merge of 100's of objects. If you have a 
few K objects, the blob get much faster than a merge.


Post a reply to this message

From: Alain Martel
Subject: Re: Speeding up rendering many spheres
Date: 6 May 2020 15:02:41
Message: <5eb309d1$1@news.povray.org>
Le 2020-05-06 à 14:44, Nicolas George a écrit :
> Nicolas George, dans le message <5eb2fc87$1@news.povray.org>, a écrit :
>> I shall test, but it would be helpful to know what is supposed to be the
>> result.
> 
> I ran the test, with the scene below.
> 
> My conclusion is that POV-Ray does not try to compute bounding boxes for
> components of a CSG object.
> 
> Can somebody confirm it is the expected behavior?
> 
> Well, that means I should gain a significant speed improvement by computing
> intermediate bounding boxes before rendering.
> 
> As a side note: maybe a directive auto_bounding_box would be a good idea to
> let the scene author hint POV-Ray: "this is a very complex CSG object, but
> this part is small, it deserves its own bounding box".
> 
> Thanks for your help.
> 
> 
> My test scene:
> 
> camera {
>    location <0, 0, -2>
>    look_at <0, 0, 0>
> }
> 
> #macro many_spheres(x0, y0, z0)
>    #local i = -10;
>    #while (i <= 10)
>      #local j = -10;
>      #while (j <= 10)
>        #local k = -10;
>        #while (k <= 10)
>          sphere { <x0 + 0.001 * i, y0 + 0.001 * j, z0 + 0.001 * k>, 0.0008 }
>          #local k = k + 1;
>        #end
>        #local j = j + 1;
>      #end
>      #local i = i + 1;
>    #end
> #end
>      
> merge {
>    //merge {
>      many_spheres(-0.5, 0.5, 0)
>      //bounded_by { box { <-0.52, 0.48, -0.02>, <-0.48, 0.52, 0.02> } }
>    //}
>    //merge {
>      many_spheres(0.5, -0.5, 0)
>      //bounded_by { box { <0.48, -0.52, -0.02>, <0.52, -0.48, 0.02> } }
>    //}
>    pigment { rgb <1, 1, 0> }
>    finish { ambient 1 }
> }
> 
> // with bounded_by:  using 8 thread(s) with 3.698 CPU-seconds total
> // without:          using 8 thread(s) with 137.005 CPU-seconds total
> // without submerge: using 8 thread(s) with 136.182 CPU-seconds total
> 

In this sample, you have pigment{rgb<1,1,0>}
This have zero transparency. Meaning that you should absolutely use an 
union and not a merge.

It becomes :

union{
     many_spheres(-0.5, 0.5, 0)
     many_spheres(0.5, -0.5, 0)
   pigment { rgb <1, 1, 0> }
   finish { ambient 1 }
}


Post a reply to this message

From: William F Pokorny
Subject: Re: Speeding up rendering many spheres
Date: 6 May 2020 15:06:58
Message: <5eb30ad2@news.povray.org>
On 5/6/20 2:05 PM, Nicolas George wrote:
> William F Pokorny , dans le message <5eb2e4cd$1@news.povray.org>, a
>   écrit :
>> Have you looked at bounding mode 2 (+bm2)? If not that's worth a shot.
> 
> I just tried with 20k spheres, it did not make a visible difference.
> 
...
> 

Ah, thanks for pounding home that you are using merge{}.

Try changing all merges to unions(1). Then perhaps +bm2 - for which 
there are a lot of tuning parameters I've played with only a little - 
might help. Just the merge to union probably more than enough speed up 
unless you're after real time rendering speeds or something.

Ignore my aside on the intersection depth issues (really a couple). Any 
real fix / improvement there is as likely to cost you time as not. If 
you're doing heavy AA though turning it off, rendering larger and 
scaling down 'might' be faster.

If you are using SDL to create those spheres, parsing could be a 
significant part of the total run time. Do you know how much time 
parsing and how much time rendering?

Somewhere I have some test cases with spheres. Let me see.... Yep. The 
one from the github comments.

-----------------------------------------------------
\time povr2 +w900 +h600 attractors.pov

2 million spheres in unions each with textures.

Parsing 17.325s / Bounding m1 3.504s

povr2 +w900 +h600
Render on my two core i3 : 33.781 seconds

Total CPU measured with \time : 136.43user 0:55.83elapsed
Memory about 1.5G

-------------

p380 (same as above,but many sphere intersections are dropped in v37/v38

107.96user 0.61system 0:45.06elapsed


Bill P.

(1) Unions unnest and so 'might' be better handled by the default 
bounding or +bm2.


Post a reply to this message

From: Nicolas George
Subject: Re: Speeding up rendering many spheres
Date: 6 May 2020 15:21:54
Message: <5eb30e52@news.povray.org>

> If those spheres are not transparent, then, you need to replace that 
> merge with an union.

Before starting, I ran a few small tests and found that merge was slightly
faster. I suppose they were too small to be significant. Indeed, with the
full scene, union is incredibly faster than merge. I should have re-tested
earlier.

Thanks.


Post a reply to this message

From: Bill Pragnell
Subject: Re: Speeding up rendering many spheres
Date: 6 May 2020 17:10:07
Message: <web.5eb326caddc056181b6c6b3a0@news.povray.org>
geo### [at] phareinvalid (Nicolas George) wrote:
> I have a scene made of 200k spheres merged on a path (like a sphere_sweep,
> but with changing pigment and a ringed look), few are big, many are tiny and
> barely visible. Unsurprisingly, it is taking forever to render.
>
> I am looking for ways to speed it up.

Without knowing where your path came from, or quite what 'ringed look' means, my
suggestion might be useless to you, so apologies in advance!

However, in this situation I think I would seriously consider building this as a
mesh, creating a ring of triangles for each point of the path. Triangle rings
can be given different textures, either picked from a list (mesh2), or UV-mapped
from a gradient of your pigment 'space'. Parsing might still take some time, but
I would think rendering would be pretty fast.

Bill


Post a reply to this message

<<< Previous 3 Messages Goto Initial 10 Messages

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.