diff --git a/README.md b/README.md deleted file mode 100644 index b5bbae4..0000000 --- a/README.md +++ /dev/null @@ -1,120 +0,0 @@ - - -# FP Rendering Engine - - -## TL;DR - -Graphics + Web + Functional Programming - -[Play it here](https://ferano.io/3d-fp/) - - -## 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. - -This is a prototype quality level project worked on for a few weeks in 2019. -However, it was just thrown into a git repo without much consideration, along -with other another small graphics project. I felt it deserved a little bit more -TLC, so I decided to spruce it up a little bit. Here's the original -[project](https://github.com/JosephFerano/elm-graphics). - - -## Showcase - -![High Quality Walkthrough](https://ferano.io/3d-fp/play1.mp4) - -![Walkthrough](screenshots/play1.gif) - -![Screenshot](screenshots/elm-fps.png) - -## Building with Elm 0.18.0 - -To install the binaries manually, follow this short guide; - [Install Binaries](https://sirfitz.medium.com/install-elm-0-18-0-in-2021-3f64ce298801) - -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 [`npm`](https://github.com/nvm-sh/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 [SOP](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) and [CORS](https://developer.mozilla.org/en-US/docs/Glossary/CORS) if curious. - -If you have Python 3 installed, simply run `python3 -m http.server`. If you would -like to use `elm-reactor`, run the command and then click on `index.html` in the -nice project webview provided. - - -## 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. - diff --git a/README.org b/README.org index dd35d28..903570c 100644 --- a/README.org +++ b/README.org @@ -21,7 +21,7 @@ with other another small graphics project. I felt it deserved a little bit more TLC, so I decided to spruce it up a little bit. Here's the original [[https://github.com/JosephFerano/elm-graphics][project]]. ** Showcase -#+caption: [[file:screenshots/play1.webm]] +#+caption: [[file:screenshots/sextus.gif]] #+caption: [[file:screenshots/elm-fps.png]] ** Building with Elm 0.18.0 @@ -30,7 +30,7 @@ To install the binaries manually, follow this short guide; - [[https://sirfitz.m 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][=npm=]] for that. I have not attempted this method +it is recommended to use [[https://github.com/nvm-sh/nvm][npm]] for that. I have not attempted this method personally, fyi. Once you have the Elm compiler, go ahead and run diff --git a/Scene.elm b/Scene.elm index 2d12c91..c1d1406 100644 --- a/Scene.elm +++ b/Scene.elm @@ -107,7 +107,7 @@ update msg model = (model.keys.a , model.keys.s , model.keys.w , model.keys.d) model.lookDir model.pos - 0.08 + 0.11 , robot = updateRobot model dt , rot = model.rot + 0.001 * dt} WindowResized size -> { model | winSize = size } @@ -126,15 +126,17 @@ update msg model = updateRobot: Model -> Time -> Robot updateRobot { robot , keys } dt = - let rr part = part + dt * 0.005 - rl part = part - dt * 0.005 + + let rotSpeed = 0.003 + rr part = part + dt * rotSpeed + rl part = part - dt * rotSpeed rot = radians robot.rot in { pos = movePos (keys.left, keys.down, keys.up, keys.right) (vec3 (sin rot) (sin rot) (cos rot)) robot.pos - 0.03 + 0.05 , rot = if keys.n then rr robot.rot else if keys.m then rl robot.rot else robot.rot , armRot = let angle = if keys.j then rr robot.armRot else if keys.h then rl robot.armRot else robot.armRot @@ -168,8 +170,8 @@ getRobot model = |> Mat4.inverse |> Maybe.withDefault Mat4.identity |> Mat4.mul (Mat4.makeTranslate3 0 0 0.6) |> Mat4.mul arm - in [ getEntity3 model (body |> Mat4.scale3 0.5 0.5 0.5) cube Color.blue - , getEntity3 model (arm |> Mat4.scale3 0.2 0.2 0.5) cube Color.green + in [ getEntity3 model (body |> Mat4.scale3 0.5 0.5 0.5) cube Color.blue + , getEntity3 model (arm |> Mat4.scale3 0.2 0.2 0.5) cube Color.green , getEntity3 model (hand |> Mat4.scale3 0.15 0.15 0.45) cube Color.red ] |> List.concat diff --git a/screenshots/sextus.gif b/screenshots/sextus.gif new file mode 100644 index 0000000..c8731a3 Binary files /dev/null and b/screenshots/sextus.gif differ