Files
Demo/sdf.fs

136 lines
2.7 KiB
GLSL

R"###(
#version 330 core
out vec4 FragColor;
in vec2 texCoords;
uniform float aspect;
vec3 center = vec3(0.0,0.0,20.0);
float radius = 5.0;
float planeHeight = -7.0;
struct Ray {
vec3 dir;
vec3 pos;
float min;
float len;
vec3 color;
};
Ray applyMin(Ray ray) {
vec3 off = ray.dir * ray.min;
ray.pos = ray.pos + off;
ray.len = ray.len + ray.min;
return ray;
}
float planeMin(vec3 pos){
return pos.y - planeHeight;
}
float sphereMin(vec3 pos){
return length(pos - center) - radius;
}
Ray minFn(Ray ray){
float sp = sphereMin(ray.pos);
float pl = planeMin(ray.pos);
if (sp < pl){
ray.color = vec3(1.0, 0.5, 0.2);
ray.min = sp;
} else {
ray.color = vec3(0.2, 0.3, 0.3);
ray.min = pl;
}
return applyMin(ray);
}
float minFn(vec3 pos){
float sp = sphereMin(pos);
float pl = planeMin(pos);
if (sp < pl){
return sp;
} else {
return pl;
}
}
Ray march(Ray ray){
//ray.min = minFn(ray.pos);
ray = minFn(ray);
int c = 0;
while(( c < 200) && (ray.min < 100.0f) && (ray.min > 0.1f) ) {
ray = minFn(ray);
c++;
}
return ray;
}
vec3 calcNormal(Ray ray){
float h = 0.001;
float m = sphereMin(ray.pos);
vec3 n = vec3(
minFn(ray.pos + vec3( h,.0,.0)) - minFn(ray.pos - vec3( h,.0,.0)),
minFn(ray.pos + vec3(.0, h,.0)) - minFn(ray.pos - vec3(.0, h,.0)),
minFn(ray.pos + vec3(.0,.0, h)) - minFn(ray.pos - vec3(.0,.0, h))
);
return normalize(n);
}
void main()
{
vec3 dir = vec3((texCoords - 0.5)*2,1.0);
dir.x *= aspect;
vec3 pos = dir;
Ray ray = Ray(normalize(dir),pos,.0,.0,vec3(.0));
ray = march(ray);
vec3 normal = calcNormal(ray);
vec3 lighDir = normalize(vec3(.5,-1.0,0.5));
float light = (- min(dot(normal,lighDir),0.0))*0.85;
float shLeve = 1.0;
vec2 offsets[8] = vec2[](
vec2( -0.94201624, -0.39906216 ),
vec2( 0.94558609, -0.76890725 ),
vec2( -0.094184101, -0.92938870 ),
vec2( 0.34495938, 0.29387760 ),
vec2( 0.94201624, 0.39906216 ),
vec2( -0.94558609, 0.76890725 ),
vec2( 0.094184101, 0.92938870 ),
vec2( -0.34495938, -0.29387760 )
);
for(int i = 0; i < 8; i++){
Ray shRay = Ray(lighDir * (-1.0) + vec3(offsets[i].x,.0,offsets[i].y)*0.05, ray.pos + 0.5*normal, .0,.0, vec3(.0));
shRay = march(shRay);
if( (dot(lighDir,normal) < 0.0) && (shRay.len <20)){
shLeve -= 0.125*max(1.0-shRay.len*0.07 , 0.0);
}
}
light *= shLeve * .8;
if(ray.min <= 0.2){
FragColor = vec4(ray.color * (light+0.3), 1.0);
} else {
FragColor = vec4(.0,0.0,0.0,1.0);
}
}
)###";