Skip to content

Commit

Permalink
Settings for gradient/normal thresholds (#208)
Browse files Browse the repository at this point in the history
Settings for gradient/normal thresholds
  • Loading branch information
mlavik1 authored Jul 1, 2023
1 parent 0d26847 commit 89d54b7
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 9 deletions.
26 changes: 26 additions & 0 deletions Assets/Editor/VolumeRenderedObjectCustomInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ public override void OnInspectorGUI()
EditorGUILayout.MinMaxSlider("Visible value range", ref visibilityWindow.x, ref visibilityWindow.y, 0.0f, 1.0f);
volrendObj.SetVisibilityWindow(visibilityWindow);

if (newRenderMode == RenderMode.IsosurfaceRendering)
{
float oldThreshold = volrendObj.GetGradientVisibilityThreshold();
float oldThresholdSqrt = Mathf.Sqrt(oldThreshold); // Convert to square root scaling (=> more precision close to 0)
float newThreshold = EditorGUILayout.Slider(
new GUIContent("Gradient visibility threshold", "Minimum gradient maginitude value that will be visible"),
oldThresholdSqrt, 0.0f, 1.0f
);
newThreshold = newThreshold * newThreshold; // Convert back to linear scaling
if (newThreshold != oldThreshold)
volrendObj.SetGradientVisibilityThreshold(newThreshold);
}

// Transfer function settings
EditorGUILayout.Space();
tfSettings = EditorGUILayout.Foldout(tfSettings, "Transfer function");
Expand Down Expand Up @@ -101,6 +114,19 @@ public override void OnInspectorGUI()
LightSource newLightSource = (LightSource)EditorGUILayout.EnumPopup("Light source", oldLightSource);
if (newLightSource != oldLightSource)
volrendObj.SetLightSource(newLightSource);

// Gradient lighting threshold: Threshold for how low gradients can contribute to lighting.
Vector2 gradLightThreshold = volrendObj.GetGradientLightingThreshold();
// Convert to square root scaling (=> more precision close to 0)
gradLightThreshold = new Vector2(Mathf.Sqrt(gradLightThreshold.x), Mathf.Sqrt(gradLightThreshold.y));
EditorGUILayout.MinMaxSlider(
new GUIContent("Gradient lighting threshold",
"Minimum and maximum threshold for gradient contribution to lighting.\n"
+ "Voxels with gradient less than min will be unlit, and with gradient >= max will fully shaded."),
ref gradLightThreshold.x, ref gradLightThreshold.y, 0.0f, 1.0f
);
// Convert back to linear scale, before setting updated value.
volrendObj.SetGradientLightingThreshold(new Vector2(gradLightThreshold.x * gradLightThreshold.x, gradLightThreshold.y * gradLightThreshold.y));
}
}

Expand Down
55 changes: 52 additions & 3 deletions Assets/Scripts/VolumeObject/VolumeRenderedObject.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Threading;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;

namespace UnityVolumeRendering
Expand All @@ -25,17 +24,33 @@ public class VolumeRenderedObject : MonoBehaviour

[SerializeField, HideInInspector]
private RenderMode renderMode;

[SerializeField, HideInInspector]
private TFRenderMode tfRenderMode;

[SerializeField, HideInInspector]
private bool lightingEnabled;

[SerializeField, HideInInspector]
private LightSource lightSource;

// Minimum and maximum gradient threshold for lighting contribution. Values below min will be unlit, and between min and max will be partly shaded.
[SerializeField, HideInInspector]
private Vector2 gradientLightingThreshold = new Vector2(0.02f, 0.15f);

// Gradient magnitude threshold. Voxels with gradient magnitude less than this will not be rendered in isosurface rendering mode.
[SerializeField, HideInInspector]
private float minGradient = 0.01f;

// Minimum/maximum data value threshold for rendering. Values outside of this range will not be rendered.
[SerializeField, HideInInspector]
private Vector2 visibilityWindow = new Vector2(0.0f, 1.0f);

// Early ray termination
[SerializeField, HideInInspector]
private bool rayTerminationEnabled = true;

// Tri-cubic interpolation of data texture (expensive, but looks better)
[SerializeField, HideInInspector]
private bool cubicInterpolationEnabled = false;

Expand Down Expand Up @@ -150,8 +165,39 @@ public async Task SetLightingEnabledAsync(bool enable, IProgressHandler progress

public void SetLightSource(LightSource source)
{
lightSource = source;
UpdateMaterialProperties();
if (lightSource != source)
{
lightSource = source;
UpdateMaterialProperties();
}
}

public void SetGradientLightingThreshold(Vector2 threshold)
{
if (gradientLightingThreshold != threshold)
{
gradientLightingThreshold = threshold;
UpdateMaterialProperties();
}
}

public Vector2 GetGradientLightingThreshold()
{
return gradientLightingThreshold;
}

public void SetGradientVisibilityThreshold(float min)
{
if (minGradient != min)
{
minGradient = min;
UpdateMaterialProperties();
}
}

public float GetGradientVisibilityThreshold()
{
return minGradient;
}

public void SetVisibilityWindow(float min, float max)
Expand Down Expand Up @@ -307,6 +353,9 @@ private void UpdateMatInternal()

meshRenderer.sharedMaterial.SetFloat("_MinVal", visibilityWindow.x);
meshRenderer.sharedMaterial.SetFloat("_MaxVal", visibilityWindow.y);
meshRenderer.sharedMaterial.SetFloat("_MinGradient", minGradient);
meshRenderer.sharedMaterial.SetFloat("_LightingGradientThresholdStart", gradientLightingThreshold.x);
meshRenderer.sharedMaterial.SetFloat("_LightingGradientThresholdEnd", gradientLightingThreshold.y);
meshRenderer.sharedMaterial.SetVector("_TextureSize", new Vector3(dataset.dimX, dataset.dimY, dataset.dimZ));

if (rayTerminationEnabled)
Expand Down
26 changes: 20 additions & 6 deletions Assets/Shaders/DirectVolumeRenderingShader.shader
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
_TFTex("Transfer Function Texture (Generated)", 2D) = "" {}
_MinVal("Min val", Range(0.0, 1.0)) = 0.0
_MaxVal("Max val", Range(0.0, 1.0)) = 1.0
_MinGradient("Gradient visibility threshold", Range(0.0, 1.0)) = 0.0
_LightingGradientThresholdStart("Gradient threshold for lighting (end)", Range(0.0, 1.0)) = 0.0
_LightingGradientThresholdEnd("Gradient threshold for lighting (start)", Range(0.0, 1.0)) = 0.0
[HideInInspector] _TextureSize("Dataset dimensions", Vector) = (1, 1, 1)
}
SubShader
Expand Down Expand Up @@ -73,6 +76,10 @@
float _MaxVal;
float3 _TextureSize;

float _MinGradient;
float _LightingGradientThresholdStart;
float _LightingGradientThresholdEnd;

#if CROSS_SECTION_ON
#define CROSS_SECTION_TYPE_PLANE 1
#define CROSS_SECTION_TYPE_BOX_INCL 2
Expand Down Expand Up @@ -336,7 +343,9 @@

// Apply lighting
#if defined(LIGHTING_ON)
src.rgb = calculateLighting(src.rgb, gradient / gradMag, getLightDirection(-ray.direction), -ray.direction, 0.3f);
float factor = smoothstep(_LightingGradientThresholdStart, _LightingGradientThresholdEnd, gradMag);
float3 shaded = calculateLighting(src.rgb, gradient / gradMag, getLightDirection(-ray.direction), -ray.direction, 0.3f);
src.rgb = lerp(src.rgb, shaded, factor);
#endif

src.rgb *= src.a;
Expand Down Expand Up @@ -428,11 +437,16 @@
const float density = getDensity(currPos);
if (density > _MinVal && density < _MaxVal)
{
float3 normal = normalize(getGradient(currPos));
col = getTF1DColour(density);
col.rgb = calculateLighting(col.rgb, normal, getLightDirection(-ray.direction), -ray.direction, 0.15);
col.a = 1.0f;
break;
float3 gradient = getGradient(currPos);
float gradMag = length(gradient);
if (gradMag > _MinGradient)
{
float3 normal = gradient / gradMag;
col = getTF1DColour(density);
col.rgb = calculateLighting(col.rgb, normal, getLightDirection(-ray.direction), -ray.direction, 0.15);
col.a = 1.0f;
break;
}
}
}

Expand Down

0 comments on commit 89d54b7

Please sign in to comment.