#+OPTIONS: toc:nil * FP Rendering Engine ** TL;DR Graphics + Web + Functional Programming [[https://ferano.io/3d-fp/][Play it here]] ** About The goal of this project is to learn about the intersection of 3 different topics; graphics, web, and functional programming. The FP acronym refers to both the fact that it's a *F*irst *P*erson camera, as well as being implemented using *F*unctional *P*rogramming. It uses Elm with WebGL to create a 3D first-person scene implementing several lower level graphics techniques including matrix transformations to model parent/child local transforms, texture mapping, and basic lighting with shaders. I worked on this project for a few weeks in 2019, however, it was just thrown into a git repo without much consideration, along with [[https://git.ferano.io/JosephFerano/pqtorusknot][this]] project. I felt this deserved a little bit more TLC, so I decided to spruce it up a little bit and move it to its own repository. Here's the original [[https://github.com/JosephFerano/elm-graphics][project]]. ** Showcase *** First Person Camera [[file:screenshots/play1.gif]] [[https://ferano.io/3d-fp/play1.mp4][Higher Resolution Version]] *** Sextus [[file:screenshots/sextus.gif]] [[https://ferano.io/3d-fp/sextus.mp4][Higher Resolution Version]] ** Building with Elm 0.18.0 To install the binaries manually, follow this short guide; - [[https://sirfitz.medium.com/install-elm-0-18-0-in-2021-3f64ce298801][Install Binaries]] If you want to use =npm= instead; - =npm install -g elm@elm0.18.0= If you use =npm=, note that you will likely need an older version of Node.js, so it is recommended to use [[https://github.com/nvm-sh/nvm][nvm]] for that. I have not attempted this method personally, fyi. Once you have the Elm compiler, go ahead and run =elm make Scene.elm= And that should first pull in all the dependencies then generate an =index.html= file. *** Issues with dependencies One of the dependencies of this project, =Zinggi/elm-obj-loader=, is getting a 404 when Elm tries to pull in all the deps during compilation. Therefore this dependency will be included in version control, on the off chance someone actually wants to build this. ** Running In order to be able to load the textures and models, the files must be served by an HTTP server because of browser security, see [[https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy][SOP]] and [[https://developer.mozilla.org/en-US/docs/Glossary/CORS][CORS]] if curious. You can use ~elm-reactor~, run the command and open up your browser to ~https://localhost:8000~ and then click on ~Scene.elm~ in the nice project webview provided. If you don't want to do that and have Python 3 installed, run =python3 -m http.server=, but make sure to compile with the ~elm make Scene.elm~ command first. ** How to Play You can walk around the scene and also control the robot which I have named Emperor Sextus, Conqueror of the Luddites. *** Keybindings - Look Around: =Mouse= - FPS Movement: =WASD= - Robot Movement: =◀ ▼ ▲ ▶= - Rotate Robot: =N | M= - Rotate Robot Arm: =H | J= - Rotate Robot Hand: =Y | U= ** Takeaways The Elm WebGL library provides a few abstractions (namely =WebGL.Entity=) that help reduce some of the boilerplate usually associated with creating a WebGL application from scratch. While it was useful for the purposes of this prototype, it remains to be seen if it would scale if this would become a proper 3D rendering engine. Despite what might be potentially undiscovered performance issues, Elm was pleasant to work with, and it sold me two ideas; functional programming and minimalism. The touted safety and correctness were noticeable, the learning curve wasn't as steep, and using the Elm debugger to be able to step back in time through the game was eye-opening in showing what's possible when you architect your state management with immutability in mind. It would be interesting to see if a modern game engine could switch between the functional, immutable data structures in a debug context and the cache-friendly mutable data structures for improved performance in a release build. Thus boosting productivity during development, while still remaining performant in the hands of players. ** License This project is licensed under the terms of the MIT license. For more information, see the included LICENSE file.