- Available only on Windows (for now).
- Unity's Enemies Hair Pipeline
- Some hair models are created from Gaussian Haircut.
- Windows 10, 11 (Although it should be easy enough to set it up for Linux).
- Vulkan SDK 1.3.* installed (With VMA and Shaderc).
- CMake installed.
- Git LFS (resources are stored with it)
- Ninja (recommended)
- Clone the repo:
git clone --recursive https://github.com/AEspinosaDev/Hair-Renderer-2.git cd Hair-Renderer-X - Build with CMake:
mkdir build cd build cmake ..
Applicaiton links against an older version of Vulkan-Engine (pretty rusty version but enough for demos).
Application loads an avatar and a hair mesh and renders it.
HairViewer: The core of the application. It orchestrates the entire program lifecycle, from initialization (init,setup) to the main execution loop (run,tick,update).WindowGLFW&ForwardRenderer:WindowGLFWhandles the application window and inputs (keyboard/mouse), whileSystems::ForwardRendereris the graphics engine responsible for drawing the scene and computing shadows.Scene,Camera, &Controller:Scene: Acts as the master container holding all 3D objects and lights.Camera: Navigated using aTools::Controllerset toORBITALmode, allowing for easy inspection of the 3D models.
- Lighting System:
PointLight: The primary light source casting dynamic shadows (with configurable bias, FOV, near planes, etc.).Skybox/TextureHDR: Handles environment map (HDRI) loading for ambient lighting and reflections.
- Meshes & Materials (
Mesh):PhysicallyBasedMaterial: Standard PBR materials used for the character's head and eyes (supporting albedo, roughness, and metalness).HairEpicMaterial: A specialized material with advanced parameters (such as strand thickness) designed specifically for realistic hair rendering.
- Resource Loading & Neural Avatars: Utilizes
Tools::Loadersfor standard assets (PLY files, textures). For heavy neural hair models, it implements a multi-threaded approach (std::threadviahair_loaders::load_neural_hair) to load assets in the background without freezing the application. - User Interface (
m_interface): Manages the overlay GUI. It provides a scene hierarchy viewer (sceneWidget) and allows for real-time editing of object properties (objectWidget).
- No Reflection: Automatic shader reflection is not implemented. Descriptor layouts must be manually defined in the C++ Pass implementation.
- Include System: A simple, non-recursive include system is available. Shaders are organized by type and utility. All module includes must be declared in the entry-point shader:
#version 450
#include utils.glsl
#include BRDFs/epic_hair_BSDF.glsl
#include montecarlo.glsl- Unified Shader Files: You can write the entire graphics pipeline (vertex, fragment, etc.) inside a single file using compilation directives. The engine compiles shaders on the fly automatically.
#version 450
#shader fragmentShaders are build on the fly autamitaclly, so no need of using no .bat or thir party executable.
Currently, both Forward and Deferred renderers are implemented. For hair rendering, the Forward Renderer is highly advised. Hair fibers are high-frequency primitives that benefit greatly from hardware MSAA, as standard TAA is usually insufficient to preserve fine strand details.
- No Render Graph: Render passes are directly created and sequenced at renderer startup.
- Dependency Tables: Resources (Render Targets, UAVs) are managed via a dependency table. To add new passes with new resources, you must increase the Render Target (RT) pool and update the dependency table.
- Atomic Operations: One RenderPass should represent an atomic render operation (e.g., a single compute pass, a G-Buffer pass, or a scattering pass). While you can pack multiple operations into one pass, resource synchronization becomes difficult.
- RHI Isolation: The RHI (Render Hardware Interface) module resides in the Graphics folder and should generally remain untouched.
Render passes live in the Core/Passes folder and follow a classic OOP inheritance model based on IBasePass. Note: This engine uses classic Vulkan RenderPass objects, not the modern VK_KHR_dynamic_rendering extension.
#pragma region Core Functions
// Setup attachments (Render Targets) and dependencies for this pass
virtual void setup_attachments(std::vector<Graphics::AttachmentInfo>& attachments,
std::vector<Graphics::SubPassDependency>& dependencies) = 0;
// Declare descriptor layouts and sets here
virtual void setup_uniforms(std::vector<Graphics::Frame>& frames) = 0;
// Define Graphics/Compute pipelines and link shaders
virtual void setup_shader_passes() = 0;
// Master setup function: calls setup_attachments, setup_uniforms, etc.
void setup(std::vector<Graphics::Frame>& frames);
// The actual execution of the rendering pipeline/commands
virtual void render(Graphics::Frame& currentFrame, Scene* const scene, uint32_t presentImageIndex = 0) = 0;
virtual void update_uniforms(uint32_t frameIndex, Scene* const scene) {}
virtual void link_previous_images(std::vector<Graphics::Image> images) {}
// Framebuffer management
virtual void create_framebuffer();
virtual void clean_framebuffer();
// Handles recreation of the pass (e.g., on window resize)
virtual void update();
// Destroys the renderpass and its shader passes
virtual void cleanup();
#pragma endregion-
Inherit: Create a new class inheriting from IBasePass.
-
Implement Setups: * setup_attachments(): Declare the render targets.
-
setup_uniforms(): Define descriptor layouts and pools.
-
setup_shader_passes(): Define your pipelines and link your shaders.
-
Implement Logic: Write your command buffer recording logic inside the render() function.
-
Instantiate: Add your new pass to the Renderer's setup_passes() function.
-
Link: Link the necessary resources (inputs/outputs) to it using the dependency table.
-
ext/Vulkan-Engine/resources/shaders/scripts/BRDFs/epic_hair_BSDF.glsl (Hair shader implementation)
-
ext/Vulkan-Engine/resources/shaders/scripts/BRDFs/schlick_smith_BRDF.glsl (Standard PBR shader)
-
ext/Vulkan-Engine/src/systems/renderers/forward.cpp (Forward Renderer logic)
-
ext/Vulkan-Engine/src/core/passes/forward_pass.cpp (Forward Pass implementation)
-
ext/Vulkan-Engine/src/core/passes/hair_scattering_pass.cpp (Example of a pure Compute Pass)
- ext/Vulkan-Engine/src/core/resource_manager.cpp (Crucial class where CPU data is arranged and uploaded to the GPU)
- ext\Vulkan-Engine\include\engine\tools\widgets.h