Advertisement
Guest User

Untitled

a guest
Dec 15th, 2017
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.85 KB | None | 0 0
  1.  
  2. struct Ray {
  3. vec3 origin;
  4. vec3 dir;
  5. };
  6.  
  7. struct Light {
  8. vec3 pos;
  9. };
  10.  
  11. struct Camera {
  12. vec3 pos;
  13. Ray ray;
  14. float rayDivergence;
  15. };
  16.  
  17. struct Sphere {
  18. vec3 center;
  19. float radius;
  20. };
  21.  
  22. struct Plane {
  23. float yCoord;
  24. };
  25.  
  26. float unionOp(float d0, float d1) {
  27. return min(d0, d1);
  28. }
  29.  
  30. float distToSphere(in Ray r, in Sphere s) {
  31. float d = distance(r.origin, s.center);
  32. return d - s.radius;
  33. }
  34.  
  35. float distToPlane(in Ray r, in Plane p) {
  36. return r.origin.y - p.yCoord;
  37. }
  38.  
  39. vec2 distToScene(in Ray r) {
  40. Plane p = Plane(0.0);
  41. float d2p = distToPlane(r, p);
  42. Sphere s = Sphere(vec3(0.0, 6.0, 0.0), 6.0);
  43. float d2s = distToSphere(r, s);
  44. float dist = unionOp(d2s, d2p);
  45. float o = 0.0; // 0 means plane is closer
  46. if (d2p > d2s) {
  47. o = 1.0; // 1 means sphere is closer
  48. }
  49. vec2 obj = vec2(dist, o);
  50. return obj;
  51. }
  52.  
  53. vec3 getNormal(in Ray ray) {
  54. vec2 eps = vec2(0.001, 0.0);
  55. vec3 n = vec3(distToScene(Ray(ray.origin + eps.xyy, ray.dir)).x -
  56. distToScene(Ray(ray.origin - eps.xyy, ray.dir)).x,
  57. distToScene(Ray(ray.origin + eps.yxy, ray.dir)).x -
  58. distToScene(Ray(ray.origin - eps.yxy, ray.dir)).x,
  59. distToScene(Ray(ray.origin + eps.yyx, ray.dir)).x -
  60. distToScene(Ray(ray.origin - eps.yyx, ray.dir)).x);
  61. return normalize(n);
  62. }
  63.  
  64. float ao(in vec3 pos, in vec3 n) {
  65. float eps = 0.01;
  66. pos += n * eps * 2.0;
  67. float occlusion = 0.0;
  68. for (float i=1.0; i<10.0; i++) {
  69. float dist = distToScene(Ray(pos, vec3(0))).x;
  70. float coneWidth = 2.0 * eps;
  71. float occlusionAmount = max(coneWidth - dist, 0.0);
  72. float occlusionFactor = occlusionAmount / coneWidth;
  73. occlusionFactor *= 1.0 - (i / 10.0);
  74. occlusion = max(occlusion, occlusionFactor);
  75. eps *= 2.0;
  76. pos += n * eps;
  77. }
  78. return max(0.0, 1.0 - occlusion);
  79. }
  80.  
  81. Camera setupCam(in vec3 pos, in vec3 target, in float fov, in vec2 uv) {
  82. uv *= fov;
  83. vec3 cw = normalize (target - pos);
  84. vec3 cp = vec3 (0.0, 1.0, 0.0);
  85. vec3 cu = normalize(cross(cw, cp));
  86. vec3 cv = normalize(cross(cu, cw));
  87. vec3 dir = normalize (uv.x * cu + uv.y * cv + 0.5 * cw);
  88. Ray ray = Ray(pos, dir);
  89. Camera cam = Camera(pos, ray, fov / iResolution.x);
  90. return cam;
  91. }
  92.  
  93. void reflectRay(inout Camera cam, vec3 n, float eps) {
  94. cam.ray.origin += n * eps;
  95. cam.ray.dir = reflect(cam.ray.dir, n);
  96. }
  97.  
  98. vec3 refractRay(float object) {
  99. vec3 rayColor = vec3(1.0);
  100. if (object == 1.0) {}
  101. else if (object == 0.0) {}
  102. return rayColor;
  103. }
  104.  
  105. void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
  106. vec2 uv = fragCoord.xy / iResolution.xy;
  107. uv = uv * 2.0 - 1.0;
  108. uv.y *= iResolution.y / iResolution.x;
  109. // Lets have the camera moving so we can see what's happening
  110. vec3 camPos = vec3(sin(iTime)*15., sin(iTime)*5.+7., cos(iTime)*15.);
  111. Camera cam = setupCam(camPos, vec3(0.0), 1.25, uv);
  112. vec3 col = vec3(1.);
  113. bool hit = false;
  114. float eps = 0.01;
  115. float object;
  116. bool inside = false;
  117.  
  118. for (int i=0; i<300; i++) {
  119. vec2 obj = distToScene(cam.ray);
  120. float dist = obj.x * (inside ? -1. : 1.);
  121. float o = obj.y;
  122. if (dist < eps) {
  123. vec3 normal = getNormal(cam.ray) * (inside ? -1. : 1.);
  124.  
  125. if (object == 0.0) {
  126. // AO on glass doesn't work, so we do AO on the floor only
  127. // Note: if ray hits floor and bounces out into the sky, then
  128. // doing AO at the end means adding AO to the sky! Has to be done here.
  129. float o = ao(cam.ray.origin, normal);
  130. col *= o;
  131. // Do the colour stuff
  132. vec2 pos = cam.ray.origin.xz;
  133. pos *= 0.1;
  134. pos = floor(mod(pos, 2.0));
  135. float check = mod(pos.x + pos.y, 2.0);
  136. col *= check * 0.6 + 0.2;
  137. // reflect the ray
  138. reflectRay(cam, normal, eps);
  139.  
  140. } else if (object == 1.0) {
  141. // Don't forget to switch in/out when we hit the glass!
  142. inside = !inside;
  143. float ior = inside ? 1.0 / 1.5 : 1.5;
  144. cam.ray.origin -= normal * eps * 2.0;
  145. cam.ray.dir = refract(cam.ray.dir, normal, ior);
  146. }
  147. // We don't hit now, since the ray is either reflected or refracted!
  148. // hit = true;
  149. }
  150. if (o == 1.0) { object = 1.0; } else { object = 0.0; }
  151. cam.ray.origin += cam.ray.dir * dist;
  152. eps += cam.rayDivergence * dist;
  153. }
  154.  
  155. // Because we ignore the 'hit' value, the ray always ends up the sky:
  156. col.rgb *= mix(vec3(.8 ,.8, .4), vec3(.4, .4, 1.), cam.ray.dir.y);
  157.  
  158. fragColor.rgb = col;
  159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement