![](https://private-user-images.githubusercontent.com/73549035/331761619-03ee6d53-90a7-40a4-b9aa-b6bdf53b3181.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjU2Nzk2ODcsIm5iZiI6MTcyNTY3OTM4NywicGF0aCI6Ii83MzU0OTAzNS8zMzE3NjE2MTktMDNlZTZkNTMtOTBhNy00MGE0LWI5YWEtYjZiZGY1M2IzMTgxLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA5MDclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwOTA3VDAzMjMwN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTBhMzJmZjA4ZWNiMmJmOTY0YTI4ZWY4MmJhZWIzYTZhNGUyMmEwYmQ1MTg2NDgwNDI0ZGY0M2Y3MzkzNTY1MWQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.IfItK-VJmUw46oa6dWvz1ENrsA8ziWI7loCmzbjCNIU)
I've always been interested in Computer Graphics and the math that goes into rendering a 3D scene, so I decided to create my own raytracer in Unity as an excercise.
Rays are cast using Unity physics engine and colliders.
- 3 Types of lights with intensity and range controls
- Directional
- Point
- Ambient
- Shadows
- Glass
- Refraction
- IOR controls per object
- Metal
- Specular Reflections
- Texture Mapping
- [Optimize] flag to render half of pixels every other frame to improve realtime performance
- Render resolution controls independent of viewport resolution
- All rendered objects must use a mesh collider in order for texture mapping to work
- [Unity Materials Raytracer] component must be disabled and enabled when adding new mesh collider objects in runtime
- All rendered objects must have a [Raytraced Material Properties] component
- Transparency for non-glass materials is not implemented
- Roughness (scattering) is not implemented for glass
- Performance is not great due to being a purely CPU based implementation
All of the below GIFs are captured realtime, in editor
![](https://private-user-images.githubusercontent.com/73549035/331761850-639618e8-cd2e-4a44-9b7c-5934776578c1.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjU2Nzk2ODcsIm5iZiI6MTcyNTY3OTM4NywicGF0aCI6Ii83MzU0OTAzNS8zMzE3NjE4NTAtNjM5NjE4ZTgtY2QyZS00YTQ0LTliN2MtNTkzNDc3NjU3OGMxLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA5MDclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwOTA3VDAzMjMwN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTlkYTU5OWRmMTA2YjljMTNjYzY0YzA0ZjcxNDM3NjNmY2UwYWU0YjU0MzY2YmQ0MGNiNGE5MzY5YzA1ZDg2OGImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.tAfnQq1ekpLbLkJ0DNoMYVR1TTizwVTJj1z58qWUDg8)
![](https://private-user-images.githubusercontent.com/73549035/331762203-ff890995-7b97-4b07-8115-e9a5458ce0b1.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjU2Nzk2ODcsIm5iZiI6MTcyNTY3OTM4NywicGF0aCI6Ii83MzU0OTAzNS8zMzE3NjIyMDMtZmY4OTA5OTUtN2I5Ny00YjA3LTgxMTUtZTlhNTQ1OGNlMGIxLmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA5MDclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwOTA3VDAzMjMwN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTlmM2JlZTE5MzRkNGM4MmY3ZWQ4MWM4ZDBiYjQzODM1YTYzYzkwMjhhOWJiYzYyZWNiNDMwZjMxMDgwMjcwYjUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.L_FO-A_YFa0YMKEM29FTn1B370_hJE9ZfsHI_hGSLzU)
![](https://private-user-images.githubusercontent.com/73549035/331762364-f5fe7dcf-773d-43c7-8028-f468845ac5c4.gif?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjU2Nzk2ODcsIm5iZiI6MTcyNTY3OTM4NywicGF0aCI6Ii83MzU0OTAzNS8zMzE3NjIzNjQtZjVmZTdkY2YtNzczZC00M2M3LTgwMjgtZjQ2ODg0NWFjNWM0LmdpZj9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA5MDclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwOTA3VDAzMjMwN1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTQyZTAxNGQ4M2Q4YzQ4MzczNjY5NjMzMjVkZjY1MWUxM2RhNjYyZTFjMmQyODFmYzcxMjJkZWE4OGY4YzZmNTcmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.0LNYYVsRPR8k6WymZ2Hi2v3vjmg8Yx1wL3NIEIA4nXE)
This project was created and tested on an M2 Macbook Pro 14 running MacOS. At 160x90 raytracing render resolution, the project averaged ~25-30 fps in editor with [Optimize] flag enabled. At 320x180 raytracing render resolution, the project averaged ~10-15 fps in editor with [Optimize] flag enabled.
Below is a short list of websites I referenced in order to create this implementation:
- https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-ray-tracing/implementing-the-raytracing-algorithm.html
- https://raytracing.github.io/books/RayTracingInOneWeekend.html
- https://www.gamedev.net/forums/topic/687535-implementing-a-cube-map-lookup-function/
- https://blog.demofox.org/2017/01/09/raytracing-reflection-refraction-fresnel-total-internal-reflection-and-beers-law/
- https://www.shadertoy.com/view/NdKyWy