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