POV-Ray : Newsgroups : povray.general : Speeding up rendering many spheres Server Time: 28 May 2020 22:09:29 GMT
  Speeding up rendering many spheres (Message 1 to 10 of 13)  
Goto Latest 10 Messages Next 3 Messages >>>
From: Nicolas George
Subject: Speeding up rendering many spheres
Date: 6 May 2020 15:47:59
Message: <5eb2dc2f@news.povray.org>
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.


Post a reply to this message

From: William F Pokorny
Subject: Re: Speeding up rendering many spheres
Date: 6 May 2020 16:24:45
Message: <5eb2e4cd$1@news.povray.org>
On 5/6/20 11:47 AM, Nicolas George wrote:
> 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.
> 
Have you looked at bounding mode 2 (+bm2)? If not that's worth a shot.

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

Bill P.


Post a reply to this message

From: Bald Eagle
Subject: Re: Speeding up rendering many spheres
Date: 6 May 2020 17:30:01
Message: <web.5eb2f40cddc05618fb0b41570@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.

For bounding, blobs are apparently the way to go.
I guess you can use a strength of 1 and that should be a good starting point.

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.

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.


Post a reply to this message

From: Nicolas George
Subject: Re: Speeding up rendering many spheres
Date: 6 May 2020 18:05:59
Message: <5eb2fc87$1@news.povray.org>
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.

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 18:08:54
Message: <5eb2fd36@news.povray.org>
"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.

> 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 18:44:15
Message: <5eb3057f$1@news.povray.org>
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


Post a reply to this message

From: Alain Martel
Subject: Re: Speeding up rendering many spheres
Date: 6 May 2020 18: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 18: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 18: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 19: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

Goto Latest 10 Messages Next 3 Messages >>>

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