parade/shaders/parade_fs.glsl

187 lines
5.3 KiB
Plaintext
Raw Normal View History

#version 430
2023-11-06 22:02:45 -05:00
uniform mat4 P;
uniform mat4 V;
uniform mat4 M;
uniform vec3 cam_pos;
uniform int window_width;
uniform int window_height;
uniform vec3 la;
uniform vec3 ld;
uniform vec3 ls;
uniform vec3 ka;
uniform vec3 kd;
uniform vec3 ks;
2023-11-07 00:15:16 -05:00
uniform float smoothing;
2023-11-07 01:17:16 -05:00
uniform vec3 sphere_center;
2023-11-06 22:02:45 -05:00
layout (std430, binding=2) buffer newPrim
{
vec3 diffuse_color;
vec3 specular_color;
vec3 ambient_color;
vec3 position;
int specular_exponent;
int shape;
float radius;
float height;
float inner_radius;
float outer_radius;
float size
}
2023-11-06 22:02:45 -05:00
out vec4 FragColor;
struct Torus
{
float R;
float r;
};
Torus torus;
struct Sphere
{
vec3 center;
float r;
};
Sphere sphere;
void initTorus()
{
torus.R = 0.5;
torus.r = 0.15;
}
void initSphere()
{
2023-11-07 01:17:16 -05:00
sphere.center = sphere_center;
2023-11-06 22:02:45 -05:00
sphere.r = 0.25;
}
float sphereSDF(vec3 p, vec3 center, float r) {
return length(p - center) - r;
}
float torusSDF(vec3 p, float R, float r) {
vec2 q = vec2(length(p.xz) - R, p.y);
return length(q) - r;
}
vec3 estimateNormalsSphere(vec3 p)
{
float epsilon = 0.001;
float x = sphereSDF(vec3(p.x + epsilon, p.y, p.z), sphere.center, sphere.r) - sphereSDF(vec3(p.x - epsilon, p.y, p.z), sphere.center, sphere.r);
float y = sphereSDF(vec3(p.x, p.y + epsilon, p.z), sphere.center, sphere.r) - sphereSDF(vec3(p.x, p.y - epsilon, p.z), sphere.center, sphere.r);
float z = sphereSDF(vec3(p.x, p.y, p.z + epsilon), sphere.center, sphere.r) - sphereSDF(vec3(p.x, p.y, p.z - epsilon), sphere.center, sphere.r);
return normalize(vec3(x, y, z));
}
vec3 estimateNormalsTorus(vec3 p)
{
float epsilon = 0.001;
float x = torusSDF(vec3(p.x + epsilon, p.y, p.z), torus.R, torus.r) - torusSDF(vec3(p.x - epsilon, p.y, p.z), torus.R, torus.r);
float y = torusSDF(vec3(p.x, p.y + epsilon, p.z), torus.R, torus.r) - torusSDF(vec3(p.x, p.y - epsilon, p.z), torus.R, torus.r);
float z = torusSDF(vec3(p.x, p.y, p.z + epsilon), torus.R, torus.r) - torusSDF(vec3(p.x, p.y, p.z - epsilon), torus.R, torus.r);
return normalize(vec3(x, y, z));
}
float smoothMinSDF(float d1, float d2, float k) {
2023-11-07 01:17:16 -05:00
if (k == 0.0) k = 0.000001;
2023-11-06 22:02:45 -05:00
float h = max(k - abs(d1 - d2), 0) / k;
return min(d1, d2) - h * h * h * k * 1.0 / 6.0;
}
float smoothMaxSDF(float d1, float d2, float k) {
2023-11-07 01:17:16 -05:00
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;
2023-11-06 22:02:45 -05:00
}
vec3 estimateSmoothNormals(vec3 p, float smoothness) {
float epsilon = 0.001;
float d = smoothMinSDF(torusSDF(p, torus.R, torus.r), sphereSDF(p, sphere.center, sphere.r), smoothness);
float nx = smoothMinSDF(torusSDF(vec3(p.x + epsilon, p.y, p.z), torus.R, torus.r), sphereSDF(vec3(p.x + epsilon, p.y, p.z), sphere.center, sphere.r), smoothness) - d;
float ny = smoothMinSDF(torusSDF(vec3(p.x, p.y + epsilon, p.z), torus.R, torus.r), sphereSDF(vec3(p.x, p.y + epsilon, p.z), sphere.center, sphere.r), smoothness) - d;
float nz = smoothMinSDF(torusSDF(vec3(p.x, p.y, p.z + epsilon), torus.R, torus.r), sphereSDF(vec3(p.x, p.y, p.z + epsilon), sphere.center, sphere.r), smoothness) - d;
return normalize(vec3(nx, ny, nz));
}
2023-11-07 01:17:16 -05:00
vec3 estimateNormalsMax(vec3 p, float smoothness) {
float epsilon = 0.001;
float d = max(torusSDF(p, torus.R, torus.r), sphereSDF(p, sphere.center, sphere.r));
float nx = max(torusSDF(vec3(p.x + epsilon, p.y, p.z), 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.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.R, torus.r), sphereSDF(vec3(p.x, p.y, p.z + epsilon), sphere.center, sphere.r)) - d;
return normalize(vec3(nx, ny, nz));
}
2023-11-06 22:02:45 -05:00
void main(void)
{
vec3 normals;
vec3 color = la;
vec4 ray_pos = vec4(cam_pos, 1.0);
float ray_dist = 0.0;
float max_dist = 100.0;
2023-11-07 01:17:16 -05:00
float epsilon = 0.0001;
2023-11-06 22:02:45 -05:00
int steps = 0;
int max_steps = 1000;
vec3 light_pos = vec3(0.0, 1.0, 0.0);
int spec_exponent = 40;
2023-11-07 00:15:16 -05:00
float k = smoothing;
2023-11-06 22:02:45 -05:00
initTorus();
initSphere();
vec2 ndc_pos = 2.0 * vec2(gl_FragCoord.x / window_width, gl_FragCoord.y / window_height) - 1.0;
vec4 cam_dir = inverse(P) * vec4(ndc_pos, 1.0, 1.0);
cam_dir /= cam_dir.w;
cam_dir = vec4(cam_dir.xyz, 0.0);
vec4 ray_dir = normalize(inverse(V) * cam_dir);
while (ray_dist < max_dist && steps < max_steps)
{
steps++;
float distTorus = torusSDF(ray_pos.xyz, torus.R, torus.r);
float distSphere = sphereSDF(ray_pos.xyz, sphere.center, sphere.r);
2023-11-07 00:15:16 -05:00
float minDist = smoothMinSDF(distTorus, distSphere, k);
2023-11-06 22:02:45 -05:00
if (minDist <= epsilon)
{
vec4 ambient_color, diffuse_color;
ambient_color = vec4(ka, 1.0);
diffuse_color = vec4(kd, 1.0);
vec4 ambient = vec4(la, 1.0) * ambient_color;
2023-11-07 00:15:16 -05:00
normals = estimateSmoothNormals(ray_pos.xyz, k);
2023-11-06 22:02:45 -05:00
vec3 nw = normalize(normals);
vec3 lw = normalize(light_pos - ray_pos.xyz);
float dist = length(vec4(ray_pos.xyz - light_pos, 1.0));
vec4 diffuse = max(dot(nw, lw), 0) * diffuse_color * vec4(ld, 1.0);
float spec;
vec3 vw = normalize(cam_pos - ray_pos.xyz);
vec3 halfwayDir = normalize(lw + vw);
spec = pow(max(dot(halfwayDir, nw), 0), spec_exponent);
vec4 specular = spec * vec4(ks * ls, 1.0);
color = (ambient + (1.0 / (dist * dist) * (diffuse + specular))).xyz;
break;
}
ray_pos += ray_dir * minDist;
ray_dist += minDist;
}
FragColor = vec4(color, 1.0);
}