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