Difference between revisions of "Reference:Isosurface"

From POV-Wiki
Jump to navigation Jump to search
m (1 revision: Initial Load (TF))
 
m (version changes)
 
(6 intermediate revisions by the same user not shown)
Line 4: Line 4:
 
{{#indexentry:keyword, isosurface}}  
 
{{#indexentry:keyword, isosurface}}  
 
{{#indexentry:function, isosurface}}
 
{{#indexentry:function, isosurface}}
{{#indexentry:keyword, function}}   
+
{{#indexentry:keyword, function}}
<p>Details about many of the things that can be done with the isosurface object are
+
{{#indexentry:keyword, polarity}}   
discussed in the isosurface tutorial section. Below you will only find the syntax basics:</p>
+
<p>See the <code>isosurface</code> [[Documentation:Tutorial Section 3.2#Isosurface Object|tutorial]] for more about working with <em>isosurfaces</em>.</p>
 +
 
 +
<p>{{New}} in version 3.8 a <code>potential</code> pattern has been added to define a pattern based on the <em>potential</em> field of a <code>blob</code> or <code>isosurface</code> object. See also: [[Reference:Potential Pattern|Potential Pattern]].</p>
 +
 
 +
<p>The syntax basics are as follows:</p>
  
 
<pre>
 
<pre>
Line 18: Line 22:
 
   [open]
 
   [open]
 
   [max_trace INTEGER] | [all_intersections]
 
   [max_trace INTEGER] | [all_intersections]
 +
  [polarity on | +VALUE | off | -VALUE]
 
   [OBJECT_MODIFIERS...]
 
   [OBJECT_MODIFIERS...]
 
   }
 
   }
Line 29: Line 34:
 
accuracy    : 0.001
 
accuracy    : 0.001
 
max_gradient : 1.1
 
max_gradient : 1.1
 +
polarity    : off
 
</pre>
 
</pre>
  
<p><code>function { ... }</code> This must be specified and be the first item of the
+
<p>Since <em>isosurfaces</em> are defined by a user supplied <code>function { ... }</code> it must be specified as the first item of the <code>isosurface</code> statement. Here you place all the mathematical functions that will describe the surface.</p>
<code>isosurface</code> statement. Here you place all the mathematical functions that
 
will describe the surface.</p>
 
  
 
{{#indexentry:contained_by, isosurface}}
 
{{#indexentry:contained_by, isosurface}}
 
{{#indexentry:keyword, contained_by}}
 
{{#indexentry:keyword, contained_by}}
<p><code>contained_by { ... }</code> The <code>contained_by</code> <em>object</em> limits the
+
<p>The <code>contained_by</code> <em>object</em> limits the area where POV-Ray samples for the surface of the function. This container can either be a <code>sphere</code> or a <code>box</code> both of which use the standard POV-Ray syntax. If nothing is specified a default <code>box</code>, as noted above, will be used. See additional usage examples below:</p>
area where POV-Ray samples for the surface of the function. This container can either be a
+
 
sphere or a box, both of which use the standard POV-Ray syntax. If not specified a
 
<code>box {&lt;-1,-1,-1&gt;, &lt;1,1,1&gt;}</code> will be used as default.</p>
 
 
<pre>
 
<pre>
 
contained_by { sphere { CENTER, RADIUS } }
 
contained_by { sphere { CENTER, RADIUS } }
Line 48: Line 50:
 
{{#indexentry:threshold, isosurface}}
 
{{#indexentry:threshold, isosurface}}
 
{{#indexentry:keyword, threshold}}
 
{{#indexentry:keyword, threshold}}
<p><code>threshold</code> This specifies how much strength, or substance to give the
+
<p>Using <code>threshold</code> specifies how much strength, or substance to give the <code>isosurface</code>. The surface appears where the <code>function</code> value equals the <code>threshold</code> value. See above for the listed default value.</p>
<code>isosurface</code>. The surface appears where the <code>function</code> value
 
equals the <code>threshold</code> value. The default threshold is 0.</p>
 
<pre>function = threshold</pre>
 
  
 
{{#indexentry:accuracy, isosurface}}
 
{{#indexentry:accuracy, isosurface}}
 
{{#indexentry:keyword, accuracy}}  
 
{{#indexentry:keyword, accuracy}}  
<p><code>accuracy</code> The isosurface finding method is a recursive subdivision method.
+
<p>The <code>isosurface</code> resolver uses a recursive subdivision method. This subdivision goes on until the length of the interval where POV-Ray finds a surface point is less than the specified <code>accuracy</code>. See above for the listed default value. Be aware that smaller values produce more accurate surfaces, but takes longer to render.</p>
This subdivision goes on until the length of the interval where POV-Ray finds a surface
 
point is less than the specified <code>accuracy</code>. The default value is 0.001.
 
<br>Smaller values produces more accurate surfaces, but it takes longer to render.</p>
 
  
 
{{#indexentry:max_gradient, isosurface}}
 
{{#indexentry:max_gradient, isosurface}}
 
{{#indexentry:keyword, max_gradient}}  
 
{{#indexentry:keyword, max_gradient}}  
<p><code>max_gradient</code> POV-Ray can find the first intersecting point between a ray and
+
<p>POV-Ray can find the first intersecting point between a ray and the <code>isosurface</code> of any continuous function if the maximum gradient of the function is known. To that end you can specify a <code>max_gradient</code> for the function. See above for the listed default value. When the <code>max_gradient</code> used to find the intersecting point is too high, the render slows down considerably. Conversely, when it is too low, artifacts or holes may appear on the isosurface, and in some cases when it is way too low, the surface does not show at all. While rendering the <code>isosurface</code> POV-Ray stores the found gradient values and issues a warning, if these values are either higher or much lower than the specified <code>max_gradient</code> value:</p>
the <code>isosurface</code> of any continuous function if the maximum gradient of the function
 
is known. Therefore you can specify a <code>max_gradient</code> for the function.
 
The default value is 1.1.  When the <code>max_gradient</code> used to find the
 
intersecting point is too high, the render slows down considerably. When it is too
 
low, artifacts or holes may appear on the isosurface. When it is way too low, the surface
 
does not show at all. While rendering the isosurface POV-Ray records the found gradient values
 
and prints a warning if these values are higher or much lower than the specified
 
<code>max_gradient</code>:</p>
 
  
 
<pre>
 
<pre>
Line 88: Line 76:
 
{{#indexentry:dynamic max_gradient}}
 
{{#indexentry:dynamic max_gradient}}
 
<p>For best performance you should specify a value close to the real maximum gradient.</p>
 
<p>For best performance you should specify a value close to the real maximum gradient.</p>
<p><code>evaluate</code> POV-Ray can also dynamically adapt the used max_gradient.
+
<p><em>Isosurfaces</em> can also dynamically adapt the used <code>max_gradient</code>. To activate this technique you have to specify the <code>evaluate</code> keyword followed by these three parameters:</p>
To activate this technique you have to specify the <code>evaluate</code> keyword
+
 
followed by three parameters:</p>
 
 
<ul>
 
<ul>
<li>&nbsp;&nbsp;P0: the minimum max_gradient in the estimation process,</li>
+
  <li><strong>P0:</strong> the minimum <code>max_gradient</code> in the estimation process.</li>
<li>&nbsp;&nbsp;P1: an over-estimating factor. This means that the max_gradient is  
+
  <li><strong>P1:</strong> an over-estimating factor. That is, the <code>max_gradient</code> is multiplied by the <em>P1</em> parameter.</li>
multiplied by the P1 parameter.</li>
+
  <li><strong>P2:</strong> an attenuation parameter of 1 or less</li>
<li>&nbsp;&nbsp;P2: an attenuation parameter (1 or less)</li>
 
 
</ul>
 
</ul>
<p>In this case POV-Ray starts with the <code>max_gradient</code> value <code>P0</code>
 
and dynamically changes it during the render using <code>P1</code> and <code>P2</code>.
 
In the evaluation process, the P1 and P2 parameters are used in
 
quadratic functions. This means that over-estimation increases more
 
rapidly with higher values and attenuation more rapidly with lower
 
values. Also with dynamic <code>max_gradient</code>, there can be artifacts and holes.</p>
 
  
<p>If you are unsure what values to use, start a render without <code>evaluate</code> to get
+
<p>In this case POV-Ray starts with the <code>max_gradient</code> value <em>P0</em> and dynamically changes it during the render using <em>P1</em> and <em>P2</em>. In the evaluation process, the <em>P1</em> and <em>P2</em> parameters are used in
a value for <code>max_gradient</code>. Now you can use it with <code>evaluate</code> like this:</p>
+
quadratic functions. This means that over-estimation increases more rapidly with higher values and attenuates more rapidly with lower values. It should also be noted that when using dynamic <code>max_gradient</code>, there can be artifacts or holes.</p>
 +
 
 +
<p>If you are unsure what values to use, just start a render <em>without</em> using <code>evaluate</code> to get a value for the <code>max_gradient</code>, then use that value with <code>evaluate</code> like this:</p>
 +
 
 
<ul>
 
<ul>
<li>P0 : found max_gradient * min_factor<br>
+
  <li><strong>P0:</strong> <code>max_gradient * Min_Factor</code></li>
<em>min_factor</em> being a float between 0 and 1 to reduce the
+
  <li><strong>P1:</strong> <code>sqrt(max_gradient/(max_gradient * Min_Factor))</code></li>
<code>max_gradient</code> to a <em>minimum max_gradient</em>. The ideal value for P0
+
  <li><strong>P2:</strong> should be 1 or less use 0.7 as a good starting point.</li>
would be the average of the found max_gradients, but we do not
 
have access to that information.<br>
 
A good starting point is 0.6 for the min_factor</li>
 
<li>P1 : sqrt(found max_gradient/(found max_gradient * min_factor))<br>
 
<em>min_factor</em> being the same as used in P0
 
this will give an over-estimation factor of more than 1, based
 
on your minimum max_gradient and the found max_gradient.</li>
 
<li>P2 : 1 or less<br>
 
0.7 is a good starting point.</li>
 
 
</ul>
 
</ul>
<p>
+
 
When there are artifacts / holes in the isosurface, increase the min_factor and / or P2 a bit.
+
<p>Where <em>Min_Factor</em> is a float between 0 and 1 to reduce the <code>max_gradient</code> to a <em>minimum</em> <code>max_gradient</code>. The ideal value for <em>P0</em> would be the average of the found maximum gradients, but we do not
Example: when the first run gives a found max_gradient of 356, start with</p>
+
have access to that information. A good starting point for <em>Min_Factor</em> is 0.6</p>
 +
 
 +
<p>If there are artifacts or holes in the <code>isosurface</code>, you can just increase <em>Min_Factor</em> and / or <em>P2</em>. For Example: when the first run gives a <em>found</em> <code>max_gradient</code> of 356, start with:</p>
 
<pre>
 
<pre>
 
#declare Min_factor= 0.6;
 
#declare Min_factor= 0.6;
Line 133: Line 109:
 
</pre>
 
</pre>
  
<p>
+
<p>This method is only an approximation of what happens internally, but it gives faster rendering speeds with the majority of <em>isosurfaces</em>.</p>
This method is only an approximation of what happens internally, but it
 
gives faster rendering speeds with the majority of isosurfaces.</p>
 
  
 
{{#indexentry:open, isosurface}}
 
{{#indexentry:open, isosurface}}
 
{{#indexentry:keyword, open}}  
 
{{#indexentry:keyword, open}}  
<p><code>open</code> When the isosurface is not fully contained within the contained_by object,
+
<p>When the <code>isosurface</code> is not fully contained within the <code>contained_by</code> object, there will be a cross section. When this happens, you will see the surface of the container. Using the <code>open</code> keyword, these cross section surfaces are removed, and the inside of the <code>isosurface</code> becomes visible.</p>
there will be a cross section. Where this happens, you will see the surface of the container.
+
 
With the <code>open</code> keyword, these cross section surfaces are removed. The inside of the isosurface
+
<p class="Note"><strong>Note:</strong> Using <code>open</code> slows down the render speed, and it is not recommended for use with CSG operations.</p>
becomes visible.</p>
 
<p class="Note"><strong>Note:</strong> Using <code>open</code> slows down the render speed, and it is not recommended to use it with CSG operations.</p>
 
  
 
{{#indexentry:max_trace, isosurface}}
 
{{#indexentry:max_trace, isosurface}}
Line 149: Line 121:
 
{{#indexentry:all_intersections, isosurface}}
 
{{#indexentry:all_intersections, isosurface}}
 
{{#indexentry:keyword, all_intersections}}
 
{{#indexentry:keyword, all_intersections}}
<p><code>max_trace</code> Isosurfaces can be used in CSG shapes since they are solid finite objects
+
<p><em>Isosurfaces</em> can be used in CSG shapes since they are solid finite objects - if not finite by themselves, they are through the cross section with the container. By default POV-Ray searches only for the first surface which the ray intersects. However, when using an <code>isosurface</code> in CSG operations, the other surfaces must also be found. Consequently, the keyword <code>max_trace</code> followed by an integer value, must be added to the <code>isosurface</code> statement. To check for all surfaces, use the keyword <code>all_intersections</code> instead. With <code>max_trace</code> it only checks until that number is reached.</p>
- if not finite by themselves, they are through the cross section with the container.
+
<p class="Note"><strong>Note:</strong> The current implementation has a <em>limit</em> of 10 <em>intersections</em> in all cases.</p>
<br>By default POV-Ray searches only for the first surface which the ray intersects. But when using an
+
<p>By default, the inside of an <code>isosurface</code> is defined as the set of all points inside the <code>contained_by</code> shape where the function values are below the threshold. {{New}} in version 3.8 this can be changed via the <code>polarity</code> keyword. Specifying a <em>positive</em> setting or <code>on</code> will instead cause function values <em>above</em> the threshold to be considered inside. Specifying a <em>negative</em> setting or <code>off</code> will give the default behavior.
<code>isosurface</code> in CSG operations, the other surfaces must also be found. Therefore,  
 
the keyword <code>max_trace</code> must be added to the <code>isosurface</code> statement.
 
It must be followed by an integer value. To check for all surfaces, use the keyword <code>all_intersections</code> instead.
 
<br>With <code>all_intersections</code> POV-Ray keeps looking until all surfaces are found.
 
With a <code>max_trace</code> it only checks until that number is reached.</p>
 

Latest revision as of 08:47, 30 June 2017

See the isosurface tutorial for more about working with isosurfaces.

New in version 3.8 a potential pattern has been added to define a pattern based on the potential field of a blob or isosurface object. See also: Potential Pattern.

The syntax basics are as follows:

isosurface {
  function { FUNCTION_ITEMS }
  [contained_by { SPHERE | BOX }]
  [threshold FLOAT_VALUE]
  [accuracy FLOAT_VALUE]
  [max_gradient FLOAT_VALUE]
  [evaluate P0, P1, P2]
  [open]
  [max_trace INTEGER] | [all_intersections]
  [polarity on | +VALUE | off | -VALUE] 
  [OBJECT_MODIFIERS...]
  }

Isosurface default values:

contained_by : box{-1,1}
threshold    : 0.0
accuracy     : 0.001
max_gradient : 1.1
polarity     : off

Since isosurfaces are defined by a user supplied function { ... } it must be specified as the first item of the isosurface statement. Here you place all the mathematical functions that will describe the surface.

The contained_by object limits the area where POV-Ray samples for the surface of the function. This container can either be a sphere or a box both of which use the standard POV-Ray syntax. If nothing is specified a default box, as noted above, will be used. See additional usage examples below:

contained_by { sphere { CENTER, RADIUS } }
contained_by { box { CORNER1, CORNER2 } }

Using threshold specifies how much strength, or substance to give the isosurface. The surface appears where the function value equals the threshold value. See above for the listed default value.

The isosurface resolver uses a recursive subdivision method. This subdivision goes on until the length of the interval where POV-Ray finds a surface point is less than the specified accuracy. See above for the listed default value. Be aware that smaller values produce more accurate surfaces, but takes longer to render.

POV-Ray can find the first intersecting point between a ray and the isosurface of any continuous function if the maximum gradient of the function is known. To that end you can specify a max_gradient for the function. See above for the listed default value. When the max_gradient used to find the intersecting point is too high, the render slows down considerably. Conversely, when it is too low, artifacts or holes may appear on the isosurface, and in some cases when it is way too low, the surface does not show at all. While rendering the isosurface POV-Ray stores the found gradient values and issues a warning, if these values are either higher or much lower than the specified max_gradient value:

Warning: The maximum gradient found was 5.257, but max_gradient of
the isosurface was set to 5.000. The isosurface may contain holes!
Adjust max_gradient to get a proper rendering of the isosurface.
Warning: The maximum gradient found was 5.257, but max_gradient of
the isosurface was set to 7.000. Adjust max_gradient to
get a faster rendering of the isosurface.

For best performance you should specify a value close to the real maximum gradient.

Isosurfaces can also dynamically adapt the used max_gradient. To activate this technique you have to specify the evaluate keyword followed by these three parameters:

  • P0: the minimum max_gradient in the estimation process.
  • P1: an over-estimating factor. That is, the max_gradient is multiplied by the P1 parameter.
  • P2: an attenuation parameter of 1 or less

In this case POV-Ray starts with the max_gradient value P0 and dynamically changes it during the render using P1 and P2. In the evaluation process, the P1 and P2 parameters are used in quadratic functions. This means that over-estimation increases more rapidly with higher values and attenuates more rapidly with lower values. It should also be noted that when using dynamic max_gradient, there can be artifacts or holes.

If you are unsure what values to use, just start a render without using evaluate to get a value for the max_gradient, then use that value with evaluate like this:

  • P0: max_gradient * Min_Factor
  • P1: sqrt(max_gradient/(max_gradient * Min_Factor))
  • P2: should be 1 or less use 0.7 as a good starting point.

Where Min_Factor is a float between 0 and 1 to reduce the max_gradient to a minimum max_gradient. The ideal value for P0 would be the average of the found maximum gradients, but we do not have access to that information. A good starting point for Min_Factor is 0.6

If there are artifacts or holes in the isosurface, you can just increase Min_Factor and / or P2. For Example: when the first run gives a found max_gradient of 356, start with:

#declare Min_factor= 0.6;
isosurface {
  ...
  evaluate 356*Min_factor,  sqrt(356/(356*Min_factor)),  0.7
  //evaluate 213.6, 1.29, 0.7
  ...
  }

This method is only an approximation of what happens internally, but it gives faster rendering speeds with the majority of isosurfaces.

When the isosurface is not fully contained within the contained_by object, there will be a cross section. When this happens, you will see the surface of the container. Using the open keyword, these cross section surfaces are removed, and the inside of the isosurface becomes visible.

Note: Using open slows down the render speed, and it is not recommended for use with CSG operations.

Isosurfaces can be used in CSG shapes since they are solid finite objects - if not finite by themselves, they are through the cross section with the container. By default POV-Ray searches only for the first surface which the ray intersects. However, when using an isosurface in CSG operations, the other surfaces must also be found. Consequently, the keyword max_trace followed by an integer value, must be added to the isosurface statement. To check for all surfaces, use the keyword all_intersections instead. With max_trace it only checks until that number is reached.

Note: The current implementation has a limit of 10 intersections in all cases.

By default, the inside of an isosurface is defined as the set of all points inside the contained_by shape where the function values are below the threshold. New in version 3.8 this can be changed via the polarity keyword. Specifying a positive setting or on will instead cause function values above the threshold to be considered inside. Specifying a negative setting or off will give the default behavior.