HaScene is a simple ASCII 3D scene editor with ray tracing renderer written in Haskell.
It consists of two parts: an ASCII 3D scene editor and a ray tracer. Below are their descriptions.
A scene editor is often an essential tool for 3D photorealistic rendering. It can build a 3D scene, provide a preview of the scene, and finally deliver scene information to a specific renderer to get a photorealistic image. To build a 3D scene, we expect our editor can place, move, rotate, and delete simple 3D models (spheres, cubes, tetrahedrons, etc.), as well as specify the materials of a particular model, the lighting of the scene, and the position of the camera. To preview the scene, we expect our editor can render a simple 3D scene only containing depth information of the model to the terminal using ASCII characters, just like the image below:
(Animation generated by a famous piece of C Code from https://www.a1k0n.net/2006/09/15/obfuscated-c-donut.html)
Scene editing & previewing will be implemented using the brick library
A ray tracer is a kind of renderer that render 3D scene using the ray tracing algorithm (which is a recursive algorithm, and we believe it has an affinity with Haskell). It is the cornerstone of modern photorealistic rendering. Considering the amount of work required to implement the scene editor, we plan to use the open-source ray tracer on GitHub and write the interface to the editor. If we have extra time, we will implement the ray tracer ourselves.
PS: Two members of our team are familiar with computer graphics, so we think it is not difficult for the team to grasp the principles behind the algorithm. However, since Haskell as a functional programming language is very different from object-oriented programming languages such as C++, we cannot guarantee that the final result of the project will be exactly as described in the proposal.
-- | Coordinates
type Coord = V3 Double
-- | Triangle in location context
type Triangle = V3 Coord
newtype Object = Object
{ _triangles :: [Triangle]
}
deriving (Eq, Show)
makeLenses ''Object
data Camera = Camera
{ _pos :: Coord
, _angle :: Coord
}
deriving (Eq, Show)
makeLenses ''Camera
-- | Game state
data Game = Game
{ _objects :: [Object]
, _camera :: Camera
, _initFile :: String
}
deriving (Eq, Show)
makeLenses ''Game
Input: the config file
0 0 -5 // the init camera position
0 1 -1 // the init light position
3 // the number of Objects
Sphere 1 2 3 1 // type, args
Block 1 2 3 4 4 90 90 90
FileObj filename.obj 1 1 2 3 90 90 90
Output: [Shape]
Input: [Shape]
Output: Console Output
Pending: the ray tracer.
new feature: the camera can be moved by the keyboard.