Top Related Projects
Source code for pbrt, the renderer described in the third edition of "Physically Based Rendering: From Theory To Implementation", by Matt Pharr, Wenzel Jakob, and Greg Humphreys.
Embree ray tracing kernels repository.
LuxCore source repository
Mitsuba 2: A Retargetable Forward and Inverse Renderer
Universal Scene Description
Advanced shading language for production GI renderers
Quick Overview
Tungsten is an open-source, physically based renderer developed by Benedikt Bitterli. It aims to produce photorealistic images using advanced rendering techniques such as unbiased Monte Carlo path tracing and bidirectional path tracing. The renderer is designed to be both efficient and extensible, making it suitable for research and production use.
Pros
- High-quality, physically based rendering capabilities
- Support for advanced features like volumetrics, subsurface scattering, and spectral rendering
- Extensible architecture allowing for easy implementation of new rendering algorithms
- Cross-platform support (Windows, macOS, and Linux)
Cons
- Steep learning curve for beginners due to its advanced nature
- Limited documentation compared to some commercial renderers
- Smaller community and ecosystem compared to more established rendering solutions
- May require significant computational resources for complex scenes
Code Examples
As Tungsten is primarily a standalone renderer rather than a code library, there are no direct code examples to provide. However, users interact with Tungsten through scene description files and command-line interfaces.
Getting Started
To get started with Tungsten:
-
Clone the repository:
git clone https://github.com/tunabrain/tungsten.git
-
Build the project following the instructions in the README.md file for your specific platform.
-
Create a scene description file (in JSON format) or use one of the provided examples.
-
Run the renderer using the command line:
./tungsten scene.json
For more detailed information on scene setup and rendering options, refer to the documentation in the repository's wiki.
Competitor Comparisons
Source code for pbrt, the renderer described in the third edition of "Physically Based Rendering: From Theory To Implementation", by Matt Pharr, Wenzel Jakob, and Greg Humphreys.
Pros of pbrt-v3
- More comprehensive documentation and educational resources
- Wider industry adoption and community support
- Extensive scene description language for complex scene setup
Cons of pbrt-v3
- Slower rendering performance for some scenes
- Less focus on real-time rendering capabilities
- Steeper learning curve for beginners
Code Comparison
Tungsten scene setup:
Scene scene;
scene.addPrimitive(std::make_shared<Sphere>(
Vec3f(0.0f, 0.0f, 0.0f),
1.0f,
std::make_shared<Lambert>(Vec3f(0.9f))
));
pbrt-v3 scene setup:
std::unique_ptr<Shape> sphere(new Sphere(Transform(), Transform(),
false, 1, -1, 1, 360));
std::shared_ptr<Material> material(new MatteMaterial(
std::make_shared<ConstantTexture<Spectrum>>(Spectrum(0.9))));
primitives.push_back(std::make_shared<GeometricPrimitive>(sphere, material));
Both Tungsten and pbrt-v3 are physically-based renderers, but they cater to different needs. Tungsten focuses on simplicity and performance, while pbrt-v3 offers a more comprehensive framework for research and education in computer graphics. The code comparison shows that Tungsten's API is generally more concise, while pbrt-v3 provides more flexibility in scene description and material definition.
Embree ray tracing kernels repository.
Pros of Embree
- Highly optimized for CPU ray tracing performance
- Supports a wide range of CPU architectures and instruction sets
- Extensive documentation and examples for integration
Cons of Embree
- Focused solely on ray tracing, lacking full rendering pipeline
- Steeper learning curve for integration into existing projects
- Less suitable for small-scale or hobby projects
Code Comparison
Tungsten (Scene setup):
Scene scene;
scene.addMesh(loadMesh("model.obj"));
scene.addLight(std::make_shared<PointLight>(Vec3f(0.0f, 5.0f, 0.0f), Vec3f(100.0f)));
Embree (Ray tracing setup):
RTCDevice device = rtcNewDevice(NULL);
RTCScene scene = rtcNewScene(device);
RTCGeometry geometry = rtcNewGeometry(device, RTC_GEOMETRY_TYPE_TRIANGLE);
rtcCommitGeometry(geometry);
rtcAttachGeometry(scene, geometry);
rtcCommitScene(scene);
Summary
Embree is a high-performance ray tracing kernel library, while Tungsten is a full-featured physically based renderer. Embree excels in raw ray tracing performance and CPU optimization, making it ideal for integration into larger rendering systems. Tungsten offers a more complete rendering solution out of the box, potentially easier for beginners or small projects, but may not match Embree's raw performance in specific ray tracing tasks.
LuxCore source repository
Pros of LuxCore
- More comprehensive feature set, including advanced rendering techniques like bidirectional path tracing and metropolis light transport
- Active development with regular updates and a larger community
- Better integration with popular 3D software like Blender
Cons of LuxCore
- Higher complexity and steeper learning curve
- Potentially slower render times for simple scenes due to more advanced algorithms
Code Comparison
LuxCore (C++):
Scene *scene = Scene::Create();
camera->Update(filmWidth, filmHeight, 0.f);
scene->SetCamera(camera);
scene->Parse(Properties("scene.scn"));
Tungsten (C++):
std::unique_ptr<Scene> scene = Scene::load(path, options);
scene->loadResources();
scene->prepareForRender();
Both projects use C++ for their core rendering engines, but LuxCore's API appears more modular and flexible, while Tungsten's approach is more straightforward for basic scene setup.
LuxCore offers a more feature-rich and actively developed rendering solution, suitable for complex projects and integration with existing 3D software. Tungsten, on the other hand, may be more approachable for beginners or those seeking a simpler, lightweight rendering solution.
Mitsuba 2: A Retargetable Forward and Inverse Renderer
Pros of Mitsuba2
- More extensive documentation and user guides
- Supports a wider range of rendering techniques and algorithms
- Better integration with Python for scripting and customization
Cons of Mitsuba2
- Steeper learning curve due to its more complex architecture
- Potentially slower rendering times for simple scenes compared to Tungsten
Code Comparison
Mitsuba2 scene definition (Python):
import mitsuba as mi
mi.set_variant('scalar_rgb')
scene = mi.load_file('scene.xml')
image = mi.render(scene)
mi.util.write_bitmap('output.png', image)
Tungsten scene definition (JSON):
{
"type": "scene",
"camera": { "type": "pinhole" },
"integrator": { "type": "path_tracer" },
"primitives": [
{ "type": "sphere", "radius": 1.0 }
]
}
Both renderers use different approaches for scene definition and rendering. Mitsuba2 leverages Python for scripting, while Tungsten uses JSON for scene description. Mitsuba2's approach offers more flexibility and programmability, while Tungsten's JSON format is simpler and more lightweight for basic scenes.
Universal Scene Description
Pros of OpenUSD
- Industry-standard format for 3D content creation and exchange
- Extensive documentation and community support
- Backed by major animation studios and software companies
Cons of OpenUSD
- Steeper learning curve due to its comprehensive nature
- Larger codebase and more complex architecture
- May be overkill for smaller projects or individual developers
Code Comparison
OpenUSD:
#include "pxr/usd/usd/stage.h"
#include "pxr/usd/usdGeom/sphere.h"
auto stage = pxr::UsdStage::CreateNew("sphere.usda");
auto spherePrim = pxr::UsdGeomSphere::Define(stage, "/mySphere");
spherePrim.CreateRadiusAttr().Set(2.0);
Tungsten:
#include "primitives/Sphere.hpp"
Sphere sphere(Vec3f(0.0f), 2.0f);
scene.addPrimitive(std::make_shared<Sphere>(sphere));
OpenUSD offers a more comprehensive approach to 3D scene description, while Tungsten focuses on physically-based rendering. OpenUSD is better suited for large-scale production pipelines, whereas Tungsten may be more appropriate for smaller rendering projects or research purposes. The code examples demonstrate the difference in complexity and abstraction level between the two libraries.
Advanced shading language for production GI renderers
Pros of OpenShadingLanguage
- Widely adopted in the film and VFX industry, with extensive community support
- Flexible and extensible shading language designed for production rendering
- Comprehensive documentation and learning resources available
Cons of OpenShadingLanguage
- Steeper learning curve compared to Tungsten's more straightforward approach
- Requires integration with a rendering system, while Tungsten is a standalone renderer
- More complex setup and configuration process
Code Comparison
OpenShadingLanguage:
shader example(
color Diffuse_Color = color(0.8),
output closure color BSDF = diffuse(N)
)
{
BSDF = Diffuse_Color * diffuse(N);
}
Tungsten:
class DiffuseBsdf : public Bsdf
{
public:
virtual Vec3f eval(const SurfaceScatterEvent &event) const override
{
return _albedo*INV_PI*std::abs(event.wi.z());
}
};
OpenShadingLanguage offers a more specialized shading language syntax, while Tungsten uses C++ for material definitions, reflecting their different approaches to shading and rendering.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
The Tungsten Renderer
About
Tungsten is a physically based renderer originally written for the yearly renderer competition at ETH. It simulates full light transport through arbitrary geometry based on unbiased integration of the rendering equation. To do this, Tungsten supports various light transport algorithms such as bidirectional path tracing, progressive photon mapping, primary sample space metropolis light transport and more.
Tungsten is written in C++11 and makes use of Intel's high-performance geometry intersection library embree. Tungsten takes full advantage of multicore systems and tries to offer good performance through frequent benchmarking and optimization. At least SSE3 support is required to run the renderer.
Documentation
Documentation is planned, but currently unavailable (sorry!). A lengthy overview of features is available in the final project report written as part of the submission for the rendering competition, although that document may be outdated.
A small selection of example scenes can be found in data/example-scenes
. There is also a material test scene found in data/materialtest
, which contains the Tungsten material test ball that you can use to test different materials and lighting setups..
License
To give developers as much freedom as is reasonable, Tungsten is distributed under the libpng/zlib license. This allows you to modify, redistribute and sell all or parts of the code without attribution.
Note that Tungsten includes several third-party libraries in the src/thirdparty
folder that come with their own licenses. Please see the LICENSE.txt
file for more information.
Compilation
Windows + MinGW
To build using MinGW, you will need a recent CMake + gcc version. CMake binary distributions are available here. I recommend using MinGW-w64 available here.
In the root folder of the repo, use these commands in an MSYS shell to build:
./setup_builds.sh
cd builds/release
make
The binaries will be placed in the build/release
directory after buiding.
Optionally, you can install the Qt framework to build the scene editor utility. If Qt is not detected during setup, the scene editor will not be built (you will still be able to use the renderer).
Windows + MSVC
To build using MSVC, you will need a recent CMake version and MSVC 2013. CMake binary distributions are available here.
After installing CMake, double click the setup_builds.bat
file. The MSVC project will be created in the folder vstudio
. Open the vstudio/Tungsten.sln
solution and press F7 to build.
Linux
Building on Linux works just like building on MINGW.
Usage
The core renderer can be invoked using
tungsten scene.json
You can also queue up multiple scenes using
tungsten scene1.json scene2.json scene3.json
and so forth. All renderer parameters, including output files, are specified in the json file.
You can test your local build by rendering the material test scene in data/materialtest/materialtest.json
.
You can also use
tungsten --help
for more information.
Code structure
src/core/
contains all the code for primitive intersection, materials, sampling, integration and so forth. It is the beefy part of the renderer and the place to start if you're interested in studying the code.
src/thirdparty
contains all the libraries used in the project. They are included in the repository, since most of them are either tiny single-file libraries or, in the case of embree, had to be modified to work with the renderer.
src/tungsten
contains the rendering application itself, which is just a small command line interface to the core rendering code.
All other folders in src
are small utilities described below.
Additional utilities
Apart from the core renderer, Tungsten also comes with several tools to make content creation easier.
tungsten_server
This is a standalone version of the renderer that comes with a built-in HTTP status server.
It will serve the following files:
/render
: The current framebuffer (possibly in an incomplete state)./status
: A JSON string containing information about the current render status./log
: A text version of the render log.
Use
tungsten_server --help
for more information.
scenemanip
scenemanip
comes with a range of tools to manipulate scene files, among others the capability to package scenes and all references resources (textures, meshes, etc.) into a zip archive.
Use
scenemanip --help
for more information.
hdrmanip
hdrmanip
comes with a few useful tools for manipulating HDR output files produced by the renderer. Where available, we recommend using established image manipulation tools, but where HDR support is sparsely available, this tool can be useful.
To convert an HDR image to low dynamic range, use
hdrmanip -o output.png input.exr
You can also specify the tonemapping operator to be applied when converting. For example, to use a filmic tonemap, use
hdrmanip --tonemap filmic -o output.png input.exr
To adjust the exposure of an HDR file, you can use
hdrmanip --exposure -1.0 -o output.exr input.exr
If you don't specify an output file, the tool will overwrite the input file. You can also modify several input files at once. For example, you can use
hdrmanip --exposure -1.0 input1.exr input2.exr input3.exr
to adjust the exposure of several files at once.
If you don't want to overwrite the input files, you can specify an output directory with -o
hdrmanip -o outputdir --exposure -1.0 input1.exr input2.exr input3.exr
When specifying multiple files, -o
is interpreted as an output directory, and its file extension is ignored. If you want to convert multiple input files to a different file format or even low dynamic range, you can use --file-type
hdrmanip --file-type png input1.exr input2.exr input3.exr
Finally, hdrmanip
also supports merging multiple HDR files together. This is useful when you split up a render across several machines and want to average the outputs to get a less noisy image. You can use --merge
for this
hdrmanip --merge -o output.exr input1.exr input2.exr input3.exr
Of course, you can also adjust the exposure and convert to low dynamic range while merging, all in one step.
Use
hdrmanip --help
for more information.
obj2json
The command
obj2json srcFile.obj dstFile.json
will parse the Wavefront OBJ srcFile.obj
, including object hierarchy and materials, and create a scene file dstFile.json
reproducing hierarchy and material assignments.
In addition, meshes in the OBJ file will be automatically converted and saved to Tungsten's native *.wo3
mesh format, which significantly reduces loading time for large meshes. This may create a large number of new files - consider pointing the dstFile.json
path into an empty subfolder to avoid file clutter.
json2xml
The command
json2xml srcFile.json dstFile.xml
will parse the scene file srcFile.json
and convert it to an XML scene description compatible with the Mitsuba renderer. All *.wo3
files will be converted to Mitsuba compatible OBJs, which may create a large number of new files - consider putting dstFile.xml
into an empty subfolder to avoid file clutter.
Note that this tool does not experience heavy testing and does not support all features of Tungsten, so it may not always work as expected.
editor
This is a minimalist scene editor written in Qt and OpenGL. It supports camera setup, manipulating transforms, compositing scenes and a few more features that I found useful.
It is usable, but a few crucial features are currently missing from it (including documentation). The code is neither exceptionally clean nor stable, so use at your own risk.
Top Related Projects
Source code for pbrt, the renderer described in the third edition of "Physically Based Rendering: From Theory To Implementation", by Matt Pharr, Wenzel Jakob, and Greg Humphreys.
Embree ray tracing kernels repository.
LuxCore source repository
Mitsuba 2: A Retargetable Forward and Inverse Renderer
Universal Scene Description
Advanced shading language for production GI renderers
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot