struct Ray { vec3 origin; vec3 direction; }; struct HitInfo { float distance; vec3 position; vec3 normal; vec3 color; }; Ray makeRay(in vec2 screenCoordinates) { // camera is at (0, 0, 0) looking towards -z axis Ray ray; ray.origin = vec3(0.0, 0.0, 0.0); float aspectRatio = iResolution.x / iResolution.y; ray.direction = vec3(screenCoordinates.x, screenCoordinates.y/aspectRatio, -1.0); return ray; } bool rayRectangleIntersect(in Ray ray, in vec3 center, in vec3 edge1, in vec3 edge2, inout HitInfo info) { vec3 normal = cross(edge1, edge2); float distance = dot(center - ray.origin, normal)/dot(ray.direction, normal); vec3 position = ray.origin + distance*ray.direction; float x = dot(position - center, edge1)/dot(edge1, edge1); float y = dot(position - center, edge2)/dot(edge2, edge2); bool hit = (distance > 0.0) && (distance < info.distance) && (abs(x) < 1.0) && (abs(y) < 1.0); if (hit) { info.distance = distance; info.position = position; info.normal = dot(ray.direction, normal) > 0.0 ? -normal : normal; } return hit; } bool raySphereIntersect(in Ray ray, in vec3 center, in float radius, inout HitInfo info) { // implement this yourself, similar to rayRectangleIntersect return false; } bool castRay(in Ray ray, out HitInfo info) { info.distance = 1000000.0; // define your scene in here! // intersect the ray against some shapes that you define // and return true if any of them were hit return false; } vec3 shadeHit(in HitInfo info) { // modify this to perform some lighting computation! return info.color; } void mainImage (out vec4 fragColor, in vec2 fragCoord) { // Normalized pixel coordinates (from -1 to 1) vec2 screenCoordinates = 2.0*fragCoord/iResolution.xy - 1.0; // Make ray corresponding to pixel Ray ray = makeRay(screenCoordinates); // Cast ray to get nearest hit HitInfo info; bool hit = castRay(ray, info); // Set pixel colour vec3 color; if (hit) { color = shadeHit(info); } else { // No hit, use a nice sky colour float y = normalize(ray.direction).y*0.5 + 0.5; color = (1.0 - y)*vec3(1.0, 1.0, 1.0) + y*vec3(0.5, 0.7, 1.0); } // Output to screen fragColor = vec4(color, 1.0); }