Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -732,14 +732,28 @@ public static ProbeSubdivisionResult BakeBricks(ProbeSubdivisionContext ctx)
{
var go = renderer.component.gameObject;
int rendererLayerMask = 1 << go.layer;
renderer.volume.CalculateCenterAndSize(out _, out var rendererBoundsSize);
float rendererBoundsVolume = rendererBoundsSize.x * rendererBoundsSize.y * rendererBoundsSize.z;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid issues with planes I'd say we should min all dimensions to avoid 0, probably to 2/3 cm?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, in this renderer size, there is already padding of 1cm in every axis


foreach (var probeVolume in overlappingProbeVolumes)
{
// Skip renderers that have a smaller volume than the min volume size from the profile or probe volume component
float minRendererBoundingBoxSize = ctx.profile.minRendererVolumeSize;
if (probeVolume.component.overrideRendererFilters)
minRendererBoundingBoxSize = probeVolume.component.minRendererVolumeSize;
if (rendererBoundsVolume < minRendererBoundingBoxSize)
continue;

if (ProbeVolumePositioning.OBBIntersect(renderer.volume, probeVolume.volume)
&& ProbeVolumePositioning.OBBIntersect(renderer.volume, cell.volume))
{
var layerMask = ctx.profile.renderersLayerMask;

if (probeVolume.component.overrideRendererFilters)
layerMask = probeVolume.component.objectLayerMask;

// Check if the renderer has a matching layer with probe volume
if ((probeVolume.component.objectLayerMask & rendererLayerMask) != 0)
if ((layerMask & rendererLayerMask) != 0)
{
validRenderers.Add(renderer);
scenesInCell.Add(go.scene);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ struct GPUProbeVolumeOBB
public int minControllerSubdivLevel;
public int maxControllerSubdivLevel;
public int maxSubdivLevelInsideVolume;
public float geometryDistanceOffset;
}

public class GPUSubdivisionContext : IDisposable
Expand Down Expand Up @@ -621,7 +620,6 @@ static void VoxelizeProbeVolumeData(CommandBuffer cmd, Bounds cellAABB,
minControllerSubdivLevel = minSubdiv,
maxControllerSubdivLevel = maxSubdiv,
maxSubdivLevelInsideVolume = subdivLevel,
geometryDistanceOffset = kp.component.geometryDistanceOffset,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ struct GPUProbeVolumeOBB
int minControllerSubdivLevel;
int maxControllerSubdivLevel;
int maxSubdivLevelInsideVolume;
float geometryDistanceOffset;
};


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,10 +419,10 @@ void DelayCreateAsset()
if (m_ProbeVolumeProfileEditor.target != set.profile)
Editor.CreateCachedEditor(set.profile, m_ProbeVolumeProfileEditor.GetType(), ref m_ProbeVolumeProfileEditor);

EditorGUILayout.LabelField("Probe Volume Profile", EditorStyles.largeLabel);
EditorGUILayout.LabelField("Probe Volume Profile", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
m_ProbeVolumeProfileEditor.OnInspectorGUI();

EditorGUILayout.Space();
EditorGUI.indentLevel--;

var serializedSets = m_ProbeSceneData.FindPropertyRelative("serializedBakingSets");
var serializedSet = serializedSets.GetArrayElementAtIndex(m_BakingSets.index);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ bool PointInsideOBB(GPUProbeVolumeOBB obbA, GPUProbeVolumeOBB obbB)
void VoxelizeProbeVolumeData(uint3 id : SV_DispatchThreadID)
{
float2 subdivisionLimits = float2(0, 0);
float maxGeometryDistance = -1e20;
float maxSubdivLevelInsideVolume = 0;

if (any(id >= uint3(_MaxBrickSize.xyz)))
Expand All @@ -222,12 +221,11 @@ void VoxelizeProbeVolumeData(uint3 id : SV_DispatchThreadID)

subdivisionLimits.x = max(subdivisionLimits.x, obb.minControllerSubdivLevel);
subdivisionLimits.y = max(subdivisionLimits.y, obb.maxControllerSubdivLevel);
maxGeometryDistance = max(maxGeometryDistance, obb.geometryDistanceOffset);
maxSubdivLevelInsideVolume = max(maxSubdivLevelInsideVolume, obb.maxSubdivLevelInsideVolume);
}
}

_Output[id] = float4(subdivisionLimits, maxGeometryDistance, maxSubdivLevelInsideVolume);
_Output[id] = float4(subdivisionLimits, 0, maxSubdivLevelInsideVolume);
}

[numthreads(8, 8, 1)]
Expand All @@ -248,7 +246,6 @@ void Subdivide(uint3 id : SV_DispatchThreadID)
if (_SubdivisionLevel < maxControllerSubdivLevel || _SubdivisionLevel > maxSubdivLevelInsideVolume)
return;


uint3 sdfId = floor(position01 * _SDFSize.xyz);

float dist = _Input[sdfId].r;
Expand All @@ -259,9 +256,6 @@ void Subdivide(uint3 id : SV_DispatchThreadID)

int minControllerSubdivLevel = _MaxSubdivisionLevel - subdivisionLevelData.x - 1;

// Add a small offset to control how the subdivision looks from the probe volume
voxelDetectionDistance += subdivisionLevelData.z * rcp(_MaxBrickSize.x);

if (dist <= voxelDetectionDistance || _SubdivisionLevel > minControllerSubdivLevel)
{
// transform id to world position
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,12 @@ static void Drawer_VolumeContent(SerializedProbeVolume serialized, Editor owner)
if (serialized.highestSubdivisionLevelOverride.intValue < 0)
serialized.highestSubdivisionLevelOverride.intValue = maxSubdiv;

serialized.highestSubdivisionLevelOverride.intValue = Mathf.Min(maxSubdiv, EditorGUILayout.IntSlider(Styles.s_HighestSubdivLevel, serialized.highestSubdivisionLevelOverride.intValue, 0, maxSubdiv));
serialized.lowestSubdivisionLevelOverride.intValue = Mathf.Min(maxSubdiv, EditorGUILayout.IntSlider(Styles.s_LowestSubdivLevel, serialized.lowestSubdivisionLevelOverride.intValue, 0, maxSubdiv));
serialized.lowestSubdivisionLevelOverride.intValue = Mathf.Min(serialized.lowestSubdivisionLevelOverride.intValue, serialized.highestSubdivisionLevelOverride.intValue);
using (new EditorGUI.IndentLevelScope())
{
serialized.highestSubdivisionLevelOverride.intValue = Mathf.Min(maxSubdiv, EditorGUILayout.IntSlider(Styles.s_HighestSubdivLevel, serialized.highestSubdivisionLevelOverride.intValue, 0, maxSubdiv));
serialized.lowestSubdivisionLevelOverride.intValue = Mathf.Min(maxSubdiv, EditorGUILayout.IntSlider(Styles.s_LowestSubdivLevel, serialized.lowestSubdivisionLevelOverride.intValue, 0, maxSubdiv));
serialized.lowestSubdivisionLevelOverride.intValue = Mathf.Min(serialized.lowestSubdivisionLevelOverride.intValue, serialized.highestSubdivisionLevelOverride.intValue);
}
EditorGUI.EndProperty();
EditorGUI.EndProperty();

Expand All @@ -214,10 +217,14 @@ static void Drawer_VolumeContent(SerializedProbeVolume serialized, Editor owner)

EditorGUILayout.LabelField("Geometry Settings", EditorStyles.boldLabel);

EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(serialized.objectLayerMask, Styles.s_ObjectLayerMask);
EditorGUILayout.PropertyField(serialized.geometryDistanceOffset, Styles.s_GeometryDistanceOffset);
EditorGUI.indentLevel--;
EditorGUILayout.PropertyField(serialized.overrideRendererFilters, Styles.s_OverrideRendererFilters);
if (serialized.overrideRendererFilters.boolValue)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(serialized.objectLayerMask, Styles.s_ObjectLayerMask);
EditorGUILayout.PropertyField(serialized.minRendererVolumeSize, Styles.s_MinRendererVolumeSize);
EditorGUI.indentLevel--;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ internal static class Styles
internal static readonly GUIContent s_HighestSubdivLevel = new GUIContent("Highest Subdivision Level", "Overrides the highest subdivision level used by the system. This determines how finely a probe volume is subdivided, lower values means larger minimum distance between probes.");
internal static readonly GUIContent s_LowestSubdivLevel = new GUIContent("Lowest Subdivision Level", "Overrides the lowest subdivision level used by the system. This determines how coarsely a probe volume is allowed to be subdivided, higher values means smaller maximum distance between probes.");
internal static readonly GUIContent s_ObjectLayerMask = new GUIContent("Layer Mask", "Control which layers will be used to select the meshes for the probe placement algorithm.");
internal static readonly GUIContent s_GeometryDistanceOffset = new GUIContent("Probe Placement Distance Offset", "Affects the minimum distance at which the subdivision system will attempts to place probes near the geometry. This value can be useful in situations where the generated probes don't fully cover an object.");
internal static readonly GUIContent s_MinRendererVolumeSize = new GUIContent("Min Volume Size", "Specifies the minimum bounding box volume of renderers to consider placing probes around.");
internal static readonly GUIContent s_OverrideRendererFilters = new GUIContent("Override Renderer Filters", "Overrides the filters used to select renderers for the probe placement.");
internal static readonly string s_ProbeVolumeChangedMessage = "The probe volume has changed since last baking or the data was never baked.\nPlease bake lighting in the lighting panel to update the lighting data.";

internal static readonly Color k_GizmoColorBase = new Color32(137, 222, 144, 255);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ internal class SerializedProbeVolume
internal SerializedProperty highestSubdivisionLevelOverride;
internal SerializedProperty lowestSubdivisionLevelOverride;
internal SerializedProperty objectLayerMask;
internal SerializedProperty geometryDistanceOffset;
internal SerializedProperty minRendererVolumeSize;
internal SerializedProperty overrideRendererFilters;

internal SerializedObject serializedObject;

Expand All @@ -21,7 +22,8 @@ internal SerializedProbeVolume(SerializedObject obj)
globalVolume = serializedObject.FindProperty("globalVolume");
size = serializedObject.FindProperty("size");
objectLayerMask = serializedObject.FindProperty("objectLayerMask");
geometryDistanceOffset = serializedObject.FindProperty("geometryDistanceOffset");
minRendererVolumeSize = serializedObject.FindProperty("minRendererVolumeSize");
overrideRendererFilters = serializedObject.FindProperty("overrideRendererFilters");
highestSubdivisionLevelOverride = serializedObject.FindProperty("highestSubdivLevelOverride");
lowestSubdivisionLevelOverride = serializedObject.FindProperty("lowestSubdivLevelOverride");
overridesSubdivision = serializedObject.FindProperty("overridesSubdivLevels");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ Shader "Hidden/ProbeVolume/VoxelizeScene"
ColorMask 0
ZWrite Off
ZClip Off
Conservative True

HLSLPROGRAM
#pragma vertex vert
#pragma geometry geom
#pragma fragment frag
#pragma target 4.5
// #pragma enable_d3d11_debug_symbols
Expand All @@ -33,15 +35,24 @@ Shader "Hidden/ProbeVolume/VoxelizeScene"
float3 _VolumeSize;
uint _AxisSwizzle;

struct VertexToFragment
struct VertexToGeometry
{
float4 vertex : SV_POSITION;
float3 cellPos01 : TEXCOORD0;
};

VertexToFragment vert(float4 vertex : POSITION)
struct GeometryToFragment
{
VertexToFragment o;
float4 vertex : SV_POSITION;
float3 cellPos01 : TEXCOORD0;
nointerpolation float2 minMaxX : TEXCOORD1;
nointerpolation float2 minMaxY : TEXCOORD2;
nointerpolation float2 minMaxZ : TEXCOORD3;
};

VertexToGeometry vert(float4 vertex : POSITION)
{
VertexToGeometry o;

float3 cellPos = mul(unity_ObjectToWorld, vertex).xyz;
cellPos -= _VolumeWorldOffset;
Expand Down Expand Up @@ -70,8 +81,33 @@ Shader "Hidden/ProbeVolume/VoxelizeScene"
return o;
}

float4 frag(VertexToFragment i) : COLOR
[maxvertexcount(3)]
void geom(triangle VertexToGeometry inputVertex[3], inout TriangleStream<GeometryToFragment> triangleStream)
{
float3 minPos = min(min(inputVertex[0].cellPos01, inputVertex[1].cellPos01), inputVertex[2].cellPos01) - rcp(_OutputSize.x);
float3 maxPos = max(max(inputVertex[0].cellPos01, inputVertex[1].cellPos01), inputVertex[2].cellPos01) + rcp(_OutputSize.x);

for (int i = 0; i < 3; i++)
{
GeometryToFragment o;
o.vertex = inputVertex[i].vertex;
o.cellPos01 = inputVertex[i].cellPos01;
o.minMaxX = float2(minPos.x, maxPos.x);
o.minMaxY = float2(minPos.y, maxPos.y);
o.minMaxZ = float2(minPos.z, maxPos.z);
triangleStream.Append(o);
}
}

float4 frag(GeometryToFragment i) : COLOR
{
if (i.cellPos01.x < i.minMaxX.x || i.cellPos01.x > i.minMaxX.y)
return 0;
if (i.cellPos01.y < i.minMaxY.x || i.cellPos01.y > i.minMaxY.y)
return 0;
if (i.cellPos01.z < i.minMaxZ.x || i.cellPos01.z > i.minMaxZ.y)
return 0;

if (any(i.cellPos01 < -EPSILON) || any(i.cellPos01 >= 1 + EPSILON))
return 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ internal enum Version
/// </summary>
public float cellSizeInMeters => (float)cellSizeInBricks * minBrickSize;

/// <summary>
/// Layer mask filter for all renderers.
/// </summary>
public LayerMask renderersLayerMask = -1;

/// <summary>
/// Specifies the minimum bounding box volume of renderers to consider placing probes around.
/// </summary>
[Min(0)]
public float minRendererVolumeSize = 0.1f;

void OnEnable()
{
if (version != CoreUtils.GetLastEnumValue<Version>())
Expand All @@ -67,7 +78,8 @@ public bool IsEquivalent(ProbeReferenceVolumeProfile otherProfile)
{
return minDistanceBetweenProbes == otherProfile.minDistanceBetweenProbes &&
cellSizeInMeters == otherProfile.cellSizeInMeters &&
simplificationLevels == otherProfile.simplificationLevels;
simplificationLevels == otherProfile.simplificationLevels &&
renderersLayerMask == otherProfile.renderersLayerMask;
}
}

Expand All @@ -79,6 +91,8 @@ internal class ProbeReferenceVolumeProfileEditor : Editor
SerializedProperty m_CellSize;
SerializedProperty m_MinDistanceBetweenProbes;
SerializedProperty m_SimplificationLevels;
SerializedProperty m_MinRendererVolumeSize;
SerializedProperty m_RenderersLayerMask;
ProbeReferenceVolumeProfile profile => target as ProbeReferenceVolumeProfile;

static class Styles
Expand All @@ -88,13 +102,17 @@ static class Styles
public static readonly string simplificationLevelsHighWarning = "High simplification levels have a big memory overhead, they are not recommended except for testing purposes.";
public static readonly GUIContent minDistanceBetweenProbes = new GUIContent("Min Distance Between Probes", "The minimal distance between two probes in meters.");
public static readonly GUIContent indexDimensions = new GUIContent("Index Dimensions", "The dimensions of the index buffer.");
public static readonly GUIContent minRendererVolumeSize = new GUIContent("Min Renderer Volume Size", "Specifies the minimum bounding box volume of renderers to consider placing probes around.");
public static readonly GUIContent renderersLayerMask = new GUIContent("Layer Mask", "Specifies the layer mask for renderers when placing probes.");
}

void OnEnable()
{
m_CellSize = serializedObject.FindProperty(nameof(ProbeReferenceVolumeProfile.cellSizeInBricks));
m_MinDistanceBetweenProbes = serializedObject.FindProperty(nameof(ProbeReferenceVolumeProfile.minDistanceBetweenProbes));
m_SimplificationLevels = serializedObject.FindProperty(nameof(ProbeReferenceVolumeProfile.simplificationLevels));
m_MinRendererVolumeSize = serializedObject.FindProperty(nameof(ProbeReferenceVolumeProfile.minRendererVolumeSize));
m_RenderersLayerMask = serializedObject.FindProperty(nameof(ProbeReferenceVolumeProfile.renderersLayerMask));
}

public override void OnInspectorGUI()
Expand All @@ -110,6 +128,12 @@ public override void OnInspectorGUI()
EditorGUILayout.PropertyField(m_MinDistanceBetweenProbes, Styles.minDistanceBetweenProbes);
EditorGUILayout.HelpBox($"The distance between probes will fluctuate between : {profile.minDistanceBetweenProbes}m and {profile.cellSizeInMeters / 3.0f}m", MessageType.Info);

EditorGUILayout.LabelField("Renderers Filter Settings", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_RenderersLayerMask, Styles.renderersLayerMask);
EditorGUILayout.PropertyField(m_MinRendererVolumeSize, Styles.minRendererVolumeSize);
EditorGUI.indentLevel--;

if (EditorGUI.EndChangeCheck())
serializedObject.ApplyModifiedProperties();
}
Expand Down
Loading