fs_raymarching.sc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. $input v_color0, v_texcoord0
  2. /*
  3. * Copyright 2011-2017 Branimir Karadzic. All rights reserved.
  4. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  5. */
  6. // References:
  7. // Sphere tracing: a geometric method for the antialiased ray tracing of implicit surfaces - John C. Hart
  8. // http://web.archive.org/web/20110331200546/http://graphics.cs.uiuc.edu/~jch/papers/zeno.pdf
  9. //
  10. // Modeling with distance functions
  11. // http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
  12. #include "../common/common.sh"
  13. #include "iq_sdf.sh"
  14. uniform mat4 u_mtx;
  15. uniform vec4 u_lightDirTime;
  16. #define u_lightDir u_lightDirTime.xyz
  17. #define u_time u_lightDirTime.w
  18. float sceneDist(vec3 _pos)
  19. {
  20. float d1 = udRoundBox(_pos, vec3(2.5, 2.5, 2.5), 0.5);
  21. float d2 = sdSphere(_pos + vec3( 4.0, 0.0, 0.0), 1.0);
  22. float d3 = sdSphere(_pos + vec3(-4.0, 0.0, 0.0), 1.0);
  23. float d4 = sdSphere(_pos + vec3( 0.0, 4.0, 0.0), 1.0);
  24. float d5 = sdSphere(_pos + vec3( 0.0,-4.0, 0.0), 1.0);
  25. float d6 = sdSphere(_pos + vec3( 0.0, 0.0, 4.0), 1.0);
  26. float d7 = sdSphere(_pos + vec3( 0.0, 0.0,-4.0), 1.0);
  27. float dist = min(min(min(min(min(min(d1, d2), d3), d4), d5), d6), d7);
  28. return dist;
  29. }
  30. vec3 calcNormal(vec3 _pos)
  31. {
  32. const vec2 delta = vec2(0.002, 0.0);
  33. float nx = sceneDist(_pos + delta.xyy) - sceneDist(_pos - delta.xyy);
  34. float ny = sceneDist(_pos + delta.yxy) - sceneDist(_pos - delta.yxy);
  35. float nz = sceneDist(_pos + delta.yyx) - sceneDist(_pos - delta.yyx);
  36. return normalize(vec3(nx, ny, nz) );
  37. }
  38. float calcAmbOcc(vec3 _pos, vec3 _normal)
  39. {
  40. float occ = 0.0;
  41. float aostep = 0.2;
  42. for (int ii = 1; ii < 4; ii++)
  43. {
  44. float fi = float(ii);
  45. float dist = sceneDist(_pos + _normal * fi * aostep);
  46. occ += (fi * aostep - dist) / pow(2.0, fi);
  47. }
  48. return 1.0 - occ;
  49. }
  50. float trace(vec3 _ray, vec3 _dir, float _maxd)
  51. {
  52. float tt = 0.0;
  53. float epsilon = 0.001;
  54. for (int ii = 0; ii < 64; ii++)
  55. {
  56. float dist = sceneDist(_ray + _dir*tt);
  57. if (dist > epsilon)
  58. {
  59. tt += dist;
  60. }
  61. }
  62. return tt < _maxd ? tt : 0.0;
  63. }
  64. vec2 blinn(vec3 _lightDir, vec3 _normal, vec3 _viewDir)
  65. {
  66. float ndotl = dot(_normal, _lightDir);
  67. vec3 reflected = _lightDir - 2.0*ndotl*_normal; // reflect(_lightDir, _normal);
  68. float rdotv = dot(reflected, _viewDir);
  69. return vec2(ndotl, rdotv);
  70. }
  71. float fresnel(float _ndotl, float _bias, float _pow)
  72. {
  73. float facing = (1.0 - _ndotl);
  74. return max(_bias + (1.0 - _bias) * pow(facing, _pow), 0.0);
  75. }
  76. vec4 lit(float _ndotl, float _rdotv, float _m)
  77. {
  78. float diff = max(0.0, _ndotl);
  79. float spec = step(0.0, _ndotl) * max(0.0, _rdotv * _m);
  80. return vec4(1.0, diff, spec, 1.0);
  81. }
  82. void main()
  83. {
  84. vec4 tmp;
  85. tmp = mul(u_mtx, vec4(v_texcoord0.xy, 0.0, 1.0) );
  86. vec3 eye = tmp.xyz/tmp.w;
  87. tmp = mul(u_mtx, vec4(v_texcoord0.xy, 1.0, 1.0) );
  88. vec3 at = tmp.xyz/tmp.w;
  89. float maxd = length(at - eye);
  90. vec3 dir = normalize(at - eye);
  91. float dist = trace(eye, dir, maxd);
  92. if (dist > 0.5)
  93. {
  94. vec3 pos = eye + dir*dist;
  95. vec3 normal = calcNormal(pos);
  96. vec2 bln = blinn(u_lightDir, normal, dir);
  97. vec4 lc = lit(bln.x, bln.y, 1.0);
  98. float fres = fresnel(bln.x, 0.2, 5.0);
  99. float val = 0.9*lc.y + pow(lc.z, 128.0)*fres;
  100. val *= calcAmbOcc(pos, normal);
  101. val = pow(val, 1.0/2.2);
  102. gl_FragColor = vec4(val, val, val, 1.0);
  103. gl_FragDepth = dist/maxd;
  104. }
  105. else
  106. {
  107. gl_FragColor = v_color0;
  108. gl_FragDepth = 1.0;
  109. }
  110. }