Advertisement
Guest User

Untitled

a guest
Feb 13th, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* This file is part of the Marble Marcher (https://github.com/HackerPoet/MarbleMarcher).
  2. * Copyright(C) 2018 CodeParade
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program.If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #version 120
  18. #define AMBIENT_OCCLUSION_COLOR_DELTA vec3(0.7)
  19. #define AMBIENT_OCCLUSION_STRENGTH 0.008
  20. #define ANTIALIASING_SAMPLES 1
  21. #define BACKGROUND_COLOR vec3(0.6,0.8,1.0)
  22. #define COL col_scene
  23. #define DE de_scene
  24. #define DIFFUSE_ENABLED 0
  25. #define DIFFUSE_ENHANCED_ENABLED 1
  26. #define FILTERING_ENABLE 0
  27. #define FOCAL_DIST 1.73205080757
  28. #define FOG_ENABLED 0
  29. #define FRACTAL_ITER 16
  30. #define LIGHT_COLOR vec3(1.0,0.95,0.8)
  31. #define LIGHT_DIRECTION vec3(-0.36, 0.8, 0.48)
  32. #define MAX_DIST 30.0
  33. #define MAX_MARCHES 1000
  34. #define MIN_DIST 1e-5
  35. #define PI 3.14159265358979
  36. #define SHADOWS_ENABLED 1
  37. #define SHADOW_DARKNESS 0.7
  38. #define SHADOW_SHARPNESS 10.0
  39. #define SPECULAR_HIGHLIGHT 40
  40. #define SPECULAR_MULT 0.25
  41. #define SUN_ENABLED 1
  42. #define SUN_SHARPNESS 2.0
  43. #define SUN_SIZE 0.004
  44. #define VIGNETTE_STRENGTH 0.5
  45.  
  46. uniform mat4 iMat;
  47. uniform vec2 iResolution;
  48. uniform vec3 iDebug;
  49.  
  50. uniform float iFracScale;
  51. uniform float iFracAng1;
  52. uniform float iFracAng2;
  53. uniform vec3 iFracShift;
  54. uniform vec3 iFracCol;
  55. uniform vec3 iMarblePos;
  56. uniform float iMarbleRad;
  57. uniform float iFlagScale;
  58. uniform vec3 iFlagPos;
  59. uniform float iExposure;
  60.  
  61. #define _iMarbleRad (iMarbleRad*0.1)
  62.  
  63. float FOVperPixel;
  64.  
  65. vec3 refraction(vec3 rd, vec3 n, float p) {
  66.     float dot_nd = dot(rd, n);
  67.     return p * (rd - dot_nd * n) + sqrt(1.0 - (p * p) * (1.0 - dot_nd * dot_nd)) * n;
  68. }
  69.  
  70. //##########################################
  71. //   Space folding
  72. //##########################################
  73. void planeFold(inout vec4 z, vec3 n, float d) {
  74.     z.xyz -= 2.0 * min(0.0, dot(z.xyz, n) - d) * n;
  75. }
  76. void sierpinskiFold(inout vec4 z) {
  77.     z.xy -= min(z.x + z.y, 0.0);
  78.     z.xz -= min(z.x + z.z, 0.0);
  79.     z.yz -= min(z.y + z.z, 0.0);
  80. }
  81. void mengerFold(inout vec4 z) {
  82.     float a = min(z.x - z.y, 0.0);
  83.     z.x -= a;
  84.     z.y += a;
  85.     a = min(z.x - z.z, 0.0);
  86.     z.x -= a;
  87.     z.z += a;
  88.     a = min(z.y - z.z, 0.0);
  89.     z.y -= a;
  90.     z.z += a;
  91. }
  92. void boxFold(inout vec4 z, vec3 r) {
  93.     z.xyz = clamp(z.xyz, -r, r) * 2.0 - z.xyz;
  94. }
  95. void rotX(inout vec4 z, float s, float c) {
  96.     z.yz = vec2(c*z.y + s*z.z, c*z.z - s*z.y);
  97. }
  98. void rotY(inout vec4 z, float s, float c) {
  99.     z.xz = vec2(c*z.x - s*z.z, c*z.z + s*z.x);
  100. }
  101. void rotZ(inout vec4 z, float s, float c) {
  102.     z.xy = vec2(c*z.x + s*z.y, c*z.y - s*z.x);
  103. }
  104. void rotX(inout vec4 z, float a) {
  105.     rotX(z, sin(a), cos(a));
  106. }
  107. void rotY(inout vec4 z, float a) {
  108.     rotY(z, sin(a), cos(a));
  109. }
  110. void rotZ(inout vec4 z, float a) {
  111.     rotZ(z, sin(a), cos(a));
  112. }
  113.  
  114. //##########################################
  115. //   Primitive DEs
  116. //##########################################
  117. float de_sphere(vec4 p, float r) {
  118.     return (length(p.xyz) - r) / p.w;
  119. }
  120. float de_box(vec4 p, vec3 s) {
  121.     vec3 a = abs(p.xyz) - s;
  122.     return (min(max(max(a.x, a.y), a.z), 0.0) + length(max(a, 0.0))) / p.w;
  123. }
  124. float de_tetrahedron(vec4 p, float r) {
  125.     float md = max(max(-p.x - p.y - p.z, p.x + p.y - p.z),
  126.                 max(-p.x + p.y + p.z, p.x - p.y + p.z));
  127.     return (md - r) / (p.w * sqrt(3.0));
  128. }
  129. float de_capsule(vec4 p, float h, float r) {
  130.     p.y -= clamp(p.y, -h, h);
  131.     return (length(p.xyz) - r) / p.w;
  132. }
  133.  
  134. //##########################################
  135. //   Main DEs
  136. //##########################################
  137. float de_fractal(vec4 p) {
  138.     for (int i = 0; i < FRACTAL_ITER; ++i) {
  139.         p.xyz = abs(p.xyz);
  140.         rotZ(p, iFracAng1);
  141.         mengerFold(p);
  142.         rotX(p, iFracAng2);
  143.         p *= iFracScale;
  144.         p.xyz += iFracShift;
  145.     }
  146.     return de_box(p, vec3(6.0)) - iMarbleRad*0.9;
  147. }
  148. vec4 col_fractal(vec4 p) {
  149.     vec3 orbit = vec3(0.0);
  150.     for (int i = 0; i < FRACTAL_ITER; ++i) {
  151.         p.xyz = abs(p.xyz);
  152.         rotZ(p, iFracAng1);
  153.         mengerFold(p);
  154.         rotX(p, iFracAng2);
  155.         p *= iFracScale;
  156.         p.xyz += iFracShift;
  157.         orbit = max(orbit, p.xyz*iFracCol);
  158.     }
  159.     return vec4(orbit, de_box(p, vec3(6.0)) - iMarbleRad*0.9);
  160. }
  161. float de_marble(vec4 p) {
  162.     return de_sphere(p - vec4(iMarblePos, 0), _iMarbleRad);
  163. }
  164. vec4 col_marble(vec4 p) {
  165.     return vec4(0, 0, 0, de_sphere(p - vec4(iMarblePos, 0), _iMarbleRad));
  166. }
  167. float de_flag(vec4 p) {
  168.     vec3 f_pos = iFlagPos + vec3(1.5, 4, 0)*iFlagScale;
  169.     float d = de_box(p - vec4(f_pos, 0), vec3(1.5, 0.8, 0.08)*iMarbleRad);
  170.     d = min(d, de_capsule(p - vec4(iFlagPos + vec3(0, iFlagScale*2.4, 0), 0), iMarbleRad*2.4, iMarbleRad*0.18));
  171.     return d;
  172. }
  173. vec4 col_flag(vec4 p) {
  174.     vec3 f_pos = iFlagPos + vec3(1.5, 4, 0)*iFlagScale;
  175.     float d1 = de_box(p - vec4(f_pos, 0), vec3(1.5, 0.8, 0.08)*iMarbleRad);
  176.     float d2 = de_capsule(p - vec4(iFlagPos + vec3(0, iFlagScale*2.4, 0), 0), iMarbleRad*2.4, iMarbleRad*0.18);
  177.     if (d1 < d2) {
  178.         return vec4(1.0, 0.2, 0.1, d1);
  179.     } else {
  180.         return vec4(0.9, 0.9, 0.1, d2);
  181.     }
  182. }
  183. float de_scene(vec4 p) {
  184.     float d = de_fractal(p);
  185.     d = min(d, de_marble(p));
  186.     d = min(d, de_flag(p));
  187.     return d;
  188. }
  189. vec4 col_scene(vec4 p) {
  190.     vec4 col = col_fractal(p);
  191.     vec4 col_f = col_flag(p);
  192.     if (col_f.w < col.w) { col = col_f; }
  193.     vec4 col_m = col_marble(p);
  194.     if (col_m.w < col.w) {
  195.         return vec4(col_m.xyz, 1.0);
  196.     }
  197.     return vec4(col.xyz, 0.0);
  198. }
  199.  
  200. //##########################################
  201. //   Main code
  202. //##########################################
  203.  
  204. //A faster formula to find the gradient/normal direction of the DE(the w component is the average DE)
  205. //credit to http://www.iquilezles.org/www/articles/normalsSDF/normalsSDF.htm
  206. vec3 calcNormal(vec4 p, float dx) {
  207.     const vec3 k = vec3(1,-1,0);
  208.     return normalize(k.xyy*DE(p + k.xyyz*dx) +
  209.                      k.yyx*DE(p + k.yyxz*dx) +
  210.                      k.yxy*DE(p + k.yxyz*dx) +
  211.                      k.xxx*DE(p + k.xxxz*dx));
  212. }
  213.  
  214. //find the average color of the fractal in a radius dx in plane s1-s2
  215. vec4 smoothColor(vec4 p, vec3 s1, vec3 s2, float dx) {
  216.     return (COL(p + vec4(s1,0)*dx) +
  217.             COL(p - vec4(s1,0)*dx) +
  218.             COL(p + vec4(s2,0)*dx) +
  219.             COL(p - vec4(s2,0)*dx))/4;
  220. }
  221.  
  222. vec4 ray_march(inout vec4 p, vec4 ray, float sharpness) {
  223.     //March the ray
  224.     float d = DE(p);
  225.     if (d < 0.0 && sharpness == 1.0) {
  226.         vec3 v;
  227.         if (abs(iMarblePos.x) >= 999.0f) {
  228.             v = (-20.0 * _iMarbleRad) * iMat[2].xyz;
  229.         } else {
  230.             v = iMarblePos.xyz - iMat[3].xyz;
  231.         }
  232.         d = dot(v, v) / dot(v, ray.xyz) - _iMarbleRad;
  233.     }
  234.     float s = 0.0;
  235.     float td = 0.0;
  236.     float min_d = 1.0;
  237.     for (; s < MAX_MARCHES; s += 1.0) {
  238.         //if the distance from the surface is less than the distance per pixel we stop
  239.         float min_dist = max(FOVperPixel*td, MIN_DIST);
  240.         if (d < min_dist) {
  241.             s += d / min_dist;
  242.             break;
  243.         } else if (td > MAX_DIST) {
  244.             break;
  245.         }
  246.         td += d;
  247.         p += ray * d;
  248.         min_d = min(min_d, sharpness * d / td);
  249.         d = DE(p);
  250.     }
  251.     return vec4(d, s, td, min_d);
  252. }
  253.  
  254. vec4 scene(inout vec4 p, inout vec4 ray, float vignette) {
  255.     //Trace the ray
  256.     vec4 d_s_td_m = ray_march(p, ray, 1.0f);
  257.     float d = d_s_td_m.x;
  258.     float s = d_s_td_m.y;
  259.     float td = d_s_td_m.z;
  260.  
  261.     //Determine the color for this pixel
  262.     vec4 col = vec4(0.0);
  263.     float min_dist = max(FOVperPixel*td, MIN_DIST);
  264.     if (d < min_dist) {
  265.         //Get the surface normal
  266.         vec3 n = calcNormal(p, min_dist*0.5);
  267.        
  268.         //find closest surface point, without this we get weird coloring artifacts
  269.         p.xyz -= n*d;
  270.  
  271.         //Get coloring
  272.         #if FILTERING_ENABLE
  273.             //sample direction 1, the cross product between the ray and the surface normal, should be parallel to the surface
  274.             vec3 s1 = normalize(cross(ray.xyz, n));
  275.             //sample direction 2, the cross product between s1 and the surface normal
  276.             vec3 s2 = cross(s1, n);
  277.             //get filtered color
  278.             vec4 orig_col = clamp(smoothColor(p, s1, s2, min_dist*0.5), 0.0, 1.0);
  279.         #else
  280.             vec4 orig_col = clamp(COL(p), 0.0, 1.0);
  281.         #endif
  282.         col.w = orig_col.w;
  283.  
  284.         //Get if this point is in shadow
  285.         float k = 1.0;
  286.         #if SHADOWS_ENABLED
  287.             vec4 light_pt = p;
  288.             light_pt.xyz += n * MIN_DIST * 100;
  289.             vec4 rm = ray_march(light_pt, vec4(LIGHT_DIRECTION, 0.0), SHADOW_SHARPNESS);
  290.             k = rm.w * min(rm.z, 1.0);
  291.         #endif
  292.  
  293.         //Get specular
  294.         #if SPECULAR_HIGHLIGHT > 0
  295.             vec3 reflected = ray.xyz - 2.0*dot(ray.xyz, n) * n;
  296.             float specular = max(dot(reflected, LIGHT_DIRECTION), 0.0);
  297.             specular = pow(specular, SPECULAR_HIGHLIGHT);
  298.             col.xyz += specular * LIGHT_COLOR * (k * SPECULAR_MULT);
  299.         #endif
  300.  
  301.         //Get diffuse lighting
  302.         #if DIFFUSE_ENHANCED_ENABLED
  303.             k = min(k, SHADOW_DARKNESS * 0.5 * (dot(n, LIGHT_DIRECTION) - 1.0) + 1.0);
  304.         #elif DIFFUSE_ENABLED
  305.             k = min(k, dot(n, LIGHT_DIRECTION));
  306.         #endif
  307.  
  308.         //Don't make shadows entirely dark
  309.         k = max(k, 1.0 - SHADOW_DARKNESS);
  310.         col.xyz += orig_col.xyz * LIGHT_COLOR * k;
  311.  
  312.         //Add small amount of ambient occlusion
  313.         float a = 1.0 / (1.0 + s * AMBIENT_OCCLUSION_STRENGTH);
  314.         col.xyz += (1.0 - a) * AMBIENT_OCCLUSION_COLOR_DELTA;
  315.  
  316.         //Add fog effects
  317.         #if FOG_ENABLED
  318.             a = td / MAX_DIST;
  319.             col.xyz = (1.0 - a) * col.xyz + a * BACKGROUND_COLOR;
  320.         #endif
  321.  
  322.         //Return normal through ray
  323.         ray = vec4(n, 0.0);
  324.     } else {
  325.         //Ray missed, start with solid background color
  326.         col.xyz += BACKGROUND_COLOR;
  327.  
  328.         col.xyz *= vignette;
  329.         //Background specular
  330.         #if SUN_ENABLED
  331.             float sun_spec = dot(ray.xyz, LIGHT_DIRECTION) - 1.0 + SUN_SIZE;
  332.             sun_spec = min(exp(sun_spec * SUN_SHARPNESS / SUN_SIZE), 1.0);
  333.             col.xyz += LIGHT_COLOR * sun_spec;
  334.         #endif
  335.     }
  336.  
  337.     return col;
  338. }
  339.  
  340. void main() {
  341.     //Calculate the view angle per pixel, with a minimum quality level
  342.     FOVperPixel = 1.0 / max(iResolution.x, 900.0);
  343.  
  344.     vec3 col = vec3(0.0);
  345.     for (int i = 0; i < ANTIALIASING_SAMPLES; ++i) {
  346.         for (int j = 0; j < ANTIALIASING_SAMPLES; ++j) {
  347.             //Get normalized screen coordinate
  348.             vec2 delta = vec2(i, j) / ANTIALIASING_SAMPLES;
  349.             vec2 screen_pos = (gl_FragCoord.xy + delta) / iResolution.xy;
  350.  
  351.             vec2 uv = 2*screen_pos - 1;
  352.             uv.x *= iResolution.x / iResolution.y;
  353.  
  354.             //Convert screen coordinate to 3d ray
  355.             vec4 ray = iMat * normalize(vec4(uv.x, uv.y, -FOCAL_DIST, 0.0));
  356.             vec4 p = iMat[3];
  357.  
  358.             //Reflect light if needed
  359.             float vignette = 1.0 - VIGNETTE_STRENGTH * length(screen_pos - 0.5);
  360.             vec3 r = ray.xyz;
  361.             vec4 col_r = scene(p, ray, vignette);
  362.  
  363.             //Check if this is the glass marble
  364.             if (col_r.w > 0.5) {
  365.                 //Calculate refraction
  366.                 vec3 n = normalize(iMarblePos - p.xyz);
  367.                 vec3 q = refraction(r, n, 1.0 / 1.5);
  368.                 vec3 p2 = p.xyz + (dot(q, n) * 2.0 * _iMarbleRad) * q;
  369.                 n = normalize(p2 - iMarblePos);
  370.                 q = (dot(q, r) * 2.0) * q - r;
  371.                 vec4 p_temp = vec4(p2 + n * (MIN_DIST * 10), 1.0);
  372.                 vec4 r_temp = vec4(q, 0.0);
  373.                 vec3 refr = scene(p_temp, r_temp, 0.8).xyz;
  374.  
  375.                 //Calculate refraction
  376.                 n = normalize(p.xyz - iMarblePos);
  377.                 q = r - n*(2*dot(r,n));
  378.                 p_temp = vec4(p.xyz + n * (MIN_DIST * 10), 1.0);
  379.                 r_temp = vec4(q, 0.0);
  380.                 vec3 refl = scene(p_temp, r_temp, 0.8).xyz;
  381.  
  382.                 //Combine for final marble color
  383.                 col += refr * 0.6f + refl * 0.4f + col_r.xyz;
  384.             } else {
  385.                 col += col_r.xyz;
  386.             }
  387.         }
  388.     }
  389.  
  390.     col *= iExposure / (ANTIALIASING_SAMPLES * ANTIALIASING_SAMPLES);
  391.     gl_FragColor = vec4(clamp(col, 0.0, 1.0), 1.0);
  392. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement