POV-Ray : Newsgroups : povray.advanced-users : Nitpicking about isosurface threshold : Re: Nitpicking about isosurface threshold Server Time
7 May 2024 03:41:15 EDT (-0400)
  Re: Nitpicking about isosurface threshold  
From: scott
Date: 10 Nov 2015 03:23:59
Message: <5641a99f$1@news.povray.org>
> I observe that the surface appears at values smaller than the threshold value if
> it is not reached. To be more precise: I have a function yielding only 0 or 1

Non-continuous functions like that are very tricky for the solver to 
work with. Look up "mandelbulb distance function" and use something like 
that rather than just a zero/one function. It will make the solver much 
more efficient (ie better results in a shorter time).

> depending on the membership to a given set. 0 indicates membership, 1 not (1
> minus the characteristic function of the set). Threshold values of 0.1, 0.2 and
> 0.9 all give the desired object. To my surprise 1.0 too, 1.1 gives the expected
> unit sphere. Threshold 0.0 yields nothing.
>
> May be a numeric issue at threshold 0.0 and 1.0.
>
> What do I miss here?

The solver tries to find a small interval (the size of which depends on 
"accuracy") where one side is below the interval and the other side is 
above the interval. It does this by looking at the function value at the 
first point on the ray, estimating how much further to look ahead based 
on that value, then repeating, until it gets a satisfactory interval.

If your function is always one before the object, the solver must step 
along very slowly taking many samples before it gets to a zero value. 
Whether your "threshold" is 0.0001 or 0.9999 or anywhere in betweween 
won't make any difference. Your function instantly flips from zero to 
one, so any interval will always contain either all the values from zero 
to one or none of them.

However if you use a distance field function, the function value might 
be 100 at the first point, so the solver can take a huge step towards 
the object. And then when it gets very close you'll get fractional 
distances, so the solver can rapidly converge on an accurate interval 
that contains the surface.

See below code from my GPU mandelbulb renderer that calculates the 
distance function at a point, if it's any help:

float MB(vec3 pos)
{
	pos.xyz = pos.xzy;
	vec3 z = pos;
	float dr = 1.0;
	float r = 0.0;
	for (int i = 0; i < 64 ; i++) {
		r = length(z);
		if (r>2.0)
			break;
			
			if(r==0.0)return 0.0;
					
		// convert to polar coordinates
		float theta = acos(z.z/r);
		float phi = atan(z.y,z.x);
		float zr = pow( r,N-1.0);
		
		dr =  zr*N*dr + 1.0;
		
		// scale and rotate the point
		theta = theta*N;
		phi = phi*N;
		
		// convert back to cartesian coordinates
		z = zr*r*vec3(sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta));
		z+=pos;
	}
	return 0.5*log(r)*r/dr;
}


Post a reply to this message

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