I realized that the method I posted earlier had some serious drawbacks. It is dependenT on the detail setting (minimum distance stopping treshold), so it is not a proper distance estimate. It also scales poorly for multiple objects (since you need to do all-pairwise distance products).
I did some Googling and found out that blending was actually already described in John Hart's original zeno paper:
http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.3825(Soft Metablobbies section)
Hart's method is local meaning you can define a radius outside which nothing will be affected. It also scales nicely to multiple objects.
#include "DE-Raytracer.frag"
uniform float R1; slider[0.1,1.1,2.3]
uniform float T; slider[0.1,1.1,2.3]
uniform float Dist; slider[0.1,1.1,2.3]
// some primitives from Quilez's lib
float maxcomp(vec3 a) { return max(a.x,max(a.y,a.z)); }
float sdToBox( vec3 p, vec3 b )
{
vec3 di = abs(p) - b;
float mc = maxcomp(di);
return min(mc,length(max(di,0.0)));
}
float sdSphere(vec3 p, float s) { return length(p)-s; }
// Hart's blending function
float CR(float r, float R) {
float rR = clamp(r/R,0,1);
float rR2= rR*rR;
return 2.0*rR2*rR-3.0*rR2+1.0;
}
// The function proposed by Knighty.
uniform float alpha; slider[0,0,1]
float munion(float a, float b, float alpha){
return 1.0/(1.0+alpha)*(a+b-sqrt(abs(a*a+b*b-2.0*alpha*a*b)));
}
float DE(vec3 p) {
float de1 = sdToBox(p-vec3(Dist,0.0,0.0),vec3(0.1));
float de2 = sdSphere(p-vec3(0.0,0.0,0.0),0.1);
//return munion(de1,de2,alpha)-0.5; // <-- for trying Knighty's approach
// Sum primitives
float sum = 0.0;
sum += CR(de1,R1);
sum += CR(de2,R1);
// ... and their radii
float radiSum = R1+R1;
return (2.0/3.0)*(T - sum)*radiSum;
}
Ooops! These operations actually give smooth distance field. You will see the difference only when you add some value to the DE:
"munion(a,b,1)" will give the same result as "min(a,b)" but "munion(a,b,1)+0.5" is different from "min(a,b)+0.5".
You want to subtract something from the 'munion', right? I tried your method - as might be seen on the picture below, it is a global method, so the sphere and box will change shapes also farther away from the melting point.