Skip to content

Volume rendering, implemented in Unity3D. Want to support the project? Donate a small sum to Save The Children(https://www.savethechildren.net/) or another charity, and send me a message, and I will be greatly motivated!

License

Notifications You must be signed in to change notification settings

mlavik1/UnityVolumeRendering

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

349 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

UnityVolumeRendering

A volume renderer, made in Unity3D. I have written a tutorial explaining the basic implementation. Have any questions? Create an issue or contact me on Mastodon or 微信: mati31415.

I also have a tutorial video that shows how to use the project

NEWS: This plugin is now being ported to Godot Engine, thanks to Riccardo Lops: https://github.com/riccardolops/GodotVolumetricRendering

alt tag

Thanks to JetBrains for providing open source license for Rider - the best C# IDE :)

Documentation
See full documentation here

Table of contents

This Readme contains a quick introduction to the library. For more info, see the complete documentation.

Getting started

For a quick demo, simply clone this repository and open the sample project in Unity.

To use this plugin in your own project, see Installation.

Installation

This project is distributed as a Unity Package Manager (UPM) package.

Via git URL (recommended):

Open the Package Manager window in Unity, click the "+" button, select "Add package from git URL..." and enter:

https://github.com/mlavik1/UnityVolumeRendering.git

To pin a specific version, append a tag:

https://github.com/mlavik1/UnityVolumeRendering.git#v1.0.0

Via manifest.json:

Add the following to your project's Packages/manifest.json:

"com.mlavik1.unityvolumerendering": "https://github.com/mlavik1/UnityVolumeRendering.git"

After installing, you can import the Basic Demo sample (scene + camera controller) and Sample Data (test datasets) from the Package Manager window.

As a submodule:

Add the repository as a git submodule, under "Packages".

Requirements

  • Unity 6 (6000.0) or newer

How to use sample scene

  • Install the package (see Installation)
  • In the Package Manager, find "Unity Volume Rendering", click the "Sampels" tab and import the "Basic Demo" and "Sample Data" samples
  • Open the imported "TestScene.unity"
  • Click "Volume Rendering" in the menu bar
  • Select "Load Raw dataset" (or something else, if you already have a dataset you want to import)
  • Pick the VisMale.raw file from the imported Sample Data
  • Click the "import"-button

Step-by-step instructions

1. Import model

Raw datasets:

In the menu bar, click "Volume Rendering" and "Load raw dataset"

Then select the dataset you wish to import..

In the next menu you can optionally set the import setting for the raw dataset. For the sample files you don't need to change anything.

DICOM:

To import a DICOM dataset, click "Volume Rendering" and "Load DICOM" and select the folder containing your DICOM files. The dataset must be of 3D nature, and contain several files - each being a slice along the Z axis.

2. Moving the model

You can move the model like any other GameObject. Simply select it in the scene view or scene hierarchy, and move/rotate it like normal.

3. Changing the visualisation

Select the model and find the "Volume Render Object" in the inspector.

Here you can change the "Render mode":

Example:

There are 3 render modes:

  • Direct Volume Rendering (using transfer functions)
  • Maximum Intensity Projection (shows the maximum density)
  • Isosurface Rendering

There are also some other settings that you can adjust:

  • "Enable lighting": Enable lighting calculations during volume rendering.
  • "Enable shadow volume": Expensive, but may look much better!
  • Enable early ray termination: Optimisation (you usually want this on). Requires the above setting to be disabled.
  • Enable cubic interpolation: Use cubic interpolation of the 3D volume texture and gradient texture.


Direct Volume Rendering

Direct volume rendering is the most standard rendering mode. It sends rays through the dataset, and uses "transfer functions" (1D or 2D) to determine the colour and opacity. Transfer functions map density (2D: also gradient magnitude) to a colour and opacity.

  • Modifying transfer functions: Click "Volume Rendering" in the menu bar and select "1D Transfer Function" or "2D Transfer Function"
    • 1D Transfer Function: X-axis represents density and Y-axis represents alpha (opaccity). Move the grey alpha knots to create a curve for opacity by density. Right-click to add new alpha knots. The bottom gradient-coloured panel maps colour to density. Right-click to add new knots and click on an existing colour knot to modify its colour.
    • 2D Transfer Function: X-axis represents density and Y-axis represents gradient magnitude. Click "add rectangle" to add a new rectangle-shape. Move the four sliders (bottom left) to modify size/position. Modify the two sliders to the right to change min/max alpha/opacity. Each rectangle can have one colour (see colour picker).

Isosurface Rendering

Isosurface rendering draws the first thing the ray hits, with a density higher than some threshold. You can set this threshold yourself, by selecting the object and changing the "Visible value range" in the inspector. These can also be used with direct volume rendering mode.

Importing DICOM and NRRD

If you're on Windows or Linux, I recommend enabling the SimpleITK importer, which is a requirement for JPEG2000 compressed DICOM and NRRD.

How to use in your own project

  • Create an instance of an importer (Directly, or indirectly using the ImporterFactory):
    IImageFileImporter importer = ImporterFactory.CreateImageFileImporter(ImageFileFormat.NRRD);
  • Call the Import()-function, which returns a Dataset:
    VolumeDataset dataset = importer.Import(file);
  • Use VolumeObjectFactory to create an object from the dataset:
    VolumeRenderedObject obj = VolumeObjectFactory.CreateObject(dataset);

See the importer documentation for more detailed information.

Development Setup

To contribute or develop the package:

  1. Clone the repository
  2. Open DevProject~/ as a Unity project
  3. Unity will automatically resolve the package from the repo root via the local file reference in DevProject~/Packages/manifest.json
  4. Edit scripts, shaders, etc. directly in the package folders - changes are immediately reflected
  5. To test samples, import them via the Package Manager window

FAQ (Frequently Asked Questions)

How to preserve real world scale of my datasets?

Imported datasets are automatically normalised, to make sure datasets where the scale unit info is missing or wrong don't become too large or small. You can undy this simply by setting the scale of the outer GameObject (the one containing the VolumeRenderedObject component) to 1,1,1.

Does this work in VR?

Yes! It should work in VR with both built-in and URP (and probably HDRP, though not tested).

What about VR performance?

Since VR requires two cameras to render each frame, you can expect worse performance. However, you can improve the FPS in two ways:

  • Open DirectVolumeRenderingShader.shader and reduce the value of MAX_NUM_STEPS in the frag_dvr, frag_mip and frag_surf functions. This will sacrifice quality for performance.
  • Disable the DEPTHWRITE_ON shader variant. You can do this from code, or just remove the line "#pragma multi_compile DEPTHWRITE_ON DEPTHWRITE_OFF" in DirectVolumeRenderingShader.shader. Note: this will remove depth writing, so you won't be able to intersect multiple datasets.
  • Make sure "Enable cubic interpolation" is checked on the volume object's inspector.

Your bottleneck will most likely be the pixel/fragment shader (where we do raymarching), so it might be possible to get better performance by enabling DLSS. This requires HDRP, which this project currently does not officially support (but it might still work fine).

Also, some users have reporter having significantly lower performance with OpenXR mode, compared to OpenVR. It might we worth a try to switch between these.

Can I use WebGL?

Yes! But keep in mind that memory will be limited, so you might not be able to load very large datasets.

I recommend that you enable ALLOW_MEMORY_GROWTH. See #125 for more info.

Also, since WebGL builds do not have access to your local filesystem, you will not be able to upload files directly (using the runtime GUI in the sample scene, etc.). You can either:

  • Import the dataset in the editor, save the scene, and create a build with the scene containing the already imported dataset.
  • Create prefabs for all the datasets you want, and make a build where you spawn these on demand.
  • Use UnityWebRequest to download the files from somewhere.

Is this project free to use?

Yes, it's free even for commercial projects. The license (MIT) only requires attribution and a copyright/license notice.

How can I make it look better?

  • Try enabling cubic sampling in the inspector.
  • Try enabling shadow volumes in the inspector.
  • Try increasing the value of "MAX_NUM_STEPS" in the DirectVolumeRenderingShader.shader (located at Runtime/Shaders/BuiltIn/DirectVolumeRenderingShader.shader)

How can I get better rendering performance with lighting enabled?

If you're on a platform that supports it (Windows, etc.), try enabling DLSS (HDRP) or FidelityFX Super Resolution (URP) and reduce the render scale.

How can I raycast the scene to find an intersection?

I'm stuck! How can I get help?

Create an issue. You can also reach me on the fediverse.

Contributing

See CONTRIBUTING.md for how to contribute.

Thanks to everyone who have contributed so far.

See Third Party Notices for libraries used by this project.

Rider C# IDE license kindly provided by JetBrains.

About

Volume rendering, implemented in Unity3D. Want to support the project? Donate a small sum to Save The Children(https://www.savethechildren.net/) or another charity, and send me a message, and I will be greatly motivated!

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published

Contributors 10