This project generates random art images based on a grammar that defines a set of operations and how they can be combined. The grammar uses a seed to produce a tree-like structure of operations, which are then evaluated to create a color value for each pixel in the output image. It also allows you to render the generated art in a window using a simple shader.
To build the project, you need to have Rust and Cargo installed. Then, navigate to the project directory in your terminal and run:
cargo build --release
This will create an optimized executable in the target/release/
directory.
You can run the project using Cargo:
cargo run --release -- [options]
-s
,--seed <SEED_STRING>
: Sets a custom seed for the random number generator. The seed can be a string or an integer. If no seed is provided, the current time is used as the seed.-d
,--depth <DEPTH>
: Sets the depth of the expression tree to generate. The default value is5
.-o
,--output <OUTPUT_FILE>
: Sets the output file name for the generated image. The default value isgenerated/random_art.png
.-r
,--render_mode <RENDER_MODE>
: Select render mode. Possible values arefile
(render to a file) andwindow
( render to a window).
Generate an image with a specific seed:
cargo run --release -- -s "my_custom_seed" -o "output/my_image.png"
Generate an image with a random seed (based on the current time) and save it to the default location:
cargo run --release
Generate an image with a numeric seed and a depth of 7:
cargo run --release -- -s 12345 -d 7 -o "seed_12345_depth_7.png"
Render to a window with a specific seed and a depth of 10:
cargo run --release -- -s "my_window_seed" -d 10 -r window
The examples/
directory contains some example images generated by the program. Here are a few examples presented in a
table:
- Offscreen Rendering for Shaders: Add a way to save the output of the
WindowRenderer
(which uses a shader) to a PNG file. This will involve offscreen rendering techniques. - GPU-based Renderer: Implement a full-fledged GPU-based renderer (
GPURenderer
) using a compute shader to significantly improve performance, especially for higher resolutions and complex expressions. Consider using libraries likewgpu
. - Animation Generation:
- Add an option to generate animations by varying the expression tree over time (e.g., by modifying the
t
variable or changing the seed). - Implement a way to save animations as a sequence of PNG files or directly as a video file (using a library like
ffmpeg
).
- Add an option to generate animations by varying the expression tree over time (e.g., by modifying the
- More Operations: Add more operations to the grammar to create more complex and varied images:
- Trigonometric functions (
cos
,tan
,atan2
). - Noise functions (Perlin noise, Simplex noise).
- Fractal functions (Mandelbrot set, Julia set).
- Conditional operations (
if-else
). - Image loading (load an image and use it as input).
- Trigonometric functions (
- Configurable Probabilities: Allow configuring the probabilities of each operation in the grammar, potentially through a configuration file.
- Graphical User Interface (GUI): Develop a GUI to make it easier to interact with the program, allowing users to:
- Adjust parameters (seed, depth, operation probabilities).
- Select the renderer (file, window, GPU).
- Preview the generated art.
- Save images and animations.
- Consider using GUI frameworks like
egui
,iced
, ordruid
.
- Multithreading: Parallelize the pixel evaluation in
FileRenderer
using threads (e.g., with therayon
crate) for performance gains. - Caching: Implement caching to store the results of sub-tree evaluations to avoid redundant computations.
- SIMD: Explore using SIMD instructions for pixel operations to improve performance.
- Configuration File: Allow users to define custom grammars and settings in a configuration file (e.g., TOML or YAML).
- Testing: Add comprehensive unit tests to ensure code correctness and prevent regressions.
This project is licensed under the MIT License.