R"###( #version 330 core out vec4 FragColor; in vec2 texCoords; uniform float aspect; uniform float t; vec3 center = vec3(0.0,-4.0,20.0); float radius = 5.0; float planeHeight = -7.0; struct SmallHit { float min; float len; bool firstHP; }; struct Ray { vec3 dir; vec3 pos; float min; float len; SmallHit small; vec3 color; }; Ray createRay(vec3 dir, vec3 pos){ return Ray(dir, pos, .0, .0, SmallHit(80.,0.,false), vec3(.0)); } Ray applyMin(Ray ray, float min) { vec3 off = ray.dir * min; ray.pos = ray.pos + off; ray.len = ray.len + min; if( (min < ray.min) && !ray.small.firstHP ){ ray.small.firstHP = true; } ray.min = min; if((ray.min < ray.small.min) && ray.small.firstHP){ ray.small.min = ray.min; ray.small.len = ray.len; } return ray; } float planeMin(vec3 pos){ return pos.y - planeHeight; } float sphereMin(vec3 pos){ return length(pos - center) - radius + 0.2*sin(5*pos.x+t)*sin(5*pos.y+t)*sin(5*pos.z+t); } Ray minFn(Ray ray){ float sp = sphereMin(ray.pos); float pl = planeMin(ray.pos); float min; if (sp < pl){ ray.color = vec3(1.0, 0.5, 0.2); min = sp; } else { ray.color = vec3(0.2, 0.3, 0.3); min = pl; } return applyMin(ray,min); } 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.01f) ) { 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 = createRay(normalize(dir),pos); 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; Ray shRay = createRay(lighDir * (-1.0), ray.pos + (-0.5)*lighDir); shRay = march(shRay); if( dot(lighDir,normal) < 0. ){ if( shRay.len <80){ shLeve = .0;//shRay.len*0.02 , 0.0; } else { shLeve = shRay.small.min / shRay.small.len; shLeve *= 9.0; //shLeve = pow(shLeve*10.0,0.5); } } shLeve = min(max(shLeve, 0.0),1.0); light *= shLeve; if(ray.min <= 0.2){ //FragColor = vec4(vec3(shRay.small.min)*0.1,1.0); FragColor = vec4(ray.color * (light+0.3), 1.0); } else { FragColor = vec4(.0,0.0,0.0,1.0); } } )###";