# How to Convert Scenes from Blender Cycles, Tungsten, or Other Renderers Using LuisaRender

> Easily convert Blender Cycles, Tungsten, or other renderer scenes to LuisaRender's native .luisa format using dedicated Python tools. Streamline your workflow today.

- Repository: [LuisaGroup/luisarender](https://github.com/luisagroup/luisarender)
- Tags: how-to-guide
- Published: 2026-03-06

---

**LuisaRender provides dedicated Python converters in the `tools/` directory that translate Tungsten JSON, LuxRender `.scn`, and glTF files into the renderer's native `.luisa` scene description format.**

To bring assets created in external renderers into LuisaRender, you use a pipeline of conversion utilities that parse source scene formats and emit the renderer's text-based DSL. The `luisagroup/luisarender` repository ships with purpose-built tools for Blender Cycles (via Tungsten), LuxRender, and glTF, allowing you to convert scenes from Blender Cycles, Tungsten, or other renderers using LuisaRender's extensible toolchain.

## Understanding LuisaRender's Scene Conversion Pipeline

LuisaRender consumes a custom scene description language compiled at runtime. The conversion process follows three distinct steps: parsing the source JSON or text format, translating material, geometry, camera, and lighting definitions into LuisaRender equivalents (such as `Surface`, `Shape`, and `Camera` blocks), and emitting a final `.luisa` file consumable by `luisa-render-cli`.

### Supported Input Formats and Converter Tools

The repository provides three primary conversion paths located in the `tools/` and `src/apps/` directories:

| Utility | Input format | Output format | Entry point |
|---------|-------------|---------------|-------------|
| [`tungsten2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tungsten2luisa.py) | Tungsten JSON (from Blender Cycles) | `.luisa` scene | `python tools/tungsten2luisa.py <scene>.json <spp>` |
| [`lux2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/lux2luisa.py) | LuxRender `.scn` | `.luisa` scene | `python tools/lux2luisa.py <scene>.scn` |
| [`export.cpp`](https://github.com/luisagroup/luisarender/blob/main/export.cpp) (glTF) | glTF (`.gltf` / `.glb`) | LuisaRender JSON | `luisa-render-export <file>.gltf` |

## Converting Blender Cycles and Tungsten Scenes

Blender Cycles scenes are most commonly converted via the Tungsten exporter, which produces a JSON file compatible with [`tungsten2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tungsten2luisa.py).

### Step 1: Export Tungsten JSON from Blender

Install the Tungsten exporter add-on in Blender and export your scene as a Tungsten JSON file (e.g., [`my_scene.json`](https://github.com/luisagroup/luisarender/blob/main/my_scene.json)). This file contains `bsdfs`, `primitives`, and `camera` fields that map directly to LuisaRender's scene graph.

### Step 2: Run tungsten2luisa.py

Execute the converter from the repository root, specifying the input file and desired samples-per-pixel:

```bash
python tools/tungsten2luisa.py path/to/my_scene.json 1024

```

The script located at [`tools/tungsten2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tools/tungsten2luisa.py) parses the JSON, invokes `tungsten2luisa(file_name, spp)`, and writes `my_scene.luisa` in the same directory.

### Step 3: Render the Converted Scene

Run the LuisaRender CLI with your preferred backend:

```bash
build/bin/luisa-render-cli -b cuda my_scene.luisa

```

Replace `cuda` with `cpu`, `dx`, or `metal` depending on your build configuration.

## Converting LuxRender and glTF Scenes

For scenes originating from LuxRender or modern glTF assets, LuisaRender provides alternative conversion paths.

### LuxRender .scn Conversion

The [`tools/lux2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tools/lux2luisa.py) script handles LuxRender's custom text format. It internally rewrites the `.scn` file into a temporary JSON structure before applying the same conversion pipeline used for Tungsten:

```bash
python tools/lux2luisa.py scene.scn

```

This produces `scene.luisa`, ready for rendering.

### glTF Export Workflow

For glTF files, build the export utility from [`src/apps/export.cpp`](https://github.com/luisagroup/luisarender/blob/main/src/apps/export.cpp):

```bash
cmake -S . -B build -D LUISA_RENDER_EXPORT=ON
cmake --build build

```

Convert the glTF asset to LuisaRender JSON:

```bash
build/bin/luisa-render-export model.gltf

```

This emits a JSON scene description that `luisa-render-cli` can consume directly.

## Architecture of the Tungsten Converter

Understanding the internal structure of [`tungsten2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tungsten2luisa.py) helps troubleshoot conversion errors and extend support for new material types.

### Core Conversion Flow in tungsten2luisa.py

The main entry point `tungsten2luisa(file_name, spp)` orchestrates the translation:

```python
def tungsten2luisa(file_name: str, spp: int):
    # Load source JSON

    with open(file_name) as file:
        scene = json.load(file)
    
    materials = scene["bsdfs"]
    shapes = scene["primitives"]
    camera = scene["camera"]
    
    # Write LuisaRender DSL

    with open(f"{file_name[:-5]}.luisa", "w") as file:
        convert_materials(file, materials)
        convert_shapes(file, shapes, materials)
        convert_camera(file, camera, spp)
        write_render(file, shapes)

```

### Material Translation Logic

The `convert_material` function dispatches based on Tungsten material types (`plastic`, `dielectric`, `mirror`, `conductor`):

```python
def convert_material(out_file, material: dict, alpha=""):
    impl = material["type"]
    if impl == "plastic" or impl == "rough_plastic":
        convert_plastic_material(out_file, material, alpha)
    elif impl == "dielectric" or impl == "rough_dielectric":
        convert_glass_material(out_file, material, alpha)
    # Additional material types...

```

For example, `convert_plastic_material` emits a `Surface` block with `Plastic` material parameters:

```python
def convert_plastic_material(out_file, material: dict, alpha=""):
    name = material["name"]
    roughness = material.get("roughness", 1e-6)
    ior = material["ior"]
    color = material["albedo"]
    print(f'''
Surface mat_{name} : Plastic {{
  Kd : {convert_albedo_texture(color)}
  eta : Constant {{ v {{ {ior} }} }}
  roughness : Constant {{ v {{ {convert_roughness(roughness)} }} }}
}}''', file=out_file)

```

### Geometry and Camera Processing

The `convert_shape` function builds transformation matrices from Tungsten's `position`, `rotation`, and `scale` parameters using `convert_transform`, then emits `Shape` blocks:

```python
def convert_transform(S, R, T):
    # Builds 4×4 matrix for LuisaRender's Matrix block

    # ...

```

Camera conversion in `convert_camera` creates a `Pinhole` camera with the specified resolution, FOV, and view matrix:

```python
def convert_camera(out_file, camera: dict, spp):
    resolution = glm.vec2(camera["resolution"])
    fov = glm.radians(camera["fov"])
    # ... emits Pinhole camera block with View transform

```

## Troubleshooting Common Conversion Issues

When converting scenes from Blender Cycles, Tungsten, or other renderers using LuisaRender's tools, several issues commonly arise:

- **Missing textures**: If the converter prints an `Image` block referencing a non-existent file, ensure all texture files from the original scene are copied to the working directory or adjust paths in the generated `.luisa` file.

- **Unsupported material types**: When `convert_material` encounters an unmapped type like `microfacet` or `subsurface`, it falls through to an unsupported branch. Extend the converter by adding a new material handler in [`tools/tungsten2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tools/tungsten2luisa.py).

- **Incorrect camera FOV**: The conversion computes horizontal FOV from Tungsten's vertical FOV specification. If the rendered image appears cropped or stretched, manually edit the `Camera` block's `fov` parameter or modify `convert_camera` to use `camera["fov_vertical"]` directly.

- **Scale inversion on primitives**: Quads and cubes may appear flipped due to hard-coded `-90°` rotations in `convert_shape`. Override the transform matrix in the output file or adjust the rotation logic for specific primitive types.

## Summary

- LuisaRender provides **dedicated conversion utilities** in [`tools/tungsten2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tools/tungsten2luisa.py), [`tools/lux2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tools/lux2luisa.py), and [`src/apps/export.cpp`](https://github.com/luisagroup/luisarender/blob/main/src/apps/export.cpp) to import scenes from Blender Cycles (via Tungsten), LuxRender, and glTF formats.

- The conversion pipeline **parses source JSON or text formats**, translates materials into `Surface` blocks, geometry into `Shape` blocks with transformation matrices, and cameras into `Pinhole` definitions, ultimately emitting a `.luisa` scene file.

- **Key functions** like `convert_material`, `convert_shape`, and `convert_camera` in [`tungsten2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tungsten2luisa.py) handle the semantic mapping between Tungsten's material types (plastic, dielectric, mirror) and LuisaRender's DSL.

- All converter scripts are located in the `tools/` directory, while the glTF exporter resides in [`src/apps/export.cpp`](https://github.com/luisagroup/luisarender/blob/main/src/apps/export.cpp), producing JSON output compatible with `luisa-render-cli`.

## Frequently Asked Questions

### What file formats can I convert to LuisaRender?

LuisaRender supports conversion from **Tungsten JSON** (exported from Blender Cycles), **LuxRender `.scn`**, and **glTF 2.0** (`.gltf` or `.glb`). The Tungsten and LuxRender converters produce `.luisa` files directly, while the glTF tool emits a JSON scene description that the CLI can parse.

### How do I handle missing textures after conversion?

If `luisa-render-cli` reports missing image files, verify that all texture assets referenced in the original scene are present in the working directory. The converters preserve original file paths in `Image` blocks; you can either copy the textures to match these paths or manually edit the generated `.luisa` file to update the texture references.

### Can I convert scenes directly from Blender without using Tungsten?

Currently, LuisaRender does not ship with a direct Blender Cycles Python exporter. You must first export from Blender using the **Tungsten exporter add-on**, which generates the JSON format that [`tools/tungsten2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tools/tungsten2luisa.py) expects. For glTF workflows, you can export glTF directly from Blender and use `luisa-render-export` instead.

### Where are the converter scripts located in the repository?

All Python conversion utilities reside in the `tools/` directory at the repository root: [`tools/tungsten2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tools/tungsten2luisa.py) handles Tungsten/Blender Cycles scenes, while [`tools/lux2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tools/lux2luisa.py) processes LuxRender files. The glTF converter is implemented as a compiled C++ application in [`src/apps/export.cpp`](https://github.com/luisagroup/luisarender/blob/main/src/apps/export.cpp), producing the `luisa-render-export` binary when built with the `LUISA_RENDER_EXPORT` CMake option enabled.