Convert Figma logo to code with AI

tunabrain logotungsten

High performance physically based renderer in C++11

1,715
165
1,715
17

Top Related Projects

4,879

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.

2,351

Embree ray tracing kernels repository.

1,149

LuxCore source repository

Mitsuba 2: A Retargetable Forward and Inverse Renderer

5,987

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:

  1. Clone the repository:

    git clone https://github.com/tunabrain/tungsten.git
    
  2. Build the project following the instructions in the README.md file for your specific platform.

  3. Create a scene description file (in JSON format) or use one of the provided examples.

  4. 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

4,879

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.

2,351

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.

1,149

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.

5,987

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 Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Tungsten Sample Render

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.