One optimization is to break a scene into chunks. First you see which chunk a ray intersects and then test a Ray vs each object in that chunk.
This lets you avoid testing most objects for intersections but adds book keeping overhead so it only works really well for specific kinds of scenes. Aka not the classic single ball and a few walls.
Their are also multiple ways to handle chunks. For a space RTS game you might box up all the ships in a squad and first test the box around the squad before testing each ship. For Minecraft you can just split the world into arbitrary boxes that don’t change frequently.
This optimization can be made systematic. From a polygon-based geometry, an algorithm automatically computes a set of "boxes" (actually, hyperpolyhedra in the general case, polygons in 2D). This allows to very quickly find what intersects any ray without checking all objects.
See https://en.wikipedia.org/wiki/Binary_space_partitioning
It's what enabled Doom to render complex geometry in real time on a i386 processor.
Except that the state of the art has evolved to bounding volume hierarchies, which are both easier to handle and more performant. I won't recommend implementing BSP or kd-trees because they have many more corner cases and numerical issues.
Absolutely, testing against bounding boxes is a quick way to exclude candidates and frustrum culling with an octree (or similar) also greatly speeds up intersection tests
An advantage of ray-marching is that the acceleration structure is built into the shader math, so it requires no additional memory or loading.
This allows the fractal to evolve in realtime, which could not be done with ray-tracing without regenerating the bounding boxes or octree every single frame.
This lets you avoid testing most objects for intersections but adds book keeping overhead so it only works really well for specific kinds of scenes. Aka not the classic single ball and a few walls.
Their are also multiple ways to handle chunks. For a space RTS game you might box up all the ships in a squad and first test the box around the squad before testing each ship. For Minecraft you can just split the world into arbitrary boxes that don’t change frequently.