浏览代码

TilePass support for arealights

/main
runes 8 年前
当前提交
6d7d07de
共有 7 个文件被更改,包括 160 次插入79 次删除
  1. 103
      Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewTiles.shader
  2. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopInspector.cs
  3. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-clustered.compute
  4. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild.compute
  5. 108
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs
  6. 3
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs.hlsl
  7. 17
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePassLoop.hlsl

103
Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewTiles.shader


Shader "Hidden/HDRenderLoop/DebugViewTiles"
{
SubShader
{
SubShader
{
Pass
{
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
HLSLPROGRAM
HLSLPROGRAM
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev

#pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
//-------------------------------------------------------------------------------------
// Include
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
// Include
//-------------------------------------------------------------------------------------
// Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new
// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
// the deferred shader will require to use multicompile.
// Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new
// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
// the deferred shader will require to use multicompile.
//-------------------------------------------------------------------------------------
// variable declaration
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
// variable declaration
//-------------------------------------------------------------------------------------
uint _ViewTilesFlags;
uint _ViewTilesFlags;
TEXTURE2D(_CameraDepthTexture);
SAMPLER2D(sampler_CameraDepthTexture);

float4 Vert(float3 positionOS : POSITION): SV_POSITION
{
return TransformWorldToHClip(TransformObjectToWorld(positionOS));
}
float4 Vert(float3 positionOS : POSITION): SV_POSITION
{
return TransformWorldToHClip(TransformObjectToWorld(positionOS));
}
float4 OverlayHeatMap(uint2 pixCoord, uint numLights)
{

return color;
}
float4 Frag(float4 positionCS : SV_POSITION) : SV_Target
{
Coordinate coord = GetCoordinate(positionCS.xy, _ScreenSize.zw);
float4 Frag(float4 positionCS : SV_POSITION) : SV_Target
{
Coordinate coord = GetCoordinate(positionCS.xy, _ScreenSize.zw);
#ifdef USE_CLUSTERED_LIGHTLIST
// Perform same calculation than in deferred.shader

float linearDepth = 0.0; // unused
#endif
int n = 0;
if (_ViewTilesFlags & DEBUGVIEWTILESFLAGS_DIRECT_LIGHTING)
{
uint punctualLightStart;
uint punctualLightCount;
GetCountAndStart(coord, DIRECT_LIGHT, linearDepth, punctualLightStart, punctualLightCount);
n += punctualLightCount;
}
int n = 0;
for(int category = 0; category < NR_LIGHT_MODELS; category++)
{
uint mask = 1u << category;
uint start;
uint count;
GetCountAndStart(coord, category, linearDepth, start, count);
n += count;
}
if (n > 0)
{
return OverlayHeatMap(int2(coord.unPositionSS.xy) & 15, n);
}
else
{
return 0.0;
}
}
if (_ViewTilesFlags & DEBUGVIEWTILESFLAGS_REFLECTION)
{
uint envLightStart;
uint envLightCount;
GetCountAndStart(coord, REFLECTION_LIGHT, linearDepth, envLightStart, envLightCount);
n += envLightCount;
}
if (n > 0)
{
return OverlayHeatMap(int2(coord.unPositionSS.xy) & 15, n);
}
else
{
return 0.0;
}
}
ENDHLSL
}
}
Fallback Off
}
ENDHLSL
}
}
Fallback Off
}

4
Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopInspector.cs


public readonly GUIContent shadowsCascades = new GUIContent("Cascade values");
public readonly GUIContent tileLightLoopSettings = new GUIContent("Tile Light Loop settings");
public readonly GUIContent tileLightLoopDebugMode = new GUIContent("Enable Debug mode", "Toggle overheat map mode");
public readonly string[] tileLightLoopDebugTileFlagStrings = new string[] { "Direct Light", "Reflection Light", "Area Light"};
public readonly GUIContent directIndirectSinglePass = new GUIContent("Enable direct and indirect lighting in single pass", "Toggle");
public readonly GUIContent bigTilePrepass = new GUIContent("Enable big tile prepass", "Toggle");
public readonly GUIContent clustered = new GUIContent("Enable clustered", "Toggle");

EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
renderLoop.tilePassLightLoop.debugViewTilesFlags = (TilePass.DebugViewTilesFlags)EditorGUILayout.EnumMaskField("DebugView Tiles", renderLoop.tilePassLightLoop.debugViewTilesFlags);
renderLoop.tilePassLightLoop.debugViewTilesFlags = EditorGUILayout.MaskField("DebugView Tiles", renderLoop.tilePassLightLoop.debugViewTilesFlags, styles.tileLightLoopDebugTileFlagStrings);
renderLoop.tilePassLightLoop.enableDirectIndirectSinglePass = EditorGUILayout.Toggle(styles.directIndirectSinglePass, renderLoop.tilePassLightLoop.enableDirectIndirectSinglePass);
renderLoop.tilePassLightLoop.enableBigTilePrepass = EditorGUILayout.Toggle(styles.bigTilePrepass, renderLoop.tilePassLightLoop.enableBigTilePrepass);
renderLoop.tilePassLightLoop.enableClustered = EditorGUILayout.Toggle(styles.clustered, renderLoop.tilePassLightLoop.enableClustered);

2
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-clustered.compute


InterlockedAdd(g_LayeredSingleIdxBuffer[0], (uint) iSpaceAvail, start); // alloc list memory
}
int modelListCount[NR_LIGHT_MODELS]={0,0}; // direct light count and reflection lights
int modelListCount[NR_LIGHT_MODELS]={0,0,0}; // direct light count and reflection lights
uint offs = start;
for(int ll=0; ll<iNrCoarseLights; ll+=4)
{

2
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild.compute


#endif
groupshared int ldsNrLightsFinal;
groupshared int ldsModelListCount[NR_LIGHT_MODELS]; // since NR_LIGHT_MODELS is 2
groupshared int ldsModelListCount[NR_LIGHT_MODELS]; // since NR_LIGHT_MODELS is 3
#ifdef PERFORM_SPHERICAL_INTERSECTION_TESTS
groupshared uint lightOffsSph;

108
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs


public static int DIRECTIONAL_LIGHT = 3;
// direct lights and reflection probes for now
public static int NR_LIGHT_MODELS = 2;
public static int NR_LIGHT_MODELS = 3;
public static int AREA_LIGHT = 2;
public enum DebugViewTilesFlags
{
DirectLighting = 1,
Reflection = 2
};
[GenerateHLSL]
public struct SFiniteLightBound
{
public Vector3 boxAxisX;

public float cotan;
public Vector3 boxInnerDist;
public uint lightCategory; // DIRECT_LIGHT=0, REFLECTION_LIGHT=1
public uint lightCategory; // DIRECT_LIGHT=0, REFLECTION_LIGHT=1, AREA_LIGHT=2
public Vector3 boxInvRange;
public float unused2;

private static int s_GenListPerBigTileKernel;
// clustered light list specific buffers and data begin
public DebugViewTilesFlags debugViewTilesFlags = 0;
public int debugViewTilesFlags = 0;
public bool enableClustered = false;
public bool disableFptlWhenClustered = true; // still useful on opaques. Should be false by default to force tile on opaque.
public bool enableBigTilePrepass = true;

// Use for the second pass (fine pruning)
var numEntries2nd = new int[numModels, numVolTypes];
// TODO manage area lights
foreach (var punctualLight in lightList.punctualLights)
{
var volType = punctualLight.lightType == GPULightType.Spot ? LightDefinitions.SPOT_LIGHT : (punctualLight.lightType == GPULightType.Point ? LightDefinitions.SPHERE_LIGHT : -1);

{
var volType = LightDefinitions.BOX_LIGHT; // always a box for now
++numEntries[LightDefinitions.REFLECTION_LIGHT, volType];
}
foreach (var areaLight in lightList.areaLights)
{
var volType = LightDefinitions.BOX_LIGHT;
++numEntries[LightDefinitions.AREA_LIGHT, volType];
// add decals here too similar to the above

//Vector3 C = bnds.center; // P + boxOffset;
var C = mat.MultiplyPoint(boxOffset); // same as commented out line above when rot is identity
var combinedExtent = e + new Vector3(blendDistance, blendDistance, blendDistance);
var combinedExtent = e + new Vector3(blendDistance, blendDistance, blendDistance);
Vector3 vx = mat.GetColumn(0);
Vector3 vy = mat.GetColumn(1);

m_lightShapeData[index] = lightShapeData;
}
for (int areaLightIndex = 0; areaLightIndex < lightList.areaLights.Count; areaLightIndex++)
{
LightData areaLightData = lightList.areaLights[areaLightIndex];
VisibleLight light = cullResults.visibleLights[lightList.areaCullIndices[areaLightIndex]];
// Fill bounds
var bound = new SFiniteLightBound();
var lightShapeData = new LightShapeData();
lightShapeData.lightType = (uint)LightDefinitions.BOX_LIGHT;
lightShapeData.lightCategory = (uint)LightDefinitions.AREA_LIGHT;
lightShapeData.lightIndex = (uint)areaLightIndex;
if (areaLightData.lightType == GPULightType.Rectangle)
{
Vector3 centerVS = worldToView.MultiplyPoint(areaLightData.positionWS);
Vector3 xAxisVS = worldToView.MultiplyVector(areaLightData.right);
Vector3 yAxisVS = worldToView.MultiplyVector(areaLightData.up);
Vector3 zAxisVS = worldToView.MultiplyVector(areaLightData.forward);
float radius = 1.0f / Mathf.Sqrt(areaLightData.invSqrAttenuationRadius);
Vector3 dimensions = new Vector3(areaLightData.size.x * 0.5f + radius, areaLightData.size.y * 0.5f + radius, radius);
if(!areaLightData.twoSided)
{
centerVS -= zAxisVS * radius * 0.5f;
dimensions.z *= 0.5f;
}
bound.center = centerVS;
bound.boxAxisX = dimensions.x * xAxisVS;
bound.boxAxisY = dimensions.y * yAxisVS;
bound.boxAxisZ = dimensions.z * zAxisVS;
bound.scaleXY.Set(1.0f, 1.0f);
bound.radius = dimensions.magnitude;
lightShapeData.lightPos = centerVS;
lightShapeData.lightAxisX = xAxisVS;
lightShapeData.lightAxisY = yAxisVS;
lightShapeData.lightAxisZ = zAxisVS;
lightShapeData.boxInnerDist = dimensions;
lightShapeData.boxInvRange.Set(1e5f, 1e5f, 1e5f);
}
else if (areaLightData.lightType == GPULightType.Line)
{
Vector3 centerVS = worldToView.MultiplyPoint(areaLightData.positionWS);
Vector3 xAxisVS = worldToView.MultiplyVector(areaLightData.right);
Vector3 yAxisVS = worldToView.MultiplyVector(areaLightData.up);
Vector3 zAxisVS = worldToView.MultiplyVector(areaLightData.forward);
float radius = 1.0f / Mathf.Sqrt(areaLightData.invSqrAttenuationRadius);
Vector3 dimensions = new Vector3(areaLightData.size.x * 0.5f + radius, radius, radius);
bound.center = centerVS;
bound.boxAxisX = dimensions.x * xAxisVS;
bound.boxAxisY = dimensions.y * yAxisVS;
bound.boxAxisZ = dimensions.z * zAxisVS;
bound.scaleXY.Set(1.0f, 1.0f);
bound.radius = dimensions.magnitude;
lightShapeData.lightPos = centerVS;
lightShapeData.lightAxisX = xAxisVS;
lightShapeData.lightAxisY = yAxisVS;
lightShapeData.lightAxisZ = zAxisVS;
lightShapeData.boxInnerDist = new Vector3(areaLightData.size.x * 0.5f, 0.01f, 0.01f);
lightShapeData.boxInvRange.Set(1.0f / radius, 1.0f / radius, 1.0f / radius);
}
else
{
Debug.Assert(false);
}
int i = LightDefinitions.AREA_LIGHT, j = LightDefinitions.BOX_LIGHT;
int index = numEntries2nd[i, j] + offsets[i, j]; ++numEntries2nd[i, j];
m_boundData[index] = bound;
m_lightShapeData[index] = lightShapeData;
}
// Sanity check
for (var m = 0; m < numModels; m++)
{

}
}
m_lightCount = lightList.punctualLights.Count + lightList.envLights.Count;
m_lightCount = lightList.punctualLights.Count + lightList.envLights.Count + lightList.areaLights.Count;
s_ConvexBoundsBuffer.SetData(m_boundData); // TODO: check with Vlad what is happening here, do we copy 1024 element always ? Could we setup the size we want to copy ?
s_LightShapeDataBuffer.SetData(m_lightShapeData);
}

m_DebugViewTilesMaterial.SetMatrix("_InvViewProjMatrix", invViewProj);
m_DebugViewTilesMaterial.SetVector("_ScreenSize", screenSize);
m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", (int)debugViewTilesFlags);
m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", debugViewTilesFlags);
m_DebugViewTilesMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DebugViewTilesMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");

3
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs.hlsl


#define SPHERE_LIGHT (1)
#define BOX_LIGHT (2)
#define DIRECTIONAL_LIGHT (3)
#define NR_LIGHT_MODELS (2)
#define NR_LIGHT_MODELS (3)
#define AREA_LIGHT (2)
//
// UnityEngine.Experimental.ScriptableRenderLoop.TilePass.DebugViewTilesFlags: static fields

17
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePassLoop.hlsl


#endif
#ifdef PROCESS_AREA_LIGHT
/*
GetCountAndStart(coord, LightCatergory.AreaLight, linearDepth, areaLightStart, areaLightCount);
GetCountAndStart(coord, AREA_LIGHT, linearDepth, areaLightStart, areaLightCount);
EvaluateBSDF_Area( context, V, positionWS, prelightData, _AreaLightList[FetchIndex(areaLightStart, i)], bsdfData,
localDiffuseLighting, localSpecularLighting);
if(_AreaLightList[i].lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Line(context, V, positionWS, prelightData, _AreaLightList[FetchIndex(areaLightStart, i)], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
else
{
EvaluateBSDF_Area(context, V, positionWS, prelightData, _AreaLightList[FetchIndex(areaLightStart, i)], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
*/
#endif
#ifdef PROCESS_ENV_LIGHT

正在加载...
取消
保存