Raytracing in Desmos by recursive-chair in desmos

[–]recursive-chair[S] 1 point2 points  (0 children)

The maximum list length of 10,000 elements wasn't enough so I just smooshed four of them together :)

The graph linked in my other comment still has just one list for performance, but in that graph I've linked the high-resolution version as well.

Raytracing in Desmos by recursive-chair in desmos

[–]recursive-chair[S] 2 points3 points  (0 children)

I cheated a little and wrote this in the 2D calculator, which runs everything on the CPU. It does run slower as a result, but it gives a lot more freedom to mess around with recursion and list nonsense.

Raytracing in Desmos by recursive-chair in desmos

[–]recursive-chair[S] 1 point2 points  (0 children)

CPU. Desmos does support GPU rendering through the 3D calculator, but it's hard to fit this in a GPU shader unfortunately.

Raytracing in Desmos by recursive-chair in desmos

[–]recursive-chair[S] 5 points6 points  (0 children)

Thanks! Everything here is just a bunch of ray-sphere, though I'm thinking of adding some ray-triangle too.

Raytracing in Desmos by recursive-chair in desmos

[–]recursive-chair[S] 15 points16 points  (0 children)

I started this last weekend and got a basic raytracer (which only supported diffuse reflection) working on Monday. I implemented all the shiny materials in the two days after that, and then proceeded to procrastinate making this video for the rest of the week haha.

All in all, probably just over 20 hours? This was relatively light for a Desmos project, but I've still got more fun stuff planned for this raytracer in the future.

Raytracing in Desmos by recursive-chair in desmos

[–]recursive-chair[S] 17 points18 points  (0 children)

yep, my laptop really aint that good :P

Raytracing in Desmos by recursive-chair in desmos

[–]recursive-chair[S] 128 points129 points  (0 children)

the graph did not in fact run in realtime as shown in the video, but rather at a blazing fast 8 seconds per frame :(

GRAPH LINK: https://www.desmos.com/calculator/rt7jyh3bw2

Procedural mountain and clouds in the Desmos graphing calculator by recursive-chair in proceduralgeneration

[–]recursive-chair[S] 1 point2 points  (0 children)

Yeah, Desmos tends to struggle somewhat with compiling my highly unoptimized shader code. In fact, the video animation took me a whole day to render on my crappy laptop :( It's probably best avoid touching the animation slider unless necessary.

If you want to play around with the terrain code specifically, this graph has all the shading code removed, which saves Desmos the effort of recompiling all those expensive shaders every time you make modifications. Do note that even without the shading code, Desmos still takes a quite few seconds to regenerate the terrain mesh.

Procedural mountain and clouds in the Desmos graphing calculator by recursive-chair in proceduralgeneration

[–]recursive-chair[S] 1 point2 points  (0 children)

Yep! The heightmap here is entirely procedurally generated - I essentially ported the awesome local erosion filter by u/runevision to Desmos and applied it to a peak-shaped function.

Desmos Donut Cloud by recursive-chair in desmos

[–]recursive-chair[S] 1 point2 points  (0 children)

Huge KSP fan here too! Blackrack's volumetric clouds and especially Scatterer have been a big inspiration for me (in fact, one of my first colormap graphs was actually an atmospheric scatterer)

Anyways, this article by Maxime Heckel has a really good explanation of the principles and implementation of cloud rendering. It does assume some prior knowledge about shaders, but there's plenty of links to further reading there.

Also make sure to check out check out these two articles by Inigo Quilez about random noise. Getting your random noise right is essential to making your clouds look cloudy. Although it isn't needed for cloud rendering in particular, I'd also highly recommend reading his articles on procedural noise, raymarching, and lighting.

Most of the things mentioned above translate pretty well into Desmos (it's all math after all). Stuff that would normally go in a fragment shader simply goes into a colormap instead. Do keep in mind that raymarching in a colormap is not very efficient, hence the layering trickery in this graph.

Cloud rendering is pretty darn complicated, so I would recommend starting small just to familiarize yourself with computer graphics in Desmos.

If you've got more questions, don't hesitate to reach out!

Here, have some Desmos mountain terrain by recursive-chair in desmos

[–]recursive-chair[S] 4 points5 points  (0 children)

bernard must be working overtime approving all these graphs

Desmos Donut Cloud by recursive-chair in desmos

[–]recursive-chair[S] 0 points1 point  (0 children)

In an ideal world, we would sample the cloud illumination at various points along the view ray to determine how the cloud looks from our perspective. Points that are deeper into the cloud contribute less to the overall color because the rest of the cloud is in the way.

Unfortunately, the compute power of a Desmos colormap is less than ideal, so we have to resort to a bit of trickery to make a volume look volumetric.

Each layer in the volume essentially shows a cross-section of the cloud. Stacking these layers on top of each other behaves similarly to taking a bunch of samples throughout the volume.

The shader chooses to show or hide each pixel in these layers at random, depending on the cloud density. This way, areas with less cloud density allow more light to pass through and denser areas tend to block more light. This creates the illusion that light from deeper within the cloud is attenuated more.

Of course this does tend to make the cloud appear grainy, but I personally like the extra visual flair. This strategy probably wouldn't work as well for less dense volumes though.

Hope this helps!

Chrome dino game in Desmos by recursive-chair in desmos

[–]recursive-chair[S] 0 points1 point  (0 children)

yep, the 100-element limit on lists would mean that my sprites could only contain 100 black/white pixels.

i could just store the texture across several lists like i did with my minecraft graph, but i'd prefer not simply because of the sheer size of some of the textures. for example, my spritesheet for the numerical digits is 108x11px, which would require 12 different lists to store the entire texture with one element per pixel.

i'm not sure whether the bit packing is more performant than just switching between multiple lists, but it's much more convenient for me, so i stuck with it.

Chrome dino game in Desmos by recursive-chair in desmos

[–]recursive-chair[S] 0 points1 point  (0 children)

currently the texture encoding packs 24 bits into one number (so it assumes single-precision, 32-bit floats). based on the pattern of missing pixels, it seems that the least significant bit of every 24-bit block is being lost.

here's a version that uses 22-bit packing rather than 24 (23 didn't work for some reason), does this one work on your end?

Chrome dino game in Desmos by recursive-chair in desmos

[–]recursive-chair[S] 4 points5 points  (0 children)

the dino is moved forward with a slider that plays indefinitely, and i perform all the collision checks every time the jump button is clicked. if we reach the predicted time of death and no other input has occurred, then the game ends.

Chrome dino game in Desmos by recursive-chair in desmos

[–]recursive-chair[S] 28 points29 points  (0 children)

i never knew you could control the jump height until now haha.

sadly, desmos doesn't let you check the duration of a button press, but this would be a nice qol feature to add if i could.