Advertisement
purplejragon

raymarching plane and sphere

Feb 13th, 2022
3,429
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #version 300 es
  2. precision highp float;
  3. uniform vec2 resolution;
  4. uniform float time;
  5. out vec4 fragColor;
  6. const int maxSteps = 500;
  7. mat3 lookAt(vec3 origin, vec3 target, float roll) {
  8.   vec3 rr = vec3(sin(roll), cos(roll), 0.0);
  9.   vec3 ww = normalize(target - origin);
  10.   vec3 uu = normalize(cross(ww, rr));
  11.   vec3 vv = normalize(cross(uu, ww));
  12.  
  13.   return mat3(uu, vv, ww);
  14. }
  15. float sdSphere(vec3 p, float r) {
  16.   return length(p) - r;
  17. }
  18. float sdPlane(vec3 p, vec3 n, float h) {
  19.   return dot(p, n) - h;
  20. }
  21. vec2 minx(vec2 a, vec2 b) {
  22.   return a.x < b.x ? a : b;
  23. }
  24. vec2 map(vec3 p) {
  25.   vec2 a = vec2(sdPlane(p, vec3(0, 1, 0), 0.5), 1);
  26.   vec2 b = vec2(sdSphere(p - vec3(0, 1, 0), 0.5), 2);
  27.  
  28.   vec2 t = minx(a, b);
  29.   return t;
  30. }
  31. float shadow(vec3 ro, vec3 rd, float maxt, float k) {
  32.   float res = 1.0;
  33.   for (float t = 0.001; t < maxt;) {
  34.     float h = map(ro + rd*t).x;
  35.     if( h<0.001 )
  36.       return 0.0;
  37.     res = min( res, k*h/t );
  38.     t += h;
  39.   }
  40.   return res;
  41. }
  42. vec2 raymarch(vec3 ro, vec3 rd) {
  43.   float t;
  44.   float m;
  45.  
  46.   float mint = 0.001;
  47.   float maxt = 1000.0;
  48.   for (int i = 0; i < maxSteps; i++) {
  49.     vec3 p = ro + rd * t;
  50.     vec2 d = map(p);
  51.     t += abs(d.x);
  52.     m = d.y;
  53.     if (d.x < 0.001) { break; }
  54.     if (t > 100.0) { return vec2(-1.0, -1.0); }
  55.   }
  56.   return vec2(t, m);
  57. }
  58. vec3 skyColor(vec3 rd) {
  59.   return mix(vec3(1), vec3(0.5, 0.7, 1.0), rd.y*0.5+0.5);
  60. }
  61. vec3 getNormal(vec3 p) {
  62.   float eps = 0.001;
  63.   float a = map(p).x;
  64.   float x = map(p + vec3(eps, 0, 0)).x;
  65.   float y = map(p + vec3(0, eps, 0)).x;
  66.   float z = map(p + vec3(0, 0, eps)).x;
  67.   return normalize((vec3(x, y, z) - a) / eps);
  68. }
  69. vec3 getMaterial(float id) {
  70.   if (id == 2.0) {
  71.     return vec3(0.4, 0.5, 1.0);
  72.   }
  73.   return vec3(0.2, 0.6, 0.3);
  74. }
  75. const vec3 sunDir = normalize(-vec3(-1.0, -1.0, -1.0));
  76. const vec3 sunCol = vec3(1.5, 1.3, 1.2);
  77. vec3 getLighting(vec3 pos, vec3 nor) {
  78.   vec3 sampSun = max(0.0, dot(nor, sunDir)) * sunCol;
  79.   float shadow = shadow(pos+nor*0.001, sunDir, 1000.0, 32.0);
  80.   vec3 sampSky = skyColor(nor) * 0.2 /** (nor.y*0.5+0.5)*/;
  81.   return sampSun*shadow + sampSky;
  82. }
  83. void main() {
  84.   vec2 p = gl_FragCoord.xy;
  85.   vec2 uv = (p - 0.5*resolution) / resolution.y;
  86.  
  87.   vec3 ro = vec3(sin(time / 6000.0)*4.0, 1.5, cos(time/6000.0)*4.0);
  88.   mat3 ma = lookAt(ro, vec3(0), 0.0);
  89.   vec3 rd = normalize(ma * vec3(uv, 1.0));
  90.  
  91.   vec3 outColor;
  92.  
  93.   vec2 t = raymarch(ro, rd);
  94.   if (t.x > 0.0) {
  95.     vec3 pos = ro + rd * t.x;
  96.     vec3 nor = getNormal(pos);
  97.     vec3 col = getMaterial(t.y) * getLighting(pos, nor);
  98.     outColor = col;
  99.     //outColor = nor * 0.5+0.5;
  100.   } else {
  101.     outColor = skyColor(rd);
  102.   }
  103.  
  104.   fragColor = vec4(pow(outColor, vec3(0.4545)), 1.0);
  105. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement