120 lines
2.2 KiB
GLSL
120 lines
2.2 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+0.3;
|
|
|
|
Ray shRay = Ray(lighDir * (-1.0), ray.pos + 0.5*normal , .0,.0, vec3(.0));
|
|
shRay = march(shRay);
|
|
|
|
if( (dot(lighDir,normal) < 0.0) && (shRay.len <20)){
|
|
light *= min(shRay.len*0.1,1.0);
|
|
}
|
|
|
|
if(ray.min <= 0.2){
|
|
FragColor = vec4(ray.color * light, 1.0);
|
|
} else {
|
|
FragColor = vec4(.0,0.0,0.0,1.0);
|
|
}
|
|
|
|
}
|
|
)###";
|