浏览代码

[PlanarReflection] (wip) refactoring env lights

/main
Frédéric Vauchelles 7 年前
当前提交
a0451785
共有 28 个文件被更改,包括 485 次插入307 次删除
  1. 15
      SampleScenes/HDTest/PlanarReflectionTests.unity
  2. 21
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDReflectionProbeEditor.Handles.cs
  3. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDReflectionProbeEditor.cs
  4. 7
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDReflectionProbeUI.Drawers.cs
  5. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDReflectionProbeUI.cs
  6. 18
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/PlanarReflectionProbeUI.Drawers.cs
  7. 16
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/SerializedPlanarReflectionProbe.cs
  8. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Volume/ProjectionVolumeComponentUI.cs
  9. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Volume/ProjectionVolumeEditor.cs
  10. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Volume/SerializedProjectionVolumeComponent.cs
  11. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs
  12. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/HDAdditionalReflectionData.cs
  13. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightDefinition.cs
  14. 32
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightDefinition.cs.hlsl
  15. 260
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  16. 28
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.hlsl
  17. 15
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoopDef.hlsl
  18. 47
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightUtilities.hlsl
  19. 55
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/PlanarReflectionProbe.cs
  20. 20
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/VolumeProjection.hlsl
  21. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumes/ProjectionVolume.cs
  22. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumes/ProxyVolumeComponent.cs
  23. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumes/ProxyVolumeComponent.cs.meta
  24. 37
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  25. 150
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/ProbeWrapper.cs
  26. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/ProbeWrapper.cs.meta
  27. 0
      /ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumes/ProxyVolumeComponent.cs
  28. 0
      /ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumes/ProxyVolumeComponent.cs.meta

15
SampleScenes/HDTest/PlanarReflectionTests.unity


LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_GIWorkflowMode: 0
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1

m_Script: {fileID: 11500000, guid: a4ee7c3a3b205a14a94094d01ff91d6b, type: 3}
m_Name:
m_EditorClassIdentifier:
m_ProjectionVolumeReference: {fileID: 1654939277}
m_ProxyVolumeReference: {fileID: 0}
m_InfluenceVolume:
m_ShapeType: 0
m_BoxBaseSize: {x: 1.7052255, y: 0.9908645, z: 0.95528436}

m_BoxInfluenceNormalNegativeFade: {x: 0, y: 0.07764101, z: 0}
m_BoxPositiveFaceFade: {x: 0, y: 0, z: 0}
m_BoxNegativeFaceFade: {x: 0, y: 0, z: 0}
m_SphereBaseRadius: 0.9066355
m_SphereBaseOffset: {x: 0, y: -0.09336448, z: 0}
m_SphereInfluenceFade: 0
m_SphereInfluenceNormalFade: 0
m_SphereBaseRadius: 1.0270488
m_SphereBaseOffset: {x: 0, y: 0, z: 0}
m_SphereInfluenceFade: 0.14740431
m_SphereInfluenceNormalFade: 0.18656206
m_CaptureOffset: {x: 0, y: 0, z: 0}
m_Dimmer: 1
m_Mode: 0
--- !u!1 &1562837666
GameObject:
m_ObjectHideFlags: 0

21
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDReflectionProbeEditor.Handles.cs


using UnityEditorInternal;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
using UnityEngine.Rendering;
namespace UnityEditor.Experimental.Rendering

var mat = Handles.matrix;
var col = Handles.color;
Handles.matrix = HDReflectionProbeEditorUtility.GetLocalSpace(sp.target);
switch ((ReflectionInfluenceShape)sp.influenceShape.enumValueIndex)
switch ((ShapeType)sp.influenceShape.enumValueIndex)
case ReflectionInfluenceShape.Box:
case ShapeType.Box:
{
blendBox.center = sp.target.center - (probeBlendDistancePositive - probeBlendDistanceNegative) * 0.5f;
blendBox.size = sp.target.size - probeBlendDistancePositive - probeBlendDistanceNegative;

}
break;
}
case ReflectionInfluenceShape.Sphere:
case ShapeType.Sphere:
{
sphereHandle.center = sp.target.center;
sphereHandle.radius = Mathf.Clamp(sp.targetData.influenceSphereRadius - probeBlendDistancePositive.x, 0, sp.targetData.influenceSphereRadius);

var mat = Handles.matrix;
var col = Handles.color;
Handles.matrix = HDReflectionProbeEditorUtility.GetLocalSpace(sp.target);
switch ((ReflectionInfluenceShape)sp.influenceShape.enumValueIndex)
switch ((ShapeType)sp.influenceShape.enumValueIndex)
case ReflectionInfluenceShape.Box:
case ShapeType.Box:
{
s.boxInfluenceHandle.center = sp.target.center;
s.boxInfluenceHandle.size = sp.target.size;

}
break;
}
case ReflectionInfluenceShape.Sphere:
case ShapeType.Sphere:
{
s.sphereInfluenceHandle.center = sp.target.center;
s.sphereInfluenceHandle.radius = sp.targetData.influenceSphereRadius;

Gizmos.matrix = HDReflectionProbeEditorUtility.GetLocalSpace(p);
switch (a.influenceShape)
{
case ReflectionInfluenceShape.Box:
case ShapeType.Box:
{
Gizmos.color = color;
if (isEdit)

break;
}
case ReflectionInfluenceShape.Sphere:
case ShapeType.Sphere:
{
Gizmos.color = color;
if (isEdit)

Gizmos.matrix = HDReflectionProbeEditorUtility.GetLocalSpace(p);
switch (a.influenceShape)
{
case ReflectionInfluenceShape.Box:
case ShapeType.Box:
{
Gizmos.color = isEdit ? k_GizmoThemeColorExtentFace : k_GizmoThemeColorExtent;
if (isEdit)

break;
}
case ReflectionInfluenceShape.Sphere:
case ShapeType.Sphere:
{
Gizmos.color = k_GizmoThemeColorExtentFace;
if (isEdit)

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDReflectionProbeEditor.cs


using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEngine.SceneManagement;
namespace UnityEditor.Experimental.Rendering
{

static void ApplyConstraintsOnTargets(HDReflectionProbeUI s, SerializedHDReflectionProbe sp, Editor o)
{
switch ((ReflectionInfluenceShape)sp.influenceShape.enumValueIndex)
switch ((ShapeType)sp.influenceShape.enumValueIndex)
case ReflectionInfluenceShape.Box:
case ShapeType.Box:
{
var maxBlendDistance = HDReflectionProbeEditorUtility.CalculateBoxMaxBlendDistance(s, sp, o);
sp.targetData.blendDistancePositive = Vector3.Min(sp.targetData.blendDistancePositive, maxBlendDistance);

break;
}
case ReflectionInfluenceShape.Sphere:
case ShapeType.Sphere:
{
var maxBlendDistance = Vector3.one * HDReflectionProbeEditorUtility.CalculateSphereMaxBlendDistance(s, sp, o);
sp.targetData.blendDistancePositive = Vector3.Min(sp.targetData.blendDistancePositive, maxBlendDistance);

7
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDReflectionProbeUI.Drawers.cs


using System;
using System.Reflection;
using UnityEditor.AnimatedValues;
using UnityEditor.IMGUI.Controls;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
using UnityEngine.Rendering;

(s, p, o) => s.isSectionExpandedInfluenceVolume,
true,
CED.FadeGroup(
(s, p, o, i) => s.IsSectionExpandedShape((ReflectionInfluenceShape)i),
(s, p, o, i) => s.IsSectionExpandedShape((ShapeType)i),
false,
CED.Action(Drawer_InfluenceBoxSettings), // Box
CED.Action(Drawer_InfluenceSphereSettings) // Sphere

(s, p, o) => s.isSectionExpandedSeparateProjection,
true,
CED.FadeGroup(
(s, p, o, i) => s.IsSectionExpandedShape((ReflectionInfluenceShape)i),
(s, p, o, i) => s.IsSectionExpandedShape((ShapeType)i),
false,
CED.Action(Drawer_ProjectionBoxSettings), // Box
CED.Action(Drawer_ProjectionSphereSettings) // Sphere

5
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/HDReflectionProbeUI.cs


using UnityEditorInternal;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
using UnityEngine.Rendering;
namespace UnityEditor.Experimental.Rendering

const int k_AnimBoolSingleFieldCount = 4;
static readonly int k_ReflectionProbeModeCount = Enum.GetValues(typeof(ReflectionProbeMode)).Length;
static readonly int k_ReflectionInfluenceShapeCount = Enum.GetValues(typeof(ReflectionInfluenceShape)).Length;
static readonly int k_ReflectionInfluenceShapeCount = Enum.GetValues(typeof(ShapeType)).Length;
static readonly int k_AnimBoolsCount = k_ReflectionProbeModeCount + k_ReflectionInfluenceShapeCount + k_AnimBoolSingleFieldCount;
[Flags]

GetReflectionProbeModeBool(i).target = i == value;
}
public AnimBool IsSectionExpandedShape(ReflectionInfluenceShape value)
public AnimBool IsSectionExpandedShape(ShapeType value)
{
return m_AnimBools[k_AnimBoolSingleFieldCount + k_ReflectionProbeModeCount + (int)value];
}

18
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/PlanarReflectionProbeUI.Drawers.cs


partial class PlanarReflectionProbeUI
{
public static readonly CED.IDrawer Inspector = CED.Group(
CED.Action((s, d, o) => EditorGUILayout.LabelField(_.GetContent("Projection Volume"), EditorStyles.boldLabel)),
CED.Action(Drawer_FieldProjectionVolumeReference),
CED.Action(Drawer_SectionPrimarySettings),
CED.space,
CED.Action((s, d, o) => EditorGUILayout.LabelField(_.GetContent("Proxy Volume"), EditorStyles.boldLabel)),
CED.Action(Drawer_FieldProxyVolumeReference),
CED.space,
CED.Action((s, d, o) => EditorGUILayout.LabelField(_.GetContent("Influence Volume"), EditorStyles.boldLabel)),
CED.Action(Drawer_Toolbar),

const EditMode.SceneViewEditMode EditInfluenceShape = EditMode.SceneViewEditMode.GridBox;
const EditMode.SceneViewEditMode EditInfluenceNormalShape = EditMode.SceneViewEditMode.Collider;
const EditMode.SceneViewEditMode EditCenter = EditMode.SceneViewEditMode.ReflectionProbeOrigin;
static void Drawer_FieldProjectionVolumeReference(PlanarReflectionProbeUI s, SerializedPlanarReflectionProbe d, Editor o)
static void Drawer_SectionPrimarySettings(PlanarReflectionProbeUI s, SerializedPlanarReflectionProbe d, Editor o)
EditorGUILayout.PropertyField(d.projectionVolumeReference, _.GetContent("Reference"));
EditorGUILayout.PropertyField(d.mode, _.GetContent("Mode"));
EditorGUILayout.PropertyField(d.captureOffset, _.GetContent("Capture Position"));
EditorGUILayout.PropertyField(d.dimmer, _.GetContent("Dimmer"));
}
static void Drawer_FieldProxyVolumeReference(PlanarReflectionProbeUI s, SerializedPlanarReflectionProbe d, Editor o)
{
EditorGUILayout.PropertyField(d.proxyVolumeReference, _.GetContent("Reference"));
}
static readonly EditMode.SceneViewEditMode[] k_Toolbar_SceneViewEditModes =

16
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/SerializedPlanarReflectionProbe.cs


using UnityEngine.Experimental.Rendering.HDPipeline;
using UnityEngine;
using UnityEngine.Experimental.Rendering.HDPipeline;
using UnityEngine.Rendering;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{

public SerializedProperty projectionVolumeReference;
public SerializedProperty proxyVolumeReference;
public SerializedProperty captureOffset;
public SerializedProperty dimmer;
public SerializedProperty mode;
projectionVolumeReference = serializedObject.Find((PlanarReflectionProbe p) => p.projectionVolumeReference);
proxyVolumeReference = serializedObject.Find((PlanarReflectionProbe p) => p.proxyVolumeReference);
captureOffset = serializedObject.Find((PlanarReflectionProbe p) => p.captureOffset);
dimmer = serializedObject.Find((PlanarReflectionProbe p) => p.dimmer);
mode = serializedObject.Find((PlanarReflectionProbe p) => p.mode);
}
public void Update()

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Volume/ProjectionVolumeComponentUI.cs


base.Update();
}
public static void DrawHandles(ProjectionVolumeComponent target, ProjectionVolumeComponentUI ui)
public static void DrawHandles(ProxyVolumeComponent target, ProjectionVolumeComponentUI ui)
{
ProjectionVolumeUI.DrawHandles(target.transform, target.projectionVolume, ui.projectionVolume, target);
}

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Volume/ProjectionVolumeEditor.cs


namespace UnityEditor.Experimental.Rendering.HDPipeline
{
[CustomEditor(typeof(ProjectionVolumeComponent))]
[CustomEditor(typeof(ProxyVolumeComponent))]
ProjectionVolumeComponent[] m_TypedTargets;
ProxyVolumeComponent[] m_TypedTargets;
SerializedProjectionVolumeComponent m_SerializedData;
ProjectionVolumeComponentUI m_UIState = new ProjectionVolumeComponentUI();
ProjectionVolumeComponentUI[] m_UIHandlerState;

m_TypedTargets = targets.Cast<ProjectionVolumeComponent>().ToArray();
m_TypedTargets = targets.Cast<ProxyVolumeComponent>().ToArray();
m_SerializedData = new SerializedProjectionVolumeComponent(serializedObject);
m_UIState.Reset(m_SerializedData, Repaint);

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Lighting/Volume/SerializedProjectionVolumeComponent.cs


{
this.serializedObject = serializedObject;
projectionVolume = new SerializedProjectionVolume(serializedObject.Find((ProjectionVolumeComponent c) => c.projectionVolume));
projectionVolume = new SerializedProjectionVolume(serializedObject.Find((ProxyVolumeComponent c) => c.projectionVolume));
}
public void Update()

5
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs


public static readonly int _CookieTextures = Shader.PropertyToID("_CookieTextures");
public static readonly int _CookieCubeTextures = Shader.PropertyToID("_CookieCubeTextures");
public static readonly int _EnvTextures = Shader.PropertyToID("_EnvTextures");
public static readonly int _EnvCubemapTextures = Shader.PropertyToID("_EnvCubemapTextures");
public static readonly int _Env2DTextures = Shader.PropertyToID("_Env2DTextures");
public static readonly int _DirectionalLightDatas = Shader.PropertyToID("_DirectionalLightDatas");
public static readonly int _DirectionalLightCount = Shader.PropertyToID("_DirectionalLightCount");
public static readonly int _LightDatas = Shader.PropertyToID("_LightDatas");

public static readonly int _EnvLightDatas = Shader.PropertyToID("_EnvLightDatas");
public static readonly int _EnvProjDatas = Shader.PropertyToID("_EnvProjDatas");
public static readonly int _EnvProxyDatas = Shader.PropertyToID("_EnvProxyDatas");
public static readonly int _EnvLightCount = Shader.PropertyToID("_EnvLightCount");
public static readonly int _EnvProjCount = Shader.PropertyToID("_EnvProjCount");
public static readonly int _ShadowDatas = Shader.PropertyToID("_ShadowDatas");

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/HDAdditionalReflectionData.cs


namespace UnityEngine.Experimental.Rendering
{
public enum ReflectionInfluenceShape { Box, Sphere };
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEngine.Experimental.Rendering
{
[RequireComponent(typeof(ReflectionProbe), typeof(MeshFilter), typeof(MeshRenderer))]
public class HDAdditionalReflectionData : MonoBehaviour
{

float m_Version = 1.0f;
#pragma warning restore 414
public ReflectionInfluenceShape influenceShape;
public ShapeType influenceShape;
[Range(0.0f,1.0f)]
public float dimmer = 1.0f;
public float influenceSphereRadius = 3.0f;

9
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightDefinition.cs


};
[GenerateHLSL]
public struct EnvProjData
public struct EnvProxyData
{
public Vector3 positionWS;
public EnvShapeType envShapeType;

// Sphere: extents.x = sphere radius
public Vector3 extents;
public int unused02;
}
[GenerateHLSL]
public enum EnvCacheType
{
Texture2D,
Cubemap
}
// Usage of StencilBits.Lighting on 2 bits.

32
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightDefinition.cs.hlsl


#define ENVCONSTANTS_SPEC_CUBE_LOD_STEP (6)
//
// UnityEngine.Experimental.Rendering.HDPipeline.EnvCacheType: static fields
//
#define ENVCACHETYPE_TEXTURE2D (0)
#define ENVCACHETYPE_CUBEMAP (1)
//
// UnityEngine.Experimental.Rendering.HDPipeline.StencilLightingUsage: static fields
//
#define STENCILLIGHTINGUSAGE_NO_LIGHTING (0)

float unused7;
};
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.EnvProjData
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.EnvProxyData
struct EnvProjData
struct EnvProxyData
{
float3 positionWS;
int envShapeType;

}
//
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.EnvProjData
// Accessors for UnityEngine.Experimental.Rendering.HDPipeline.EnvProxyData
float3 GetPositionWS(EnvProjData value)
float3 GetPositionWS(EnvProxyData value)
int GetEnvShapeType(EnvProjData value)
int GetEnvShapeType(EnvProxyData value)
float3 GetForward(EnvProjData value)
float3 GetForward(EnvProxyData value)
float GetMinProjectionDistance(EnvProjData value)
float GetMinProjectionDistance(EnvProxyData value)
float3 GetUp(EnvProjData value)
float3 GetUp(EnvProxyData value)
int GetUnused00(EnvProjData value)
int GetUnused00(EnvProxyData value)
float3 GetRight(EnvProjData value)
float3 GetRight(EnvProxyData value)
int GetUnused01(EnvProjData value)
int GetUnused01(EnvProxyData value)
float3 GetExtents(EnvProjData value)
float3 GetExtents(EnvProxyData value)
int GetUnused02(EnvProjData value)
int GetUnused02(EnvProxyData value)
{
return value.unused02;
}

260
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs


static ComputeBuffer s_DirectionalLightDatas = null;
static ComputeBuffer s_LightDatas = null;
static ComputeBuffer s_EnvLightDatas = null;
static ComputeBuffer s_EnvProjDatas = null;
static ComputeBuffer s_EnvProxyDatas = null;
static ComputeBuffer s_shadowDatas = null;
static Texture2DArray s_DefaultTexture2DArray;

static HDAdditionalLightData defaultHDAdditionalLightData { get { return ComponentSingleton<HDAdditionalLightData>.instance; } }
static HDAdditionalCameraData defaultHDAdditionalCameraData { get { return ComponentSingleton<HDAdditionalCameraData>.instance; } }
ReflectionProbeCache m_ReflectionPlanarProbeCache;
ReflectionProbeCache m_ReflectionProbeCache;
TextureCache2D m_CookieTexArray;
TextureCacheCubemap m_CubeCookieTexArray;

public List<DirectionalLightData> directionalLights;
public List<LightData> lights;
public List<EnvLightData> envLights;
public List<EnvProjData> envProjs;
public List<EnvProxyData> envProxies;
public List<ShadowData> shadows;
public List<SFiniteLightBound> bounds;

directionalLights.Clear();
lights.Clear();
envLights.Clear();
envProjs.Clear();
envProxies.Clear();
shadows.Clear();
bounds.Clear();

directionalLights = new List<DirectionalLightData>();
lights = new List<LightData>();
envLights = new List<EnvLightData>();
envProjs = new List<EnvProjData>();
envProxies = new List<EnvProxyData>();
shadows = new List<ShadowData>();
bounds = new List<SFiniteLightBound>();

s_DirectionalLightDatas = new ComputeBuffer(k_MaxDirectionalLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLightData)));
s_LightDatas = new ComputeBuffer(k_MaxPunctualLightsOnScreen + k_MaxAreaLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_EnvLightDatas = new ComputeBuffer(k_MaxEnvLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
s_EnvProjDatas = new ComputeBuffer(k_MaxEnvLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvProjData)));
s_EnvProxyDatas = new ComputeBuffer(k_MaxEnvLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvProxyData)));
s_shadowDatas = new ComputeBuffer(k_MaxCascadeCount + k_MaxShadowOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowData)));
GlobalLightLoopSettings gLightLoopSettings = hdAsset.GetRenderPipelineSettings().lightLoopSettings;

CoreUtils.SafeRelease(s_DirectionalLightDatas);
CoreUtils.SafeRelease(s_LightDatas);
CoreUtils.SafeRelease(s_EnvLightDatas);
CoreUtils.SafeRelease(s_EnvProjDatas);
CoreUtils.SafeRelease(s_EnvProxyDatas);
CoreUtils.SafeRelease(s_shadowDatas);
if (m_ReflectionProbeCache != null)

m_lightList.lightVolumes.Add(lightVolumeData);
}
class ProbeWrapper
{
public Vector3 influencePositionWS;
public Vector3 offsetLS;
public Vector3 projectionPositionWS;
public ProbeWrapper(VisibleReflectionProbe probe, PlanarReflectionProbe planarProbe)
{
}
public EnvShapeType influenceShapeType { get; set; }
public float dimmer { get; set; }
public Vector3 influenceExtents { get; set; }
public Vector3 blendNormalDistancePositive { get; set; }
public Vector3 blendNormalDistanceNegative { get; set; }
public Vector3 blendDistancePositive { get; set; }
public Vector3 blendDistanceNegative { get; set; }
public Vector3 boxSideFadePositive { get; set; }
public Vector3 boxSideFadeNegative { get; set; }
public Vector3 influenceRight { get; set; }
public Vector3 influenceUp { get; set; }
public Vector3 influenceForward { get; set; }
public EnvShapeType projectionShapeType { get; set; }
public Vector3 projectionRight { get; set; }
public Vector3 projectionUp { get; set; }
public Vector3 projectionForward { get; set; }
public Vector3 projectionExtents { get; set; }
public float minProjectionDistance { get; set; }
}
public bool GetEnvLightData(CommandBuffer cmd, Camera camera, VisibleReflectionProbe probe, PlanarReflectionProbe planarProbe)
public bool GetEnvLightData(CommandBuffer cmd, Camera camera, ProbeWrapper probe)
var p = new ProbeWrapper(probe, planarProbe);
if (probe.probe.mode == ReflectionProbeMode.Realtime && camera.cameraType == CameraType.Reflection)
if (probe.mode == ReflectionProbeMode.Realtime && camera.cameraType == CameraType.Reflection)
int envIndex = m_ReflectionProbeCache.FetchSlice(cmd, probe.texture);
// 31 bits index, 1 bit cache type
var envIndex = -1;
switch (probe.texture.dimension)
{
case TextureDimension.Tex2D:
// TODO: Do Planar Reflection Cache
//envIndex = m_ReflectionPlanarProbeCache.FetchSlice(cmd, probe.texture);
//envIndex = envIndex << 1 | (int) ProbeCacheType.Texture2D;
break;
case TextureDimension.Cube:
envIndex = m_ReflectionProbeCache.FetchSlice(cmd, probe.texture);
envIndex = envIndex << 1 | (int)EnvCacheType.Cubemap;
break;
}
// Build light data
envLightData.envShapeType = p.influenceShapeType;
envLightData.dimmer = p.dimmer;
envLightData.positionWS = p.influencePositionWS;
envLightData.influenceExtents = p.influenceExtents;
envLightData.blendNormalDistancePositive = p.blendNormalDistancePositive;
envLightData.blendNormalDistanceNegative = p.blendNormalDistanceNegative;
envLightData.blendDistancePositive = p.blendDistancePositive;
envLightData.blendDistanceNegative = p.blendDistanceNegative;
envLightData.boxSideFadePositive = p.boxSideFadePositive;
envLightData.boxSideFadeNegative = p.boxSideFadeNegative;
envLightData.envShapeType = probe.influenceShapeType;
envLightData.dimmer = probe.dimmer;
envLightData.influenceExtents = probe.influenceExtents;
envLightData.blendNormalDistancePositive = probe.blendNormalDistancePositive;
envLightData.blendNormalDistanceNegative = probe.blendNormalDistanceNegative;
envLightData.blendDistancePositive = probe.blendDistancePositive;
envLightData.blendDistanceNegative = probe.blendDistanceNegative;
envLightData.boxSideFadePositive = probe.boxSideFadePositive;
envLightData.boxSideFadeNegative = probe.boxSideFadeNegative;
envLightData.right = p.influenceRight;
envLightData.up = p.influenceUp;
envLightData.forward = p.influenceForward;
var influenceToWorld = probe.influenceToWorld;
envLightData.right = influenceToWorld.GetColumn(0).normalized;
envLightData.up = influenceToWorld.GetColumn(1).normalized;
envLightData.forward = influenceToWorld.GetColumn(2).normalized;
envLightData.positionWS = influenceToWorld.GetColumn(3);
envLightData.offsetLS = p.offsetLS;
envLightData.offsetLS = probe.captureOffsetLS;
var envProjData = new EnvProjData();
envProjData.envShapeType = p.projectionShapeType;
envProjData.right = p.projectionRight;
envProjData.up = p.projectionUp;
envProjData.forward = p.projectionForward;
envProjData.extents = p.projectionExtents;
envProjData.positionWS = p.projectionPositionWS;
envProjData.minProjectionDistance = p.minProjectionDistance;
m_lightList.envProjs.Add(envProjData);
#if false
var additionalData = GetHDAdditionalReflectionData(probe);
var extents = probe.bounds.extents;
var influenceBlendDistancePositive = Vector3.one * probe.blendDistance;
var influenceBlendDistanceNegative = Vector3.one * probe.blendDistance;
// For now we won't display real time probe when rendering one.
// TODO: We may want to display last frame result but in this case we need to be careful not to update the atlas before all realtime probes are rendered (for frame coherency).
// Unfortunately we don't have this information at the moment.
if (probe.probe.mode == ReflectionProbeMode.Realtime && camera.cameraType == CameraType.Reflection)
return false;
int envIndex = m_ReflectionProbeCache.FetchSlice(cmd, probe.texture);
// -1 means that the texture is not ready yet (ie not convolved/compressed yet)
if (envIndex == -1)
return false;
var envLightData = new EnvLightData();
var envProjData = new EnvProjData();
// CAUTION: localToWorld is the transform for the widget of the reflection probe. i.e the world position of the point use to do the cubemap capture (mean it include the local offset)
envLightData.positionWS = probe.localToWorld.GetColumn(3);
envProjData.positionWS = envLightData.positionWS;
envLightData.boxSideFadePositive = Vector3.one;
envLightData.boxSideFadeNegative = Vector3.one;
// Build projection data
var envProxyData = new EnvProxyData();
envProxyData.envShapeType = probe.proxyShapeType;
envProxyData.extents = probe.proxyExtents;
envProxyData.minProjectionDistance = probe.infiniteProjection ? 65504f : 0;
envLightData.minProjectionDistance = 0;
switch (additionalData.influenceShape)
{
case ReflectionInfluenceShape.Box:
{
envLightData.envShapeType = EnvShapeType.Box;
envProjData.envShapeType = EnvShapeType.Box;
envLightData.boxSideFadePositive = additionalData.boxSideFadePositive;
envLightData.boxSideFadeNegative = additionalData.boxSideFadeNegative;
break;
}
case ReflectionInfluenceShape.Sphere:
envLightData.envShapeType = EnvShapeType.Sphere;
envProjData.envShapeType = EnvShapeType.Sphere;
extents = Vector3.one * additionalData.influenceSphereRadius;
break;
}
var proxyToWorld = probe.proxyToWorld;
envProxyData.right = proxyToWorld.GetColumn(0).normalized;
envProxyData.up = proxyToWorld.GetColumn(1).normalized;
envProxyData.forward = proxyToWorld.GetColumn(2).normalized;
envProxyData.positionWS = proxyToWorld.GetColumn(3);
if (probe.boxProjection == 0)
envLightData.minProjectionDistance = 65504.0f;
envLightData.dimmer = additionalData.dimmer;
envLightData.blendNormalDistancePositive = additionalData.blendNormalDistancePositive;
envLightData.blendNormalDistanceNegative = additionalData.blendNormalDistanceNegative;
influenceBlendDistancePositive = additionalData.blendDistancePositive;
influenceBlendDistanceNegative = additionalData.blendDistanceNegative;
// remove scale from the matrix (Scale in this matrix is use to scale the widget)
envLightData.right = probe.localToWorld.GetColumn(0).normalized;
envLightData.up = probe.localToWorld.GetColumn(1).normalized;
envLightData.forward = probe.localToWorld.GetColumn(2).normalized;
envProjData.right = envLightData.right;
envProjData.up = envLightData.up;
envProjData.forward = envLightData.forward;
// Artists prefer to have blend distance inside the volume!
// So we let the current UI but we assume blendDistance is an inside factor instead
// Blend distance can't be larger than the max radius
// probe.bounds.extents is BoxSize / 2
var blendDistancePositive = Vector3.Min(probe.bounds.extents, influenceBlendDistancePositive);
var blendDistanceNegative = Vector3.Min(probe.bounds.extents, influenceBlendDistanceNegative);
envLightData.influenceExtents = extents;
envProjData.extents = extents;
envLightData.envIndex = envIndex;
envLightData.offsetLS = probe.center; // center is misnamed, it is the offset (in local space) from center of the bounding box to the cubemap capture point
envLightData.blendDistancePositive = blendDistancePositive;
envLightData.blendDistanceNegative = blendDistanceNegative;
m_lightList.envLights.Add(envLightData);
m_lightList.envProjs.Add(envProjData);
#endif
m_lightList.envProxies.Add(envProxyData);
public void GetEnvLightVolumeDataAndBound(VisibleReflectionProbe probe, PlanarReflectionProbe planarProbe, LightVolumeType lightVolumeType, Matrix4x4 worldToView)
public void GetEnvLightVolumeDataAndBound(ProbeWrapper probe, LightVolumeType lightVolumeType, Matrix4x4 worldToView)
var add = GetHDAdditionalReflectionData(probe);
var centerOffset = probe.center; // reflection volume offset relative to cube map capture point
var mat = probe.localToWorld;
var mat = probe.influenceToWorld;
Vector3 vx = mat.GetColumn(0);
Vector3 vy = mat.GetColumn(1);
Vector3 vz = mat.GetColumn(2);
Vector3 vw = mat.GetColumn(3);
vx.Normalize(); // Scale shouldn't affect the probe or its bounds
vy.Normalize();
vz.Normalize();
var vx = mat.GetColumn(0).normalized; // Scale shouldn't affect the probe or its bounds
var vy = mat.GetColumn(1).normalized;
var vz = mat.GetColumn(2).normalized;
var vw = mat.GetColumn(3);
var influenceExtents = probe.bounds.extents; // 0.5f * Vector3.Max(-boxSizes[p], boxSizes[p]);
var centerWS = vx * centerOffset.x + vy * centerOffset.y + vz * centerOffset.z + vw;
var influenceExtents = probe.influenceExtents; // 0.5f * Vector3.Max(-boxSizes[p], boxSizes[p]);
// transform to camera space (becomes a left hand coordinate frame in Unity since Determinant(worldToView)<0)
vx = worldToView.MultiplyVector(vx);

var centerVS = worldToView.MultiplyPoint(centerWS);
var influencePositionVS = worldToView.MultiplyPoint(vw);
lightVolumeData.lightCategory = (uint)LightCategory.Env;
lightVolumeData.lightVolume = (uint)lightVolumeType;

{
case LightVolumeType.Sphere:
{
lightVolumeData.lightPos = centerVS;
lightVolumeData.radiusSq = add.influenceSphereRadius * add.influenceSphereRadius;
lightVolumeData.lightPos = influencePositionVS;
lightVolumeData.radiusSq = influenceExtents.x * influenceExtents.x;
bound.center = centerVS;
bound.boxAxisX = vx * add.influenceSphereRadius;
bound.boxAxisY = vy * add.influenceSphereRadius;
bound.boxAxisZ = vz * add.influenceSphereRadius;
bound.center = influencePositionVS;
bound.boxAxisX = vx * influenceExtents.x;
bound.boxAxisY = vy * influenceExtents.x;
bound.boxAxisZ = vz * influenceExtents.x;
bound.radius = add.influenceSphereRadius;
bound.radius = influenceExtents.x;
bound.center = centerVS;
bound.center = influencePositionVS;
bound.boxAxisX = influenceExtents.x * vx;
bound.boxAxisY = influenceExtents.y * vy;
bound.boxAxisZ = influenceExtents.z * vz;

// The culling system culls pixels that are further
// than a threshold to the box influence extents.
// So we use an arbitrary threshold here (k_BoxCullingExtentOffset)
lightVolumeData.lightPos = centerVS;
lightVolumeData.lightPos = influencePositionVS;
lightVolumeData.lightAxisX = vx;
lightVolumeData.lightAxisY = vy;
lightVolumeData.lightAxisZ = vz;

}
LightVolumeType lightVolumeType = LightVolumeType.Box;
if (additional != null && additional.influenceShape == ReflectionInfluenceShape.Sphere)
if (additional != null && additional.influenceShape == ShapeType.Sphere)
lightVolumeType = LightVolumeType.Sphere;
++envLightCount;

else
planarProbe = reflectionProbeCullResults.visiblePlanarReflectionProbes[probeIndex];
if (GetEnvLightData(cmd, camera, probe, planarProbe))
var probeWrapper = ProbeWrapper.Wrap(probe, planarProbe);
if (GetEnvLightData(cmd, camera, probeWrapper))
GetEnvLightVolumeDataAndBound(probe, planarProbe, lightVolumeType, worldToView);
GetEnvLightVolumeDataAndBound(probeWrapper, lightVolumeType, worldToView);
// We make the light position camera-relative as late as possible in order
// to allow the preceding code to work with the absolute world space coordinates.

envLightData.positionWS -= camPosWS;
m_lightList.envLights[n - 1] = envLightData;
var envProjData = m_lightList.envProjs[n - 1];
var envProjData = m_lightList.envProxies[n - 1];
m_lightList.envProjs[n - 1] = envProjData;
m_lightList.envProxies[n - 1] = envProjData;
}
}
}

Debug.Assert(m_lightList.bounds.Count == m_lightCount);
Debug.Assert(m_lightList.lightVolumes.Count == m_lightCount);
Debug.Assert(m_lightList.envProjs.Count == m_lightList.envLights.Count);
Debug.Assert(m_lightList.envProxies.Count == m_lightList.envLights.Count);
UpdateDataBuffers();

s_DirectionalLightDatas.SetData(m_lightList.directionalLights);
s_LightDatas.SetData(m_lightList.lights);
s_EnvLightDatas.SetData(m_lightList.envLights);
s_EnvProjDatas.SetData(m_lightList.envProjs);
s_EnvProxyDatas.SetData(m_lightList.envProxies);
s_shadowDatas.SetData(m_lightList.shadows);
// These two buffers have been set in Rebuild()

add = defaultHDAdditionalReflectionData;
add.blendDistancePositive = Vector3.one * probe.blendDistance;
add.blendDistanceNegative = add.blendDistancePositive;
add.influenceShape = ReflectionInfluenceShape.Box;
add.influenceShape = ShapeType.Box;
}
return add;
}

cmd.SetGlobalTexture(HDShaderIDs._CookieTextures, m_CookieTexArray.GetTexCache());
cmd.SetGlobalTexture(HDShaderIDs._CookieCubeTextures, m_CubeCookieTexArray.GetTexCache());
cmd.SetGlobalTexture(HDShaderIDs._EnvTextures, m_ReflectionProbeCache.GetTexCache());
cmd.SetGlobalTexture(HDShaderIDs._EnvCubemapTextures, m_ReflectionProbeCache.GetTexCache());
cmd.SetGlobalTexture(HDShaderIDs._Env2DTextures, m_ReflectionPlanarProbeCache.GetTexCache());
cmd.SetGlobalBuffer(HDShaderIDs._DirectionalLightDatas, s_DirectionalLightDatas);
cmd.SetGlobalInt(HDShaderIDs._DirectionalLightCount, m_lightList.directionalLights.Count);

cmd.SetGlobalBuffer(HDShaderIDs._EnvLightDatas, s_EnvLightDatas);
cmd.SetGlobalBuffer(HDShaderIDs._EnvProjDatas, s_EnvProjDatas);
cmd.SetGlobalBuffer(HDShaderIDs._EnvProxyDatas, s_EnvProxyDatas);
cmd.SetGlobalInt(HDShaderIDs._EnvProjCount, m_lightList.envProjs.Count);
cmd.SetGlobalInt(HDShaderIDs._EnvProjCount, m_lightList.envProxies.Count);
cmd.SetGlobalBuffer(HDShaderIDs._ShadowDatas, s_shadowDatas);
cmd.SetGlobalInt(HDShaderIDs._NumTileFtplX, GetNumTileFtplX(camera));

28
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.hlsl


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LightLoop
// ----------------------------------------------------------------------------

#else
uint envLightIndex = i;
#endif
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, _EnvLightDatas[envLightIndex], _EnvProjDatas[envLightIndex], bsdfData, _EnvLightDatas[envLightIndex].envShapeType,
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, _EnvLightDatas[envLightIndex], _EnvProxyDatas[envLightIndex], bsdfData,
_EnvLightDatas[envLightIndex].envShapeType, _EnvProxyDatas[envLightIndex].envShapeType,
GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION, reflectionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);
}

#else
uint envLightIndex = i;
#endif
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, _EnvLightDatas[envLightIndex], _EnvProjDatas[envLightIndex], bsdfData, _EnvLightDatas[envLightIndex].envShapeType,
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, _EnvLightDatas[envLightIndex], _EnvProxyDatas[envLightIndex], bsdfData,
_EnvLightDatas[envLightIndex].envShapeType, _EnvProxyDatas[envLightIndex].envShapeType,
GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION, refractionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);
}

{
// The sky is a single cubemap texture separate from the reflection probe texture array (different resolution and compression)
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_SKY;
EnvLightData envLightSky = InitSkyEnvLightData(0); // The sky data are generated on the fly so the compiler can optimize the code
IndirectLighting lighting = EvaluateBSDF_Env(context, V, posInput, preLightData, envLightSky, (EnvProjData) 0, bsdfData, ENVSHAPETYPE_SKY, GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION, reflectionHierarchyWeight);
// The sky data are generated on the fly so the compiler can optimize the code
EnvLightData envLightSky = InitSkyEnvLightData(0);
EnvProxyData envProxySky = InitSkyEnvProxyData(0);
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, envLightSky, envProxySky, bsdfData,
ENVSHAPETYPE_SKY, ENVSHAPETYPE_SKY,
GPUIMAGEBASEDLIGHTINGTYPE_REFLECTION, reflectionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);
}

{
// The sky is a single cubemap texture separate from the reflection probe texture array (different resolution and compression)
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_SKY;
EnvLightData envLightSky = InitSkyEnvLightData(0); // The sky data are generated on the fly so the compiler can optimize the code
IndirectLighting lighting = EvaluateBSDF_Env(context, V, posInput, preLightData, envLightSky, (EnvProjData) 0, bsdfData, ENVSHAPETYPE_SKY, GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION, refractionHierarchyWeight);
// The sky data are generated on the fly so the compiler can optimize the code
EnvLightData envLightSky = InitSkyEnvLightData(0);
EnvProxyData envProxySky = InitSkyEnvProxyData(0);
IndirectLighting lighting = EvaluateBSDF_Env( context, V, posInput, preLightData, envLightSky, envProxySky, bsdfData,
ENVSHAPETYPE_SKY, ENVSHAPETYPE_SKY,
GPUIMAGEBASEDLIGHTINGTYPE_REFRACTION, refractionHierarchyWeight);
AccumulateIndirectLighting(lighting, aggregateLighting);
}
}

15
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoopDef.hlsl


StructuredBuffer<DirectionalLightData> _DirectionalLightDatas;
StructuredBuffer<LightData> _LightDatas;
StructuredBuffer<EnvLightData> _EnvLightDatas;
StructuredBuffer<EnvProjData> _EnvProjDatas;
StructuredBuffer<EnvProxyData> _EnvProxyDatas;
StructuredBuffer<ShadowData> _ShadowDatas;
// Used by directional and spot lights

TEXTURECUBE_ARRAY_ABSTRACT(_CookieCubeTextures);
// Use texture array for reflection (or LatLong 2D array for mobile)
TEXTURECUBE_ARRAY_ABSTRACT(_EnvTextures);
TEXTURECUBE_ARRAY_ABSTRACT(_EnvCubemapTextures);
TEXTURE2D_ARRAY(_Env2DTextures);
TEXTURE2D(_DeferredShadowTexture);

// EnvIndex can also be use to fetch in another array of struct (to atlas information etc...).
float4 SampleEnv(LightLoopContext lightLoopContext, int index, float3 texCoord, float lod)
{
// 31 bit index, 1 bit cache type
uint cacheType = index & 1;
index = index >> 1;
return SAMPLE_TEXTURECUBE_ARRAY_LOD_ABSTRACT(_EnvTextures, s_trilinear_clamp_sampler, texCoord, index, lod);
if (index == ENVCACHETYPE_TEXTURE2D)
return SAMPLE_TEXTURE2D_ARRAY_LOD(_Env2DTextures, s_trilinear_clamp_sampler, texCoord.xy, index, lod);
else if (index == ENVCACHETYPE_CUBEMAP)
return SAMPLE_TEXTURECUBE_ARRAY_LOD_ABSTRACT(_EnvCubemapTextures, s_trilinear_clamp_sampler, texCoord, index, lod);
return float4(0, 0, 0, 0);
}
else // SINGLE_PASS_SAMPLE_SKY
{

47
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightUtilities.hlsl


#ifndef UNITY_LIGHT_UTILITIES_INCLUDED
#ifndef UNITY_LIGHT_UTILITIES_INCLUDED
#define UNITY_LIGHT_UTILITIES_INCLUDED
#include "LightDefinition.cs.hlsl"

EnvLightData InitSkyEnvLightData(int envIndex)
{
EnvLightData output;
output.envShapeType = ENVSHAPETYPE_SKY;
output.envIndex = envIndex;
output.forward = float3(0.0, 0.0, 1.0);
output.up = float3(0.0, 1.0, 0.0);
output.right = float3(1.0, 0.0, 0.0);
output.positionWS = float3(0.0, 0.0, 0.0);
output.offsetLS = float3(0.0, 0.0, 0.0);
output.influenceExtents = float3(0.0, 0.0, 0.0);
output.blendDistancePositive = float3(0.0, 0.0, 0.0);
output.blendDistanceNegative = float3(0.0, 0.0, 0.0);
output.blendNormalDistancePositive = float3(0.0, 0.0, 0.0);
output.blendNormalDistanceNegative = float3(0.0, 0.0, 0.0);
output.boxSideFadePositive = float3(0.0, 0.0, 0.0);
output.boxSideFadeNegative = float3(0.0, 0.0, 0.0);
output.dimmer = 1.0;
output.envShapeType = ENVSHAPETYPE_SKY;
output.envIndex = envIndex;
output.forward = float3(0.0, 0.0, 1.0);
output.up = float3(0.0, 1.0, 0.0);
output.right = float3(1.0, 0.0, 0.0);
output.positionWS = float3(0.0, 0.0, 0.0);
output.offsetLS = float3(0.0, 0.0, 0.0);
output.influenceExtents = float3(0.0, 0.0, 0.0);
output.blendDistancePositive = float3(0.0, 0.0, 0.0);
output.blendDistanceNegative = float3(0.0, 0.0, 0.0);
output.blendNormalDistancePositive = float3(0.0, 0.0, 0.0);
output.blendNormalDistanceNegative = float3(0.0, 0.0, 0.0);
output.boxSideFadePositive = float3(0.0, 0.0, 0.0);
output.boxSideFadeNegative = float3(0.0, 0.0, 0.0);
output.dimmer = 1.0;
return output;
}
EnvProxyData InitSkyEnvProxyData(int envIndex)
{
EnvProxyData output;
output.positionWS = float3(0.0, 0.0, 0.0);
output.envShapeType = ENVSHAPETYPE_SKY;
output.forward = float3(0.0, 0.0, 1.0);
output.up = float3(0.0, 1.0, 0.0);
output.right = float3(1.0, 0.0, 0.0);
output.minProjectionDistance = 65504.0f;
output.extents = float3(0.0, 0.0, 0.0);
return output;
}

55
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/PlanarReflectionProbe.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline
ProjectionVolumeComponent m_ProjectionVolumeReference;
ProxyVolumeComponent m_ProxyVolumeReference;
[SerializeField]
Vector3 m_CaptureOffset;
[SerializeField]
[Range(0, 1)]
float m_Dimmer = 1;
[SerializeField]
ReflectionProbeMode m_Mode = ReflectionProbeMode.Baked;
public ProjectionVolumeComponent projectionVolumeReference { get { return m_ProjectionVolumeReference; } }
public ProxyVolumeComponent proxyVolumeReference { get { return m_ProxyVolumeReference; } }
public BoundingSphere boundingSphere { get { return m_InfluenceVolume.GetBoundingSphereAt(transform); } }
public Texture texture { get; private set; }
public Bounds bounds { get { return m_InfluenceVolume.GetBoundsAt(transform); } }
public Matrix4x4 influenceToWorld { get { return transform.localToWorldMatrix; } }
public Vector3 captureOffset { get { return m_CaptureOffset; } }
public float dimmer { get { return m_Dimmer; } }
public ReflectionProbeMode mode { get { return m_Mode; } }
public BoundingSphere boundingSphere
#region Proxy Properties
public Matrix4x4 proxyToWorld
{
get
{
return m_ProxyVolumeReference != null
? m_ProxyVolumeReference.transform.localToWorldMatrix
: transform.localToWorldMatrix;
}
}
public ShapeType proxyShape
{
get
{
return m_ProxyVolumeReference != null
? m_ProxyVolumeReference.projectionVolume.shapeType
: influenceVolume.shapeType;
}
}
public Vector3 proxyExtents
get { return m_InfluenceVolume.GetBoundingSphereAt(transform); }
get
{
return m_ProxyVolumeReference != null
? m_ProxyVolumeReference.projectionVolume.boxSize
: influenceVolume.boxBaseSize;
}
public Texture texture { get; private set; }
public Bounds bounds { get { return m_InfluenceVolume.GetBoundsAt(transform); } }
public bool infiniteProjection { get { return m_ProxyVolumeReference != null && m_ProxyVolumeReference.projectionVolume.infiniteProjection; } }
#endregion
void OnEnable()
{

20
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/VolumeProjection.hlsl


#define ENVMAP_FEATURE_PERFACEFADE
#define ENVMAP_FEATURE_INFLUENCENORMAL
float3x3 WorldToProjectionSpace(EnvProjData projData)
float3x3 WorldToProxySpace(EnvProxyData proxyData)
return transpose(float3x3(projData.right, projData.up, projData.forward)); // worldToLocal assume no scaling
return transpose(float3x3(proxyData.right, proxyData.up, proxyData.forward)); // worldToLocal assume no scaling
float3 WorldToProjectionPosition(EnvProjData projData, float3x3 worldToLS, float3 positionWS)
float3 WorldToProjectionPosition(EnvProxyData proxyData, float3x3 worldToLS, float3 positionWS)
float3 positionLS = positionWS - projData.positionWS;
float3 positionLS = positionWS - proxyData.positionWS;
float IntersectSphereProxy(EnvProjData projData, float3 dirPS, float3 positionPS)
float IntersectSphereProxy(EnvProxyData proxyData, float3 dirPS, float3 positionPS)
float sphereOuterDistance = projData.extents.x;
float sphereOuterDistance = proxyData.extents.x;
projectionDistance = max(projectionDistance, projData.minProjectionDistance); // Setup projection to infinite if requested (mean no projection shape)
projectionDistance = max(projectionDistance, proxyData.minProjectionDistance); // Setup projection to infinite if requested (mean no projection shape)
float IntersectBoxProxy(EnvProjData projData, float3 dirPS, float3 positionPS)
float IntersectBoxProxy(EnvProxyData proxyData, float3 dirPS, float3 positionPS)
float3 boxOuterDistance = projData.extents;
float3 boxOuterDistance = proxyData.extents;
projectionDistance = max(projectionDistance, projData.minProjectionDistance); // Setup projection to infinite if requested (mean no projection shape)
projectionDistance = max(projectionDistance, proxyData.minProjectionDistance); // Setup projection to infinite if requested (mean no projection shape)
return projectionDistance;
}

9
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumes/ProjectionVolume.cs


public float sphereRadius { get { return m_SphereRadius; } set { m_SphereRadius = value; } }
public Vector3 sphereOffset { get { return m_SphereOffset; } set { m_SphereOffset = value; } }
public bool sphereInfiniteProjection { get { return m_SphereInfiniteProjection; } }
public bool infiniteProjection
{
get
{
return shapeType == ShapeType.Box && boxInfiniteProjection
|| shapeType == ShapeType.Sphere && sphereInfiniteProjection;
}
}
}
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumes/ProxyVolumeComponent.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public class ProjectionVolumeComponent : MonoBehaviour
public class ProxyVolumeComponent : MonoBehaviour
{
[SerializeField]
ProjectionVolume m_ProjectionVolume = new ProjectionVolume();

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumes/ProxyVolumeComponent.cs.meta


fileFormatVersion: 2
guid: 86d2527ad2205af4b9326464d02c7642
guid: d5c61b7a04f29ad49a0985f4fb6c436d
MonoImporter:
externalObjects: {}
serializedVersion: 2

37
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl


// _preIntegratedFGD and _CubemapLD are unique for each BRDF
IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext,
float3 V, PositionInputs posInput,
PreLightData preLightData, EnvLightData lightData, EnvProjData projData, BSDFData bsdfData, int envShapeType, int GPUImageBasedLightingType,
PreLightData preLightData, EnvLightData lightData, EnvProxyData proxyData, BSDFData bsdfData,
int influenceShapeType, int projectionShapeType, int GPUImageBasedLightingType,
inout float hierarchyWeight)
{
IndirectLighting lighting;

float3x3 worldToLS = WorldToLightSpace(lightData);
float3 positionLS = WorldToLightPosition(lightData, worldToLS, positionWS);
float3 dirLS = mul(R, worldToLS); // Projection and influence share the space
float3 dirPS = dirLS;
// Note: using envShapeType instead of lightData.envShapeType allow to make compiler optimization in case the type is know (like for sky)
if (envShapeType == ENVSHAPETYPE_SPHERE)
// 1. First process the projection
// Note: using influenceShapeType and projectionShapeType instead of (lightData|proxyData).shapeType allow to make compiler optimization in case the type is know (like for sky)
if (projectionShapeType == ENVSHAPETYPE_SPHERE)
// 1. First process the projection
float3 dirPS = mul(R, worldToPS);
float projectionDistance = IntersectSphereProxy(projData, dirPS, positionPS);
float projectionDistance = IntersectSphereProxy(proxyData, dirPS, positionPS);
// We can reuse dist calculate in LS directly in WS as there is no scaling. Also the offset is already include in lightData.positionWS
R = (positionWS + projectionDistance * R) - lightData.positionWS;

dirPS = mul(coatR, worldToPS);
projectionDistance = IntersectSphereProxy(projData, dirPS, positionPS);
projectionDistance = IntersectSphereProxy(proxyData, dirPS, positionPS);
// 2. Process the influence
float3 dirLS = dirPS; // Projection and influence share the space
weight = InfluenceSphereWeight(lightData, bsdfData, positionWS, positionLS, dirLS);
else if (envShapeType == ENVSHAPETYPE_BOX)
else if (projectionShapeType == ENVSHAPETYPE_BOX)
// 1. First process the projection
float3 dirPS = mul(R, worldToPS);
float projectionDistance = IntersectBoxProxy(projData, dirPS, positionPS);
float projectionDistance = IntersectBoxProxy(proxyData, dirPS, positionPS);
// No need to normalize for fetching cubemap
// We can reuse dist calculate in LS directly in WS as there is no scaling. Also the offset is already include in lightData.positionWS
R = (positionWS + projectionDistance * R) - lightData.positionWS;

if (bsdfData.materialId == MATERIALID_LIT_CLEAR_COAT && HasMaterialFeatureFlag(MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
dirPS = mul(coatR, worldToPS);
projectionDistance = IntersectBoxProxy(projData, dirPS, positionPS);
projectionDistance = IntersectBoxProxy(proxyData, dirPS, positionPS);
}
// 2. Process the influence
float3 dirLS = dirPS; // Projection and influence share the space
// 2. Process the influence
if (influenceShapeType == ENVSHAPETYPE_SPHERE)
weight = InfluenceSphereWeight(lightData, bsdfData, positionWS, positionLS, dirLS);
else if (influenceShapeType == ENVSHAPETYPE_BOX)
}
// Smooth weighting
weight = Smoothstep01(weight);

150
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/ProbeWrapper.cs


using System;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public abstract class ProbeWrapper
{
public static ProbeWrapper Wrap(VisibleReflectionProbe probe, PlanarReflectionProbe planarProbe)
{
if (probe.probe != null)
return new VisibleReflectionProbeWrapper(probe);
if (planarProbe != null)
return new PlanarReflectionProbeWrapper(planarProbe);
throw new ArgumentException();
}
protected static EnvShapeType ConvertShape(ShapeType shape)
{
switch (shape)
{
default:
case ShapeType.Box:
return EnvShapeType.Box;
case ShapeType.Sphere:
return EnvShapeType.Sphere;
}
}
public abstract ReflectionProbeMode mode { get; }
public abstract Texture texture { get; }
public abstract Vector3 captureOffsetLS { get; }
public abstract float dimmer { get; }
public abstract Matrix4x4 influenceToWorld { get; }
public abstract EnvShapeType influenceShapeType { get; }
public abstract Vector3 influenceExtents { get; }
public abstract Vector3 blendNormalDistancePositive { get; }
public abstract Vector3 blendNormalDistanceNegative { get; }
public abstract Vector3 blendDistancePositive { get; }
public abstract Vector3 blendDistanceNegative { get; }
public abstract Vector3 boxSideFadePositive { get; }
public abstract Vector3 boxSideFadeNegative { get; }
public abstract Matrix4x4 proxyToWorld { get; }
public abstract EnvShapeType proxyShapeType { get; }
public abstract Vector3 proxyExtents { get; }
public abstract bool infiniteProjection { get; }
}
class VisibleReflectionProbeWrapper : ProbeWrapper
{
static HDAdditionalReflectionData defaultHDAdditionalReflectionData { get { return ComponentSingleton<HDAdditionalReflectionData>.instance; } }
VisibleReflectionProbe probe;
HDAdditionalReflectionData additional;
public VisibleReflectionProbeWrapper(VisibleReflectionProbe probe)
{
this.probe = probe;
additional = GetHDAdditionalReflectionData(probe);
}
static HDAdditionalReflectionData GetHDAdditionalReflectionData(VisibleReflectionProbe probe)
{
var add = probe.probe.GetComponent<HDAdditionalReflectionData>();
if (add == null)
{
add = defaultHDAdditionalReflectionData;
add.blendDistancePositive = Vector3.one * probe.blendDistance;
add.blendDistanceNegative = add.blendDistancePositive;
add.influenceShape = ShapeType.Box;
}
return add;
}
public override Matrix4x4 influenceToWorld { get { return probe.localToWorld; } }
public override Texture texture { get { return probe.texture; } }
public override ReflectionProbeMode mode { get { return probe.probe.mode; } }
public override Vector3 captureOffsetLS { get { return probe.center; } } // center is misnamed, it is the offset (in local space) from center of the bounding box to the cubemap capture point
public override EnvShapeType influenceShapeType { get { return ConvertShape(additional.influenceShape); } }
public override float dimmer { get { return additional.dimmer; } }
public override Vector3 influenceExtents
{
get
{
switch (additional.influenceShape)
{
default:
case ShapeType.Box:
return probe.bounds.extents;
case ShapeType.Sphere:
return Vector3.one * additional.influenceSphereRadius;
}
}
}
public override Vector3 blendNormalDistancePositive { get { return additional.blendNormalDistancePositive; } }
public override Vector3 blendNormalDistanceNegative { get { return additional.blendNormalDistanceNegative; } }
public override Vector3 blendDistancePositive { get { return additional.blendDistancePositive; } }
public override Vector3 blendDistanceNegative { get { return additional.blendDistanceNegative; } }
public override Vector3 boxSideFadePositive { get { return additional.boxSideFadePositive; } }
public override Vector3 boxSideFadeNegative { get { return additional.boxSideFadeNegative; } }
public override Matrix4x4 proxyToWorld { get { return influenceToWorld; } }
public override EnvShapeType proxyShapeType { get { return influenceShapeType; } }
public override Vector3 proxyExtents { get { return influenceExtents; } }
public override bool infiniteProjection { get { return probe.boxProjection == 0; } }
}
class PlanarReflectionProbeWrapper : ProbeWrapper
{
PlanarReflectionProbe probe;
public PlanarReflectionProbeWrapper(PlanarReflectionProbe probe)
{
this.probe = probe;
}
public override Matrix4x4 influenceToWorld { get { return probe.influenceToWorld; } }
public override Texture texture { get { return probe.texture; } }
public override Vector3 captureOffsetLS { get { return probe.captureOffset; } }
public override EnvShapeType influenceShapeType { get { return ConvertShape(probe.influenceVolume.shapeType); } }
public override float dimmer { get { return probe.dimmer; } }
public override Vector3 influenceExtents
{
get
{
switch (probe.influenceVolume.shapeType)
{
default:
case ShapeType.Box:
return probe.influenceVolume.boxBaseSize;
case ShapeType.Sphere:
return probe.influenceVolume.sphereBaseRadius * Vector3.one;
}
}
}
public override Vector3 blendNormalDistancePositive { get { return probe.influenceVolume.boxInfluenceNormalPositiveFade; } }
public override Vector3 blendNormalDistanceNegative { get { return probe.influenceVolume.boxInfluenceNormalNegativeFade; } }
public override Vector3 blendDistancePositive { get { return probe.influenceVolume.boxInfluencePositiveFade; } }
public override Vector3 blendDistanceNegative { get { return probe.influenceVolume.boxInfluenceNegativeFade; } }
public override Vector3 boxSideFadePositive { get { return probe.influenceVolume.boxPositiveFaceFade; } }
public override Vector3 boxSideFadeNegative { get { return probe.influenceVolume.boxNegativeFaceFade; } }
public override Matrix4x4 proxyToWorld { get { return probe.proxyToWorld; } }
public override EnvShapeType proxyShapeType { get { return ConvertShape(probe.proxyShape); } }
public override Vector3 proxyExtents { get { return probe.proxyExtents; } }
public override bool infiniteProjection { get { return probe.infiniteProjection; } }
public override ReflectionProbeMode mode { get { return probe.mode; } }
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/ProbeWrapper.cs.meta


fileFormatVersion: 2
guid: a40a2c0073f3f8d409c820add29133d8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

/ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumes/ProjectionVolumeComponent.cs → /ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumes/ProxyVolumeComponent.cs

/ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumes/ProjectionVolumeComponent.cs.meta → /ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/Volumes/ProxyVolumeComponent.cs.meta

正在加载...
取消
保存