Renderer and basis for physics and lighting.
class Space, for any Material:
constructor(location : Location, generate : Location -> Space) : Space
this[Point]: Material
this[Point] = Material
class Location(origin : Point, edge : int)
# edge is a _logarithm_ of size, since shl is a fast op
class Point(x, y, z : int)
class Camera(position : Point, rotation : Rotation)
class RayEmitter(camera : Camera):
getRay(Point2D): Sequence<Point>
class Buffer, for any Material:
this[x, y : int]: Material
this[x, y : int] = Material
class Render<Material>:
render(buffer : Buffer<Material>) : voidSo, thats how the rendering works: 0) we have
- ray emitter (base impl will shoot rays in parallel, creating isometry or 1:7:8)
- some space (for now it will be a thin wrapper around Octree)
- camera position (will ignore rotation for now, only take position into account
- lightning space? (do we, or we store lightning in "Material" itself? how to update it?)
- For each point in buffer, we ask ray emitter to generate a ray a) For each point in the ray, we retrieve this point's material and add to accumulator. If the accumulator saturates (alpha >= 0.99? alpha >= 0.8?), we stop. b) Later, I will introduce a level-of-detail optimisation to not go into atoms that aren't woth a pixel or just too far. c) We put accumulator into the buffer.
- We render the buffer.
For start, I'll probably will use 3D array of material as Space. Read things below only if you want some programming math to be thrown into your face.
For production, I've chose to implement space as an Octree.
Pros:
- Memory efficiency. We, basically will only generate and store only atoms we can see - the surface, and if there is a tight pack of similar atoms somewhere, they will be structurally optimised.
Cons:
- May be not effective in terms of speed. It is the tree, so we will have n cache jumps trying to render a cube of size 2^n. I have an idea how to optimise this, reusing C++ std::vector; however, it should be tested. (Also this optimisation will help to obtain fast save/load).
- As we don't generate what we cannot see, the physics for these objects will not work until we see them. We can, however, implement an algorithm that forces generation in some sphere (or cube) around the point (in parallel) to start actually simulating things before we see them, but thats the story for another time.
Octree problems:
- There are 2 kinds of Octree impls - mutable one and immutable one:
- mutable
- Pros:
- Simple => Fast in terms of access.
- Cons:
- Probably can't save/render in the same time you mutating the tree.
- if implemented with help of std::vector, you surely can't do anything while mutating the tree.
- Pros:
- immutable:
- Pros:
- You have a tree, and then you save, render and mutate in parallel. No synchronisation/locks are needed. Each mutation generates new tree, which mostly refers to the old tree.
- You can actually update the tree in multiple places for one descent into it.
- You can update 2 branches of the tree in parallel, provided you don't go sideways between branches.
- Cons:
- Forget about
Freemancache. - The iterator is slow and complex and will copy things ALOT will only small changes done to them (can be optimised).
- Forget about
- Pros:
- conclusion:
- As the impls do not differ in the interface of Space, I'll probably implement both to test the speed.
- Notice that on both impl parallel raytracing is a thing.
- mutable
Space problems:
-
We have the world in one piece. Its hard to do anything with it. So I thing actually putting "subspaces" into Space. This will work like that:
- We enter a Space and are trying to descent to a point1.
- We travel to the point until we reach a special
Subspacenode, which contains refs to 2 subtrees - one represeting an object and another representing the rest of the world. - We go into first one and try to reach the point1. If the material received is not Air, we return it; otherwise, we go into the second subtree.
Also, we will have index of mounted subspaces in the Space, but since this will only add to the interface of space, this all is a lesser concern.