Skip to content

Commit 26ff37d

Browse files
committed
Probe volumes rotation + reflection probe normalization fixes and improvements. Also lots of cleanup to avoid debug-only + lightmapper work when in playmode. Cleaned out old deadcode + comments. Cleaned some GC cases (#1)
Co-authored-by: pastasfuture <[email protected]>
1 parent f15a4d4 commit 26ff37d

26 files changed

+1152
-205
lines changed

com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDProbeEditor.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ interface IHDProbeEditor
1414
HDProbe GetTarget(Object editorTarget);
1515

1616
bool showChromeGizmo { get; set; }
17+
bool showLuminanceSH { get; set; }
1718
}
1819

1920
abstract class HDProbeEditor<TProvider, TSerialized> : Editor, IHDProbeEditor, IDefaultFrameSettingsType
@@ -53,13 +54,28 @@ public bool showChromeGizmo
5354
}
5455
}
5556

57+
const string k_ShowLuminanceSHKey = "HDRP:ReflectionProbe:LuminanceSH";
58+
static bool m_ShowLuminanceSH = true;
59+
public bool showLuminanceSH
60+
{
61+
get => m_ShowLuminanceSH;
62+
set
63+
{
64+
m_ShowLuminanceSH = value;
65+
EditorPrefs.SetBool(k_ShowLuminanceSHKey, value);
66+
}
67+
}
68+
5669
protected virtual void OnEnable()
5770
{
5871
m_SerializedHDProbe = NewSerializedObject(serializedObject);
5972

6073
if (EditorPrefs.HasKey(k_ShowChromeGizmoKey))
6174
m_ShowChromeGizmo = EditorPrefs.GetBool(k_ShowChromeGizmoKey);
6275

76+
if (EditorPrefs.HasKey(k_ShowLuminanceSHKey))
77+
m_ShowLuminanceSH = EditorPrefs.GetBool(k_ShowLuminanceSHKey);
78+
6379
m_SerializedHDProbePerTarget = new Dictionary<Object, TSerialized>(targets.Length);
6480
m_TypedTargets = new HDProbe[targets.Length];
6581
for (var i = 0; i < m_TypedTargets.Length; i++)

com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDProbeUI.Drawers.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ internal enum ToolBar
2323
MirrorPosition = 1 << 4,
2424
MirrorRotation = 1 << 5,
2525
ShowChromeGizmo = 1 << 6, //not really an edit mode. Should be move later to contextual tool overlay
26+
ShowLuminanceSH = 1 << 7, //not really an edit mode. Should be move later to contextual tool overlay
2627
}
2728

2829
internal interface IProbeUISettingsProvider
@@ -92,6 +93,10 @@ static Drawer()
9293
{
9394
listContent.Add(k_ToolbarContents[toolbarJ]);
9495
}
96+
else if (toolBar == ToolBar.ShowLuminanceSH)
97+
{
98+
listContent.Add(k_ToolbarContents[toolbarJ]);
99+
}
95100
else
96101
{
97102
listMode.Add(k_ToolbarMode[toolbarJ]);
@@ -114,15 +119,23 @@ public static void DrawToolbars(SerializedHDProbe serialized, Editor owner)
114119
GUILayout.FlexibleSpace();
115120
GUI.changed = false;
116121

117-
for (int i = 0; i < k_ListModes.Length - 1; ++i)
122+
for (int i = 0; i < k_ListModes.Length - 2; ++i)
118123
EditMode.DoInspectorToolbar(k_ListModes[i], k_ListContent[i], HDEditorUtils.GetBoundsGetter(owner), owner);
119124

120125
//Special case: show chrome gizmo should be mouved to overlay tool.
121126
//meanwhile, display it as an option of toolbar
122127
EditorGUI.BeginChangeCheck();
123128
IHDProbeEditor probeEditor = owner as IHDProbeEditor;
124-
int selected = probeEditor.showChromeGizmo ? 0 : -1;
125-
int newSelected = GUILayout.Toolbar(selected, new[] { k_ListContent[k_ListModes.Length - 1][0] }, GUILayout.Height(20), GUILayout.Width(30));
129+
int selected = -1;
130+
if (probeEditor.showChromeGizmo)
131+
{
132+
selected = 0;
133+
}
134+
else if (probeEditor.showLuminanceSH)
135+
{
136+
selected = 1;
137+
}
138+
int newSelected = GUILayout.Toolbar(selected, new[] { k_ListContent[k_ListModes.Length - 2][0], k_ListContent[k_ListModes.Length - 1][0] }, GUILayout.Height(20), GUILayout.Width(30 * 2));
126139
if(EditorGUI.EndChangeCheck())
127140
{
128141
//allow deselection
@@ -131,6 +144,7 @@ public static void DrawToolbars(SerializedHDProbe serialized, Editor owner)
131144
else
132145
selected = newSelected;
133146
probeEditor.showChromeGizmo = selected == 0;
147+
probeEditor.showLuminanceSH = selected == 1;
134148
SceneView.RepaintAll();
135149
}
136150

com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDProbeUI.Skin.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ static partial class HDProbeUI
3232
{ ToolBar.MirrorPosition, EditorGUIUtility.TrIconContent("MoveTool", "Change the mirror position.") },
3333
{ ToolBar.MirrorRotation, EditorGUIUtility.TrIconContent("RotateTool", "Change the mirror rotation.") },
3434
{ ToolBar.ShowChromeGizmo, EditorGUIUtility.TrIconContent(IconReflectionProbeGizmoId, "Display the chrome gizmo.") },
35+
{ ToolBar.ShowLuminanceSH, EditorGUIUtility.TrIconContent(IconReflectionProbeLuminanceSHGizmoId, "Display Luminance SH (Reflection Probe Normalization Data).") },
3536
};
3637

3738
const string IconReflectionProbeGizmoId =
@@ -41,5 +42,7 @@ static partial class HDProbeUI
4142
"ReflectionProbe Gizmo"
4243
#endif
4344
;
45+
46+
const string IconReflectionProbeLuminanceSHGizmoId = "d_PreMatLight0";
4447
}
4548
}

com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDReflectionProbeEditor.Gizmos.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
using UnityEngine;
22
using UnityEngine.Rendering.HighDefinition;
3+
using UnityEngine.Rendering;
34

45
namespace UnityEditor.Rendering.HighDefinition
56
{
67
sealed partial class HDReflectionProbeEditor
78
{
89
static Mesh sphere;
910
static Material material;
11+
static Material materialLuminanceSH;
1012

1113
[DrawGizmo(GizmoType.Selected)]
1214
static void DrawSelectedGizmo(ReflectionProbe reflectionProbe, GizmoType gizmoType)
@@ -25,15 +27,23 @@ static void DrawSelectedGizmo(ReflectionProbe reflectionProbe, GizmoType gizmoTy
2527
);
2628

2729
if (e.showChromeGizmo)
30+
{
2831
Gizmos_CapturePoint(reflectionProbe);
32+
}
33+
else if (e.showLuminanceSH)
34+
{
35+
Gizmos_CapturePointLuminanceSH(reflectionProbe);
36+
}
2937
}
3038

3139
static void Gizmos_CapturePoint(ReflectionProbe target)
3240
{
3341
if(sphere == null)
3442
sphere = Resources.GetBuiltinResource<Mesh>("New-Sphere.fbx");
43+
3544
if(material == null)
3645
material = new Material(Shader.Find("Hidden/Debug/ReflectionProbePreview"));
46+
3747
var probe = target.GetComponent<HDAdditionalReflectionData>();
3848
var probePositionSettings = ProbeCapturePositionSettings.ComputeFrom(probe, null);
3949
HDRenderUtilities.ComputeCameraSettingsFromProbeSettings(
@@ -43,6 +53,7 @@ static void Gizmos_CapturePoint(ReflectionProbe target)
4353
var capturePosition = cameraPositionSettings.position;
4454

4555
material.SetTexture("_Cubemap", probe.texture);
56+
4657
material.SetPass(0);
4758
Graphics.DrawMeshNow(sphere, Matrix4x4.TRS(capturePosition, Quaternion.identity, Vector3.one * capturePointPreviewSize));
4859

@@ -64,5 +75,55 @@ static void Gizmos_CapturePoint(ReflectionProbe target)
6475
Handles.DrawWireDisc(hit.point, hit.normal, 0.5f);
6576
}
6677
}
78+
79+
static void Gizmos_CapturePointLuminanceSH(ReflectionProbe target)
80+
{
81+
if (sphere == null)
82+
sphere = Resources.GetBuiltinResource<Mesh>("New-Sphere.fbx");
83+
if (materialLuminanceSH == null)
84+
materialLuminanceSH = new Material(Shader.Find("Hidden/Debug/ReflectionProbeLuminanceSHPreview"));
85+
86+
var probe = target.GetComponent<HDAdditionalReflectionData>();
87+
var probePositionSettings = ProbeCapturePositionSettings.ComputeFrom(probe, null);
88+
HDRenderUtilities.ComputeCameraSettingsFromProbeSettings(
89+
probe.settings, probePositionSettings,
90+
out _, out var cameraPositionSettings, 0
91+
);
92+
var capturePosition = cameraPositionSettings.position;
93+
94+
bool _LuminanceSHEnabled = true;
95+
if (!probe.GetLuminanceSHL2ForNormalization(out Vector4 _L0L1, out Vector4 _L2_1, out float _L2_2))
96+
{
97+
_LuminanceSHEnabled = false;
98+
_L0L1 = Vector4.zero;
99+
_L2_1 = Vector4.zero;
100+
_L2_2 = 0.0f;
101+
}
102+
materialLuminanceSH.SetInt("_LuminanceSHEnabled", _LuminanceSHEnabled ? 1 : 0);
103+
materialLuminanceSH.SetVector("_L0L1", _L0L1);
104+
materialLuminanceSH.SetVector("_L2_1", _L2_1);
105+
materialLuminanceSH.SetFloat("_L2_2", _L2_2);
106+
107+
materialLuminanceSH.SetPass(0);
108+
Graphics.DrawMeshNow(sphere, Matrix4x4.TRS(capturePosition, Quaternion.identity, Vector3.one * capturePointPreviewSize));
109+
110+
var ray = new Ray(capturePosition, Vector3.down);
111+
if (Physics.Raycast(ray, out RaycastHit hit))
112+
{
113+
var startPoint = capturePosition - Vector3.up * 0.5f * capturePointPreviewSize;
114+
var c = InfluenceVolumeUI.k_GizmoThemeColorBase;
115+
c.a = 0.8f;
116+
Handles.color = c;
117+
Handles.zTest = UnityEngine.Rendering.CompareFunction.LessEqual;
118+
Handles.DrawLine(startPoint, hit.point);
119+
Handles.DrawWireDisc(hit.point, hit.normal, 0.5f);
120+
121+
c.a = 0.25f;
122+
Handles.color = c;
123+
Handles.zTest = UnityEngine.Rendering.CompareFunction.Greater;
124+
Handles.DrawLine(capturePosition, hit.point);
125+
Handles.DrawWireDisc(hit.point, hit.normal, 0.5f);
126+
}
127+
}
67128
}
68129
}

com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/HDReflectionProbeEditor.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ struct HDProbeSettingsProvider : HDProbeUI.IProbeUISettingsProvider, InfluenceVo
106106
{
107107
HDProbeUI.ToolBar.InfluenceShape | HDProbeUI.ToolBar.NormalBlend | HDProbeUI.ToolBar.Blend,
108108
HDProbeUI.ToolBar.CapturePosition,
109-
HDProbeUI.ToolBar.ShowChromeGizmo
109+
HDProbeUI.ToolBar.ShowChromeGizmo,
110+
HDProbeUI.ToolBar.ShowLuminanceSH
110111
};
111112
HDProbeUI.ToolBar[] HDProbeUI.IProbeUISettingsProvider.toolbars => k_ToolBars;
112113

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
Shader "Debug/ReflectionProbeLuminanceSHPreview"
2+
{
3+
Properties
4+
{
5+
_LuminanceSHEnabled("_LuminanceSHEnabled", Int) = 0
6+
_L0L1("_L0L1", Vector) = (0,0,0,0)
7+
_L2_1("_L2_1", Vector) = (0,0,0,0)
8+
_L2_2("_L2_2", Float) = 0.0
9+
_Exposure("_Exposure", Range(-10.0,10.0)) = 0.0
10+
11+
}
12+
13+
SubShader
14+
{
15+
Tags{ "RenderPipeline" = "HDRenderPipeline" "RenderType" = "Opaque" "Queue" = "Transparent" }
16+
ZWrite On
17+
Cull Back
18+
19+
Pass
20+
{
21+
Name "ForwardUnlit"
22+
Tags{ "LightMode" = "Forward" }
23+
24+
HLSLPROGRAM
25+
26+
#pragma editor_sync_compilation
27+
28+
#pragma vertex vert
29+
#pragma fragment frag
30+
31+
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
32+
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
33+
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
34+
35+
struct appdata
36+
{
37+
float4 positionOS : POSITION;
38+
float3 normalOS : NORMAL;
39+
};
40+
41+
struct v2f
42+
{
43+
float4 positionCS : SV_POSITION;
44+
float3 normalWS : NORMAL;
45+
float3 positionWS : TEXCOORD0;
46+
};
47+
48+
int _LuminanceSHEnabled;
49+
float4 _L0L1;
50+
float4 _L2_1;
51+
float _L2_2;
52+
float _Exposure;
53+
54+
v2f vert(appdata v)
55+
{
56+
v2f o;
57+
// Transform local to world before custom vertex code
58+
o.positionWS = TransformObjectToWorld(v.positionOS.xyz);
59+
o.positionCS = TransformWorldToHClip(o.positionWS);
60+
o.normalWS = TransformObjectToWorldNormal(v.normalOS);
61+
62+
return o;
63+
}
64+
65+
// Ref: "Efficient Evaluation of Irradiance Environment Maps" from ShaderX 2
66+
float SHEvalLinearL0L1Luminance(float3 N, float4 shA)
67+
{
68+
// Linear (L1) + constant (L0) polynomial terms
69+
return dot(shA.xyz, N) + shA.w;
70+
}
71+
72+
float SHEvalLinearL2Luminance(float3 N, float4 shB, float shC)
73+
{
74+
// 4 of the quadratic (L2) polynomials
75+
float4 vB = N.xyzz * N.yzzx;
76+
float x2 = dot(shB, vB);
77+
78+
// Final (5th) quadratic (L2) polynomial
79+
float vC = N.x * N.x - N.y * N.y;
80+
float x3 = shC * vC;
81+
82+
return x2 + x3;
83+
}
84+
85+
float SampleSH9Luminance(float3 N, float4 shA, float4 shB, float shC)
86+
{
87+
// Linear + constant polynomial terms
88+
float res = SHEvalLinearL0L1Luminance(N, shA);
89+
90+
// Quadratic polynomials
91+
res += SHEvalLinearL2Luminance(N, shB, shC);
92+
93+
return res;
94+
}
95+
96+
float GetReflectionProbeNormalizationFactor(float3 sampleDirectionWS, float4 reflProbeSHL0L1, float4 reflProbeSHL2_1, float reflProbeSHL2_2)
97+
{
98+
// SHEvalLinearL0L1() expects coefficients in float4 shAr, float4 shAg, float4 shAb vectors whos channels are laid out {x, y, z, DC}
99+
float4 shALuminance = float4(reflProbeSHL0L1.w, reflProbeSHL0L1.y, reflProbeSHL0L1.z, reflProbeSHL0L1.x);
100+
101+
float4 shBLuminance = reflProbeSHL2_1;
102+
float shCLuminance = reflProbeSHL2_2;
103+
104+
// // Normalize DC term:
105+
shALuminance.w -= shBLuminance.z;
106+
107+
// // Normalize Quadratic term:
108+
shBLuminance.z *= 3.0f;
109+
110+
return SampleSH9Luminance(sampleDirectionWS, shALuminance, shBLuminance, shCLuminance);
111+
}
112+
113+
float4 frag(v2f i) : SV_Target
114+
{
115+
float3 N = normalize(i.normalWS);
116+
117+
float luminanceSH = GetReflectionProbeNormalizationFactor(N, _L0L1, _L2_1, _L2_2);
118+
float4 colorLuminanceSH = (_LuminanceSHEnabled > 0)
119+
? (luminanceSH < 0.0f)
120+
? float4(1.0f, 0.0f, 0.0f, 1.0f)
121+
: float4(luminanceSH, luminanceSH, luminanceSH, 1.0f)
122+
: float4(1.0f, 0.0f, 1.0f, 1.0f);
123+
124+
float4 color = colorLuminanceSH;
125+
126+
color.rgb = color.rgb * exp2(_Exposure) * GetCurrentExposureMultiplier();
127+
128+
return float4(color);
129+
}
130+
ENDHLSL
131+
}
132+
}
133+
}

com.unity.render-pipelines.high-definition/Editor/Lighting/Reflection/ReflectionProbesLuminanceSHPreview.shader.meta

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)