Got soft subtract kinda working
This commit is contained in:
parent
8b08b92494
commit
679589554e
|
@ -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++)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue