Got soft subtract kinda working

This commit is contained in:
Jack Christensen 2023-11-30 17:33:35 -05:00
parent 8b08b92494
commit 679589554e
1 changed files with 127 additions and 109 deletions

View File

@ -71,8 +71,6 @@ struct NormalEstimationData
GLSLPrimitive secondClosestPrimitive;
};
float sphereSDF(vec3 p, vec3 center, float r)
{
return length(p - center) - r;
@ -148,98 +146,142 @@ float sdf(vec3 pos, GLSLPrimitive prim)
float smoothMinSDF(float d1, float d2, float k)
{
if (k == 0.0) k = 0.000001;
float h = max(k - abs(d1 - d2), 0) / k;
if (k == 0.0) return min(d1, d2);
float h = max(k - abs(d1 - d2), 0.0) / k;
return min(d1, d2) - h * h * h * k * 1.0 / 6.0;
}
float smoothMaxSDF(float d1, float d2, float k)
{
if (k == 0.0) k = 0.000001;
float h = min(k - abs(d1 - d2), 0) / k;
return min(d1, d2) - h * h * h * k * 1.0 / 6.0;
if (k == 0.0) return max(d1, d2);
float h = max(k - abs(d1 - d2), 0.0) / k;
return max(d1, d2) - h * h * k * 0.25;
}
void estimateSmoothNormals(vec3 p, float smoothness, float epsilon, inout vec3 normals)
float opSmoothSubtraction(float d1, float d2, float k)
{
float d, nx, ny, nz;
for (int i = 0; i < primitives.length(); i++)
{
if (primitives[i].subtract == 1) continue;
if (i == 0)
{
d = sdf(p, primitives[0]);
nx = sdf(vec3(p.x + epsilon, p.y, p.z), primitives[0]);
ny = sdf(vec3(p.x, p.y + epsilon, p.z), primitives[0]);
nz = sdf(vec3(p.x, p.y, p.z + epsilon), primitives[0]);
}
else
{
d = smoothMinSDF(d, sdf(p, primitives[i]), smoothness);
nx = smoothMinSDF(nx, sdf(vec3(p.x + epsilon, p.y, p.z), primitives[i]), smoothness);
ny = smoothMinSDF(ny, sdf(vec3(p.x, p.y + epsilon, p.z), primitives[i]), smoothness);
nz = smoothMinSDF(nz, sdf(vec3(p.x, p.y, p.z + epsilon), primitives[i]), smoothness);
}
}
for (int i = 0; i < primitives.length(); i++)
{
if (primitives[i].subtract == 1)
{
d = max(d, -sdf(p, primitives[i]));
nx = max(nx, -sdf(vec3(p.x + epsilon, p.y, p.z), primitives[i]));
ny = max(ny, -sdf(vec3(p.x, p.y + epsilon, p.z), primitives[i]));
nz = max(nz, -sdf(vec3(p.x, p.y, p.z + epsilon), primitives[i]));
}
}
nx -= d;
ny -= d;
nz -= d;
normals = normalize(vec3(nx, ny, nz));
float h = clamp(0.5 - 0.5 * (d2 + d1) / k, 0.0, 1.0);
return mix(d2, -d1, h) + k * h * (1.0 - h);
}
void estimateSmoothNormalsMax(vec3 p, float smoothness, float epsilon, inout vec3 normals)
{
float d = sdf(p, primitives[0]);
float nx = sdf(vec3(p.x + epsilon, p.y, p.z), primitives[0]);
float ny = sdf(vec3(p.x, p.y + epsilon, p.z), primitives[0]);
float nz = sdf(vec3(p.x, p.y, p.z + epsilon), primitives[0]);
for (int i = 0; i < primitives.length(); i++)
{
d = smoothMaxSDF(d, sdf(p, primitives[i]), smoothness);
nx = smoothMaxSDF(nx, sdf(vec3(p.x + epsilon, p.y, p.z), primitives[i]), smoothness);
ny = smoothMaxSDF(ny, sdf(vec3(p.x, p.y + epsilon, p.z), primitives[i]), smoothness);
nz = smoothMaxSDF(nz, sdf(vec3(p.x, p.y, p.z + epsilon), primitives[i]), smoothness);
}
nx -= d;
ny -= d;
nz -= d;
normals = normalize(vec3(nx, ny, nz));
}
vec3 estimateNormals(vec3 p, GLSLPrimitive prim, float epsilon)
{
float x = sdf(vec3(p.x + epsilon, p.y, p.z), prim) - sdf(vec3(p.x - epsilon, p.y, p.z), prim);
float y = sdf(vec3(p.x, p.y + epsilon, p.z), prim) - sdf(vec3(p.x, p.y - epsilon, p.z), prim);
float z = sdf(vec3(p.x, p.y, p.z + epsilon), prim) - sdf(vec3(p.x, p.y, p.z - epsilon), prim);
return normalize(vec3(x, y, z));
}
//vec3 estimateNormalsMax(vec3 p, float smoothness) {
// float epsilon = 0.001;
// float d = max(torusSDF(p, torus.center, torus.R, torus.r), sphereSDF(p, sphere.center, sphere.r));
// float nx = max(torusSDF(vec3(p.x + epsilon, p.y, p.z), torus.center, torus.R, torus.r), sphereSDF(vec3(p.x + epsilon, p.y, p.z), sphere.center, sphere.r)) - d;
// float ny = max(torusSDF(vec3(p.x, p.y + epsilon, p.z), torus.center, torus.R, torus.r), sphereSDF(vec3(p.x, p.y + epsilon, p.z), sphere.center, sphere.r)) - d;
// float nz = max(torusSDF(vec3(p.x, p.y, p.z + epsilon), torus.center, torus.R, torus.r), sphereSDF(vec3(p.x, p.y, p.z + epsilon), sphere.center, sphere.r)) - d;
// return normalize(vec3(nx, ny, nz));
//void estimateSmoothNormals(vec3 p, float smoothness, float epsilon, inout vec3 normals)
//{
// float d, nx, ny, nz;
//
// for (int i = 0; i < primitives.length(); i++)
// {
// if (i == 0)
// {
// d = sdf(p, primitives[0]);
// nx = sdf(vec3(p.x + epsilon, p.y, p.z), primitives[0]);
// ny = sdf(vec3(p.x, p.y + epsilon, p.z), primitives[0]);
// nz = sdf(vec3(p.x, p.y, p.z + epsilon), primitives[0]);
// }
// if (primitives[i].subtract == 1) continue;
// else
// {
// d = smoothMinSDF(d, sdf(p, primitives[i]), smoothness);
// nx = smoothMinSDF(nx, sdf(vec3(p.x + epsilon, p.y, p.z), primitives[i]), smoothness);
// ny = smoothMinSDF(ny, sdf(vec3(p.x, p.y + epsilon, p.z), primitives[i]), smoothness);
// nz = smoothMinSDF(nz, sdf(vec3(p.x, p.y, p.z + epsilon), primitives[i]), smoothness);
// }
// }
//
// for (int i = 0; i < primitives.length(); i++)
// {
// if (primitives[i].subtract == 1)
// {
// d = smoothMaxSDF(d, -sdf(p, primitives[i]), smoothness);
// nx = smoothMaxSDF(nx, -sdf(vec3(p.x + epsilon, p.y, p.z), primitives[i]), smoothness);
// ny = smoothMaxSDF(ny, -sdf(vec3(p.x, p.y + epsilon, p.z), primitives[i]), smoothness);
// nz = smoothMaxSDF(nz, -sdf(vec3(p.x, p.y, p.z + epsilon), primitives[i]), smoothness);
// }
// }
//
// nx -= d;
// ny -= d;
// nz -= d;
//
// normals = normalize(vec3(nx, ny, nz));
//}
//void estimateSmoothNormalsMax(vec3 p, float smoothness, float epsilon, inout vec3 normals)
//{
// float d = sdf(p, primitives[0]);
// float nx = sdf(vec3(p.x + epsilon, p.y, p.z), primitives[0]);
// float ny = sdf(vec3(p.x, p.y + epsilon, p.z), primitives[0]);
// float nz = sdf(vec3(p.x, p.y, p.z + epsilon), primitives[0]);
//
//
// for (int i = 0; i < primitives.length(); i++)
// {
// d = smoothMaxSDF(d, sdf(p, primitives[i]), smoothness);
// nx = smoothMaxSDF(nx, sdf(vec3(p.x + epsilon, p.y, p.z), primitives[i]), smoothness);
// ny = smoothMaxSDF(ny, sdf(vec3(p.x, p.y + epsilon, p.z), primitives[i]), smoothness);
// nz = smoothMaxSDF(nz, sdf(vec3(p.x, p.y, p.z + epsilon), primitives[i]), smoothness);
// }
// nx -= d;
// ny -= d;
// nz -= d;
//
// normals = normalize(vec3(nx, ny, nz));
//}
float calcDist(vec3 pos, inout float dist)
{
for (int i = 0; i < primitives.length(); i++)
{
float newDist = sdf(pos, primitives[i]);
if (primitives[i].subtract == 0)
dist = smoothMinSDF(dist, newDist, smoothing);
else
dist = opSmoothSubtraction(newDist, dist, smoothing);
}
return dist;
}
float calcDist2(vec3 pos)
{
float dist = 999999.0;
for (int i = 0; i < primitives.length(); i++)
{
float newDist = sdf(pos, primitives[i]);
if (primitives[i].subtract == 0)
dist = smoothMinSDF(newDist, dist, smoothing);
else
dist = opSmoothSubtraction(newDist, dist, smoothing);
}
return dist;
}
vec3 estimateNormals(vec3 p, float epsilon)
{
/*float d1 = 99999.0;
float d2 = 99999.0;
float x = calcDist(vec3(p.x + epsilon, p.y, p.z), d1) - calcDist(vec3(p.x - epsilon, p.y, p.z), d2);
d1 = 99999.0;
d2 = 99999.0;
float y = calcDist(vec3(p.x, p.y + epsilon, p.z), d1) - calcDist(vec3(p.x, p.y - epsilon, p.z), d2);
d1 = 99999.0;
d2 = 99999.0;
float z = calcDist(vec3(p.x, p.y, p.z + epsilon), d1) - calcDist(vec3(p.x, p.y, p.z - epsilon), d2);
return normalize(vec3(x, y, z));*/
vec2 e = vec2(1.0, -1.0) * 0.5773;
return normalize(e.xyy * calcDist2(p + e.xyy * epsilon) +
e.yyx * calcDist2(p + e.yyx * epsilon) +
e.yxy * calcDist2(p + e.yxy * epsilon) +
e.xxx * calcDist2(p + e.xxx * epsilon));
}
vec4 blendColors(vec4 color1, vec4 color2, float blendFactor)
{
return mix(color1, color2, blendFactor);
@ -317,27 +359,12 @@ void main(void)
{
steps++;
float minDist = 999999.0;
float maxDist = 0.0;
calcDist(ray_pos.xyz, minDist);
for (int i = 0; i < primitives.length(); i++)
{
if (primitives[i].subtract == 1) {
continue;
}
float dist = sdf(ray_pos.xyz, primitives[i]);
float weight = weightFunction(dist, smoothing, epsilon);
if (dist < sdf(ray_pos.xyz, primitives[closestIndex]))
{
closestIndex = i;
}
minDist = smoothMinSDF(minDist, dist, k);
//minDist = smoothMaxSDF(maxDist, dist, k);
//minDist = max(-minDist, dist);
//minDist = min(minDist, dist);
/*if(i == 3)
minDist = max(-minDist, dist);*/
float weight = weightFunction(minDist, smoothing, epsilon);
accumulatedDiffuse += primitives[i].diffuse_color * weight;
accumulatedSpecular += primitives[i].specular_color * weight;
accumulatedAmbient += primitives[i].ambient_color * weight;
@ -345,14 +372,6 @@ void main(void)
totalWeight += weight;
}
for (int i = 0; i < primitives.length(); i++)
{
if (primitives[i].subtract == 1) {
float dist = sdf(ray_pos.xyz, primitives[i]);
minDist = max(minDist, -dist);
}
}
if (minDist <= epsilon)
{
if (totalWeight > 0.0) {
@ -370,8 +389,7 @@ void main(void)
vec3 lw;
ambient_color = vec4(accumulatedAmbient.rgb, 1.0);
diffuse_color = vec4(accumulatedDiffuse.rgb, 1.0);
estimateSmoothNormals(ray_pos.xyz, k, epsilon, normals);
//normals = estimateNormals(ray_pos.xyz, primitives[closestIndex], 0.001);
normals = estimateNormals(ray_pos.xyz, epsilon);
for (int i = 0; i < lights.length(); i++)
{