Compare commits
3
Commits
60003e4beb
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1e2ef2261 | ||
|
|
dad5943ff5 | ||
|
|
bc28d9fdf2 |
No files matched your search
@@ -1,117 +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
|
|
||||||

|
|
||||||
https://git.ferano.io/JosephFerano/fp-rendering-engine/media/branch/master/screenshots/play1.webm
|
|
||||||

|
|
||||||
|
|
||||||
## 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.
|
|
||||||
|
|
||||||
+20
-10
@@ -15,14 +15,22 @@ scene implementing several lower level graphics techniques including matrix
|
|||||||
transformations to model parent/child local transforms, texture mapping, and
|
transformations to model parent/child local transforms, texture mapping, and
|
||||||
basic lighting with shaders.
|
basic lighting with shaders.
|
||||||
|
|
||||||
This is a prototype quality level project worked on for a few weeks in 2019.
|
I worked on this project for a few weeks in 2019, however, it was just thrown
|
||||||
However, it was just thrown into a git repo without much consideration, along
|
into a git repo without much consideration, along with [[https://git.ferano.io/JosephFerano/pqtorusknot][this]] project. I felt this
|
||||||
with other another small graphics project. I felt it deserved a little bit more
|
deserved a little bit more TLC, so I decided to spruce it up a little bit and
|
||||||
TLC, so I decided to spruce it up a little bit. Here's the original [[https://github.com/JosephFerano/elm-graphics][project]].
|
move it to its own repository. Here's the original [[https://github.com/JosephFerano/elm-graphics][project]].
|
||||||
|
|
||||||
** Showcase
|
** Showcase
|
||||||
#+caption: [[file:screenshots/play1.webm]]
|
|
||||||
#+caption: [[file:screenshots/elm-fps.png]]
|
*** 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
|
** 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]]
|
To install the binaries manually, follow this short guide; - [[https://sirfitz.medium.com/install-elm-0-18-0-in-2021-3f64ce298801][Install Binaries]]
|
||||||
@@ -30,7 +38,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 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
|
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][nvm]] for that. I have not attempted this method
|
||||||
personally, fyi.
|
personally, fyi.
|
||||||
|
|
||||||
Once you have the Elm compiler, go ahead and run
|
Once you have the Elm compiler, go ahead and run
|
||||||
@@ -50,9 +58,11 @@ actually wants to build this.
|
|||||||
In order to be able to load the textures and models, the files must be served by
|
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.
|
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.
|
||||||
|
|
||||||
If you have Python 3 installed, simply run =python3 -m http.server=. If you would
|
You can use ~elm-reactor~, run the command and open up your browser to
|
||||||
like to use =elm-reactor=, run the command and then click on =index.html= in the
|
~https://localhost:8000~ and then click on ~Scene.elm~ in the nice project webview
|
||||||
nice project webview provided.
|
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
|
** How to Play
|
||||||
You can walk around the scene and also control the robot which I have named
|
You can walk around the scene and also control the robot which I have named
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ update msg model =
|
|||||||
(model.keys.a , model.keys.s , model.keys.w , model.keys.d)
|
(model.keys.a , model.keys.s , model.keys.w , model.keys.d)
|
||||||
model.lookDir
|
model.lookDir
|
||||||
model.pos
|
model.pos
|
||||||
0.08
|
0.11
|
||||||
, robot = updateRobot model dt
|
, robot = updateRobot model dt
|
||||||
, rot = model.rot + 0.001 * dt}
|
, rot = model.rot + 0.001 * dt}
|
||||||
WindowResized size -> { model | winSize = size }
|
WindowResized size -> { model | winSize = size }
|
||||||
@@ -126,15 +126,16 @@ update msg model =
|
|||||||
|
|
||||||
updateRobot: Model -> Time -> Robot
|
updateRobot: Model -> Time -> Robot
|
||||||
updateRobot { robot , keys } dt =
|
updateRobot { robot , keys } dt =
|
||||||
let rr part = part + dt * 0.005
|
let rotSpeed = 0.003
|
||||||
rl part = part - dt * 0.005
|
rr part = part + dt * rotSpeed
|
||||||
|
rl part = part - dt * rotSpeed
|
||||||
rot = radians robot.rot
|
rot = radians robot.rot
|
||||||
in { pos =
|
in { pos =
|
||||||
movePos
|
movePos
|
||||||
(keys.left, keys.down, keys.up, keys.right)
|
(keys.left, keys.down, keys.up, keys.right)
|
||||||
(vec3 (sin rot) (sin rot) (cos rot))
|
(vec3 (sin rot) (sin rot) (cos rot))
|
||||||
robot.pos
|
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
|
, rot = if keys.n then rr robot.rot else if keys.m then rl robot.rot else robot.rot
|
||||||
, armRot =
|
, armRot =
|
||||||
let angle = if keys.j then rr robot.armRot else if keys.h then rl robot.armRot else robot.armRot
|
let angle = if keys.j then rr robot.armRot else if keys.h then rl robot.armRot else robot.armRot
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 488 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.1 MiB |
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 554 KiB |
Reference in new issue
Block a user