浏览代码

First draft of new light editor

/main
sebastienlagarde 7 年前
当前提交
19d8082a
共有 11 个文件被更改,包括 875 次插入96 次删除
  1. 1
      ScriptableRenderPipeline/Core/Shadow/AdditionalShadowData.cs
  2. 2
      ScriptableRenderPipeline/HDRenderPipeline/AdditionalData/HDAdditionalCameraData.cs
  3. 132
      ScriptableRenderPipeline/HDRenderPipeline/AdditionalData/HDAdditionalLightData.cs
  4. 14
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs
  5. 142
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  6. 10
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor.meta
  7. 265
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/EditorLightUtilities.cs
  8. 13
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/EditorLightUtilities.cs.meta
  9. 379
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.cs
  10. 13
      ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.cs.meta

1
ScriptableRenderPipeline/Core/Shadow/AdditionalShadowData.cs


public int cascadeCount { get { return shadowCascadeCount; } }
public void GetShadowCascades(out int cascadeCount, out float[] cascadeRatios, out float[] cascadeBorders) { cascadeCount = shadowCascadeCount; cascadeRatios = shadowCascadeRatios; cascadeBorders = shadowCascadeBorders; }
public void SetShadowCascades(int cascadeCount, float[] cascadeRatios, float[] cascadeBorders) { shadowCascadeCount = cascadeCount; shadowCascadeRatios = cascadeRatios; shadowCascadeBorders = cascadeBorders; }
public void GetShadowAlgorithm(out int algorithm, out int variant, out int precision) { algorithm = shadowAlgorithm; variant = shadowVariant; precision = shadowPrecision; }
public void SetShadowAlgorithm(int algorithm, int variant, int precision, int format, int[] data)
{

2
ScriptableRenderPipeline/HDRenderPipeline/AdditionalData/HDAdditionalCameraData.cs


namespace UnityEngine.Experimental.Rendering
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
// This struct allow to add specialized path in HDRenderPipeline (can be use to render mini map or planar reflection etc...)
public enum RenderingPathHDRP { Default, Unlit };

132
ScriptableRenderPipeline/HDRenderPipeline/AdditionalData/HDAdditionalLightData.cs


namespace UnityEngine.Experimental.Rendering
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnityEngine.Experimental.Rendering.HDPipeline
public enum LightShape
{
Directional = 0,
Point = 1,
Spot = 2,
Rectangle = 3,
Line = 4,
// Sphere = 5,
// Disc = 6,
}
public enum LightArchetype { Punctual, Area };
public enum SpotLightShape { Cone, Pyramid, Box };

[RequireComponent(typeof(Light))]
public class HDAdditionalLightData : MonoBehaviour
{
[Range(0.0F, 100.0F)]
public float m_innerSpotPercent = 0.0f; // To display this field in the UI this need to be public
[Range(0.0f, 100.0f)]
public float m_InnerSpotPercent = 0.0f; // To display this field in the UI this need to be public
return Mathf.Clamp(m_innerSpotPercent, 0.0f, 100.0f) / 100.0f;
return Mathf.Clamp(m_InnerSpotPercent, 0.0f, 100.0f) / 100.0f;
[Range(0.0F, 1.0F)]
[Range(0.0f, 1.0f)]
public float lightDimmer = 1.0f;
// Not used for directional lights.

public bool affectSpecular = true;
public LightArchetype archetype = LightArchetype.Punctual;
public SpotLightShape spotLightShape = SpotLightShape.Cone; // Note: Only for Spotlight, should be hide for other light
// Caution m_lightShape need to be in sync with m_Type of original light component (i.e it need to drive the value). This is necessary for the GI to work correctly and this is handled by the HLightEditor
public LightShape m_LightShape; // To display this field in the UI this need to be public
// This setter/getter here can be use by C# code when creating procedural light.
public void SetLightshape(LightShape lightShape)
{
m_LightShape = lightShape;
Light light = gameObject.GetComponent<Light>();
switch (lightShape)
{
case LightShape.Directional:
light.type = LightType.Directional;
break;
case LightShape.Point:
light.type = LightType.Point;
break;
case LightShape.Spot:
light.type = LightType.Spot;
break;
case LightShape.Rectangle:
light.type = LightType.Area;
break;
case LightShape.Line:
light.type = LightType.Area;
break;
default:
light.type = LightType.Area;
break;
}
}
public LightShape GetLightShape()
{
return m_LightShape;
}
// Only for Spotlight, should be hide for other light
public SpotLightShape spotLightShape = SpotLightShape.Cone;
// Only for Rectangle/Line/projector lights
public float lightLength = 0.0f; // Area & projector lights
public float shapeLength = 0.5f;
// Only for Rectangle/projector lights
public float lightWidth = 0.0f; // Area & projector lights
public float shapeWidth = 0.5f;
// Only for Sphere/Disc
public float shapeRadius = 0.0f;
// Only for Spot/Point - use to cheaply fake specular spherical area light
public float maxSmoothness = 1.0f; // this is use with punctual light to fake an area lights
public float maxSmoothness = 1.0f;
// If true, we apply the smooth attenuation factor on the range attenuation to get 0 value, else the attenuation is just inverse square and never reach 0
public bool applyRangeAttenuation = true;
// This is specific for the LightEditor GUI and not use at runtime
public bool useOldInspector = false;
public bool showAdditionalSettings = true;
public bool castShadows = false;
public bool applyRangeAttenuation = true; // If true, we apply the smooth attenuation factor on the range attenuation to get 0 value, else the attenuation is juste inverse square and never reach 0
#if UNITY_EDITOR
private void DrawGizmos(bool selected)
{
var light = gameObject.GetComponent<Light>();
var gizmoColor = light.color;
gizmoColor.a = selected ? 1.0f : 0.3f; // Fade for the gizmo
Gizmos.color = Handles.color = gizmoColor;
switch (m_LightShape)
{
case LightShape.Directional:
EditorLightUtilities.DrawDirectionalLightGizmo(light);
break;
case LightShape.Point:
EditorLightUtilities.DrawPointlightGizmo(light, selected);
break;
case LightShape.Spot:
if(spotLightShape == SpotLightShape.Cone)
EditorLightUtilities.DrawSpotlightGizmo(light, selected);
if (spotLightShape == SpotLightShape.Pyramid)
EditorLightUtilities.DrawFrustumlightGizmo(light);
if (spotLightShape == SpotLightShape.Box) // TODO
EditorLightUtilities.DrawFrustumlightGizmo(light);
break;
case LightShape.Rectangle:
EditorLightUtilities.DrawArealightGizmo(light);
break;
case LightShape.Line:
EditorLightUtilities.DrawArealightGizmo(light);
break;
}
}
private void OnDrawGizmos()
{
DrawGizmos(false);
}
private void OnDrawGizmosSelected()
{
DrawGizmos(true);
}
#endif
}
}

14
ScriptableRenderPipeline/HDRenderPipeline/Lighting/LightDefinition.cs


Line, // Keep Line lights before Rectangle. This is needed because of a compiler bug (see LightLoop.hlsl)
Rectangle,
// Currently not supported in real time (just use for reference)
Sphere,
Disk,
Hemisphere,
Cylinder
// Sphere,
// Disk,
};
// These structures share between C# and hlsl need to be align on float4, so we pad them.

public Vector3 forward;
public int cookieIndex; // -1 if unused
public Vector3 right; // Rescaled by (2 / lightLength)
public Vector3 right; // Rescaled by (2 / shapeLenght)
public Vector3 up; // Rescaled by (2 / lightWidth)
public Vector3 up; // Rescaled by (2 / shapeWidth)
public float diffuseScale;
};

public Vector3 forward;
public int cookieIndex; // -1 if unused
public Vector3 right; // If spot: rescaled by cot(outerHalfAngle); if projector: rescaled by (2 / lightLength)
public Vector3 right; // If spot: rescaled by cot(outerHalfAngle); if projector: rescaled by (2 / shapeLenght)
public Vector3 up; // If spot: rescaled by cot(outerHalfAngle); if projector: rescaled by * (2 / lightWidth)
public Vector3 up; // If spot: rescaled by cot(outerHalfAngle); if projector: rescaled by * (2 / shapeWidth)
public float diffuseScale;
public float angleScale; // Spot light

142
ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


GPUShadowType shadowType = GPUShadowType.Unknown;
switch (ald.archetype)
switch (ald.GetLightShape())
case LightArchetype.Punctual:
case LightShape.Directional:
case LightShape.Spot:
case LightShape.Point:
// Area and projector not supported yet
}

static ComputeBuffer s_GlobalLightListAtomic = null;
// clustered light list specific buffers and data end
private static GameObject s_DefaultAdditionalLightDataGameObject;
private static HDAdditionalLightData s_DefaultAdditionalLightData;
bool usingFptl
{
get

}
}
private static HDAdditionalLightData DefaultAdditionalLightData
{
get
{
if (s_DefaultAdditionalLightDataGameObject == null)
{
s_DefaultAdditionalLightDataGameObject = new GameObject("Default Light Data");
s_DefaultAdditionalLightDataGameObject.hideFlags = HideFlags.HideAndDontSave;
s_DefaultAdditionalLightData = s_DefaultAdditionalLightDataGameObject.AddComponent<HDAdditionalLightData>();
s_DefaultAdditionalLightDataGameObject.SetActive(false);
}
return s_DefaultAdditionalLightData;
}
}
Material m_DeferredAllMaterialSRT = null;
Material m_DeferredAllMaterialMRT = null;

Utilities.Destroy(m_SingleDeferredMaterialSRT);
Utilities.Destroy(m_SingleDeferredMaterialMRT);
Utilities.Destroy(s_DefaultAdditionalLightDataGameObject);
s_DefaultAdditionalLightDataGameObject = null;
s_DefaultAdditionalLightData = null;
}
public void NewFrame()

// Light direction for directional is opposite to the forward direction
directionalLightData.forward = light.light.transform.forward;
// Rescale for cookies and windowing.
directionalLightData.up = light.light.transform.up * 2 / additionalData.lightWidth;
directionalLightData.right = light.light.transform.right * 2 / additionalData.lightLength;
directionalLightData.up = light.light.transform.up * 2 / additionalData.shapeWidth;
directionalLightData.right = light.light.transform.right * 2 / additionalData.shapeLength;
directionalLightData.positionWS = light.light.transform.position;
directionalLightData.color = GetLightColor(light);
directionalLightData.diffuseScale = additionalData.affectDiffuse ? diffuseDimmer : 0.0f;

lightData.up = light.light.transform.up;
lightData.right = light.light.transform.right;
lightData.size = new Vector2(additionalLightData.lightLength, additionalLightData.lightWidth);
lightData.size = new Vector2(additionalLightData.shapeLength, additionalLightData.shapeWidth);
lightData.right *= 2 / additionalLightData.lightLength;
lightData.up *= 2 / additionalLightData.lightWidth;
lightData.right *= 2 / additionalLightData.shapeLength;
lightData.up *= 2 / additionalLightData.shapeWidth;
}
if (lightData.lightType == GPULightType.Spot)

// We only process light with additional data
var additionalData = light.light.GetComponent<HDAdditionalLightData>();
// Debug.Assert(additionalData == null, "Missing HDAdditionalData on a light - Should have been create by HDLightEditor");
additionalData = DefaultAdditionalLightData;
return;
// Note: LightType.Area is offline only, use for baking, no need to test it
if (additionalData.archetype == LightArchetype.Punctual)
{
switch (additionalData.GetLightShape())
{
case LightShape.Point:
if (punctualLightcount >= k_MaxPunctualLightsOnScreen)
continue;
switch (light.lightType)
gpuLightType = GPULightType.Point;
lightVolumeType = LightVolumeType.Sphere;
break;
case LightShape.Spot:
if (punctualLightcount >= k_MaxPunctualLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
switch (additionalData.spotLightShape)
case LightType.Point:
if (punctualLightcount >= k_MaxPunctualLightsOnScreen)
continue;
gpuLightType = GPULightType.Point;
lightVolumeType = LightVolumeType.Sphere;
case SpotLightShape.Cone:
gpuLightType = GPULightType.Spot;
lightVolumeType = LightVolumeType.Cone;
case LightType.Spot:
if (punctualLightcount >= k_MaxPunctualLightsOnScreen)
continue;
switch (additionalData.spotLightShape)
{
case SpotLightShape.Cone:
gpuLightType = GPULightType.Spot;
lightVolumeType = LightVolumeType.Cone;
break;
case SpotLightShape.Pyramid:
gpuLightType = GPULightType.ProjectorPyramid;
lightVolumeType = LightVolumeType.Cone;
break;
case SpotLightShape.Box:
gpuLightType = GPULightType.ProjectorBox;
lightVolumeType = LightVolumeType.Box;
break;
default:
Debug.Assert(false, "Encountered an unknown SpotLightShape.");
break;
}
case SpotLightShape.Pyramid:
gpuLightType = GPULightType.ProjectorPyramid;
lightVolumeType = LightVolumeType.Cone;
case LightType.Directional:
if (directionalLightcount >= k_MaxDirectionalLightsOnScreen)
continue;
gpuLightType = GPULightType.Directional;
// No need to add volume, always visible
lightVolumeType = LightVolumeType.Count; // Count is none
case SpotLightShape.Box:
gpuLightType = GPULightType.ProjectorBox;
lightVolumeType = LightVolumeType.Box;
Debug.Assert(false, "Encountered an unknown LightType.");
Debug.Assert(false, "Encountered an unknown SpotLightShape.");
}
else // LightArchetype.Area
{
if (areaLightCount >= k_MaxAreaLightsOnScreen) { continue; }
break;
case LightShape.Directional:
if (directionalLightcount >= k_MaxDirectionalLightsOnScreen)
continue;
lightCategory = LightCategory.Punctual;
gpuLightType = GPULightType.Directional;
// No need to add volume, always visible
lightVolumeType = LightVolumeType.Count; // Count is none
break;
case LightShape.Rectangle:
if (areaLightCount >= k_MaxAreaLightsOnScreen)
continue;
lightCategory = LightCategory.Area;
gpuLightType = GPULightType.Rectangle;
lightVolumeType = LightVolumeType.Box;
break;
case LightShape.Line:
if (areaLightCount >= k_MaxAreaLightsOnScreen)
continue;
gpuLightType = (additionalData.lightWidth > 0) ? GPULightType.Rectangle : GPULightType.Line;
gpuLightType = GPULightType.Line;
break;
default:
Debug.Assert(false, "Encountered an unknown LightType.");
break;
}
uint shadow = m_ShadowIndices.ContainsKey(lightIndex) ? 1u : 0;

int lightIndex = (int)(sortKey & 0xFFFF);
var light = cullResults.visibleLights[lightIndex];
var additionalLightData = light.light.GetComponent<HDAdditionalLightData>() ?? DefaultAdditionalLightData;
var additionalLightData = light.light.GetComponent<HDAdditionalLightData>();
var additionalShadowData = light.light.GetComponent<AdditionalShadowData>(); // Can be null
// Directional rendering side, it is separated as it is always visible so no volume to handle here

10
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor.meta


fileFormatVersion: 2
guid: 636a5a3ca5205984e90e86aec12f7eb2
folderAsset: yes
timeCreated: 1505218693
licenseType: Pro
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

265
ScriptableRenderPipeline/HDRenderPipeline/Lighting/EditorLightUtilities.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
#if UNITY_EDITOR
using UnityEditor;
#endif
using Object = UnityEngine.Object;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
#if UNITY_EDITOR
public static class EditorLightUtilities
{
public static void DrawSpotlightGizmo(Light spotlight, bool selected)
{
var flatRadiusAtRange = spotlight.range * Mathf.Tan(spotlight.spotAngle * Mathf.Deg2Rad * 0.5f);
var vectorLineUp = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.up * flatRadiusAtRange - spotlight.gameObject.transform.position);
var vectorLineDown = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.up * -flatRadiusAtRange - spotlight.gameObject.transform.position);
var vectorLineRight = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.right * flatRadiusAtRange - spotlight.gameObject.transform.position);
var vectorLineLeft = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.right * -flatRadiusAtRange - spotlight.gameObject.transform.position);
var rangeDiscDistance = Mathf.Cos(Mathf.Deg2Rad * spotlight.spotAngle / 2) * spotlight.range;
var rangeDiscRadius = spotlight.range * Mathf.Sin(spotlight.spotAngle * Mathf.Deg2Rad * 0.5f);
var nearDiscDistance = Mathf.Cos(Mathf.Deg2Rad * spotlight.spotAngle / 2) * spotlight.shadowNearPlane;
var nearDiscRadius = spotlight.shadowNearPlane * Mathf.Sin(spotlight.spotAngle * Mathf.Deg2Rad * 0.5f);
//Draw Range disc
Handles.Disc(spotlight.gameObject.transform.rotation, spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * rangeDiscDistance, spotlight.gameObject.transform.forward, rangeDiscRadius, false, 1);
//Draw Lines
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineUp * spotlight.range);
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineDown * spotlight.range);
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineRight * spotlight.range);
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineLeft * spotlight.range);
if (selected)
{
//Draw Range Arcs
Handles.DrawWireArc(spotlight.gameObject.transform.position, spotlight.gameObject.transform.right, vectorLineUp, spotlight.spotAngle, spotlight.range);
Handles.DrawWireArc(spotlight.gameObject.transform.position, spotlight.gameObject.transform.up, vectorLineLeft, spotlight.spotAngle, spotlight.range);
//Draw Near Plane Disc
if (spotlight.shadows != LightShadows.None) Handles.Disc(spotlight.gameObject.transform.rotation, spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * nearDiscDistance, spotlight.gameObject.transform.forward, nearDiscRadius, false, 1);
//Inner Cone
var additionalLightData = spotlight.GetComponent<HDAdditionalLightData>();
DrawInnerCone(spotlight,additionalLightData);
}
}
public static void DrawInnerCone(Light spotlight, HDAdditionalLightData additionalLightData)
{
if (additionalLightData == null) return;
var flatRadiusAtRange = spotlight.range * Mathf.Tan(spotlight.spotAngle * additionalLightData.m_InnerSpotPercent * 0.01f * Mathf.Deg2Rad * 0.5f);
var vectorLineUp = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.up * flatRadiusAtRange - spotlight.gameObject.transform.position);
var vectorLineDown = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.up * -flatRadiusAtRange - spotlight.gameObject.transform.position);
var vectorLineRight = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.right * flatRadiusAtRange - spotlight.gameObject.transform.position);
var vectorLineLeft = Vector3.Normalize(spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * spotlight.range + spotlight.gameObject.transform.right * -flatRadiusAtRange - spotlight.gameObject.transform.position);
//Draw Lines
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineUp * spotlight.range);
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineDown * spotlight.range);
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineRight * spotlight.range);
Gizmos.DrawLine(spotlight.gameObject.transform.position, spotlight.gameObject.transform.position + vectorLineLeft * spotlight.range);
var innerAngle = spotlight.spotAngle * additionalLightData.GetInnerSpotPercent01();
if (innerAngle > 0)
{
var innerDiscDistance = Mathf.Cos(Mathf.Deg2Rad * innerAngle * 0.5f) * spotlight.range;
var innerDiscRadius = spotlight.range * Mathf.Sin(innerAngle * Mathf.Deg2Rad * 0.5f);
//Draw Range disc
Handles.Disc(spotlight.gameObject.transform.rotation, spotlight.gameObject.transform.position + spotlight.gameObject.transform.forward * innerDiscDistance, spotlight.gameObject.transform.forward, innerDiscRadius, false, 1);
}
}
public static void DrawArealightGizmo(Light arealight)
{
var RectangleSize = new Vector3(arealight.areaSize.x, arealight.areaSize.y, 0);
Gizmos.matrix = arealight.transform.localToWorldMatrix;
Gizmos.DrawWireCube(Vector3.zero, RectangleSize);
Gizmos.matrix = Matrix4x4.identity;
Gizmos.DrawWireSphere(arealight.transform.position, arealight.range);
}
public static void DrawPointlightGizmo(Light pointlight, bool selected)
{
if (pointlight.shadows != LightShadows.None && selected) Gizmos.DrawWireSphere(pointlight.transform.position, pointlight.shadowNearPlane);
Gizmos.DrawWireSphere(pointlight.transform.position, pointlight.range);
}
public static void DrawSpherelightGizmo(Light spherelight)
{
var additionalLightData = spherelight.GetComponent<HDAdditionalLightData>();
if (additionalLightData == null) return;
Gizmos.DrawSphere(spherelight.transform.position, additionalLightData.shapeLength);
if (spherelight.shadows != LightShadows.None) Gizmos.DrawWireSphere(spherelight.transform.position, spherelight.shadowNearPlane);
Gizmos.DrawWireSphere(spherelight.transform.position, spherelight.range);
}
public static void DrawFrustumlightGizmo(Light frustumlight)
{
var additionalLightData = frustumlight.GetComponent<HDAdditionalLightData>();
if (additionalLightData == null) return;
var frustumSize = new Vector3(additionalLightData.shapeLength / frustumlight.gameObject.transform.localScale.x, additionalLightData.shapeWidth / frustumlight.gameObject.transform.localScale.y, frustumlight.range - frustumlight.shadowNearPlane / frustumlight.gameObject.transform.localScale.z);
Gizmos.matrix = frustumlight.transform.localToWorldMatrix;
Gizmos.DrawWireCube(Vector3.forward * (frustumSize.z * 0.5f + frustumlight.shadowNearPlane), frustumSize);
Gizmos.matrix = Matrix4x4.identity;
}
public static void DrawDirectionalLightGizmo(Light directionalLight)
{
var gizmoSize = 0.2f;
Handles.Disc(directionalLight.transform.rotation, directionalLight.transform.position, directionalLight.gameObject.transform.forward, gizmoSize, false, 1);
Gizmos.DrawLine(directionalLight.transform.position, directionalLight.transform.position + directionalLight.transform.forward);
Gizmos.DrawLine(directionalLight.transform.position + directionalLight.transform.up * gizmoSize, directionalLight.transform.position + directionalLight.transform.up * gizmoSize + directionalLight.transform.forward);
Gizmos.DrawLine(directionalLight.transform.position + directionalLight.transform.up * -gizmoSize, directionalLight.transform.position + directionalLight.transform.up * -gizmoSize + directionalLight.transform.forward);
Gizmos.DrawLine(directionalLight.transform.position + directionalLight.transform.right * gizmoSize, directionalLight.transform.position + directionalLight.transform.right * gizmoSize + directionalLight.transform.forward);
Gizmos.DrawLine(directionalLight.transform.position + directionalLight.transform.right * -gizmoSize, directionalLight.transform.position + directionalLight.transform.right * -gizmoSize + directionalLight.transform.forward);
}
public static void DrawCross(Transform m_transform)
{
var gizmoSize = 0.25f;
Gizmos.DrawLine(m_transform.position, m_transform.position + m_transform.TransformVector(m_transform.root.forward * gizmoSize / m_transform.localScale.z));
Gizmos.DrawLine(m_transform.position, m_transform.position + m_transform.TransformVector(m_transform.root.forward * -gizmoSize / m_transform.localScale.z));
Gizmos.DrawLine(m_transform.position, m_transform.position + m_transform.TransformVector(m_transform.root.up * gizmoSize / m_transform.localScale.y));
Gizmos.DrawLine(m_transform.position, m_transform.position + m_transform.TransformVector(m_transform.root.up * -gizmoSize / m_transform.localScale.y));
Gizmos.DrawLine(m_transform.position, m_transform.position + m_transform.TransformVector(m_transform.root.right * gizmoSize / m_transform.localScale.x));
Gizmos.DrawLine(m_transform.position, m_transform.position + m_transform.TransformVector(m_transform.root.right * -gizmoSize / m_transform.localScale.x));
}
public static bool DrawHeader(string title, bool activeField)
{
var backgroundRect = GUILayoutUtility.GetRect(1f, 17f);
var labelRect = backgroundRect;
labelRect.xMin += 16f;
labelRect.xMax -= 20f;
var toggleRect = backgroundRect;
toggleRect.y += 2f;
toggleRect.width = 13f;
toggleRect.height = 13f;
var menuIcon = EditorGUIUtility.isProSkin
? (Texture2D)EditorGUIUtility.Load("Builtin Skins/DarkSkin/Images/pane options.png")
: (Texture2D)EditorGUIUtility.Load("Builtin Skins/LightSkin/Images/pane options.png");
var menuRect = new Rect(labelRect.xMax + 4f, labelRect.y + 4f, menuIcon.width, menuIcon.height);
// Background rect should be full-width
backgroundRect.xMin = 0f;
backgroundRect.width += 4f;
// Background
float backgroundTint = EditorGUIUtility.isProSkin ? 0.1f : 1f;
EditorGUI.DrawRect(backgroundRect, new Color(backgroundTint, backgroundTint, backgroundTint, 0.2f));
// Title
using (new EditorGUI.DisabledScope(!activeField))
EditorGUI.LabelField(labelRect, title, EditorStyles.boldLabel);
// Active checkbox
activeField = GUI.Toggle(toggleRect, activeField, GUIContent.none, new GUIStyle("ShurikenCheckMark"));
var e = Event.current;
if (e.type == EventType.MouseDown && backgroundRect.Contains(e.mousePosition) && e.button == 0)
{
activeField = !activeField;
e.Use();
}
EditorGUILayout.Space();
return activeField;
}
public static void DrawHeader(string title)
{
var backgroundRect = GUILayoutUtility.GetRect(1f, 17f);
var labelRect = backgroundRect;
labelRect.xMin += 16f;
labelRect.xMax -= 20f;
var foldoutRect = backgroundRect;
foldoutRect.y += 1f;
foldoutRect.width = 13f;
foldoutRect.height = 13f;
// Background rect should be full-width
backgroundRect.xMin = 0f;
backgroundRect.width += 4f;
// Background
float backgroundTint = EditorGUIUtility.isProSkin ? 0.1f : 1f;
EditorGUI.DrawRect(backgroundRect, new Color(backgroundTint, backgroundTint, backgroundTint, 0.2f));
// Title
EditorGUI.LabelField(labelRect, title, EditorStyles.boldLabel);
EditorGUILayout.Space();
}
public static void DrawSplitter()
{
EditorGUILayout.Space();
var rect = GUILayoutUtility.GetRect(1f, 1f);
// Splitter rect should be full-width
rect.xMin = 0f;
rect.width += 4f;
if (Event.current.type != EventType.Repaint)
return;
EditorGUI.DrawRect(rect, !EditorGUIUtility.isProSkin
? new Color(0.6f, 0.6f, 0.6f, 1.333f)
: new Color(0.12f, 0.12f, 0.12f, 1.333f));
}
public static bool DrawHeaderFoldout(string title, bool state)
{
var backgroundRect = GUILayoutUtility.GetRect(1f, 17f);
var labelRect = backgroundRect;
labelRect.xMin += 16f;
labelRect.xMax -= 20f;
var foldoutRect = backgroundRect;
foldoutRect.y += 1f;
foldoutRect.width = 13f;
foldoutRect.height = 13f;
// Background rect should be full-width
backgroundRect.xMin = 0f;
backgroundRect.width += 4f;
// Background
float backgroundTint = EditorGUIUtility.isProSkin ? 0.1f : 1f;
EditorGUI.DrawRect(backgroundRect, new Color(backgroundTint, backgroundTint, backgroundTint, 0.2f));
// Title
EditorGUI.LabelField(labelRect, title, EditorStyles.boldLabel);
// Active checkbox
state = GUI.Toggle(foldoutRect, state, GUIContent.none, EditorStyles.foldout);
var e = Event.current;
if (e.type == EventType.MouseDown && backgroundRect.Contains(e.mousePosition) && e.button == 0)
{
state = !state;
e.Use();
}
return state;
}
}
#endif
}

13
ScriptableRenderPipeline/HDRenderPipeline/Lighting/EditorLightUtilities.cs.meta


fileFormatVersion: 2
guid: f38354ca887c51245a6780e4cd3e6609
timeCreated: 1505227267
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

379
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.cs


using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
[CustomEditor(typeof(Light))]
[CanEditMultipleObjects]
public class HDLightEditor : Editor
{
// Original light editor
SerializedProperty m_Type;
SerializedProperty m_Range;
SerializedProperty m_SpotAngle;
SerializedProperty m_CookieSize;
SerializedProperty m_Color;
SerializedProperty m_Intensity;
SerializedProperty m_BounceIntensity;
SerializedProperty m_ColorTemperature;
SerializedProperty m_UseColorTemperature;
SerializedProperty m_Cookie;
SerializedProperty m_ShadowsType;
SerializedProperty m_ShadowsStrength;
SerializedProperty m_ShadowsResolution;
SerializedProperty m_ShadowsBias;
SerializedProperty m_ShadowsNormalBias;
SerializedProperty m_ShadowsNearPlane;
SerializedProperty m_Flare;
SerializedProperty m_RenderMode;
SerializedProperty m_CullingMask;
SerializedProperty m_Lightmapping;
SerializedProperty m_AreaSizeX;
SerializedProperty m_AreaSizeY;
SerializedProperty m_BakedShadowRadius;
SerializedProperty m_BakedShadowAngle;
// HD Light editor part
SerializedObject additionalDataSerializedObject;
SerializedObject shadowDataSerializedObject;
SerializedProperty m_SpotInnerAngle;
SerializedProperty m_LightDimmer;
SerializedProperty m_FadeDistance;
SerializedProperty m_AffectDiffuse;
SerializedProperty m_AffectSpecular;
SerializedProperty m_LightShape;
SerializedProperty m_SpotLightShape;
SerializedProperty m_ShapeLength;
SerializedProperty m_ShapeWidth;
SerializedProperty m_ShapeRadius;
SerializedProperty m_MaxSmoothness;
SerializedProperty m_ApplyRangeAttenuation;
// Extra data for GUI only
SerializedProperty m_UseOldInspector;
SerializedProperty m_ShowAdditionalSettings;
SerializedProperty m_CastShadows;
SerializedProperty m_ShadowDimmer;
SerializedProperty m_ShadowFadeDistance;
SerializedProperty m_ShadowCascadeCount;
SerializedProperty m_ShadowCascadeRatios;
SerializedProperty m_ShadowResolution;
private Light light { get { return target as Light; } }
private void OnEnable()
{
m_Type = serializedObject.FindProperty("m_Type");
m_Range = serializedObject.FindProperty("m_Range");
m_SpotAngle = serializedObject.FindProperty("m_SpotAngle");
m_CookieSize = serializedObject.FindProperty("m_CookieSize");
m_Color = serializedObject.FindProperty("m_Color");
m_Intensity = serializedObject.FindProperty("m_Intensity");
m_BounceIntensity = serializedObject.FindProperty("m_BounceIntensity");
m_ColorTemperature = serializedObject.FindProperty("m_ColorTemperature");
m_UseColorTemperature = serializedObject.FindProperty("m_UseColorTemperature");
m_Cookie = serializedObject.FindProperty("m_Cookie");
m_ShadowsType = serializedObject.FindProperty("m_Shadows.m_Type");
m_ShadowsStrength = serializedObject.FindProperty("m_Shadows.m_Strength");
m_ShadowsResolution = serializedObject.FindProperty("m_Shadows.m_Resolution");
m_ShadowsBias = serializedObject.FindProperty("m_Shadows.m_Bias");
m_ShadowsNormalBias = serializedObject.FindProperty("m_Shadows.m_NormalBias");
m_ShadowsNearPlane = serializedObject.FindProperty("m_Shadows.m_NearPlane");
m_Flare = serializedObject.FindProperty("m_Flare");
m_RenderMode = serializedObject.FindProperty("m_RenderMode");
m_CullingMask = serializedObject.FindProperty("m_CullingMask");
m_Lightmapping = serializedObject.FindProperty("m_Lightmapping");
m_AreaSizeX = serializedObject.FindProperty("m_AreaSize.x");
m_AreaSizeY = serializedObject.FindProperty("m_AreaSize.y");
m_BakedShadowRadius = serializedObject.FindProperty("m_ShadowRadius");
m_BakedShadowAngle = serializedObject.FindProperty("m_ShadowAngle");
// Automatically add HD data if not present
var additionalData = light.GetComponent<HDAdditionalLightData>();
var shadowData = light.GetComponent<AdditionalShadowData>();
if (additionalData == null || shadowData == null)
{
AddAdditionalComponents(additionalData, shadowData);
}
additionalDataSerializedObject = new SerializedObject(additionalData);
shadowDataSerializedObject = new SerializedObject(shadowData);
// Additional data
m_SpotInnerAngle = additionalDataSerializedObject.FindProperty("m_InnerSpotPercent");
m_LightDimmer = additionalDataSerializedObject.FindProperty("lightDimmer");
m_FadeDistance = additionalDataSerializedObject.FindProperty("fadeDistance");
m_AffectDiffuse = additionalDataSerializedObject.FindProperty("affectDiffuse");
m_AffectSpecular = additionalDataSerializedObject.FindProperty("affectSpecular");
m_LightShape = additionalDataSerializedObject.FindProperty("m_LightShape");
m_SpotLightShape = additionalDataSerializedObject.FindProperty("spotLightShape");
m_ShapeLength = additionalDataSerializedObject.FindProperty("shapeLength");
m_ShapeWidth = additionalDataSerializedObject.FindProperty("shapeWidth");
m_ShapeRadius = additionalDataSerializedObject.FindProperty("shapeRadius");
m_MaxSmoothness = additionalDataSerializedObject.FindProperty("maxSmoothness");
m_ApplyRangeAttenuation = additionalDataSerializedObject.FindProperty("applyRangeAttenuation");
// Editor only
m_UseOldInspector = additionalDataSerializedObject.FindProperty("useOldInspector");
m_ShowAdditionalSettings = additionalDataSerializedObject.FindProperty("showAdditionalSettings");
m_CastShadows = additionalDataSerializedObject.FindProperty("castShadows");
// Shadow data
m_ShadowDimmer = shadowDataSerializedObject.FindProperty("shadowDimmer");
m_ShadowFadeDistance = shadowDataSerializedObject.FindProperty("shadowFadeDistance");
m_ShadowCascadeCount = shadowDataSerializedObject.FindProperty("shadowCascadeCount");
m_ShadowCascadeRatios = shadowDataSerializedObject.FindProperty("shadowCascadeRatios");
m_ShadowResolution = shadowDataSerializedObject.FindProperty("shadowResolution");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
// Sanity check
if (additionalDataSerializedObject == null || shadowDataSerializedObject == null)
return;
additionalDataSerializedObject.Update();
shadowDataSerializedObject.Update();
var additionalData = light.GetComponent<HDAdditionalLightData>();
var shadowData = light.GetComponent<AdditionalShadowData>();
if (GUILayout.Button("Toggle light editor"))
{
m_UseOldInspector.boolValue = !m_UseOldInspector.boolValue;
}
EditorGUILayout.Space();
if (m_UseOldInspector.boolValue)
{
base.DrawDefaultInspector();
ApplyAdditionalComponentsVisibility(false);
serializedObject.ApplyModifiedProperties();
// It is required to save m_UseOldInspector value
additionalDataSerializedObject.ApplyModifiedProperties();
shadowDataSerializedObject.ApplyModifiedProperties();
return;
}
ApplyAdditionalComponentsVisibility(true);
// Light features
EditorGUI.indentLevel++;
EditorGUILayout.LabelField(new GUIContent("Light features"), EditorStyles.boldLabel);
EditorLightUtilities.DrawSplitter();
// m_affectDiffuse.isExpanded = EditorLightUtilities.DrawHeaderFoldout("Light features", m_AffectDiffuse.isExpanded);
EditorGUI.indentLevel = 1;
//Resolve shadows
m_CastShadows.boolValue = m_ShadowsType.enumValueIndex == 0 ? false : true;
/*
if (m_AffectDiffuse.isExpanded)
{
EditorGUILayout.PropertyField(m_AffectDiffuse, new GUIContent("Diffuse"), GUILayout.MaxWidth(EditorGUIUtility.labelWidth + 30));
var AffectDiffuseRect = GUILayoutUtility.GetLastRect();
var AffectSpecularRect = new Rect(EditorGUIUtility.labelWidth + 30, AffectDiffuseRect.y, EditorGUIUtility.labelWidth + 30, AffectDiffuseRect.height);
EditorGUI.PropertyField(AffectSpecularRect, m_AffectSpecular, new GUIContent("Specular"));
EditorGUILayout.PropertyField(m_CastShadows, new GUIContent("Shadows"));
}
*/
// LightShape
EditorGUI.indentLevel--;
EditorLightUtilities.DrawSplitter();
m_Type.isExpanded = EditorLightUtilities.DrawHeaderFoldout("Shape", m_Type.isExpanded);
EditorGUI.indentLevel++;
if (m_Type.isExpanded)
{
EditorGUILayout.PropertyField(m_LightShape);
// LightShape is HD specific, it need to drive Lighttype from the original lighttype when it make sense, so the GI is still in sync with the light shape
switch ((LightShape)m_LightShape.enumValueIndex)
{
case LightShape.Directional:
m_Type.enumValueIndex = (int)LightType.Directional;
break;
case LightShape.Point:
m_Type.enumValueIndex = (int)LightType.Point;
EditorGUILayout.PropertyField(m_MaxSmoothness);
break;
case LightShape.Spot:
m_Type.enumValueIndex = (int)LightType.Spot;
EditorGUILayout.PropertyField(m_SpotLightShape);
//Cone Spot
if (m_SpotLightShape.enumValueIndex == (int)SpotLightShape.Cone)
{
EditorGUILayout.Slider(m_SpotAngle, 1f, 179f);
EditorGUILayout.Slider(m_SpotInnerAngle, 0f, 100f);
}
// TODO : replace with angle and ratio
if (m_SpotLightShape.enumValueIndex == (int)SpotLightShape.Pyramid)
{
EditorGUILayout.Slider(m_ShapeLength, 0.01f, 10);
EditorGUILayout.Slider(m_ShapeWidth, 0.01f, 10);
}
if (m_SpotLightShape.enumValueIndex == (int)SpotLightShape.Box)
{
EditorGUILayout.PropertyField(m_ShapeLength);
EditorGUILayout.PropertyField(m_ShapeWidth);
}
EditorGUILayout.PropertyField(m_MaxSmoothness);
break;
case LightShape.Rectangle:
m_Type.enumValueIndex = (int)LightType.Area;
EditorGUILayout.PropertyField(m_ShapeLength);
EditorGUILayout.PropertyField(m_ShapeWidth);
m_AreaSizeX.floatValue = m_ShapeLength.floatValue;
m_AreaSizeY.floatValue = m_ShapeWidth.floatValue;
m_ShadowsType.enumValueIndex = 0; // No shadow
break;
case LightShape.Line:
m_Type.enumValueIndex = (int)LightType.Area;
EditorGUILayout.PropertyField(m_ShapeLength);
m_ShapeWidth.floatValue = 0;
// Fake line with a small rectangle in vanilla unity for GI
m_AreaSizeX.floatValue = m_ShapeLength.floatValue;
m_AreaSizeY.floatValue = 0.01f;
break;
default:
Debug.Assert(false, "Not implemented light type");
break;
}
}
// Light
EditorGUI.indentLevel--;
EditorLightUtilities.DrawSplitter();
m_Intensity.isExpanded = EditorLightUtilities.DrawHeaderFoldout("Light", m_Intensity.isExpanded);
EditorGUI.indentLevel++;
if (m_Intensity.isExpanded)
{
EditorGUILayout.PropertyField(m_Color);
EditorGUILayout.PropertyField(m_Intensity);
EditorGUILayout.PropertyField(m_BounceIntensity);
EditorGUILayout.PropertyField(m_Range);
EditorGUILayout.PropertyField(m_Lightmapping);
EditorGUILayout.PropertyField(m_Cookie);
if (m_Cookie.objectReferenceValue != null && m_Type.enumValueIndex == 1)
{
EditorGUILayout.PropertyField(m_CookieSize);
m_ShapeLength.floatValue = m_CookieSize.floatValue;
m_ShapeWidth.floatValue = m_CookieSize.floatValue;
}
}
// Shadows
if (m_CastShadows.boolValue)
m_ShadowsType.enumValueIndex = Mathf.Clamp(m_ShadowsType.enumValueIndex, 1, 2);
else
m_ShadowsType.enumValueIndex = 0; // No shadow
if (m_CastShadows.boolValue)
{
EditorGUI.indentLevel--;
EditorLightUtilities.DrawSplitter();
m_ShadowsType.isExpanded = EditorLightUtilities.DrawHeaderFoldout("Shadows", m_ShadowsType.isExpanded);
EditorGUI.indentLevel++;
if (m_ShadowsType.isExpanded)
{
if (m_Lightmapping.enumValueIndex != 1)
{
EditorGUILayout.PropertyField(m_ShadowsType);
EditorGUILayout.PropertyField(m_ShadowResolution);
EditorGUILayout.Slider(m_ShadowsBias, 0.001f, 1);
EditorGUILayout.Slider(m_ShadowsNormalBias, 0.001f, 1);
EditorGUILayout.Slider(m_ShadowsNearPlane, 0.01f, 10);
}
if (m_Lightmapping.enumValueIndex != 2)
{
switch (m_Type.enumValueIndex)
{
case 1:
EditorGUILayout.PropertyField(m_BakedShadowAngle, new GUIContent("Bake shadow angle"));
break;
case 0:
EditorGUILayout.PropertyField(m_BakedShadowRadius, new GUIContent("Bake shadow radius"));
break;
case 2:
EditorGUILayout.PropertyField(m_BakedShadowRadius, new GUIContent("Bake shadow radius"));
break;
}
}
}
}
// shadow cascade
if (m_CastShadows.boolValue && m_Type.enumValueIndex == 1)
{
EditorGUI.indentLevel--;
EditorLightUtilities.DrawSplitter();
m_ShadowCascadeCount.isExpanded = EditorLightUtilities.DrawHeaderFoldout("ShadowCascades", m_ShadowCascadeCount.isExpanded);
EditorGUI.indentLevel++;
if (m_ShadowCascadeCount.isExpanded)
{
EditorGUILayout.IntSlider(m_ShadowCascadeCount, 1, 4);
}
}
// AdditionalSettings
EditorGUI.indentLevel--;
EditorLightUtilities.DrawSplitter();
m_ShowAdditionalSettings.boolValue = EditorLightUtilities.DrawHeaderFoldout("Additional Settings", m_ShowAdditionalSettings.boolValue);
EditorGUI.indentLevel++;
if (m_ShowAdditionalSettings.boolValue)
{
EditorGUILayout.LabelField(new GUIContent("General"), EditorStyles.boldLabel);
EditorGUILayout.PropertyField(m_CullingMask);
EditorGUILayout.PropertyField(m_AffectDiffuse);
EditorGUILayout.PropertyField(m_AffectSpecular);
EditorGUILayout.PropertyField(m_FadeDistance);
EditorGUILayout.LabelField(new GUIContent("Shadows"), EditorStyles.boldLabel);
EditorGUILayout.PropertyField(m_ShadowFadeDistance);
}
EditorGUI.indentLevel--;
serializedObject.ApplyModifiedProperties();
additionalDataSerializedObject.ApplyModifiedProperties();
shadowDataSerializedObject.ApplyModifiedProperties();
}
void AddAdditionalComponents(HDAdditionalLightData additionalData, AdditionalShadowData shadowData)
{
if (additionalData == null)
additionalData = light.gameObject.AddComponent<HDAdditionalLightData>();
if (shadowData == null)
shadowData = light.gameObject.AddComponent<AdditionalShadowData>();
}
void ApplyAdditionalComponentsVisibility(bool hide)
{
var additionalData = light.GetComponent<HDAdditionalLightData>();
var shadowData = light.GetComponent<AdditionalShadowData>();
additionalData.hideFlags = hide ? HideFlags.HideInInspector : HideFlags.None;
shadowData.hideFlags = hide ? HideFlags.HideInInspector : HideFlags.None;
}
}
}

13
ScriptableRenderPipeline/HDRenderPipeline/Lighting/Editor/HDLightEditor.cs.meta


fileFormatVersion: 2
guid: f2cd83e80bf0aee45b3de08f571be4ac
timeCreated: 1505208164
licenseType: Pro
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存