A little toolkit for single-quad fragment shader demos
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
2.2 KiB

  1. #version 330 core
  2. #define FOV 90
  3. #define EPSILON 0.01
  4. #define MAX_STEPS 64
  5. #define NEAR_D 0.
  6. #define FAR_D 20.
  7. #define GRAD_EPSILON 0.0001
  8. #define saturate(x) clamp(x, 0, 1)
  9. uniform vec2 u_Resolution;
  10. uniform vec4 u_Mouse;
  11. uniform float u_Time;
  12. out vec4 color;
  13. #include "utils.glsl"
  14. #include "march_prolog.glsl"
  15. #include "hg_sdf.glsl"
  16. #include "colormap_cool.glsl"
  17. vec3 ray_dir(float fov, vec2 uv) {
  18. float z = 1./tan(radians(fov)/2.);
  19. return normalize(vec3(uv, z));
  20. }
  21. SceneResult scene_f(vec3 p) {
  22. SceneResult box = SceneResult(fBox(p, vec3(1)), 1.);
  23. SceneResult sphere = SceneResult(fSphere(p + vec3(1), 1.0), 2.);
  24. return min_sr(box, sphere);
  25. }
  26. vec3 estimate_scene_normal(vec3 p) {
  27. vec3 dx = vec3(GRAD_EPSILON, 0, 0);
  28. vec3 dy = vec3(0, GRAD_EPSILON, 0);
  29. vec3 dz = vec3(0, 0, GRAD_EPSILON);
  30. return normalize(vec3(
  31. scene_f(p + dx).d - scene_f(p - dx).d,
  32. scene_f(p + dy).d - scene_f(p - dy).d,
  33. scene_f(p + dz).d - scene_f(p - dz).d
  34. ));
  35. }
  36. vec3 raymarch(vec3 o, vec3 d, float start, float end) {
  37. float t = start;
  38. for (int i = 0; i < MAX_STEPS; i++) {
  39. SceneResult sr = scene_f(o + d*t);
  40. if (sr.d < EPSILON || t > end)
  41. return vec3(t, sr.mat_idx, i);
  42. t += sr.d;
  43. }
  44. return vec3(end, -1., MAX_STEPS);
  45. }
  46. vec4 shade_material(vec3 p, vec3 norm, float mat_idx) {
  47. return vec4(1.);
  48. }
  49. vec4 shade(vec3 p, float mat_idx) {
  50. vec3 norm = estimate_scene_normal(p);
  51. vec4 color_mat = shade_material(p, norm, mat_idx);
  52. return color_mat;
  53. }
  54. void main() {
  55. vec2 mouse_uv = u_Mouse.xy * 2.0 / u_Resolution.xy - 1.0;
  56. vec2 uv = gl_FragCoord.xy * 2.0 / u_Resolution.xy - 1.0;
  57. uv.x *= u_Resolution.x/u_Resolution.y;
  58. float an = 0.3 * u_Time;
  59. float d = 2. + sin(an) * 1.6;
  60. vec3 eye = vec3(3. * sin(an), 2., 3. * cos(an)) * d;
  61. vec3 target = vec3(0., 0., 0.);
  62. mat3 lookAt = look_mat(eye, target, 0);
  63. vec3 dir = normalize(lookAt * ray_dir(FOV, uv));
  64. color = vec4(0.);
  65. vec3 result = raymarch(eye, dir, NEAR_D, FAR_D);
  66. float depth = result.x;
  67. float mat_idx = result.y;
  68. float iters = result.z;
  69. if (depth >= FAR_D) {
  70. color = vec4(0.);
  71. return;
  72. }
  73. // color = colormap(iters/MAX_STEPS+0.5);
  74. vec3 p = eye + dir * depth; // recast the ray
  75. color = shade(p, mat_idx);
  76. }