Advertisement
Phantom2155

Untitled

Oct 18th, 2018
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.58 KB | None | 0 0
  1. //Map defines what primitive shapes our scene is made of
  2. float map(float3 p)
  3. {
  4. //This is just a sphere. It's returning the distance from any point p to the edge of the sphere
  5. //This can kinda be described as if a point is inside the sphere, length(p) will be less than S, so it will be a negative value
  6. //Mostly just refer to this for signed distance functions
  7. //http://iquilezles.org/www/articles/distfunctions/distfunctions.htm
  8. return length(p) - 1;//Our sphere is 1 unit big here
  9. }
  10. #define STEPS 64
  11. float march(float3 origin, float3 rayDir)
  12. {
  13. //t is the distance this ray has traveled so far.
  14. float t = 0;
  15. for(int i = 0; i < STEPS; i++)
  16. {
  17. //p is the current point the ray is at.
  18. //Think of it like this: Start at the starting point(origin) and travel t unity in the direction the ray is pointing.
  19. //That's our new point
  20. float3 p = origin + rayDir * t;
  21. //Feed the point into our map function, which returns the distance to the closest edge.
  22. //Since this is the distance to the closest edge, that means if we traveled exactly that distance we wouldn't colide or go through anything.
  23. float dist = map(p);
  24. //0.01 here is our "epsilon" value. That just means the minimum distance required to register that we've hit the surface and can break out of the loop
  25. if(dist < 0.01)
  26. {
  27. break;
  28. }
  29. //Travel exactly the distance to the closest edge. You can travel less, but going more than this will run the risk of traveling through the surface.
  30. t += dist;
  31. }
  32. return t;
  33. }
  34.  
  35. float3 getNormal(in float3 p) {
  36. //This get the normal by partial differention I think.
  37. //I kinda understand this, but I usually just use big brain boys functions from shadertoy.
  38. //It's basically taking the slope from a point slightly to the left/right of our final hit point. Slope = normal.
  39. const float eps = 0.001;
  40. return normalize(float3(
  41. map(float3(p.x+eps,p.y,p.z))-map(float3(p.x-eps,p.y,p.z)),
  42. map(float3(p.x,p.y+eps,p.z))-map(float3(p.x,p.y-eps,p.z)),
  43. map(float3(p.x,p.y,p.z+eps))-map(float3(p.x,p.y,p.z-eps))
  44. ));
  45.  
  46. }
  47.  
  48. void mainImage(out float4 fragColor, in float2 fragCoord)
  49. {
  50. //This is shadertoy style setup, so fragCoord is a number between [0, resolution] so we have to divide it by resolution to get uvs in the range [0,1]
  51. float2 uv = fragCoord/iResolution.xy;
  52. //Centered them so they go from [-1,1]
  53. uv = -1 + 2* uv;//Center the uvs
  54. //Now we correct for the aspect ratio. Everything would be stretched depending on the resolution.
  55. uv.x *= iResolution.x / iResolution.y;//Aspect ratio correction
  56.  
  57. //Arbitrary origin really, but this is where your camera is at in the scene. Our sphere is at 0,0,0
  58. float3 origin = float3(0,0,-2);
  59. //Since we have centered uvs, this basically gives us our x,y direction we just need to add a z component (this controls our fov) of 1 and then normalize that to get the actual direction
  60. float3 rayDir = normalize(float3(uv,1));
  61.  
  62. //Run the marching algorithm
  63. float dist = march(origin, rayDir);
  64. //Using the distance we get back we can calculate the hit point in the same way we do inside the ray marching function
  65. float3 hitPos = origin + rayDir * dist;
  66. //This could probably be done better, but since we are just drawing a sphere here, rays > 10 units can be treated as a background color of black
  67. if(dist > 10)
  68. {
  69. fragColor = 0;
  70. return;
  71. }
  72. float3 normal = getNormal(hitPos);
  73. float fresnel = pow(1-clamp(dot(-rayDir, normal),0,1),2);
  74. fragColor = float4(fresnel*float3(0,0,1),1);
  75. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement