Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Buffer A:
- // Quaternion multiplication function
- vec4 QMult( vec4 q1, vec4 q2 )
- {
- return vec4(
- q1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,
- q1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,
- q1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,
- q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z
- );
- }
- // Quaternion rotation function
- vec4 quaternion_rotation(vec3 axis, float angle) {
- float half_angle = angle * 0.5;
- return vec4(axis * sin(half_angle), cos(half_angle));
- }
- #define keyToggle(ascii) ( texelFetch(iChannel1,ivec2(ascii,2),0).x > 0.)
- #define keyClick(ascii) ( texelFetch(iChannel1,ivec2(ascii,1),0).x > 0.)
- #define keyDown(ascii) ( texelFetch(iChannel1,ivec2(ascii,0),0).x > 0.)
- #define shift ( texelFetch(iChannel1,ivec2(16,0),0).x > 0.)
- #define ctrl ( texelFetch(iChannel1,ivec2(17,0),0).x > 0.)
- #define alt ( texelFetch(iChannel1,ivec2(18,0),0).x > 0.)
- void mainImage(out vec4 fragColor, in vec2 fragCoord) {
- // Initialize the camera position and orientation
- vec3 camera_position = vec3(0.0, 0.0, 5.0);
- vec4 camera_orientation = vec4(1.0, 0.0, 0.0, 1.0);
- vec3 cameraUp = vec3(0.0,1.0,0.0);
- // If iFrame > 0, read the camera position and orientation from iChannel0
- if (iFrame > 0) {
- camera_position = texelFetch(iChannel0, ivec2(0, 0), 0).rgb;
- camera_orientation = texelFetch(iChannel0, ivec2(1, 0), 0);
- }
- // Update the camera position and orientation based on keyboard input
- float move_speed = 0.5;
- float turn_speed = 0.0005;
- vec3 move_delta = vec3(0.0);
- vec4 turn_delta = vec4(0.0, 0.0, 0.0, 0.0);
- // Read the keyboard input from iChannel1
- vec4 key_input = texelFetch(iChannel1, ivec2(0, 0), 0).rgba;
- // W - move forward
- if (keyDown(87)) move_delta -= camera_orientation.xyz * move_speed;
- // A - move left
- if (keyDown(65)) move_delta -= cross(camera_orientation.xyz, cameraUp) * move_speed;
- // S - move backward
- if (keyDown(83)) move_delta += camera_orientation.xyz * move_speed;
- // D - move right
- if (keyDown(68)) move_delta += cross(camera_orientation.xyz, cameraUp) * move_speed;
- // Q - turn left
- if (keyDown(81)) turn_delta = quaternion_rotation(vec3(0.0, 1.0, 0.0), turn_speed);
- // E - turn right
- if (keyDown(69)) turn_delta = quaternion_rotation(vec3(0.0, 1.0, 0.0), -turn_speed);
- // Update the camera position and orientation
- camera_position += move_delta;
- camera_orientation = normalize(QMult(QMult(turn_delta, camera_orientation),-turn_delta));
- // Store the updated camera position and orientation in fragColor
- fragColor = vec4(camera_position, 1.0);
- fragColor = fragColor;
- }
- Image:
- float QNorm( vec4 q1 )
- {
- return sqrt(
- pow(q1.x,2.0)+
- pow(q1.y,2.0)+
- pow(q1.z,2.0)+
- pow(q1.w,2.0)
- );
- }
- vec4 QConj( vec4 q1 )
- {
- return q1 * vec4(-1.0,-1.0,-1.0,1.0);
- }
- vec4 QVersor( vec4 q1 )
- {
- return q1/QNorm(q1);
- }
- vec4 QMult( vec4 q1, vec4 q2 )
- {
- return vec4(
- q1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,
- q1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,
- q1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,
- q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z
- );
- }
- vec3 rotateVector( vec4 quat, vec3 vec )
- {
- vec4 qv = QMult(quat, vec4(vec, 0.0));
- return QMult(qv, vec4(-quat.x, -quat.y, -quat.z, quat.w)).xyz;
- }
- vec4 QSquare( vec4 v1 )
- {
- return QMult(v1, v1);
- }
- vec4 QInverse( vec4 v1 )
- {
- return QConj(v1)/(QMult(v1,QConj(v1)));
- }
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- // Ray-sphere intersection
- bool intersect_sphere(vec3 ray_origin, vec3 ray_dir, vec3 sphere_center, float sphere_radius, out float t)
- {
- vec3 oc = ray_origin - sphere_center;
- float a = dot(ray_dir, ray_dir);
- float b = 2.0 * dot(oc, ray_dir);
- float c = dot(oc, oc) - sphere_radius * sphere_radius;
- float discriminant = b * b - 4.0 * a * c;
- if (discriminant < 0.0) {
- return false;
- } else {
- t = (-b - sqrt(discriminant)) / (2.0 * a);
- return true;
- }
- }
- // Ray-plane intersection
- bool intersect_plane(vec3 ray_origin, vec3 ray_dir, vec3 plane_normal, vec3 plane_point, out float t)
- {
- float denom = dot(plane_normal, ray_dir);
- if (abs(denom) > 1e-6) {
- vec3 p0l0 = plane_point - ray_origin;
- t = dot(p0l0, plane_normal) / denom;
- return (t >= 0.0);
- }
- return false;
- }
- vec3 phong_shading(vec3 normal, vec3 view_dir, vec3 light_dir, vec3 light_color, vec3 material_color, float shininess)
- {
- // Ambient component
- vec3 ambient = 0.1 * material_color;
- // Diffuse component
- float diffuse_intensity = max(dot(normal, light_dir), 0.0);
- vec3 diffuse = diffuse_intensity * light_color * material_color;
- // Specular component
- vec3 reflect_dir = reflect(-light_dir, normal);
- float spec_intensity = pow(max(dot(view_dir, reflect_dir), 0.0), shininess);
- vec3 specular = spec_intensity * light_color;
- return ambient + diffuse + specular;
- }
- struct Object {
- int type; // 0: sphere, 1: plane
- vec3 position;
- vec3 scale;
- vec3 color;
- float shininess;
- };
- const int object_count = 5;
- Object objects[object_count] = Object[](
- Object(0, vec3(-5.0, 0.0, 0.0), vec3(1.0), vec3(0.0, 0.0, 1.0), 32.0),
- Object(0, vec3(0.0, 0.0, -5.0), vec3(1.0), vec3(1.0, 0.0, 0.0), 32.0),
- Object(0, vec3(5.0, 0.0, 0.0), vec3(1.0), vec3(0.0, 1.0, 1.0), 32.0),
- Object(0, vec3(0.0, 0.0, 5.0), vec3(1.0), vec3(1.0, 1.0, 0.0), 32.0),
- Object(1, vec3(0.0, -1.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, 1.0, 0.0), 8.0)
- );
- // Raycasting
- vec4 raycast(vec3 origin, vec3 direction, vec4 rotation, int max_bounces) {
- vec3 ray_dir = direction;
- vec4 result_color = vec4(0.0); // Initialize as black
- vec3 viewing_direction = normalize(-origin);
- float cull_threshold = cos(FOV / 2.0);
- // Define your scene objects (sphere and plane)
- vec3 light_position = vec3(0.0, 5.0, -2.0);
- vec3 light_color = vec3(1.0, 1.0, 1.0);
- for (int bounce = 0; bounce < max_bounces; ++bounce) {
- ray_dir = rotateVector(rotation, ray_dir);
- float min_t = 1e20;
- int hit_object = -1;
- for (int i = 0; i < object_count; i++) {
- float t;
- bool hit;
- if (objects[i].type == 0) {
- hit = intersect_sphere(origin, ray_dir, objects[i].position, objects[i].scale.x, t);
- } else if (objects[i].type == 1) {
- hit = intersect_plane(origin, ray_dir, objects[i].scale, objects[i].position, t);
- }
- if (hit && t < min_t) {
- min_t = t;
- hit_object = i;
- }
- }
- if (hit_object != -1) {
- float t = min_t;
- // Compute the intersection point
- vec3 intersection_point = origin + ray_dir * t;
- // Compute the normal at the intersection point
- vec3 normal = objects[hit_object].type == 0 ? normalize(intersection_point - objects[hit_object].position) : objects[hit_object].scale;
- // Compute the view direction (from the intersection point to the ray origin)
- vec3 view_dir = normalize(origin - intersection_point);
- // Compute the light direction (from the intersection point to the light source)
- vec3 light_dir = normalize(light_position - intersection_point);
- // Calculate the Phong shading
- vec3 material_color = objects[hit_object].color;
- float shininess = objects[hit_object].shininess;
- vec3 shaded_color = phong_shading(normal, view_dir, light_dir, light_color, material_color, shininess);
- // Update result_color based on the shading result
- result_color.rgb += shaded_color;
- // Update ray_dir for the next bounce (reflect or refract)
- ray_dir = reflect(ray_dir, normal);
- // Update the ray origin for the next bounce
- origin = intersection_point;
- } else {
- // No intersection, break the loop
- break;
- }
- }
- // Set the alpha component to 1.0
- result_color.a = 1.0;
- return result_color;
- }
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- void mainImage(out vec4 fragColor, in vec2 fragCoord)
- {
- if (iFrame == 0) return;
- // Read the camera position and orientation from iChannel0
- vec3 camera_position = texelFetch(iChannel0, ivec2(0, 0), 0).rgb;
- vec4 camera_orientation = texelFetch(iChannel0, ivec2(1, 0), 0);
- // Define the camera properties
- vec3 camera_target = camera_position + camera_orientation.xyz;
- vec3 camera_up = vec3(0.0, 1.0, 0.0);
- float fov = radians(60.0);
- // Calculate the camera basis vectors
- vec3 camera_z = normalize(camera_position - camera_target);
- vec3 camera_x = normalize(cross(camera_up, camera_z));
- vec3 camera_y = cross(camera_z, camera_x);
- // Calculate the image plane size
- float aspect_ratio = iResolution.x / iResolution.y;
- float image_plane_height = 2.0 * tan(fov * 0.5);
- float image_plane_width = image_plane_height * aspect_ratio;
- // Calculate the pixel size
- vec2 pixel_size = vec2(image_plane_width / iResolution.x, image_plane_height / iResolution.y);
- // Initialize the output color
- vec4 color = vec4(0.0);
- // Perform 2x2 supersampling
- for (int x = 0; x < 2; ++x) {
- for (int y = 0; y < 2; ++y) {
- // Calculate the subpixel position on the image plane
- vec2 subpixel_offset = vec2(float(x) - 0.5, float(y) - 0.5) * 0.5;
- vec2 subpixel_position = (fragCoord + subpixel_offset - 0.5 * iResolution.xy) * pixel_size;
- // Calculate the ray direction from the camera to the subpixel
- vec3 ray_direction = normalize(subpixel_position.x * camera_x + subpixel_position.y * camera_y - camera_z);
- // Perform the raycast
- color += raycast(camera_position, ray_direction, vec4(0.0, 0.0, 0.0, 1.0), 2);
- }
- }
- // Average the supersampled colors
- color /= 4.0;
- // Set the output fragColor
- fragColor = color;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement