GraphicsProt is a simple and straightforward graphics prototyping(programming) framework for C++ and Vulkan, featuring sample implementations.
- Windows & Mac cross platform
- C++ & GLSL code only (no editor)
- game engine like easy API, short code
- prototyping purpose only (currently not support for production)
- including sample implementations for my research / hobby purpose (this is main focus)
- Windows : CMake and shader compilation by executing Generate_Windows_VS2022.bat (more details later)
- Mac : CMake and Visual Studio Code (more details later)
C++(17), Vulkan, GLFW, ImGUI, stb_image, glm
minimum code to draw .obj- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Minimum
- 3D model credit "Steven Universe House" by Zypheos : https://sketchfab.com/3d-models/steven-universe-house-ea77c49785fc4802b697bde0f7cfda8f
- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/GerstnerWaves
- Demo : https://www.youtube.com/watch?v=WFtOAE4n0-w
Gerstner Waves is a famous algorithm that draws pseudo ocean
background texture is generated by DreamStudio
- References
(1) GPU Gems Chapter 1. Effective Water Simulation from Physical Models
(2) 【ポケットモンスター スカーレット・バイオレット】 パルデア地方を描き出す――見た目の仕組みを徹底解説!
https://cedec.cesa.or.jp/2023/session/detail/s64242ce14adbf
simple grayscale post process implementation
(1) Grayscale - Wikipedia
https://en.wikipedia.org/wiki/Grayscale
grass texture is generated by DreamStudio
floor texture is created at Test Grid Generator : https://wahooney.itch.io/texture-grid-generator
-
Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/Grass
-
References
(1) UnrelVFXCollection - Grass
https://github.com/mushe/UnrealVFXCollection/tree/main/Content/VFXCollections/Grass
normal map texture is generated at https://cpetry.github.io/NormalMap-Online/
Instancing is a standard technique for drawing many objects
drawing shapes(rect, circle, triangle, line) with a handy API
engine->BeginRenderToScreen();
// call between BeginRenderToScreen and EndRenderToScreen
ShapeDrawer::Rect(Vec2(0.25), Vec2(0.25)); // position, scale, (color)
ShapeDrawer::Circle(Vec2(0.75), Vec2(0.25), Vec4(1)); // position, scale, (color)
ShapeDrawer::Line(Vec2(0.625, 0.125), Vec2(0.875, 0.375)); // start, end, (width), (color)
ShapeDrawer::Triangle(Vec2(0.25, 0.75), Vec2(0.25), Vec2(0.25)); // position, direction, scale, (color)
engine->EndRenderToScreen();
procedurally generated maze
-
Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/Maze
-
References
(1) 自動生成迷路
https://www5d.biglobe.ne.jp/~stssk/maze/make.html
Plot points at random against some location in the circle circumscribed by the square. Then the number of points in the circle / number of points in the square = π / 4, which gets closer as the number of points increases. Using this logic, we can approximate pi.
Shift the RGB color pick position for each RGB individually
(1) コンピュータグラフィックス編集委員会, "コンピュータグラフィックス", 画像情報教育振興協会, 2008, p199.
- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/Posterization
- Image Credit : https://pixabay.com/photos/mountain-nature-landscape-picture-646389/
- References
(1) コンピュータグラフィックス編集委員会, "コンピュータグラフィックス", 画像情報教育振興協会, 2008, p221.
- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/PseudoColor
- Image Credit : https://en.wikipedia.org/wiki/File:Milwaukee_City_Hall_Old_Public_Domain_Photo.jpg
- References
(1) コンピュータグラフィックス編集委員会, "コンピュータグラフィックス", 画像情報教育振興協会, 2008, p224.
nostalgic post process
- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/Sepia
- References
(1) How to convert a color image into sepia image - Image Processing Project - dyclassroom
https://dyclassroom.com/image-processing-project/how-to-convert-a-color-image-into-sepia-image
handy text rendering API
- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/TextRender
- Font Credit : https://levien.com/type/myfonts/inconsolata.html
(1) Catmull–Rom Spline補間
https://zenn.dev/mushe/articles/92c65e0c8023aa
(1) mushe/UnrealVFXCollection:
https://github.com/mushe/UnrealVFXCollection
(1) mushe/UnrealVFXCollection:
https://github.com/mushe/UnrealVFXCollection
- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/SierpinskiTriangle
- References
(1) Sierpiński triangle - Wikipedia
https://en.wikipedia.org/wiki/Sierpiński_triangle
(1) Koch snowflake - Wikipedia
https://en.wikipedia.org/wiki/Koch_snowflake
- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/Hover
- References
(1) UnrelVFXCollection - HoverGame
https://github.com/mushe/UnrealVFXCollection
(1) Flocks, herds and schools: A distributed behavioral model
https://dl.acm.org/doi/10.1145/37402.37406
https://gist.github.com/mushe/17acdb2b90db663948cddb1a0f21e490
(1) Basic BSP Dungeon generation
https://www.roguebasin.com/index.php/Basic_BSP_Dungeon_generation
wall texture is generated by stable diffusion
- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/DungeonGeneration
- References
(1) Basic BSP Dungeon generation
https://www.roguebasin.com/index.php/Basic_BSP_Dungeon_generation
(1) Basic BSP Dungeon generation
https://www.roguebasin.com/index.php/Basic_BSP_Dungeon_generation
(1) Basic BSP Dungeon generation
https://www.roguebasin.com/index.php/Basic_BSP_Dungeon_generation
- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/VHS
- References
(1) UnrelVFXCollection - VHS
https://github.com/mushe/UnrealVFXCollection
- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/River
- References
(1) UnrelVFXCollection - SimpleRiver
https://github.com/mushe/UnrealVFXCollection
- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/PoissonDiskSampling
- References :
(1) Fast Poisson Disk Sampling in Arbitrary Dimensions
https://www.cs.ubc.ca/~rbridson/docs/bridson-siggraph07-poissondisk.pdf
- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/Fish
- References :
(1) Reynolds, Craig (1987). Flocks, herds and schools: A distributed behavioral model. SIGGRAPH '87: Proceedings of the 14th Annual Conference on Computer Graphics and Interactive Techniques.
(2) UnrelVFXCollection - Flocking
https://github.com/mushe/UnrealVFXCollection
- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/Blur
- References :
(1) Marius Bjørge(2015), Bandwidth-Efficient Rendering, SIGGRAPH 2015
- Code : https://github.com/mushe/GraphicsProt/tree/main/src/Samples/Demo/FluidSim
- References :
(1) Doyub Kim, "Fluid Engine Development", A K Peters/CRC Press, 2017
https://www.amazon.co.jp/-/en/Doyub-Kim-ebook/dp/B01MRDA6S8
(2) Matthias Müller et al, "Particle-based fluid simulation for interactive applications", ACM SIGGRAPH/Eurographics symposium on Computer animation, 2003
https://dl.acm.org/doi/10.5555/846276.846298
(3) Screen Space Fluid Rendering for Games - Nvidia
https://developer.download.nvidia.com/presentations/2010/gdc/Direct3D_Effects.pdf
(4) 武者 拓也, "Unreal Engine 5で学ぶビジュアルエフェクト実装 基本機能からNiagara、シミュレーションまで", 翔泳社, 2023
https://www.shoeisha.co.jp/book/detail/9784798177700
#include "Core/Engine.h"
int main()
{
// engine initialization
auto engine = Engine::Init();
// create mesh from obj
auto mesh = Mesh::FromOBJ("../Models/StevenUNiverseRoom/StevenUNiverseRoom.obj");
mesh->SetPosition(Vec3(0, -1.0f, 0));
mesh->SetRotation(Vec3(0));
mesh->SetScale(Vec3(0.1f));
// load texture
auto tex = Texture::FromPNG("../Models/StevenUNiverseRoom/StevenUNiverseRoom.png");
// create material by shader and texture
auto mat = Material::Create("Standard.vert", "UnlitTexture.frag", { tex });
// set material to mesh
mesh->SetMaterial(mat);
// create camera for object rendering
Camera camera;
// main rendering loop
while (engine->Running())
{
engine->BeginFrame(); // must be called at the beginning of every frame
// input handling
if (Input::KeyDown(KeyCode::Escape)) engine->Quit();
// camera orbital control with mouse
OrbitalControl::Update(camera);
// object rendering to screen by camera
engine->BeginRenderToScreen();
mesh->Draw(camera);
engine->EndRenderToScreen();
engine->EndFrame(); // must be called at the end of every frame
}
engine->Terminate();
}
auto rt = RenderTarget::Create(1920, 1080);
...
rt->BeginRenderToTexture();
mesh->Draw(camera);
rt->EndRenderToTexture();
post process etc.. implemented using this feature
engine->BlitToRenderTarget(material, rt);
...
engine->BlitToScreen(material);
// create material by shader and texture
auto mat = Material::Create("standard.vert", "unlitTexture.frag", { tex });
PostProcessUBO ubo{};
material->SetUniformBufferData(&ubo);
auto mesh = Mesh::FromOBJ("../path/to/obj/X.obj");
auto tex = Texture::FromPNG("../path/to/png/X.png");
imgui accessor
engine->OnGUI([&]()
{
GUI::Float(scale_, "scale", 0.1f);
GUI::FloatSlider(colorLerp, "colorLerp", 0.0f, 1.0f);
GUI::Color(color_, "color_");
GUI::Vector(g_objPos, "g_objPos", 0.01f);
GUI::VectorSlider(lightDir, "lightDir", -1.0f, 1.0f);
});
// key handling
if (Input::KeyDown(KeyCode::Escape)) engine->Quit();
// mouse drag delta
glm::vec2 rightMouseDrag = Input::LeftMouseDrag();
// mouse sheel delta
float wheelVel = Input::MouseWheelDelta();
Camera camera;
OrbitalControl::Update(camera);
// text, position, scale, color
Text("ABC", Vec2(0.5f, 0.5f), 1.0f, Vec4(1,1,1,1));
engine->BeginRenderToScreen();
// call between BeginRenderToScreen and EndRenderToScreen
ShapeDrawer::Rect(Vec2(0.25), Vec2(0.25)); // position, scale, (color)
ShapeDrawer::Circle(Vec2(0.75), Vec2(0.25), Vec4(1)); // position, scale, (color)
ShapeDrawer::Line(Vec2(0.625, 0.125), Vec2(0.875, 0.375)); // start, end, (width), (color)
ShapeDrawer::Triangle(Vec2(0.25, 0.75), Vec2(0.25), Vec2(0.25)); // position, direction, scale, (color)
engine->EndRenderToScreen();