Skip to content

Commit 72dc346

Browse files
committed
Update readme, add Lua.md and update Scene.md
1 parent bb7aa6e commit 72dc346

4 files changed

Lines changed: 217 additions & 20 deletions

File tree

README.md

Lines changed: 74 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
![](docs/Images/Demo/default.png)
1+
# Simple ray tracer for pixel-themed scenes and animations
22

3-
> More demo images can be found [here](docs/Images/Demo/)
3+
| ![](docs/Images/Demo/default.png) |
4+
|:--:|
5+
|Static base scene|
6+
7+
8+
| ![](docs/Images/defaultGif.gif) |
9+
|:--:|
10+
| Animation from base scene|
11+
12+
> More static demo images can be found [here](docs/Images/Demo/)
413
514
## Table of contents
615

716
- [<u>How to use</u>](#how-to-use)
817
- [<u>Scene</u>](#scene)
18+
- [<u>Scripting</u>](#scripting)
919
- [<u>Pixel-look</u>](#pixel-look)
1020
- [<u>Building from source</u>](#building-from-source)
1121
- [<u>Running tests</u>](#running-tests)
@@ -14,6 +24,9 @@
1424

1525
## How to use
1626

27+
**Executables for Windows** (and probably Linux-x64) will be added soon. Otherwise you need to
28+
[build from source](#building-from-source).
29+
1730
To produce an output image, paths for scene and output files are required:
1831

1932
```bash
@@ -27,6 +40,7 @@ call default image opener program via shell execution:
2740
PixelRay -i scene.json -o output.png -p
2841
```
2942

43+
To avoid file path issues, just keep scene (and script) file in the same directory with executable
3044

3145
#### All commands
3246

@@ -36,11 +50,30 @@ PixelRay -i scene.json -o output.png -p
3650

3751
- `-o <path>` or `--output <path>`
3852

39-
Output file path. Image format is either **png** or **ppm**-
53+
Output file path. Image format is either **.png** or **.ppm**.
4054
- `-p` or `--preview`:
4155

4256
Attempts to open the output image after rendering by executing the image file, thus calling the default viewing
4357
tool in process. Only available for png images as basic editors seldom support ppm.
58+
59+
- `-s <luaScript> <frameCount> {gif}` or `--script <luaScript> <frameCount> {gif}`
60+
61+
Uses the static scene from `-i` command as a baseline then runs Lua script to produce output frames into
62+
`./frames` directory. Output format is always **png**, frame count defaults to 60 if frameCount is not a valid integer value.
63+
- script file uses Lua language and must there end in .lua
64+
- cannot be used with output or preview flags
65+
- automatically flushes `frames` directory to remove old images
66+
- can optionally pass `-g` / `--gif` flag to produce a GIF file from saved frames.
67+
68+
Example:
69+
70+
```bash
71+
PixelRay -i scene.json -s script.lua 30 -g
72+
```
73+
74+
produces files frame0.png to frame29.png in `./frames` and
75+
then combines these into a gif file as `outputGif.gif`
76+
4477
- `--debug <mode>`
4578

4679
Renders image based on selected debug mode. These are:
@@ -54,11 +87,25 @@ PixelRay -i scene.json -o output.png -p
5487
5588
## Scene
5689
90+
> Scene file and animation script templates can be found in [here](scene-template).
91+
5792
Scenes use **json** format.
58-
Default scene file can be found [here](docs/scene.json).
5993
6094
For all scene parameters and their explanations, see [Scene.md](docs/Scene.md)
6195
96+
### Scripting
97+
98+
Scripts use [Lua programming language](https://www.lua.org/start.html) embedded into C#
99+
via [MoonSharp](https://github.com/moonsharp-devs/moonsharp).
100+
101+
Scripting can be applied to
102+
103+
- object transforms (translation/positioning, scaling, rotations)
104+
- camera (position, forward/upward direction, fov, aspect ratio)
105+
106+
For scripting API, see [Lua.md](docs/Lua.md)
107+
108+
62109
## Pixel-look
63110
64111
To enforce pixelated theme:
@@ -79,8 +126,11 @@ To enforce pixelated theme:
79126

80127
## Building from source
81128

82-
`SixLabors.ImageSharp` is the only required third-party package
83-
and happens to be well-supported on both Linux and macOS. It's used for producing output images in PNG format
129+
Both third-party packages
130+
- `SixLabors.ImageSharp` for png and gif generation
131+
- `MoonSharp` for Lua scripting support
132+
133+
are be well-supported on Windows, Linux and macOS.
84134

85135
---
86136

@@ -93,9 +143,9 @@ Build command for .NET is
93143
> dotnet publish -c Release -r \<rid\> \<args\>
94144

95145
There are generally two ways to build into an executable:
96-
1. Self-contained exe. This dll is SILK.NET native dependency and needs be included
97-
- larger executable (~37 MB on Windows, ~39 MB on Ubuntu) but runs on its own, no .NET runtime installation
98-
required for end user
146+
1. Self-contained executable
147+
- larger size (~37 MB on Windows, ~39 MB on Ubuntu) but runs on its own, no .NET runtime installation
148+
required from end user
99149
2. minimal exe + DLLs
100150
- very small, but end user must have **.NET 10.0 Runtime** installed
101151

@@ -161,18 +211,28 @@ copy-pasting all the colors)
161211
- maybe depth of field/blur in some form
162212
- materials/mediums: glass, matte, lambertian, fog/gas
163213
- maybe also simplistic emissive materials
164-
- objects:
214+
- geometry:
165215
- simple meshes for custom shapes. Also some kind of preview tool could be useful
166216
- maybe some new primitives
167217
- maybe new transforms like shear
218+
- shared materials (and meshes): current system adds materials in each object, prevent reusing them
168219
- performance
169220
- at least BHV when meshes get added
170221
- otherwise some smaller optimizations here and there
171-
- scripting support via Lua language (complex scenes + animations)
172-
- more unit tests + maybe a few integration tests
222+
- scipting: add lights (transforms and camera controls already there)
223+
- more tests
173224

174225
#### Priority
175-
1. Lua scripting support
226+
1. light manipulation in scripts
176227
2. meshes + BHV
177228
3. new materials/mediums
178-
4. the rest
229+
4. shared materials and meshes
230+
4. the rest
231+
232+
233+
TODO:
234+
235+
- scripting: custom frame count
236+
- Lua: add light support
237+
- make a basic animation, add it into scene (along with scene.json)
238+
- update README: add Scripting section

docs/Images/defaultGif.gif

3.49 MB
Loading

docs/Lua.md

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
**This document is about creating scripts to produce dynamic scenes**.
2+
3+
**You still need a static scene file for initial state. If you don't have one, see [Scene.md](Scene.md)**
4+
5+
**Scene and script file templates used for producing README image + gif can be in [scene-template](../scene-template/) directory**
6+
7+
8+
## How to
9+
10+
- create a scene json file
11+
- for objects you want to manipulate: add `name` field and add identifier e.g. `"name": "sphere1"`
12+
- write a script in Lua format
13+
- use `PixelRay -i <scene> -s <script> <frames> -g` to produce frames and combine them into a gif
14+
15+
## Lua API
16+
17+
`camera` is for camera access, you can manipulate
18+
- position (`camera:Position`)
19+
- look direction (`camera:LookAt`)
20+
- upward axis (`camera:Up`)
21+
- field of view (`camera:Fov`)
22+
- aspect ratio (`camera:AspectRatio`)
23+
- no internal calculation are performed so this just a raw value
24+
25+
`scene` can be used to access the scene itself
26+
27+
- To access an object instance, use `GetObject(name)` and store reference to a variable:
28+
29+
```lua
30+
obj = scene:GetObject("torus1")
31+
```
32+
33+
You should use a descriptive name, especially in complex scenes:
34+
35+
```lua
36+
torus1 = scene:GetObject("torus1")
37+
```
38+
39+
Currently only transforms can be manipulated.
40+
41+
### Transforms
42+
43+
#### Order of operations (IMPORTANT)
44+
45+
For static scenes, PixelRay will always perform translation in this order:
46+
47+
scale -> rotate -> translate
48+
49+
Reason is that all geometry objects primitives are origin-centered so matrix transforms behave as expected.
50+
51+
**What this means for animations:**
52+
53+
- translations work always
54+
- scaling and rotating:
55+
- requires you to translate object into origin (0, 0, 0)
56+
- then perform scaling and/or rotating
57+
- then translate back to actual position
58+
59+
For example: object at (1, 0.5, -2), you want to scale it. You then first move to (0, 0, 0) by applying inverse translation (-1, -0.5, 2) then scale, then apply translation (1, 0.5, -2) again.
60+
61+
**It's important to follow this principle, otherwise your animations will not produce correct frames.**
62+
63+
---
64+
65+
#### Transform commands
66+
67+
- `ResetTransform()`
68+
Resets object back to base transformation defined in json scene file
69+
70+
- this is good for parametric equations: instead of using previous state, reset back to initial then let **t** define new state
71+
- it also good to use this for stability purposes: long animations require stacking lots of transformations -> lots of matrix multiplication -> possible numerical instability
72+
73+
**Example:**
74+
```lua
75+
obj:ResetTransform()
76+
```
77+
78+
- `Translate(x, y, z)`
79+
Move object to new position along vector (x, y, z) from current position
80+
81+
- this doesn't move you TO position (x, y, z), but rather adds the vector so you move along it's direction and magnitude (= summing two vectors)
82+
83+
**Example:**
84+
```lua
85+
obj:Translate(1, -3, 1)
86+
```
87+
88+
Here, if `obj` current position is (1, 2, 3), `obj:Translate(1, -3, 1)` moves it to (2, -1, 4)
89+
90+
- `Scale(x, y, z)`
91+
Scale each object axis individually
92+
93+
**Example:**
94+
```lua
95+
obj:Scale(0.5, 1, 1)
96+
```
97+
98+
Scales object in x-direction to 0.5, others stay unchanged
99+
100+
- `ScaleUniform(t)`
101+
Scale all axes equally
102+
103+
**Example:**
104+
```lua
105+
obj:Scale(0.5)
106+
```
107+
108+
This is same as using `obj:Scale(0.5, 0.5, 0.5)`
109+
110+
- `Rotate(x, y, z, w)`
111+
Rotate object with respect to axis direction (x, y, z) using angle w (in degrees)
112+
113+
**Example:**
114+
```lua
115+
obj:Rotate(0, 1, 0, 90)
116+
```
117+
118+
This would rotate object around y-axis for 90 degrees
119+
120+
- `RotateMultiple(r1, r2, ...)`
121+
Apply multiple rotation one after another
122+
- useful for complex rotations: instead of calculating final rotation, you can progress step by step
123+
- uses Lua tables {x1, y1, z1, w1} to separate rotations
124+
125+
**Example:**
126+
```lua
127+
obj:RotateMultiple({1, 0, 0, 90}, {0, 1, 0, 90}, {0, 0, 1, 90})
128+
```
129+
130+
This would first perform 90 degree x-direction rotation, then same for y-direction and finally for z-direction. In this case, outcome is same as a single (0, 1, 0, 90) rotation.
131+
132+
133+
134+

docs/Scene.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## Right-hand coordinates:
1+
## Right-hand coordinates:
22
- standard:
33
- x increases to right, y increases upwards, camera points to negative z-axis
44
- `lookAt = (0, 0, -1)`, `up = (0, 1, 0)` matches to this system
@@ -31,7 +31,7 @@ Here are all the scene entities and their parameters
3131

3232
#### render
3333

34-
- `threading`: `boolean, default=false`
34+
- `threading`: `boolean, default=true`
3535
- for parallelized rendering
3636
- `width`: `integer >= 0`
3737
- image width
@@ -73,7 +73,8 @@ Here are all the scene entities and their parameters
7373

7474
### Objects
7575

76-
#### primitives:
76+
Each object has optional `name` field. This can be used for accessing specific object in Lua scripts.
77+
7778
- `sphere` unit sphere
7879
- `disc` unit disc pointing at (0, 1, 0)
7980
- `plane` plane pointing at (0, 1, 0)
@@ -93,8 +94,9 @@ Here are all the scene entities and their parameters
9394
Use transforms to change object geometry, and materials to change color & how light is reflected
9495

9596
#### transforms
96-
- `position`: `[x, y, z]`
97-
- translation/shifting/moving object position
97+
- `translate`: `[x, y, z]`
98+
- translation/shifting/moving object position alongside vector (x, y, z)
99+
- it doesn't move object TO (x, y, z), instead adds this vector to your current position
98100
- `rotation`: `list of [x, y, z, w]`
99101
- 4D vector [x, y, z, w] where (x,y,z) is the rotation axis and w the angle in degrees (not radians!)
100102
- rotations are always treated as a list of rotations so even for a single rotation, use `[[1, 0, 0, 90]]`. If no
@@ -216,7 +218,7 @@ For radius types:
216218
"fov": 90
217219
},
218220
"render": { // renderer configurations
219-
"threading": true, // default is 'false', but keep this enabled for major rendering speed boost (unless very old cpu)
221+
"threading": true, // default is 'true' so this line is unnecessary. Keep enabled for major rendering speed boost
220222
"width": 250,
221223
"height": 140,
222224
"upScaleFactor": 3,
@@ -293,6 +295,7 @@ For radius types:
293295
}
294296
},
295297
{
298+
"name": "torus1" // optional name, useful for referring to specific objects when scripting
296299
"type": "torus",
297300
"minorRadius": 0.2,
298301
"majorRadius": 0.1,

0 commit comments

Comments
 (0)