# LuisaRender JSON Scene Description Format: A Complete Guide to Writing Custom Scenes

> Learn LuisaRender's JSON scene description format to define custom scenes for the renderer. Explore hierarchical objects for render settings, cameras, materials, and geometry.

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

---

**LuisaRender defines its own hierarchical JSON-based scene description language where top-level objects like `render`, `camera`, `bsdfs`, and `primitives` define global settings, materials, and geometry that the renderer consumes directly via the `luisa-render-cli` command-line interface.**

The `luisagroup/luisarender` repository implements a GPU-accelerated physically based renderer that reads scene descriptions directly from structured JSON files. Understanding the **LuisaRender JSON scene description format** allows you to author custom scenes from scratch or convert existing assets from other rendering systems using the provided toolchain.

## Core Structure of Scene Files

A valid scene file is a single JSON document containing hierarchical objects that describe every aspect of the rendering pipeline. All keys are optional unless required by a specific renderer component, and references between objects use string names rather than embedded definitions.

### Top-Level Scene Objects

The format recognizes several well-known top-level keys that organize scene data:

- **`render`** – Global rendering settings including the integrator type, resolution, sample count, and tonemapping configuration.
- **`camera`** – Camera description defining position, orientation, lens parameters, and projection type.
- **`bsdfs`** or **`materials`** – Dictionaries of material definitions (BSDFs) referenced by name from geometry primitives.
- **`primitives`** or **`objects`** – Geometry instances including meshes, spheres, and triangles with associated transforms and material bindings.
- **`lights`** – Explicit light sources defined as specialized primitives or emissive materials.
- **`textures`** – Texture assets referenced by materials, supporting image files and procedural generation.
- **`environment`** – Optional HDR environment map for image-based lighting.

References function by name: a primitive’s `material` field contains the string name of an entry in the `bsdfs` object, while texture references point to keys in the `textures` dictionary.

## Writing Your First Custom Scene File

Below is a minimal, fully-functional scene that renders a single matte sphere under a point light. This example demonstrates the hierarchical structure and name-based referencing system:

```json
{
  "render": {
    "integrator": "path",
    "resolution": [800, 600],
    "samples": 256,
    "tonemap": { "type": "aces", "exposure": -0.5 }
  },

  "camera": {
    "type": "perspective",
    "position": [0, 1, 5],
    "target": [0, 0, 0],
    "up": [0, 1, 0],
    "fov": 45
  },

  "bsdfs": {
    "mat_matte": {
      "type": "lambertian",
      "albedo": [0.8, 0.2, 0.2]
    }
  },

  "primitives": {
    "sphere": {
      "type": "sphere",
      "center": [0, 0, 0],
      "radius": 1.0,
      "material": "mat_matte"
    }
  },

  "lights": {
    "point_light": {
      "type": "point",
      "position": [2, 4, 3],
      "intensity": 10.0,
      "color": [1, 1, 1]
    }
  }
}

```

The `render` block configures a path integrator with 256 samples and ACES tonemapping. The `camera` establishes a perspective projection from position `[0, 1, 5]` looking toward the origin. Materials defined in `bsdfs` are bound to primitives via the `material` string field, creating the association between geometry and shading.

## Converting Existing Scenes to LuisaRender Format

Rather than authoring JSON manually, you can convert scenes from other renderers using the conversion utilities in the `tools` directory. These scripts parse foreign scene formats and output correctly structured [`scene.json`](https://github.com/luisagroup/luisarender/blob/main/scene.json) files using Python’s `json.dump` serialization.

### Conversion Utilities

- **[`tools/lux2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tools/lux2luisa.py)** – Reads LuxRender scene files and builds the corresponding JSON structure.
- **[`tools/glslpt2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tools/glslpt2luisa.py)** – Converts GLSL-PathTracer scenes into LuisaRender format.
- **[`tools/tungsten2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tools/tungsten2luisa.py)** – Translates Tungsten renderer scenes to the JSON description format.

For glTF-based workflows, [`src/apps/export.cpp`](https://github.com/luisagroup/luisarender/blob/main/src/apps/export.cpp) implements a core exporter that writes [`lr_exported_scene.json`](https://github.com/luisagroup/luisarender/blob/main/lr_exported_scene.json) from glTF inputs, handling mesh data, materials, and camera transformations.

## Running the Renderer

Once your JSON scene file is complete, execute the renderer using the CLI command documented in [`BUILD.md`](https://github.com/luisagroup/luisarender/blob/main/BUILD.md):

```bash
<build-folder>/bin/luisa-render-cli -b cuda scene.json

```

The `-b` flag specifies the GPU backend (CUDA, Metal, DX, or CPU). The renderer validates the JSON structure, resolves all name-based references, and begins path tracing according to the parameters defined in the `render` object.

## Summary

- **Hierarchical JSON structure**: Scene files organize data into top-level objects (`render`, `camera`, `bsdfs`, `primitives`, `lights`, `textures`, `environment`).
- **Name-based referencing**: Materials and textures are referenced by string keys, allowing reusable definitions across multiple primitives.
- **Conversion ecosystem**: Tools like [`tools/lux2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tools/lux2luisa.py), [`tools/glslpt2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tools/glslpt2luisa.py), and [`tools/tungsten2luisa.py`](https://github.com/luisagroup/luisarender/blob/main/tools/tungsten2luisa.py) automate migration from other renderers.
- **Direct CLI consumption**: The `luisa-render-cli` binary reads JSON scenes directly without intermediate compilation steps.

## Frequently Asked Questions

### What are the required fields in a LuisaRender JSON scene file?

Only the `render` and `camera` top-level objects are strictly necessary for the renderer to execute. The `render` object must specify at minimum an `integrator` type and `resolution`, while `camera` requires `position`, `target`, and projection parameters. Missing sections for materials, lights, or environments are silently ignored, though the resulting render may be black or unlit.

### How do I reference materials and textures in scene primitives?

Use string names to establish relationships between objects. In the `primitives` section, set the `material` field to the name of a BSDF defined in the `bsdfs` object. Similarly, texture references within materials point to keys in the `textures` dictionary. This decoupled approach allows multiple primitives to share identical material definitions.

### Can I convert scenes from other renderers to LuisaRender format?

Yes. The repository includes Python conversion scripts in the `tools` directory that handle LuxRender, GLSL-PathTracer, and Tungsten scene formats. These utilities parse the source format and emit valid JSON through `json.dump` calls. For glTF assets, the [`src/apps/export.cpp`](https://github.com/luisagroup/luisarender/blob/main/src/apps/export.cpp) application generates compatible scene files with embedded geometry and material mappings.

### Where does the renderer look for texture and mesh files referenced in the JSON?

The renderer resolves relative paths from the working directory where `luisa-render-cli` is executed. The `textures` object typically contains `filename` fields pointing to HDR or PNG images, while primitives may reference external mesh files depending on the shape type. Ensure all asset paths are correct relative to the execution context or use absolute paths in the JSON document.