Notes:
Currently working on:
- Looking desperately for optimizations(let me know if you have any ideas)
- Volumetric Clouds(struggling, they look garbage)
- Volumetric Voxels(Struggling to make it fast enough, have so far tried sparse voxel octrees, DDA, and now brickmaps, but its not fast enough, any advice is welcome)
- Need More Ideas
A passion projects that has been going on for awhile(about a year in unity, with my earliest version I can find being version 30(whereas I am now on version 263), which was made on 5-7-2021), finally at a place where I feel comfortable tentatively uploading it to Github for others to use What is it? Its my attempt at a Real-Time pathtracer built from scratch in Unity using Compute Shaders
- Somewhat fast Compute Shader based path tracing
- Diffuse, Glossy(kinda), Diffuse Transmission, Emissive, Plastic, and Disney BSDF materials
- Ability to move, add, and remove objects during play
- Ability to update material properties on the fly during play
- ASVGF, SVGF, and Atrous Denoiser
- BVH Building off of main thread for loading objects, allows objects to be spawned, and then built without lagging the main thread, and appearing when its done(All lag from spawning objects actually comes from remaking the texture atlas, lower res atlas's remove all lag, still investigating different ways of loading textures because of this)
- Compressed Wide Bounding Volume Hierarchy as the Acceleration Structure (See Ylitie et al. 2017 below)
- PBR Textures(just apply them to the GameObjects material)
- Next Event Estimation with Multiple Importance Sampling for Explicit Light Sampling
- Objects are loaded as gameobject meshes(most common way of having meshes in unity)
- Support for default unity lights which interact via NEE(Supports Directional, Point, and Spot lights)
- Support for Normal maps and Emission masks
- Global homogenous fog with adjustable density
- Taking Full Resolution Screenshots
- Bloom
- No specific GPU vendor needed(this will run on integrated graphics if you so wish it, aka no RTX cores)
- MagicaVoxel support
- Ability to pathtrace voxels and triangle scenes at the same time seamlessly
- Depth of Field
- AutoExposure
- Temporal Anti-Aliasing
- ReSTIR for better sampling of many lights
- Explicit light sampling for faster convergence
- Precomputed Multiple Atmospheric Scattering for dynamic and realtime sky(from ebruneton below)
- Object Instancing
- Multiple Importance Sampling for helping NEE converge much faster
- ReSTIR GI for faster convergence in complex scenes and more complete images in scenes with changing lighting
If you have any questions, or suggestions, etc. let me know either through github issues or something else! I am always looking for more stuff to add, and more ways to make it more user friendly or appealing for others to use, and ways to improve this overall
Let me know if you use this for anything, I would be excited to see any use of this! Just please give some credit somewhere if you use it, thank you!
- Set the Color Space to Linear through Edit Tab(Top Left) -> Project Settings -> Player -> Other Settings -> Color Space, and change from Gamma to Linear
- Change the Graphics Api for Windows to DirectX12 through Edit Tab(Top Left) -> Project Settings -> Player -> Other Settings -> Untoggle "Auto Graphics API For Windows", then click the little + that appears, select "Direct3D12(Experimental)", and drag that to the top. A restart of the editor is required
- Enable Unsafe Code(Its for memory management) through Edit -> Project Settings -> Player -> Other Settings -> "Allow 'unsafe' Code" (near the bottom)
## Additional Requirements
- You need to make sure that all textures have Read/Write enabled in their import settings(click on a texture in the Project menu, look at its options in the inspector, turning on Read/Write, and clicking apply at the bottom). I would also reccomend turning off MipMapping
- For Skinned Meshes, their index format needs to be set to 32 bits, and their mesh to Read/Write enabled. This can be found by clicking on the imported fbx, going to it in the inspector, going to the Model tab, turning on Read/Write, changing the Index Format from Auto to 32 Bit, and clicking Apply at the bottom
## General Setup
- Download and import the UnityPackage provided
- For quick setup, make sure you have a Main Camera(there by unity default), just open the Pathtracer Settings menu under the Pathtracer tab, it will reorganize the Hierarchy a bit, and give everything their required scripts
## Basic script structure breakdown:
- Top Level is a gameobject called Scene with an AssetManager script attatched
- Second Level: Parent Object Script - Attatch this to all objects that will have children with meshes you want to raytrace(can be a child to any gameobject as long as its eventual parent is the AssetManager script)
- Third Level: RayTracingObject Script - This defines what meshes get raytraced, must either be a direct child of a gameobject with the ParentObject Script, or in the same gameobject as the ParentObject Script
- Misc Level: Unity Lights - Must have a RayTracingLight script attatched to be considered(and UseNEE needs to be on), can be ANYWHERE in the hierarchy, only supports Point, Spotlight, and 1 Directional
- Objects can be added and removed at will simply by toggling the associated gameobject with a ParentObject script on/off in the hierarchy(dont click them if they are complex objects), but they will take time to appear as the acceleration structure needs to be rebuilt
- If you change the emissiveness of an object, you need to dissable and re-enable its parent(basically reloading it) if you want to take advantage of NEE correctly sampling it(Does not need to be reloaded for Naive tracing)
- If you use normal maps, they need to be in unity normal map format
- To set up PBR, all textures go into their proper names, but Roughness goes into the Occlusion texture(Since path tracing gets ambient occlusion by default, this texture is not normally needed, and there being no proper place for a Roughness texture in the default material, I have decided this was a good compromise)
- If you are using blendshapes to change geometry of a skinned mesh, you may need to go to the import settings of it(in the inspector), turn off Legacy Blendshape Normals, and make sure all normals are imported, not calculated
- Before anything, the files need to be in .txt format, to do this, go to the file in file explorer, and rename the .vox to .txt and change the format
- Firstly, you still need to have a gameobject under the scene gameobject to attatch your voxel model to
- Second, you need to attatch a VoxelObject to that gameobject(Located under Assets->Resources->BVH->VoxelObject)
- Next you need to attatch the voxel model to this script, by dragging your voxel model asset in the project tab to the VoxelRef space in the VoxelObject script
- That should be it, it will get grouped into the building along with meshes, and having at least 1 voxel object in the scene will turn on its inclusion. Removing or turning off all voxel related gameobjects will turn it back off
## Using Instancing
- First, there needs to be a gameobject called InstancedStorage in the scene with the InstanceManager attatched to it as a sibling object of the Scene gameobject
- Second, all objects that will be the source of instanced objects will need to go under the InstancedStorage and can be arranged like normal objects(with regards to the layout of parentobject to raytracingobjects)
- Finally, to instance the objects, you just need empty gameobjects with the InstanceObject script attatched to them under the Scene gameobject, and then drag the desired object instance from the hierarchy to the Instance Parent slot in the InstanceObject script(all of this is displayed in the demoscene)
Camera Controls: WASD, Mouse, and press T to freeze/unfreeze the camera(Camera starts frozen)
BVH Options Description -
- Build Aggregated BVH - Allows you to pre-build objects BVH's before running so you dont have to wait every time you go into play mode for it to build. To know when its done building, the Object Parent Name will appear in the console telling you its complete(and thus wont need to be rebuilt every time you hit play)
- Clear Parent Data - Clears the data stored in parent gameobjects, allowing you to actually click them without crashing or lagging(but will then require the BVH to be rebuilt)
- Sun Position - REMOVED, so now the sun can be anywhere, not just in a disk
- Max Bounces - Sets the maximum number of bounces a ray can achieve
- Use Russian Roulette - Highly reccomended to leave this on, kills rays that may not contribute much early, and thus greatly increases performance
- Enable Object Moving - Allows objects to be moved during play, and allows for added objects to spawn in when they are done building
- Allow Image Accumulation - Allows the image to accumulate while the camera is not moving
- Use Next Event Estimation - Enables shadow rays/NEE for direct light sampling
- Allow Volumetrics - Turns on pathtracing of global volumetric homogenous fog
- (If Allow Volumetrics is on) Volume Density - Adjusts density of the global fog
- Allow Mesh Skinning - Turns on the ability for skinned meshes to be animated or deformed with respect to their armeture
- Allow Bloom - Turns on or off Bloom
- Use DoF - Turns on or off Depth of Field, and its associated settings
- Use Auto Exposure - Turns on or off Auto Exposure(impacts a lot more than I thought it would)
- Use ReSTIR - Enables the much better sampling for lots of lights
- Allow ReSTIR Sample Regeneration - Applies if Precomputed Sampling is on, Regenerates the light samples every frame
- Allow ReSTIR Precomputed Sampling - Samples lights in a more efficient way but introduces artifacts due to sample correlation
- Allow ReSTIR Temporal - Enables the Temporal pass of ReSTIR(allows samples to travel across time
- Allow ReSTIR Spatial - Enables the Spatial pass of ReSTIR(Allows pixels to choose to use the neighboring pixels sample instead)
- ReSTIR Spatial M-Cap - Tuneable parameter, increase this if you have lots of lights(standard values would be between 32 and 640 for reference, but going higher or lower is needed at times)
- Use Temporal Antialiasing - Enables Temporal Antialiasing(TAA)
- Use SVGF Denoiser - Turns on the SVGF denoiser
- (If SVGF Denosier is on)Atrous Kernel Size - The amount of times the SVGF denoiser runs through the Atrous kernel
- Use ASVGF Denoiser - Turns on the ASVGF denoiser
- (If ASVGF Denoiser is on)ASVGF Atrous Kernel Size - The amount of iterations the final ASVGF atrous goes through, limited to 4, 5, and 6
- Use Atrous Denoiser - Turns on the Atrous denoiser(can be combined with SVGF)
- Enable Tonemapping - Turns on Filmic Tonemapping
- Atmospheric Scatter Samples - Lower this to 1 if you keep crashing on entering game mode(controls how many atmospheric samples are precomputed)
- Current Samples - Shows how many samples have currently been accumulated
- Take Screenshot - Takes a screenshot at game view resolution and saves it to Assets/ScreenShots(You need to create this folder)
- QuickStart - Will attempt to automatially assign RayTracingObjects and ParentObjects to all child under the GameObject named "Scene" with an AssetManager attatched
- Do Sample Connection Validation - Makes shadows sharper by confirming connection points, reduces performance though due to the 2 shadow rays(hence why its an option
- ReSTIR GI Update Rate - Controls how fast temporal samples are thrown away, setting it to 0 means images will be much cleaner over time, but wont react to lighting, while for scenes with changing lighting, I have found that a value around 9 is an acceptable midpoint
- Use ReSTIR GI Temporal - Just turns on or off the ability for samples to be temporally reprojected(re-used from previous frames)
- ReSTIR GI Temporal M Cap - Similar to Update Rate, and goes hand in hand and should be used together with it, 12 is an acceptable midpoint, and 0 allows it to accumulate forever(produces much cleaner image but doesnt react to lighting or object changes)
- Use ReSTIR GI Spatial - Allows samples to draw from neighbors to try and find a better path
- ReSTIR GI Spatial Sample Count - The number of neighbors a sample is allowed to sample
- Enable Spatial Stabalizer - Allows low sample count samples to be re-fed into temporal, useful if you have a fast moving object, reduces trailing noise by a lot, but can introduce artifacts
- Material Options - Select your type of material you want
- BaseColor - If theres no Albedo Texture, this is the color the object will be
- Emission - The emittance of an object
- Emission Color - Changes the color of emissive objects, most useful when you have an emission mask on an object
- Roughness - Roughness of the object
- IOR - Index of Refraction of an object
- Metallic - How metallic an object is. Affects only Disney BSDF
- Specular Tint - Affects color of specular materials. Affects only Disney BSDF
- Sheen - Adds Sheen to objects. Affects only Disney BSDF
- SheenTint - Allows you to choose if an objects sheen is white or is that objects base color. Affects only Disney BSDF
- ClearCoat - Adds a Clearcoat effect to the object. Affects only Disney BSDF
- ClearCoatGloss - Influences the Clearcoat. Affects only Disney BSDF
- Anisotropic - Makes the material(mostly metallic) anisotropic. Affects only Disney BSDF
- Flatness - Affects Thin objects. Affects only Disney BSDF
- DiffTrans - Makes an object Diffuse but Transmissive(transluscent). Affects only Disney BSDF
- SpecTrans - Makes an object more or less like glass. Affects only Disney BSDF(Play with the IOR for this)
- Thin - Marks an object as thing so it can be better handled by the BSDF. Affects only Disney BSDF
# Known Bugs:
- Error that RayTracingShader is using too many UAV's. This isnt really a bug, but happens because you cant dissable DX11 which doesnt allow more than 8(whereas DX12, what is actually used, allows a lot more)
https://user-images.githubusercontent.com/31225585/194152525-e77ad1d2-546d-4a91-8069-91897b1a7130.mp4
Biggest thanks to Zuen who helped me a huge amount with the new BVH and traversal, thanks to them I got to where I am now, and I am very thankful to them for their help and patience
https://github.com/jan-van-bergen
Scenes From:
- https://benedikt-bitterli.me/resources/
- https://casual-effects.com/data/
- https://www.intel.com/content/www/us/en/developer/topic-technology/graphics-research/samples.html
- https://sketchfab.com/3d-models/tallers-de-la-fundacio-llorenc-artigas-22-5224b721b0854998a1808fcea3cff924
- https://sketchfab.com/3d-models/dae-bilora-bella-46-camera-game-ready-asset-eeb9d9f0627f4783b5d16a8732f0d1a4
- https://www.unrealengine.com/marketplace/en-US/product/victorian-train-station-and-railroad-modular-set
Disney BSDF from: https://www.shadertoy.com/view/sltXRl
Find an alternative to atlas's, Reduce memory consumption, work on adding back in Mitsuba scene support