• API
• FAQ
• Tools
• Archive
SHARE
TWEET # RaymarchedHyperboloid.glsl a guest Sep 21st, 2019 118 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. // raymarched hyperboloid
2. //boilerplate
3. //#ifdef GL_ES
4. precision highp float;
5. //#endif
6.
7. uniform float time;
8. uniform vec2 mouse;
9. uniform vec4 color;
10. uniform vec2 resolution;
11.
12. float scale = 3.3333;// .5*exp(1./max(.00125,color.r));
13. vec3 iResolution = vec3(resolution.xy * scale * .5, 1.);
14. float iTime = time;
15. vec4 iDate = vec4(color.r, iTime*.125, iTime*.5, iTime);
16. vec4 iMouse=vec4(mouse*iResolution.xy,1.,1.);
17.
19.
20. //Blakes graphing calculator - test ver
21. float sdfOfBound(vec3, vec3, vec3);
22. float sgn(float);
23. float LineHeight(float, vec2, float);
24. vec2 intersectionOfTwoLines(vec2, float, vec2, float);
25.
26. // So the idea of this shader is to raymarch some function given some information about it.
27. // The relevant information consists of 3 functions, along with some bounds.
28. // The three functions below define the function we are going to raymarch. df is the first
29. // derivative of f, and ddf is the second derivative of f. Along with that, some bounds need to
30. // be defined as well, but we'll get to that.
31.
32.
33. //////// HACKS!!!!!
34. float yscale=.7; // underestimate f(x) by this factor and scale point to counteract.
35. float ddffactor=40.; // overestimate ddf/dx by this factor (why?!)
36.
37. float f(float x)
38. {
39.     // return the function when fed an x value
40.     // given the roots of the cubic, calculate the function of x
41.     return yscale*sqrt(1.+x*x);
42. }
43.
44. float ff(float x)
45. {
46.     // return the function when fed an x value
47.     // given the roots of the cubic, calculate the function of x
48.     return sqrt(1.+x*x);
49. }
50. float df(float x)
51. {
52.     // return the derivative of the function when fed an x value
53.     // given the roots of the cubic, calculate the derivative of x
54.     return (2.)*x/ff(x);
55. }
56. float ddf(float x)
57. {
58.     return (ff(x)*2.-2.*x*(ddffactor)*x/ff(x))/(1.+x*x);
59. }
60. vec3 GetBoundary(int i, vec3 pt)
61. {
62.
63.     float ex0 = -1000.0;
64.     float ex1 = -1000.;//-120000.;//-2.5/2./fscale;//3.1415926;
65.     float ex2 = 1000.;//2.5/2./fscale;//3.1415926;
66.     float ex3 = 1000.0;
67.
68.     float i0 = -1000.0;
69.     float i1 = pt.z>0.?1./30.:-1./30.;
70.     float i2 = 1000.0;
71.
72.     if (i == 0)
73.     {
74.         return vec3(ex0, i0, ex1);
75.     }
76.     if (i == 1)
77.     {
78.         return vec3(ex1, i1, ex2);
79.     }
80.     if (i == 2)
81.     {
82.         return vec3(ex2, i2, ex3);
83.     }
84.     return vec3(0.0,0.0,0.0);
85. }
86.
87. float sdfFunction(vec3 Point, vec3 Center)
88. {
89.     // The number of extrema (not counting infinities
90.     const int EXTREMA_COUNT = 2;
91.         vec3 pnt = Point - Center;
92.     //pnt.xz = mod(pnt.xz + vec2(2.0), vec2(4.0))-vec2(2.0);
93.     float h = length(pnt.xz);
94.     h = h * sgn(pnt.x)*sgn(pnt.z);
95.         Point = vec3(0.,yscale*pnt.y, h) + Center;
96. vec3 invPoint = vec3(0.,-yscale*pnt.y, h) + Center;
97.     float d = 100000.0;
98.     for (int i = 0; i < EXTREMA_COUNT + 1; i++)
99.     {
100.         d = min(d, min(sdfOfBound(Point, Center, GetBoundary(i,Point)), sdfOfBound(invPoint, Center, GetBoundary(i,invPoint))));
101.     }
102.     return d;
103. }
104.
105. ///////////////////////
106.
107. // End of user input //
108.
109. ///////////////////////
110.
111. float sdfOfBound(vec3 Point, vec3 Center, vec3 Keys)
112. {
113.     vec3 pnt = Point - Center;
114.     //pnt.xz = mod(pnt.xz + vec2(1.0), vec2(2.0))-vec2(1.0);
115.     float h = pnt.z;//length(pnt.x);//pnt.x + pnt.z; //max(abs(pnt.x),abs(pnt.z));
116.     //h = h * sgn(pnt.x)*sgn(pnt.z);
117.     float k = pnt.y;
118.
119.     float a = Keys.x;
120.     float b = Keys.z;
121.     float I = Keys.y;
122.
123.     vec2 P_temp = vec2(h, k);
124.     h = clamp(h, a, b);
125.     vec2 P = vec2(h,k);
126.
127.     bool tangent_method = sgn(f(h) - k) == sgn(ddf(h));
128.
129.     float tan_at_I = df(I);
130.     float nor_at_I = -1.0 / tan_at_I;
131.     vec2 pnt_at_I = vec2(I, f(I));
132.     float line_height = LineHeight(nor_at_I, pnt_at_I, h);
133.     bool chord_method = (k*ddf(h) < line_height*ddf(h)) && !tangent_method;
134.     bool clamped_tangent = !chord_method && !tangent_method;
135.
136.     float ct_slope = tan_at_I;
137.     vec2 ct_pnt = pnt_at_I;
138.
139.     float t_slope = df(h);
140.     vec2 t_pnt = vec2(h, f(h));
141.
142.     float ch_samp_d = abs(f(h) - k) * sgn(df(h)) * sgn(ddf(h));
143.     if (P_temp.x < a || P_temp.x > b)
144.     {
145.          ch_samp_d = abs(f(h) - k) * -sgn(P_temp.x-h);
146.     }
147.     float ch_raw_Q = h + ch_samp_d;
148.     float ch_clamped_Q = clamp(ch_raw_Q, min(I, ch_raw_Q), max(I, ch_raw_Q));
149.     vec2 ch_P = vec2(h, f(h));
150.     vec2 ch_Q = vec2(ch_clamped_Q, f(ch_clamped_Q));
151.     float ch_slope = (ch_P.y - ch_Q.y) / (ch_P.x - ch_Q.x);
152.     vec2 ch_pnt = ch_P;
153.     vec2 ct_closest = intersectionOfTwoLines(ct_pnt, ct_slope, P, -1.0 / ct_slope);
154.     vec2 t_closest = intersectionOfTwoLines(t_pnt, t_slope, P, -1.0 / t_slope);
155.     vec2 ch_closest = intersectionOfTwoLines(ch_pnt, ch_slope, P, -1.0 / ch_slope);
156.
157.     float ct_dist = distance(ct_closest, P);
158.     float t_dist = distance(t_closest, P);
159.     float ch_dist = distance(ch_closest, P);
160.
161.     float d = -1.0;
162.     if (clamped_tangent){ d = ct_dist;}
163.     if (tangent_method) { d = t_dist; }
164.     if (chord_method)   { d = ch_dist;}
165.
166.    float dx = d;
167.     d = max(d , -(P_temp.x - a));
168.     d = max(d , (P_temp.x - b));
169.     //if (f(h) > k)         { d *= -1.0;  }
170.     return dx > 0. ? d: dx;//max(dx,-1111111.);
171. }
172.
173.
174. // Convert degrees to radians
176. {
177.     return deg / 360.0 * 2.0 * 3.14159;
178. }
179.
180. // Write a float4 function for some of the HLSL Code conversion
181. vec4 float4(float x, float y, float z, float w)
182. {
183.     return vec4(x,y,z,w);
184. }
185.
186. // Write a float3 function for the same purpose
187. vec3 float3(float x, float y, float z)
188. {
189.     return vec3(x,y,z);
190. }
191.
192. // and a float2 function as well
193. vec2 float2(float x, float y)
194. {
195.     return vec2(x, y);
196. }
197.
198. // A method for intersecting two lines in R-two.
199. vec2 intersectionOfTwoLines(vec2 A, float sa, vec2 B, float sb)
200. {
201.     float buffer = (sa*A.x - A.y - sb * B.x + B.y) / (sa - sb);
202.     vec2 intersection = float2(buffer, sa*(buffer - A.x) + A.y);
203.     return intersection;
204. }
205.
206. // Exact SDF for a sphere
207. float dSphere(vec3 pos, vec3 center, float radius)
208. {
209.     // find the distance to the center
210.     vec3 v = pos - center;
211.
212.     // return that, minus the radius
214. }
215.
216. // Exact intersection of a sphere. Resolves a quatratic equation. Returns the
217. // min distance, max distance, and discriminant to determine if the intersections
218. // actually exist.
219. vec3 intersections_of_sphere(vec3 pos_vector, vec3 dir_vector, float sphere_radius)
220. {
221.     // Derivation for formula:
222.     //      Let the ray be represented as a point P plus a scalar multiple t of the direction vector v,
223.     //      The ray can then be expressed as P + vt
224.     //
225.     //      The point of intersection I = (x, y, z) must be expressed as this, but must also be some distance r
226.     //      from the center of the sphere, thus x*x + y*y + z*z = r*r, or in vector notation, I*I = r*r
227.     //
228.     //      It therefore follows that (P + vt)*(P + vt) = r*r, or when expanded and rearranged,
229.     //      (v*v)t^2 + (2P*v)t + (P*P - r*r) = 0. For this we will use the quadratic equation for the points of
230.     //      intersection
231.
232.     // a, b, and c correspond to the second, first, and zeroth order terms of t, the parameter we are trying to solve for.
233.     float a = dot(dir_vector, dir_vector);
234.     float b = 2.0 * dot(pos_vector, dir_vector);
236.
237.     // to avoid imaginary number, we will find the absolute value of the discriminant.
238.     float discriminant = b * b - 4.0 * a*c;
239.     float abs_discriminant = abs(discriminant);
240.     float min_dist = (-b - sqrt(abs_discriminant)) / (2.0 * a);
241.     float max_dist = (-b + sqrt(abs_discriminant)) / (2.0 * a);
242.
243.     // return the two intersections, along with the discriminant to determine if
244.     // the intersections actually exist.
245.     return float3(min_dist, max_dist, discriminant);
246.
247. }
248.
249. float sgn(float x)
250. {
251.     if (x < 0.0)
252.     {
253.         return -1.0;
254.     }
255.     return 1.0;
256. }
257.
258. float LineHeight(float slope, vec2 point, float x)
259. {
260.     return slope*(x - point.x) + point.y;
261. }
262.
263. // Distance estimation for the scene
264. float DE(vec3 p, vec3 c)
265. {
266.     // Raymarch a bounding sphere
267.     float sphere = dSphere(p, c, sphererad);
268.
269.     // Raymarch generic sdf for a function
270.     float function = sdfFunction(p,c);
271.
272.     // cut out the bounding sphere
273.     float d = max(sphere, function);
274.
275.     // return the distance
276.     return d;
277. }
278.
279. void mainImage( out vec4 fragColor, in vec2 fragCoord )
280. {
281.     // Define the iterations for the marcher.
282.     const int ITERATIONS = 60;
283.
284.     // Define the roation speed. Set to 0 to disable
285.     const float ROTATION_SPEED = 0.2;
286.
287.     // Define the start angle for the rotation (in degrees)
288.     const float START_ANGLE = 0.0;
289.
290.     // Define the orbit radius
291.     const float ORBIT_RADIUS = 16.0;
292.
293.     // Define the epsilon value for closeness to be considered a hit
294.     const float EPSILON = 0.001;
295.
296.     const bool HIDE_BACKGROUND = false;
297.
298.
299.
300.     // Define the center of the julia set
301.     vec3 sdf_center = vec3(0.0, 0.0, 0.0);
302.
303.     // Calculate the starting angles for the orbit
304.     float theta = iTime * ROTATION_SPEED;
306.
307.     // Take some mouse input
308.     vec4 mouse = iMouse / iResolution.xyxx;
309.
310.     // If the mouse is being held down
311.     //if (mouse.z > 0.0)
312.     {
313.         // convert the mouse input to angles
314.         theta = mouse.x * 2.0 * 3.14159;
315.         phi = (mouse.y - 0.5) * 1.0 * 3.14159;
316.     }
317.
318.     // Define an orbital path based on time
319.     vec3 orbit = vec3(cos(theta)*cos(phi), sin(phi), sin(theta)*cos(phi));
320.
321.     // Cacluate the normal of the path. Since its a circle, it will just
322.     // be back down into the center
323.     vec3 normal = -normalize(orbit);
324.
325.     // Calculate the tangent of the path
326.     // A circle consists of <cost, sint>, which when differentiated yields
327.     // <-sint, cost>. since z is already sint, and x is already cost, the equation
328.     // is as follows.
329.     vec3 tangent = normalize(vec3(-normal.z, 0.0, normal.x));
330.
331.     // Calculate the UV coordinates
332.     vec2 uv = fragCoord/iResolution.xy;
333.
334.     // Convert the UV coordinates to a range between -1 and 1
335.     vec2 range = uv*2.0 - vec2(1.0,1.0);
336.
337.     //// Define the Camera position
338.     //vec3 cam_pos = vec3(0,0,-2);
339.
340.     //// Define the forward, up, and right vectors (needs rework)
341.     //vec3 forward = normalize(vec3(0,0,1));
342.     //vec3 up = normalize(vec3(0,1,0));
343.     //vec3 right = normalize(vec3(1,0,0));
344.
345.     // Define the Camera position
347.
348.     // Define the forward, up, and right vectors (needs rework)
349.     vec3 forward = normal;
350.     vec3 up = normalize(cross(normal, tangent));
351.     vec3 right = tangent;
352.
353.     // Calculate the aspect ratio of the screen
354.     float aspect = float(iResolution.y) / float(iResolution.x);
355.
356.     // Calculate the ray as a normalized combination of the forward, right, and up vectors.
357.     // Note that the purely forward + horizonal combination yield vectors 45 degrees outward
358.     // for a 90 degree field of view. This may be updated with a fov option
359.     vec3 ray = normalize(forward + range.x*right + range.y*up*aspect);
360.
361.     // Initialize the ray marched point p
362.     vec3 p = cam_pos;
363.
364.
365.     // Initialize the distance
366.     float dist = 1.0;
367.
368.     // Calculate the exact distance from a sphere of radius 2 using a raytracing function
369.     vec3 init_distance = intersections_of_sphere(p - sdf_center, ray, sphererad);
370.
371.     // If we are outside a bubble around the raymarched fractal
372.     if (init_distance.z > 0.0)
373.     {
374.         // Step onto the sphere so we start off a bit closer.
375.         p += ray * clamp(init_distance.x, 0.0, init_distance.x);
376.     }
377.
378.     // declare a dummy variable to store the number of iterations into.
379.     // I'm doing it this way because on my phone it didnt let me use an
380.     // already declared variable as the loop iterator.
381.     int j;
382.
383.     float min_dist = 1.0;
384.     // Begin the raymarch
385.     for (int i = 0; i < ITERATIONS; i++)
386.     {
387.         // Estimate the distance to the julia set
388.         dist = DE(p, sdf_center);
389.
390.         min_dist = min(dist, min_dist);
391.
392.         // Move forward that distance
393.         p += ray*dist;
394.
395.         // Record the number of iterations we are on
396.         j = i;
397.
398.         // If we hit the julia set, or get too far away form it
399.         if (dist < EPSILON || dot(p - sdf_center, p-sdf_center) > sphererad * sphererad + 0.1)
400.         {
401.             // Break the loop.
402.             break;
403.         }
404.
405.     }
406.
407.         // determine if we hit the fractal or not
408.     float hit = step(dist, EPSILON);
409.
410.
411.     // calculate the brightness based on iterations used
412.     float di = (1.0 - (float(j) + (dist / EPSILON)*hit) / float(ITERATIONS));
413.     float glow = 1.0 - (min_dist / 1.0);
414.
415.     //di = (di * hit) + (glow*(1.0-hit));
416.     if (HIDE_BACKGROUND)
417.     {
418.         di *= hit;
419.     }
420.
421.
422.
423.
424.     // define some phase angle
426.
427.     // Time varying pixel color (included in default shadertoy project)
428.     //vec3 col = 0.8 + 0.2*cos(iTime*0.5+uv.xyx+vec3(0,2,4) + psi*hit);
429.
430.     // Boring old white instead of the above commented code. Will tweak rendering later
431.     vec3 col = vec3(1.0,1.0,1.0);
432.
433.
434.     // Output to screen. Modifiy the color with the brightness calculated as di.
435.     fragColor = vec4(col*di,1.0);
436. }
437.
438. void main( void ) {
439.     gl_FragColor = vec4(0.,10.,0.,0.);
440.     vec2 zoomedCoord = (color.gb - .5) * .125 * iResolution.y - (mouse.xy-vec2(.5,.5)) * iResolution.xy + gl_FragCoord.xy - resolution*.5;
441. zoomedCoord = gl_FragCoord.xy + resolution*.33;
442.     mainImage( gl_FragColor, zoomedCoord.xy );
443. }
444. // P.S. vrchat is blessed. ~Ly
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy.

Top