# How the invert_depth Parameter Alters 3D Relief Visualization in MCP 3D Relief

> Discover how the invert_depth parameter in MCP 3D Relief flips grayscale to depth, inverting topography for unique 3D relief visualizations. Learn to control peaks and valleys.

- Repository: [bigchx/mcp_3d_relief](https://github.com/bigchx/mcp_3d_relief)
- Tags: how-to-guide
- Published: 2026-02-26

---

**The `invert_depth` flag flips the grayscale-to-depth conversion so that bright pixels become low points (valleys) and dark pixels become high points (peaks), inverting the topography of the generated 3D relief.**

The `invert_depth` parameter in the **bigchx/mcp_3d_relief** repository controls whether bright image regions produce raised ridges or recessed valleys in the final STL model. This boolean flag directly manipulates the depth map generation logic in [`relief.py`](https://github.com/bigchx/mcp_3d_relief/blob/main/relief.py) to invert the height mapping before 3D mesh construction begins, as documented in the README at lines 74-75.

## What invert_depth Does to the Depth Map

When generating a 3D relief from a 2D image, the code first converts the input to a luminance array (`gray`) representing elevation values. By default, brighter pixels (values near 255) translate to higher Z-heights in the final model. When `invert_depth=True`, the algorithm subtracts each pixel value from 255, reversing this relationship according to the source code implementation.

In [`relief.py`](https://github.com/bigchx/mcp_3d_relief/blob/main/relief.py) at lines 42-44, the inversion occurs during standard depth-map generation:

```python
if invert_depth:
    gray = 255 - gray               # ← invert depth

```

This single operation transforms the height field so that dark areas (originally low) become peaks and bright areas become troughs.

## How Depth Inversion Works in Different Pipeline Paths

The MCP 3D Relief tool provides two pathways for depth map creation, and `invert_depth` affects both.

### Standard Depth Map Generation

In the default workflow, the input image undergoes processing to produce a normalized grayscale depth map. The inversion happens immediately after grayscale conversion but before the depth map is written to disk, ensuring the saved PNG reflects the inverted values.

### Skip-Depth Path

When using the `--skip_depth` flag (or `skip_depth=True` programmatically), the tool bypasses custom depth processing and uses a blurred version of the original image as the height map. Here, inversion applies to the resized image at lines 27-29 in [`relief.py`](https://github.com/bigchx/mcp_3d_relief/blob/main/relief.py):

```python
if invert_depth:
    depth_map = 255 - depth_map      # ← invert depth

```

Both paths produce a depth map where pixel values are subsequently scaled to physical heights.

## Impact on Final STL Geometry

The inverted depth map directly determines vertex heights in the generated STL file. The mesh construction logic in [`relief.py`](https://github.com/bigchx/mcp_3d_relief/blob/main/relief.py) scales normalized depth values (0-255) to the specified `model_thickness`:

```python
vertices[y, x] = (depth_map[y, x] / 255.0) * model_thickness

```

Because this calculation uses the potentially inverted `depth_map`, the parameter determines the physical interpretation of image brightness:

- **`invert_depth=False` (default)**: Bright areas print as raised relief (ridges).
- **`invert_depth=True`**: Bright areas print as recessed relief (valleys).

## Using invert_depth in Practice

You can enable depth inversion through the command line, REST API, or direct Python calls.

**Command-line usage:**

```bash

# Normal relief (bright = high)

python relief.py path/to/photo.jpg

# Inverted relief (bright = low)

python relief.py path/to/photo.jpg --invert_depth

```

**FastAPI request via the built-in server:**

```python
import requests

payload = {
    "image_path": "https://example.com/photo.jpg",
    "model_width": 60,
    "model_thickness": 6,
    "base_thickness": 3,
    "skip_depth": False,
    "invert_depth": True,        # ← flip the relief

    "detail_level": 1.2,
}
response = requests.post("http://localhost:8000/convert", data=payload)
print(response.json())

```

The response contains absolute paths to the generated `depth_map_path` and `stl_path`.

**Programmatic Python call:**

```python
import asyncio
from relief import relief

async def make_relief():
    result = await relief(
        input_image_path="local_image.png",
        invert_depth=True,        # ← enable inversion

        model_width=80,
        model_thickness=10,
    )
    print(result)

asyncio.run(make_relief())

```

## Summary

- The `invert_depth` parameter in `bigchx/mcp_3d_relief` inverts the grayscale-to-height mapping by executing `255 - pixel_value` on the depth map.
- In [`relief.py`](https://github.com/bigchx/mcp_3d_relief/blob/main/relief.py), this operation occurs at lines 42-44 during standard processing and lines 27-29 when using `--skip_depth`.
- When enabled, bright image regions become valleys (low points) and dark regions become peaks (high points) in the final STL.
- The inversion affects both the intermediate PNG depth map and the resulting 3D mesh vertices, which are calculated as `(depth_map[y, x] / 255.0) * model_thickness`.
- You can activate this feature via CLI flag, FastAPI payload in [`server.py`](https://github.com/bigchx/mcp_3d_relief/blob/main/server.py), or the Python `relief()` function.

## Frequently Asked Questions

### What is the default behavior of invert_depth in MCP 3D Relief?

By default, `invert_depth` is set to `False`, meaning bright pixels in the source image generate high points (ridges) in the 3D model and dark pixels generate low points. This follows the conventional interpretation where lighter colors represent elevation.

### Does invert_depth affect the depth map PNG file or just the STL?

The parameter affects both outputs. In [`relief.py`](https://github.com/bigchx/mcp_3d_relief/blob/main/relief.py), the inversion is applied to the depth array before it is saved as a PNG file, so the written depth map reflects the inverted values. The STL generation subsequently uses this same inverted array to calculate vertex heights.

### Can I use invert_depth with the --skip_depth flag?

Yes. When `--skip_depth` is enabled, the code uses a blurred version of the original image as the depth map and applies the inversion at lines 27-29 in [`relief.py`](https://github.com/bigchx/mcp_3d_relief/blob/main/relief.py) via `depth_map = 255 - depth_map`. This ensures consistent behavior regardless of which depth-generation path you choose.

### How does invert_depth interact with model_thickness?

The `invert_depth` parameter changes which pixels are considered high or low, but `model_thickness` still determines the total vertical scale. After inversion, the depth map values (now inverted) are normalized to 0.0-1.0 and multiplied by `model_thickness` to set the final vertex heights in the STL file.