opendefocus

Crates.ioopendefocus
lib.rsopendefocus
version0.1.9
created_at2025-12-25 01:01:05.070981+00
updated_at2026-01-23 09:36:33.47091+00
descriptionAn advanced open-source convolution library for image post-processing
homepagehttps://opendefocus.codeberg.page
repositoryhttps://codeberg.org/gillesvink/opendefocus
max_upload_size
id2004063
size335,796
Gilles Vink (gillesvink)

documentation

https://docs.rs/opendefocus/

README


OpenDefocus

Logo thanks to Welmoed Boersma!

An advanced open-source convolution library for image post-processing

License Version Gitea Issues Tests Nuke Versions


DonateFeaturesDownloadDocumentationIssuesChangelog


Features

User

  • Entirely free! (but please consider donating!)

  • Native integration for camera data to match convolution to real world camera data.

  • GPU accelerated (Vulkan/Metal)

  • Both simple 2D defocus as well as depth based (1/Z, real or direct math based)

  • Custom quality option, for quick renders with less precision or heavier higher precision renders.

  • Lots of non uniform artifacts:

  • Easy to use bokeh creator or use your own image

  • Foundry Nuke native plugin (through CXX FFI). Basically a wrapper around the Rust crate (serves as a good developer reference on how to integrate it in other DCC's or applications!).

Technical

  • Process each pixel coordinate and channel on the image with a custom filter kernel. For a simple RGBA 1920x1080 image, that is at least 8.294.400 custom kernels!
  • 100% written in pure Rust (stable channel) without external library dependencies.
  • Same algorithm on GPU and CPU with same source code (thanks to Rust-GPU spirv compiler).
  • Easy to use and open API to hook into your own application or DCC.
  • Lots of control over the output, take a look at all options available.

Examples

Simple convolution

use anyhow::Result;
use image::{DynamicImage, Rgba32FImage};
use image_ndarray::prelude::ImageArray;
use opendefocus::OpenDefocusRenderer;
use opendefocus::datamodel::Settings;

#[tokio::main]
async fn main() -> Result<()> {
    let mut settings = Settings::default();
    // set the defocus size in pixel radius, you can change whatever you want
    settings.defocus.circle_of_confusion.size = 25.0;

    // initialize a new renderer, this contains the runner instance (wgpu for example)
    // its fine to throw away if you only use one image, else its good to reuse to prevent initializing all the time
    let renderer = OpenDefocusRenderer::new(true, &mut settings).await?;

    // load an example image
    let image = image::load_from_memory(include_bytes!("../../examples/simple/toad.png"))?.to_rgba32f();
    let mut array = image.to_ndarray();

    // then here we actually render
    renderer
        .render(settings, array.view_mut(), None, None)
        .await?;

    // just some loading to the image crate once again after rendering and storing it
    let image: Rgba32FImage = Rgba32FImage::from_ndarray(array)?;
    let image = DynamicImage::from(image).to_rgba8();
    image.save("./result.png")?;
    Ok(())
}

Structure

The project has multiple crates defined at the crates directory:

Crate Name Description
opendefocus The actual public library itself. The main crate.
opendefocus-datastructure Datastructure bindings to protobuf and implementations.
opendefocus-kernel Kernel (no-std) source code. Runs on both GPU and CPU.
opendefocus-nuke Nuke specific source code. Includes both C++ and Rust.
opendefocus-shared Code that can be used by both the kernel and main opendefocus crate.
spirv-cli-build Wrapper around the SPIR-V from Rust-GPU to compile using nightly for opendefocus-kernel.

Besides that, these crates have been located outside of this repository as they have a bigger scope than just convolution:

Crate Name Description
circle-of-confusion Circle of confusion algorithm to calculate the actual circle of confusion from real world camera data or create a nice depth falloff based on selection
bokeh-creator Filter kernel generation library
inpaint Telea inpainting algorithm in pure Rust

Build

You need to have Rust installed: Both the stable version (1.92+) as well as the nightly version listed in spirv-cli-build/rust-toolchain.toml

That's it basically.

All compilation is handled through xtasks. Call cargo xtask --help for more information.

Nuke

For Nuke building you need additional dependencies. As the linking process needs to have the DDImage library and headers installed, the xtask fetches these sources automatically.

For extracting of the archives, msiextract needs to be installed for Windows installs.

In theory C++11 is supported so it would work with Nuke 10 and higher, but that is not tested.

When compiling Nuke and fetching sources, to speed up downloading it is recommended to either use a machine in the USA or use a VPN. Because its an AWS bucket in the US-East region which does not have geo-replication enabled.

Example to compile Nuke 15:

cargo xtask \
  --compile \
  --nuke-versions 15.1,15.2 \
  --target-platform linux \
  --output-to-package

This will create the package with Linux compiled binaries in the package.

Now you are able to copy this folder to some other location, or add it to your NUKE_PATH and it should show up.

export NUKE_PATH=$(pwd)/package

# launch your nuke etc...
Commit count: 220

cargo fmt