CapsuleAO point light
This commit is contained in:
parent
4a9d7cc4ab
commit
45c479df00
@ -1,6 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
using UnityEditor.EditorTools;
|
||||||
using UnityEditor.IMGUI.Controls;
|
using UnityEditor.IMGUI.Controls;
|
||||||
using UnityEditorInternal;
|
using UnityEditorInternal;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -18,17 +19,18 @@ namespace X.Rendering.Scene
|
|||||||
|
|
||||||
SerializedProperty boundsProperty;
|
SerializedProperty boundsProperty;
|
||||||
private BoxBoundsHandle boundsHandle = new();
|
private BoxBoundsHandle boundsHandle = new();
|
||||||
|
LightData[] lightDatas = null;
|
||||||
|
|
||||||
public override VisualElement CreateInspectorGUI()
|
public override VisualElement CreateInspectorGUI()
|
||||||
{
|
{
|
||||||
transform = (target as MonoBehaviour).transform;
|
transform = (target as MonoBehaviour).transform;
|
||||||
var mainLight = GameObject.FindGameObjectWithTag("MainLight")?.GetComponent<Light>();
|
var mainLight = GameObject.FindGameObjectWithTag("MainLight")?.GetComponent<Light>();
|
||||||
if (mainLight == null )
|
if (mainLight == null)
|
||||||
{
|
{
|
||||||
mainLight = GameObject.FindObjectsOfType<Light>().Where(l => l.type == LightType.Directional).First();
|
mainLight = GameObject.FindObjectsOfType<Light>().Where(l => l.type == LightType.Directional).First();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mainLight != null )
|
if (mainLight != null)
|
||||||
{
|
{
|
||||||
mainLightDir = (mainLight.transform.rotation * Vector3.forward).normalized;
|
mainLightDir = (mainLight.transform.rotation * Vector3.forward).normalized;
|
||||||
mainLightDir.w = 1;
|
mainLightDir.w = 1;
|
||||||
@ -40,6 +42,8 @@ namespace X.Rendering.Scene
|
|||||||
Debug.Log($"{lightList.index}");
|
Debug.Log($"{lightList.index}");
|
||||||
selectIndex = lightList.index;
|
selectIndex = lightList.index;
|
||||||
};
|
};
|
||||||
|
var t = serializedObject.targetObject.GetType().GetField("capsuleLights", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
||||||
|
lightDatas = t.GetValue(serializedObject.targetObject) as LightData[];
|
||||||
|
|
||||||
lightList.onAddCallback += (_) =>
|
lightList.onAddCallback += (_) =>
|
||||||
{
|
{
|
||||||
@ -48,8 +52,20 @@ namespace X.Rendering.Scene
|
|||||||
lightList.index = 0;
|
lightList.index = 0;
|
||||||
}
|
}
|
||||||
lightList.serializedProperty.InsertArrayElementAtIndex(lightList.index);
|
lightList.serializedProperty.InsertArrayElementAtIndex(lightList.index);
|
||||||
lightList.serializedProperty.GetArrayElementAtIndex(lightList.index).vector4Value = mainLightDir;
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
|
||||||
|
var light = new LightData()
|
||||||
|
{
|
||||||
|
isPointLight = true,
|
||||||
|
lightIntensity = 1,
|
||||||
|
lightPosition = transform.position + Vector3.up
|
||||||
|
};
|
||||||
|
|
||||||
|
if (lightDatas != null)
|
||||||
|
{
|
||||||
|
lightDatas[lightList.index] = light;
|
||||||
lightList.Select(lightList.index);
|
lightList.Select(lightList.index);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
lightList.drawHeaderCallback = DrawHeader;
|
lightList.drawHeaderCallback = DrawHeader;
|
||||||
@ -63,8 +79,26 @@ namespace X.Rendering.Scene
|
|||||||
|
|
||||||
private void DrawListItems(Rect rect, int index, bool isActive, bool isFocused)
|
private void DrawListItems(Rect rect, int index, bool isActive, bool isFocused)
|
||||||
{
|
{
|
||||||
SerializedProperty element = lightList.serializedProperty.GetArrayElementAtIndex(index);
|
if(index < 0 )
|
||||||
EditorGUI.LabelField(new Rect(rect.x, rect.y, 200, EditorGUIUtility.singleLineHeight), $"{element.vector4Value}");
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var light = lightDatas[index];
|
||||||
|
float x = rect.x;
|
||||||
|
//EditorGUI.LabelField(new Rect(x, rect.y, 50, EditorGUIUtility.singleLineHeight), "点光");
|
||||||
|
//x += 50;
|
||||||
|
EditorGUI.LabelField(new Rect(x, rect.y, 150, EditorGUIUtility.singleLineHeight), $"{light.lightPosition}");
|
||||||
|
x += 140;
|
||||||
|
light.lightIntensity = EditorGUI.Slider(new Rect(x, rect.y, 200, EditorGUIUtility.singleLineHeight), light.lightIntensity, 0.2f, 2);
|
||||||
|
x += 210;
|
||||||
|
light.isPointLight = EditorGUI.ToggleLeft(new Rect(x, rect.y, 50, EditorGUIUtility.singleLineHeight), "点光", light.isPointLight);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
Undo.RecordObject(target, "DrawListItems");
|
||||||
|
CallValidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawHeader(Rect rect)
|
private void DrawHeader(Rect rect)
|
||||||
@ -81,6 +115,11 @@ namespace X.Rendering.Scene
|
|||||||
serializedObject.ApplyModifiedProperties();
|
serializedObject.ApplyModifiedProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnDestroy()
|
||||||
|
{
|
||||||
|
Tools.hidden = false;
|
||||||
|
}
|
||||||
|
|
||||||
public void OnSceneGUI()
|
public void OnSceneGUI()
|
||||||
{
|
{
|
||||||
DrawBoundHandle();
|
DrawBoundHandle();
|
||||||
@ -88,16 +127,44 @@ namespace X.Rendering.Scene
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SerializedProperty element = lightList.serializedProperty.GetArrayElementAtIndex(selectIndex);
|
var light = lightDatas[selectIndex];
|
||||||
|
Tools.hidden = true;
|
||||||
var rot = new float4(element.vector4Value).xyz;
|
|
||||||
|
|
||||||
rot += DrawRotationHandle(element.vector4Value);
|
|
||||||
element.vector4Value = new float4(rot, element.vector4Value.w);
|
|
||||||
|
|
||||||
|
if (!light.isPointLight)
|
||||||
|
{
|
||||||
|
var rot = (float3)light.lightPosition;
|
||||||
|
rot += DrawRotationHandle(light.lightPosition);
|
||||||
|
light.lightPosition = rot;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var pos = (float3)light.lightPosition;
|
||||||
|
pos += DrawPositionHandle(light.lightPosition);
|
||||||
|
light.lightPosition = pos;
|
||||||
|
}
|
||||||
serializedObject.ApplyModifiedProperties();
|
serializedObject.ApplyModifiedProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void CallValidate()
|
||||||
|
{
|
||||||
|
target.GetType().GetMethod("OnValidate", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).Invoke(target, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float3 DrawPositionHandle(Vector3 vec)
|
||||||
|
{
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
var newPos = Handles.PositionHandle(vec, Quaternion.identity);
|
||||||
|
float3 delta = float3.zero;
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
Undo.RecordObject(target, "DrawPositionHandle");
|
||||||
|
delta = newPos - vec;
|
||||||
|
CallValidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
protected float3 DrawRotationHandle(Vector3 vec)
|
protected float3 DrawRotationHandle(Vector3 vec)
|
||||||
{
|
{
|
||||||
EditorGUI.BeginChangeCheck();
|
EditorGUI.BeginChangeCheck();
|
||||||
@ -125,18 +192,13 @@ namespace X.Rendering.Scene
|
|||||||
|
|
||||||
Handles.color = col;
|
Handles.color = col;
|
||||||
|
|
||||||
float3 delta;
|
float3 delta = float3.zero;
|
||||||
var newVec = (Quaternion.Euler(newEuler) * Vector3.forward).normalized;
|
var newVec = (Quaternion.Euler(newEuler) * Vector3.forward).normalized;
|
||||||
if (newVec != vec)
|
if (newVec != vec)
|
||||||
{
|
{
|
||||||
Undo.RecordObject(target, "DrawRotationHandle");
|
Undo.RecordObject(target, "DrawRotationHandle");
|
||||||
|
|
||||||
// Perform the handle move and update the serialized data
|
|
||||||
delta = newVec - vec;
|
delta = newVec - vec;
|
||||||
}
|
CallValidate();
|
||||||
else
|
|
||||||
{
|
|
||||||
delta = float3.zero;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return delta;
|
return delta;
|
||||||
|
|||||||
@ -14550,16 +14550,18 @@ MonoBehaviour:
|
|||||||
CascadeShadowOffset: {x: 0, y: 0, z: 1}
|
CascadeShadowOffset: {x: 0, y: 0, z: 1}
|
||||||
updateInterval: 1
|
updateInterval: 1
|
||||||
capsuleLights:
|
capsuleLights:
|
||||||
- {x: 0.009531173, y: -0.76794606, z: -0.6404436, w: 1}
|
- lightPosition: {x: 0.30918866, y: -0.7392774, z: -0.5982234}
|
||||||
|
lightIntensity: 0.92
|
||||||
|
isPointLight: 0
|
||||||
capsuleAOSetting:
|
capsuleAOSetting:
|
||||||
AmbientIntensity: 3.5
|
AmbientIntensity: 3.5
|
||||||
ConeAngle: 10.72
|
ConeAngle: 7.86
|
||||||
ShadowIntensity: 0.28
|
ShadowIntensity: 0.28
|
||||||
ShadowSharpness: 10.59
|
ShadowSharpness: 10.3
|
||||||
lightStartID: 0
|
lightStartID: 0
|
||||||
lightEndID: 1
|
lightEndID: 1
|
||||||
CapsuleLightsDir:
|
CapsuleLightsDir:
|
||||||
- {x: -0.009531173, y: 0.76794606, z: 0.6404436, w: 1}
|
- {x: -0.30918866, y: 0.7392774, z: 0.5982234, w: 0.92}
|
||||||
- {x: 0, y: 0, z: 0, w: 0}
|
- {x: 0, y: 0, z: 0, w: 0}
|
||||||
- {x: 0, y: 0, z: 0, w: 0}
|
- {x: 0, y: 0, z: 0, w: 0}
|
||||||
- {x: 0, y: 0, z: 0, w: 0}
|
- {x: 0, y: 0, z: 0, w: 0}
|
||||||
@ -14594,9 +14596,9 @@ MonoBehaviour:
|
|||||||
CapsuleLightsDirCount: 1
|
CapsuleLightsDirCount: 1
|
||||||
capsuleAOAreaSettings:
|
capsuleAOAreaSettings:
|
||||||
- AmbientIntensity: 3.5
|
- AmbientIntensity: 3.5
|
||||||
ConeAngle: 10.72
|
ConeAngle: 7.86
|
||||||
ShadowIntensity: 0.28
|
ShadowIntensity: 0.28
|
||||||
ShadowSharpness: 10.59
|
ShadowSharpness: 10.3
|
||||||
lightStartID: 0
|
lightStartID: 0
|
||||||
lightEndID: 1
|
lightEndID: 1
|
||||||
sceneAreaEffects: []
|
sceneAreaEffects: []
|
||||||
|
|||||||
@ -9,7 +9,7 @@ namespace X.Rendering.Scene
|
|||||||
[SerializeField]
|
[SerializeField]
|
||||||
internal CapsuleShadowAreaSetting capsuleAOSetting = CapsuleShadowAreaSetting.GetDefault();
|
internal CapsuleShadowAreaSetting capsuleAOSetting = CapsuleShadowAreaSetting.GetDefault();
|
||||||
[SerializeField, HideInInspector]
|
[SerializeField, HideInInspector]
|
||||||
internal Vector4[] capsuleLights;
|
internal LightData[] capsuleLights;
|
||||||
[SerializeField, HideInInspector]
|
[SerializeField, HideInInspector]
|
||||||
internal Bounds Bounds = new Bounds(Vector3.zero, Vector3.one);
|
internal Bounds Bounds = new Bounds(Vector3.zero, Vector3.one);
|
||||||
|
|
||||||
|
|||||||
@ -46,6 +46,14 @@ namespace X.Rendering.Scene
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class LightData
|
||||||
|
{
|
||||||
|
public Vector3 lightPosition;
|
||||||
|
public float lightIntensity = 1;
|
||||||
|
public bool isPointLight = true;
|
||||||
|
}
|
||||||
|
|
||||||
internal class CapsuleShadowPass : ScriptableRenderPass, IDisposable
|
internal class CapsuleShadowPass : ScriptableRenderPass, IDisposable
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
|
|||||||
@ -64,8 +64,7 @@ namespace X.Rendering.Scene
|
|||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
{
|
{
|
||||||
Shader.DisableKeyword(MultiCapsuleAO);
|
SetEnable(false);
|
||||||
Shader.DisableKeyword(MultiCapsuleShadowAndAO);
|
|
||||||
shadowRemapPass?.Dispose();
|
shadowRemapPass?.Dispose();
|
||||||
capsuleAOPass?.Dispose();
|
capsuleAOPass?.Dispose();
|
||||||
Instance = null;
|
Instance = null;
|
||||||
@ -87,6 +86,8 @@ namespace X.Rendering.Scene
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Shader.DisableKeyword(MultiCapsuleAO);
|
||||||
|
Shader.DisableKeyword(MultiCapsuleShadowAndAO);
|
||||||
RenderPipelineManager.beginCameraRendering -= OnBeginCamera;
|
RenderPipelineManager.beginCameraRendering -= OnBeginCamera;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,6 +109,7 @@ namespace X.Rendering.Scene
|
|||||||
UpdateCapsuleLights();
|
UpdateCapsuleLights();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void OnValidate()
|
private void OnValidate()
|
||||||
{
|
{
|
||||||
UpdateRenderAssetsSettings();
|
UpdateRenderAssetsSettings();
|
||||||
@ -127,13 +129,18 @@ namespace X.Rendering.Scene
|
|||||||
for (int i = 0; i < capsuleLights?.Length; i++)
|
for (int i = 0; i < capsuleLights?.Length; i++)
|
||||||
{
|
{
|
||||||
var light = capsuleLights[i];
|
var light = capsuleLights[i];
|
||||||
var v = -Vector3.Normalize(light);
|
var v = light.lightPosition;
|
||||||
|
if(!light.isPointLight)
|
||||||
|
{
|
||||||
|
v = -Vector3.Normalize(light.lightPosition);
|
||||||
|
}
|
||||||
|
|
||||||
lightDirs.Add(new Vector4()
|
lightDirs.Add(new Vector4()
|
||||||
{
|
{
|
||||||
x = v.x,
|
x = v.x,
|
||||||
y = v.y,
|
y = v.y,
|
||||||
z = v.z,
|
z = v.z,
|
||||||
w = light.w
|
w = light.lightIntensity
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
capsuleAOSetting.lightStartID = 0;
|
capsuleAOSetting.lightStartID = 0;
|
||||||
@ -148,13 +155,18 @@ namespace X.Rendering.Scene
|
|||||||
for (int j = 0; j < sceneAreaEffect.capsuleLights.Length; j++)
|
for (int j = 0; j < sceneAreaEffect.capsuleLights.Length; j++)
|
||||||
{
|
{
|
||||||
var light = sceneAreaEffect.capsuleLights[j];
|
var light = sceneAreaEffect.capsuleLights[j];
|
||||||
var v = -Vector3.Normalize(light);
|
var v = light.lightPosition;
|
||||||
|
if (!light.isPointLight)
|
||||||
|
{
|
||||||
|
v = -Vector3.Normalize(light.lightPosition);
|
||||||
|
}
|
||||||
|
|
||||||
lightDirs.Add(new Vector4()
|
lightDirs.Add(new Vector4()
|
||||||
{
|
{
|
||||||
x = v.x,
|
x = v.x,
|
||||||
y = v.y,
|
y = v.y,
|
||||||
z = v.z,
|
z = v.z,
|
||||||
w = light.w
|
w = light.lightIntensity
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +248,7 @@ namespace X.Rendering.Scene
|
|||||||
|
|
||||||
#region CapsuleAO
|
#region CapsuleAO
|
||||||
[SerializeField , HideInInspector]
|
[SerializeField , HideInInspector]
|
||||||
private Vector4[] capsuleLights;
|
private LightData[] capsuleLights;
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private CapsuleShadowAreaSetting capsuleAOSetting = CapsuleShadowAreaSetting.GetDefault();
|
private CapsuleShadowAreaSetting capsuleAOSetting = CapsuleShadowAreaSetting.GetDefault();
|
||||||
[HideInInspector]
|
[HideInInspector]
|
||||||
|
|||||||
@ -256,8 +256,9 @@ void CalcCapsuleShadow(float3 worldPos, float3 worldNormal, out float shadow, o
|
|||||||
for (uint b = area.lightStartID; b < area.lightEndID; ++b)
|
for (uint b = area.lightStartID; b < area.lightEndID; ++b)
|
||||||
{
|
{
|
||||||
float4 lightDir = _CapsuleLightsDir[b];
|
float4 lightDir = _CapsuleLightsDir[b];
|
||||||
float4 cone = GetConeProperties(lightDir.xyz, area.ConeAngle);
|
//float4 cone = GetConeProperties(lightDir.xyz, area.ConeAngle);
|
||||||
float tempIntensity = intensity / saturate(1 * smoothstep(0.1, 2, lightDir.w));
|
float4 cone = GetConeProperties(normalize(lightDir.xyz - worldPos), area.ConeAngle);
|
||||||
|
float tempIntensity = intensity / smoothstep(0.1, 2, lightDir.w);
|
||||||
float tempShadow = CalcCapsuleShadowByIndex(worldPos, cone.xyz, c.capsuleStartID, c.capsuleEndID, area.ShadowSharpness, tempIntensity, area.ShadowIntensity);
|
float tempShadow = CalcCapsuleShadowByIndex(worldPos, cone.xyz, c.capsuleStartID, c.capsuleEndID, area.ShadowSharpness, tempIntensity, area.ShadowIntensity);
|
||||||
// float tempShadow = CalcCapsuleShadowByIndexV2(worldPos, cone, c.capsuleStartID, c.capsuleEndID, tempIntensity, area.ShadowIntensity);
|
// float tempShadow = CalcCapsuleShadowByIndexV2(worldPos, cone, c.capsuleStartID, c.capsuleEndID, tempIntensity, area.ShadowIntensity);
|
||||||
shadow = min(shadow, tempShadow);
|
shadow = min(shadow, tempShadow);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user