Advertisement
MrMaccaMan

GLSL Raycasting

Jun 19th, 2023
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Godot GLSL 10.38 KB | Software | 0 0
  1. Buffer A:
  2.  
  3. // Quaternion multiplication function
  4. vec4 QMult( vec4 q1, vec4 q2 )
  5. {
  6.     return vec4(
  7.         q1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,
  8.         q1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,
  9.         q1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,
  10.         q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z
  11.     );
  12. }
  13.  
  14. // Quaternion rotation function
  15. vec4 quaternion_rotation(vec3 axis, float angle) {
  16.     float half_angle = angle * 0.5;
  17.     return vec4(axis * sin(half_angle), cos(half_angle));
  18. }
  19.  
  20. #define keyToggle(ascii)  ( texelFetch(iChannel1,ivec2(ascii,2),0).x > 0.)
  21. #define keyClick(ascii)   ( texelFetch(iChannel1,ivec2(ascii,1),0).x > 0.)
  22. #define keyDown(ascii)    ( texelFetch(iChannel1,ivec2(ascii,0),0).x > 0.)
  23.  
  24. #define shift             ( texelFetch(iChannel1,ivec2(16,0),0).x  > 0.)
  25. #define ctrl              ( texelFetch(iChannel1,ivec2(17,0),0).x  > 0.)
  26. #define alt               ( texelFetch(iChannel1,ivec2(18,0),0).x  > 0.)
  27.  
  28. void mainImage(out vec4 fragColor, in vec2 fragCoord) {
  29.     // Initialize the camera position and orientation
  30.     vec3 camera_position = vec3(0.0, 0.0, 5.0);
  31.     vec4 camera_orientation = vec4(1.0, 0.0, 0.0, 1.0);
  32.    
  33.     vec3 cameraUp = vec3(0.0,1.0,0.0);
  34.  
  35.     // If iFrame > 0, read the camera position and orientation from iChannel0
  36.     if (iFrame > 0) {
  37.         camera_position = texelFetch(iChannel0, ivec2(0, 0), 0).rgb;
  38.         camera_orientation = texelFetch(iChannel0, ivec2(1, 0), 0);
  39.     }
  40.  
  41.     // Update the camera position and orientation based on keyboard input
  42.     float move_speed = 0.5;
  43.     float turn_speed = 0.0005;
  44.     vec3 move_delta = vec3(0.0);
  45.     vec4 turn_delta = vec4(0.0, 0.0, 0.0, 0.0);
  46.  
  47.     // Read the keyboard input from iChannel1
  48.     vec4 key_input = texelFetch(iChannel1, ivec2(0, 0), 0).rgba;
  49.  
  50.     // W - move forward
  51.     if (keyDown(87)) move_delta -= camera_orientation.xyz * move_speed;
  52.     // A - move left
  53.     if (keyDown(65)) move_delta -= cross(camera_orientation.xyz, cameraUp) * move_speed;
  54.     // S - move backward
  55.     if (keyDown(83)) move_delta += camera_orientation.xyz * move_speed;
  56.     // D - move right
  57.     if (keyDown(68)) move_delta += cross(camera_orientation.xyz, cameraUp) * move_speed;
  58.     // Q - turn left
  59.     if (keyDown(81)) turn_delta = quaternion_rotation(vec3(0.0, 1.0, 0.0), turn_speed);
  60.     // E - turn right
  61.     if (keyDown(69)) turn_delta = quaternion_rotation(vec3(0.0, 1.0, 0.0), -turn_speed);
  62.  
  63.     // Update the camera position and orientation
  64.     camera_position += move_delta;
  65.     camera_orientation = normalize(QMult(QMult(turn_delta, camera_orientation),-turn_delta));
  66.  
  67.     // Store the updated camera position and orientation in fragColor
  68.     fragColor = vec4(camera_position, 1.0);
  69.     fragColor = fragColor;
  70. }
  71.  
  72.  
  73.  
  74. Image:
  75.  
  76. float QNorm( vec4 q1 )
  77. {
  78.     return sqrt(
  79.     pow(q1.x,2.0)+
  80.     pow(q1.y,2.0)+
  81.     pow(q1.z,2.0)+
  82.     pow(q1.w,2.0)
  83.     );
  84. }
  85.  
  86. vec4 QConj( vec4 q1 )
  87. {
  88.     return q1 * vec4(-1.0,-1.0,-1.0,1.0);
  89. }
  90.  
  91. vec4 QVersor( vec4 q1 )
  92. {
  93.     return q1/QNorm(q1);
  94. }
  95.  
  96. vec4 QMult( vec4 q1, vec4 q2 )
  97. {
  98.     return vec4(
  99.         q1.w * q2.x + q1.x * q2.w + q1.z * q2.y - q1.y * q2.z,
  100.         q1.w * q2.y + q1.y * q2.w + q1.x * q2.z - q1.z * q2.x,
  101.         q1.w * q2.z + q1.z * q2.w + q1.y * q2.x - q1.x * q2.y,
  102.         q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z
  103.     );
  104. }
  105.  
  106. vec3 rotateVector( vec4 quat, vec3 vec )
  107. {
  108.     vec4 qv = QMult(quat, vec4(vec, 0.0));
  109.     return QMult(qv, vec4(-quat.x, -quat.y, -quat.z, quat.w)).xyz;
  110. }
  111.  
  112. vec4 QSquare( vec4 v1 )
  113. {
  114.     return QMult(v1, v1);
  115. }
  116.  
  117. vec4 QInverse( vec4 v1 )
  118. {
  119.     return QConj(v1)/(QMult(v1,QConj(v1)));
  120. }
  121.  
  122. // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  123.  
  124. // Ray-sphere intersection
  125. bool intersect_sphere(vec3 ray_origin, vec3 ray_dir, vec3 sphere_center, float sphere_radius, out float t)
  126. {
  127.     vec3 oc = ray_origin - sphere_center;
  128.     float a = dot(ray_dir, ray_dir);
  129.     float b = 2.0 * dot(oc, ray_dir);
  130.     float c = dot(oc, oc) - sphere_radius * sphere_radius;
  131.     float discriminant = b * b - 4.0 * a * c;
  132.     if (discriminant < 0.0) {
  133.         return false;
  134.     } else {
  135.         t = (-b - sqrt(discriminant)) / (2.0 * a);
  136.         return true;
  137.     }
  138. }
  139.  
  140. // Ray-plane intersection
  141. bool intersect_plane(vec3 ray_origin, vec3 ray_dir, vec3 plane_normal, vec3 plane_point, out float t)
  142. {
  143.     float denom = dot(plane_normal, ray_dir);
  144.     if (abs(denom) > 1e-6) {
  145.         vec3 p0l0 = plane_point - ray_origin;
  146.         t = dot(p0l0, plane_normal) / denom;
  147.         return (t >= 0.0);
  148.     }
  149.     return false;
  150. }
  151.  
  152. vec3 phong_shading(vec3 normal, vec3 view_dir, vec3 light_dir, vec3 light_color, vec3 material_color, float shininess)
  153. {
  154.     // Ambient component
  155.     vec3 ambient = 0.1 * material_color;
  156.  
  157.     // Diffuse component
  158.     float diffuse_intensity = max(dot(normal, light_dir), 0.0);
  159.     vec3 diffuse = diffuse_intensity * light_color * material_color;
  160.  
  161.     // Specular component
  162.     vec3 reflect_dir = reflect(-light_dir, normal);
  163.     float spec_intensity = pow(max(dot(view_dir, reflect_dir), 0.0), shininess);
  164.     vec3 specular = spec_intensity * light_color;
  165.  
  166.     return ambient + diffuse + specular;
  167. }
  168.  
  169. struct Object {
  170.     int type; // 0: sphere, 1: plane
  171.     vec3 position;
  172.     vec3 scale;
  173.     vec3 color;
  174.     float shininess;
  175. };
  176.  
  177. const int object_count = 5;
  178. Object objects[object_count] = Object[](
  179.     Object(0, vec3(-5.0, 0.0, 0.0), vec3(1.0), vec3(0.0, 0.0, 1.0), 32.0),
  180.     Object(0, vec3(0.0, 0.0, -5.0), vec3(1.0), vec3(1.0, 0.0, 0.0), 32.0),
  181.     Object(0, vec3(5.0, 0.0, 0.0), vec3(1.0), vec3(0.0, 1.0, 1.0), 32.0),
  182.     Object(0, vec3(0.0, 0.0, 5.0), vec3(1.0), vec3(1.0, 1.0, 0.0), 32.0),
  183.     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)
  184. );
  185.  
  186. // Raycasting
  187. vec4 raycast(vec3 origin, vec3 direction, vec4 rotation, int max_bounces) {
  188.     vec3 ray_dir = direction;
  189.     vec4 result_color = vec4(0.0); // Initialize as black
  190.    
  191.     vec3 viewing_direction = normalize(-origin);
  192.     float cull_threshold = cos(FOV / 2.0);
  193.  
  194.     // Define your scene objects (sphere and plane)
  195.     vec3 light_position = vec3(0.0, 5.0, -2.0);
  196.     vec3 light_color = vec3(1.0, 1.0, 1.0);
  197.  
  198.     for (int bounce = 0; bounce < max_bounces; ++bounce) {
  199.         ray_dir = rotateVector(rotation, ray_dir);
  200.  
  201.         float min_t = 1e20;
  202.         int hit_object = -1;
  203.         for (int i = 0; i < object_count; i++) {
  204.             float t;
  205.             bool hit;
  206.             if (objects[i].type == 0) {
  207.                 hit = intersect_sphere(origin, ray_dir, objects[i].position, objects[i].scale.x, t);
  208.             } else if (objects[i].type == 1) {
  209.                 hit = intersect_plane(origin, ray_dir, objects[i].scale, objects[i].position, t);
  210.             }
  211.  
  212.             if (hit && t < min_t) {
  213.                 min_t = t;
  214.                 hit_object = i;
  215.             }
  216.         }
  217.  
  218.         if (hit_object != -1) {
  219.             float t = min_t;
  220.  
  221.             // Compute the intersection point
  222.             vec3 intersection_point = origin + ray_dir * t;
  223.  
  224.             // Compute the normal at the intersection point
  225.             vec3 normal = objects[hit_object].type == 0 ? normalize(intersection_point - objects[hit_object].position) : objects[hit_object].scale;
  226.  
  227.             // Compute the view direction (from the intersection point to the ray origin)
  228.             vec3 view_dir = normalize(origin - intersection_point);
  229.  
  230.             // Compute the light direction (from the intersection point to the light source)
  231.             vec3 light_dir = normalize(light_position - intersection_point);
  232.  
  233.             // Calculate the Phong shading
  234.             vec3 material_color = objects[hit_object].color;
  235.             float shininess = objects[hit_object].shininess;
  236.             vec3 shaded_color = phong_shading(normal, view_dir, light_dir, light_color, material_color, shininess);
  237.  
  238.             // Update result_color based on the shading result
  239.             result_color.rgb += shaded_color;
  240.  
  241.             // Update ray_dir for the next bounce (reflect or refract)
  242.             ray_dir = reflect(ray_dir, normal);
  243.  
  244.             // Update the ray origin for the next bounce
  245.             origin = intersection_point;
  246.         } else {
  247.             // No intersection, break the loop
  248.             break;
  249.         }
  250.     }
  251.  
  252.     // Set the alpha component to 1.0
  253.     result_color.a = 1.0;
  254.  
  255.     return result_color;
  256. }
  257. // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
  258.  
  259. void mainImage(out vec4 fragColor, in vec2 fragCoord)
  260. {
  261.     if (iFrame == 0) return;
  262.  
  263.     // Read the camera position and orientation from iChannel0
  264.     vec3 camera_position = texelFetch(iChannel0, ivec2(0, 0), 0).rgb;
  265.     vec4 camera_orientation = texelFetch(iChannel0, ivec2(1, 0), 0);
  266.  
  267.     // Define the camera properties
  268.     vec3 camera_target = camera_position + camera_orientation.xyz;
  269.     vec3 camera_up = vec3(0.0, 1.0, 0.0);
  270.     float fov = radians(60.0);
  271.  
  272.     // Calculate the camera basis vectors
  273.     vec3 camera_z = normalize(camera_position - camera_target);
  274.     vec3 camera_x = normalize(cross(camera_up, camera_z));
  275.     vec3 camera_y = cross(camera_z, camera_x);
  276.  
  277.     // Calculate the image plane size
  278.     float aspect_ratio = iResolution.x / iResolution.y;
  279.     float image_plane_height = 2.0 * tan(fov * 0.5);
  280.     float image_plane_width = image_plane_height * aspect_ratio;
  281.  
  282.     // Calculate the pixel size
  283.     vec2 pixel_size = vec2(image_plane_width / iResolution.x, image_plane_height / iResolution.y);
  284.  
  285.     // Initialize the output color
  286.     vec4 color = vec4(0.0);
  287.  
  288.     // Perform 2x2 supersampling
  289.     for (int x = 0; x < 2; ++x) {
  290.         for (int y = 0; y < 2; ++y) {
  291.             // Calculate the subpixel position on the image plane
  292.             vec2 subpixel_offset = vec2(float(x) - 0.5, float(y) - 0.5) * 0.5;
  293.             vec2 subpixel_position = (fragCoord + subpixel_offset - 0.5 * iResolution.xy) * pixel_size;
  294.  
  295.             // Calculate the ray direction from the camera to the subpixel
  296.             vec3 ray_direction = normalize(subpixel_position.x * camera_x + subpixel_position.y * camera_y - camera_z);
  297.  
  298.             // Perform the raycast
  299.             color += raycast(camera_position, ray_direction, vec4(0.0, 0.0, 0.0, 1.0), 2);
  300.         }
  301.     }
  302.  
  303.     // Average the supersampled colors
  304.     color /= 4.0;
  305.  
  306.     // Set the output fragColor
  307.     fragColor = color;
  308. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement