Raymarcher Technical & APi Documentation
Mesh To Tex3D
Namespace: Raymarcher.Toolkit
Raymarcher provides the capability to convert/render regular meshes into volume data, specifically into a 3D texture.

There are three different ways to achieve this:

- Mesh Printer
Prints the vertices of a target mesh instantly or progressively into a volume box.

- Mesh Slice Renderer
Renders target meshes with the 'slice shader' and packs the rendered slices into a 3D texture.

- Perspective Driven Volume Renderer
Renders targets from three different perspectives.

Each option has its advantages and disadvantages in terms of precision and data storage. You can create mono objects for each converter/renderer via GameObject/Raymarcher/Toolkit.
You can watch an official video documentation here.



Mesh Printer
The Mesh Printer is likely the most effective way to convert regular meshes into volumes.
It prints the mesh vertices directly into a 3D texture.
However, one drawback is that it tracks mesh vertices, so if the target meshes are low-poly, it may be noticeable that the 'printer' created points on those vertices, resulting in a less detailed model.
Additionally, this component is not compatible with mobiles/webGL as it utilizes compute shaders and consumes a significant amount of GPU resources.
The advantage, however, is that you can print any high-poly mesh, and you can observe the printing process.

After creating the component, assign the target tex3DVolumeBox.
You can assign the root into the 'Get Childs From Root' field of all the meshes you would like to print, or you can assign individual meshes into the 'Target Mesh Filters' field.

Similar to the Volume Voxel Painter, you need to define the volume resolution, and you can set the initial volume canvas that will be included in every print process.

There are two print modes: Instant and Progressive.

- Instant prints the mesh instantly.
- Progressive prints the mesh progressively every frame, and there is an option to travel from vertex-to-vertex over a specific duration.

Once your print canvas already exists, you can print 'As New' or 'Additive' to add the new volume data to the existing RT3D.
Afterward, you can release the results or save the printed 3D canvas.


Properties & Fields
// You must set all fields/properties below before manually invoking printing via code...

// Target common volume resolution for printing
public CommonVolumeResolution commonVolumeResolution = CommonVolumeResolution.x64;
// Initial 3D texture that will be 'blit' at the beginning of the printing
public Texture3D initialVolumeCanvas3D;

// Target print mode (Progressive or Instant)
public PrintMode printMode;

// If print mode is Progressive:
// The printing process will paint the mesh vertices progressivelly from one vertex to another over specific time
public bool travelVertexToVertex = false;
// Travelling duration from one vertex to another
public float vertexTravelDurationInSeconds;

// If print mode is Instant:
// Spherical or Cubical brush shape?
public BrushShape brushShape;

// Brush Settings
public float brushRadius;
public float brushIntensity01;
public float brushSmoothness01;
public bool eraseVoxels;

// Material Settings (optional)
public int selectedMaterialIndex;
public int maxMaterialIndexInstance;
public RMModifier_VolumeMaterialCompositor materialCompositor;

public RMSdf_Tex3DVolumeBox TargetTex3DVolumeBox { get; }
public RMVolumeVoxelPainter VolumeVoxelPainter { get; }
public MeshFilter[] TargetMeshFilters { get; }

public bool IsPrinting { get; }
// Process progress 0 - 1
public float PrintingProgress { get; }
// World position of the current printing 'handle'
public Vector3 VirtualBrushWorldPosition { get; }
// Current 3D render texture target the printing process is aimed to
public RenderTexture WorkingTargetRT { get; }
Methods
// Assign a custom volume voxel painter and a root transform of all target meshes you would like to voxelize (meshes will be received automatically from the root as its children)
public void UpdateMeshPrinter(RMVolumeVoxelPainter newTargetVoxelPainter, Transform getChildsFromRoot)
// Assign a custom volume voxel painter and an array of target mesh filters you would like to voxelize
public void UpdateMeshPrinter(RMVolumeVoxelPainter newTargetVoxelPainter, MeshFilter[] newTargetMeshFilters)

// Initiate the printing process with 'new' canvas or 'additive' with current component settings - if the param is false, the existing 3D canvas will be overpainted with the new one
public void PrintTargetMeshesToTex3DVolume(bool printAdditive)

// Stop the printing process immediately (this will keep all the resources and will not dispose anything except the printing coroutine)
public void StopAndRelease()

// Dispose volume voxel painter and current 3D render texture (this will clear your current progress completely)
public void DisposeSensitiveResources()

// Assign a new target 3D render texture (working canvas) to print into (you can choose whether to release a content in the current one)
public void SetWorkingCanvas(RenderTexture newWorkingCanvas = null, bool releaseCurrent = true)
Mesh Slice Renderer
The Mesh Slice Renderer converts sliced meshes into volume tex3D data.
It is the least precise technique as it renders the 'white' pixels of the current slice progress.
The major disadvantage is that meshes whose faces are aligned perpendicularly towards the rendering camera won't be captured.
Additionally, this component only works in the Unity Editor.

The advantage here is that it is not dependent on vertex count, but you need to properly align the mesh faces so they are visible to the rendering camera.

After creating the component, assign the target 'slice' material.
Create a new material and assign the shader Matej Vanco/Raymarcher/Extras/RMTex3DRenderSlicer.
Assign this material to all the meshes you want to convert to volume using this technique and place them within the camera's defined bounding box.

You can preview the slice progress right in the editor, adjust mesh vertices to the camera's view, and change the slice width.
It's highly recommended to use the 'Common Volume Resolution' so that you can easily get the output 3D texture to the voxel painter and modify that texture at runtime.
Custom resolutions for voxel modification are not supported.
All the methods and fields are available in editor only.


Perspective-Driven Volume Renderer
The Perspective-Driven Volume Renderer automatically creates three 2D textures from three cameras, each from a different perspective towards the volume box.

The disadvantage is that meshes are very approximated, and the result depends on the appearance of the meshes.
The brightness of the rendered mesh material affects the visibility of the voxels.
Additionally, the memory allocation is higher as there are three unique 2D render textures.
The advantage is that it is quick, compatible with all platforms, and can be used for animated meshes at runtime.
This component is closely related to the PDVolumeBox sdf object.

To use this renderer:

1. Create a PDVolumeBox in GameObject/Raymarcher/Volumes.
2. Create a PDVolumeRenderer in GameObject/Raymarcher/Toolkit.
3. Assign the created PDVolumeRenderer component to the Volume Renderer field in the PDVolumeBox.
4. All meshes rendered in the PDVolumeRenderer will be displayed in the PDVolumeBox.

You can then create a Snapshot of the currently rendered meshes and voxelize them into a single 3D texture.
There is also a possibility to Merge the snapshot of the currently rendered 3D texture to an existing 3D texture.


Properties & Fields
public float VolumeSize { get; set; }
public float NearClipOffset { get; set; }
public LayerMask RenderingLayerMask { get; set; }

public int VolumeResolution { get; }
public bool VolumeFilteringBilinear { get; }
public CommonVolumeResolution CurrentCommonVolumeResolution { get; }
// Is using custom volume resolution or Raymarcher's common volume resolution?
public bool UseCommonVolumeResolution { get; }

// Currently cached top,right,front 2D render textures
public RenderTexture RTTop { get; }
public RenderTexture RTRight { get; }
public RenderTexture RTFront { get; }
Methods
// Setup the PD Volume Renderer manually
public void SetupPDVolumeRenderer()

// Set custom volume resolution to all three 2D render textures (max 2048)
public void SetCustomVolumeResolution(int resolution)
// Set common volume resolution to all three 2D render textures (more preferred)
public void SetCommonVolumeResolution(CommonVolumeResolution commonVolumeRes)
// Set filtering
public void SetVolumeFiltering(bool bilinear)
// Refresh the PD Volume Renderer manually (refreshes all three cameras)
public void RefreshVolumeRenderer()

// Returns a snapshot (3D Render Texture) of the currently rendered content in all three 2D render textures (might return null)
// You can provide a custom 3D render texture to merge the current content to an existing one
public RenderTexture CreatePDVolumeSnapshot(RenderTexture optionalExistingRT3DToMergeWith = null)