Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Map defines what primitive shapes our scene is made of
- float map(float3 p)
- {
- //This is just a sphere. It's returning the distance from any point p to the edge of the sphere
- //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
- //Mostly just refer to this for signed distance functions
- //http://iquilezles.org/www/articles/distfunctions/distfunctions.htm
- return length(p) - 1;//Our sphere is 1 unit big here
- }
- #define STEPS 64
- float march(float3 origin, float3 rayDir)
- {
- //t is the distance this ray has traveled so far.
- float t = 0;
- for(int i = 0; i < STEPS; i++)
- {
- //p is the current point the ray is at.
- //Think of it like this: Start at the starting point(origin) and travel t unity in the direction the ray is pointing.
- //That's our new point
- float3 p = origin + rayDir * t;
- //Feed the point into our map function, which returns the distance to the closest edge.
- //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.
- float dist = map(p);
- //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
- if(dist < 0.01)
- {
- break;
- }
- //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.
- t += dist;
- }
- return t;
- }
- float3 getNormal(in float3 p) {
- //This get the normal by partial differention I think.
- //I kinda understand this, but I usually just use big brain boys functions from shadertoy.
- //It's basically taking the slope from a point slightly to the left/right of our final hit point. Slope = normal.
- const float eps = 0.001;
- return normalize(float3(
- map(float3(p.x+eps,p.y,p.z))-map(float3(p.x-eps,p.y,p.z)),
- map(float3(p.x,p.y+eps,p.z))-map(float3(p.x,p.y-eps,p.z)),
- map(float3(p.x,p.y,p.z+eps))-map(float3(p.x,p.y,p.z-eps))
- ));
- }
- void mainImage(out float4 fragColor, in float2 fragCoord)
- {
- //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]
- float2 uv = fragCoord/iResolution.xy;
- //Centered them so they go from [-1,1]
- uv = -1 + 2* uv;//Center the uvs
- //Now we correct for the aspect ratio. Everything would be stretched depending on the resolution.
- uv.x *= iResolution.x / iResolution.y;//Aspect ratio correction
- //Arbitrary origin really, but this is where your camera is at in the scene. Our sphere is at 0,0,0
- float3 origin = float3(0,0,-2);
- //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
- float3 rayDir = normalize(float3(uv,1));
- //Run the marching algorithm
- float dist = march(origin, rayDir);
- //Using the distance we get back we can calculate the hit point in the same way we do inside the ray marching function
- float3 hitPos = origin + rayDir * dist;
- //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
- if(dist > 10)
- {
- fragColor = 0;
- return;
- }
- float3 normal = getNormal(hitPos);
- float fresnel = pow(1-clamp(dot(-rayDir, normal),0,1),2);
- fragColor = float4(fresnel*float3(0,0,1),1);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement