浏览代码

HDRenderPipeline: revert recent change on structure buffer for shader for PS4 as it was not the problem

/fptl_cleanup
sebastienlagarde 8 年前
当前提交
f16a65f7
共有 5 个文件被更改,包括 398 次插入453 次删除
  1. 7
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  2. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Resources/Deferred.shader
  3. 59
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  4. 50
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl
  5. 733
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl

7
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


cmd.SetGlobalMatrix("_InvProjMatrix", hdCamera.invProjectionMatrix);
cmd.SetGlobalVector("_InvProjParam", hdCamera.invProjectionParam);
// TODO: setting the Sky Settings to 'None' appears to do nothing (so no invalidation happens).
// TODO: cmd.SetGlobalInt() does not exist, so we are forced to use Shader.SetGlobalInt() instead.
Shader.EnableKeyword("SKY_LIGHTING");
Shader.SetGlobalInt("_EnvLightSkyEnabled", 1);
Shader.DisableKeyword("SKY_LIGHTING");
Shader.SetGlobalInt("_EnvLightSkyEnabled", 0);
}
// Broadcast SSS parameters to all shaders.

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/Resources/Deferred.shader


#pragma shader_feature _ SSS_PRE_SCATTER_TEXTURING SSS_POST_SCATTER_TEXTURING
// #endif
#pragma multi_compile _ SKY_LIGHTING
#pragma multi_compile _ LIGHTING_DEBUG
//-------------------------------------------------------------------------------------

59
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


public const int k_MaxCascadeCount = 4; //Should be not less than m_Settings.directionalLightCascadeCount;
// Static keyword is required here else we get a "DestroyBuffer can only be call in main thread"
static ComputeBuffer s_LightingSettings = null; // We use a structured buffer instead of a constant buffer due to the delay between setting values via constant and other buffer types on PS4
static ComputeBuffer s_DirectionalLightDatas = null;
static ComputeBuffer s_LightDatas = null;
static ComputeBuffer s_EnvLightDatas = null;

int m_areaLightCount = 0;
int m_lightCount = 0;
// See LightingSettings in TilePass.hlsl.
public struct LightingSettings
{
public uint directionalLightCount;
public uint punctualLightCount;
public uint areaLightCount;
public uint envLightCount;
public uint numTileFtplX;
public uint numTileFtplY;
public uint pad0, pad1; // 16-byte alignment
// public uint numTileClusteredX;
// public uint numTileClusteredY;
// public uint isLogBaseBufferEnabled;
// public uint log2NumClusters;
// public float clusterScale;
// public float clusterBase;
// public float nearPlane;
// public float farPlane;
public Vector4 dirShadowSplitSpheres0;
public Vector4 dirShadowSplitSpheres1;
public Vector4 dirShadowSplitSpheres2;
public Vector4 dirShadowSplitSpheres3;
};
LightingSettings[] m_LightingSettings = new LightingSettings[1];
private ComputeShader buildScreenAABBShader { get { return m_PassResources.buildScreenAABBShader; } }
private ComputeShader buildPerTileLightListShader { get { return m_PassResources.buildPerTileLightListShader; } }
private ComputeShader buildPerBigTileLightListShader { get { return m_PassResources.buildPerBigTileLightListShader; } }

m_lightList = new LightList();
m_lightList.Allocate();
s_LightingSettings = new ComputeBuffer(1, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightingSettings)));
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)));

UnityEditor.SceneView.onSceneGUIDelegate -= OnSceneGUI;
#endif
Utilities.SafeRelease(s_LightingSettings);
Utilities.SafeRelease(s_DirectionalLightDatas);
Utilities.SafeRelease(s_LightDatas);
Utilities.SafeRelease(s_EnvLightDatas);

SetGlobalTexture("_CookieCubeTextures", m_CubeCookieTexArray.GetTexCache());
SetGlobalTexture("_EnvTextures", m_CubeReflTexArray.GetTexCache());
SetGlobalBuffer("_LightingSettings", s_LightingSettings);
SetGlobalInt("_DirectionalLightCount", m_lightList.directionalLights.Count);
SetGlobalInt("_PunctualLightCount", m_punctualLightCount);
SetGlobalInt("_AreaLightCount", m_areaLightCount);
SetGlobalInt("_EnvLightCount", m_lightList.envLights.Count);
SetGlobalVectorArray("_DirShadowSplitSpheres", m_lightList.directionalShadowSplitSphereSqr);
SetGlobalInt("_NumTileFtplX", GetNumTileFtplX(camera));
SetGlobalInt("_NumTileFtplY", GetNumTileFtplY(camera));
SetGlobalInt("_NumTileClusteredX", GetNumTileClusteredX(camera));
SetGlobalInt("_NumTileClusteredY", GetNumTileClusteredY(camera));

{
var cmd = new CommandBuffer { name = "Push Global Parameters" };
m_LightingSettings[0].directionalLightCount = (uint)m_lightList.directionalLights.Count;
m_LightingSettings[0].punctualLightCount = (uint)m_punctualLightCount;
m_LightingSettings[0].areaLightCount = (uint)m_areaLightCount;
m_LightingSettings[0].envLightCount = (uint)m_lightList.envLights.Count;
m_LightingSettings[0].numTileFtplX = (uint)GetNumTileFtplX(camera);
m_LightingSettings[0].numTileFtplY = (uint)GetNumTileFtplY(camera);
// m_LightingSettings[0].numTileClusteredX = (uint)GetNumTileClusteredX(camera);
// m_LightingSettings[0].numTileClusteredY = (uint)GetNumTileClusteredY(camera);
// m_LightingSettings[0].isLogBaseBufferEnabled = (uint)(k_UseDepthBuffer ? 1 : 0);
// m_LightingSettings[0].log2NumClusters = k_Log2NumClusters;
// m_LightingSettings[0].clusterBase = k_ClustLogBase;
// m_LightingSettings[0].clusterScale = m_ClustScale;
// m_LightingSettings[0].nearPlane = camera.nearClipPlane;
// m_LightingSettings[0].farPlane = camera.farClipPlane;
m_LightingSettings[0].dirShadowSplitSpheres0 = m_lightList.directionalShadowSplitSphereSqr[0];
m_LightingSettings[0].dirShadowSplitSpheres1 = m_lightList.directionalShadowSplitSphereSqr[1];
m_LightingSettings[0].dirShadowSplitSpheres2 = m_lightList.directionalShadowSplitSphereSqr[2];
m_LightingSettings[0].dirShadowSplitSpheres3 = m_lightList.directionalShadowSplitSphereSqr[3];
s_LightingSettings.SetData(m_LightingSettings);
s_DirectionalLightDatas.SetData(m_lightList.directionalLights.ToArray());
s_LightDatas.SetData(m_lightList.lights.ToArray());
s_EnvLightDatas.SetData(m_lightList.envLights.ToArray());

Utilities.SetMatrixCS(cmd, shadeOpaqueShader, "_InvViewProjMatrix", invViewProjection);
Utilities.SetMatrixCS(cmd, shadeOpaqueShader, "_ViewProjMatrix", viewProjection);
Utilities.SetMatrixCS(cmd, shadeOpaqueShader, "g_mInvScrProjection", Shader.GetGlobalMatrix("g_mInvScrProjection"));
cmd.SetComputeVectorParam(shadeOpaqueShader, "_ScreenSize", Shader.GetGlobalVector("_ScreenSize"));
cmd.SetComputeIntParam(shadeOpaqueShader, "_UseTileLightList", Shader.GetGlobalInt("_UseTileLightList"));

cmd.SetComputeVectorParam(shadeOpaqueShader, "_ScreenParams", Shader.GetGlobalVector("_ScreenParams"));
cmd.SetComputeVectorParam(shadeOpaqueShader, "_ZBufferParams", Shader.GetGlobalVector("_ZBufferParams"));
cmd.SetComputeVectorParam(shadeOpaqueShader, "unity_OrthoParams", Shader.GetGlobalVector("unity_OrthoParams"));
cmd.SetComputeIntParam(shadeOpaqueShader, "_EnvLightSkyEnabled", Shader.GetGlobalInt("_EnvLightSkyEnabled"));
Texture skyTexture = Shader.GetGlobalTexture("_SkyTexture");
Texture IESArrayTexture = Shader.GetGlobalTexture("_IESArray");

50
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.hlsl


#include "TilePass.cs.hlsl"
// For FPTL
uint _NumTileFtplX;
uint _NumTileFtplY;
StructuredBuffer<uint> g_vLightListGlobal; // don't support Buffer yet in unity
#ifdef USE_FPTL_LIGHTLIST

// these uniforms are only needed for when OPAQUES_ONLY is NOT defined
// but there's a problem with our front-end compilation of compute shaders with multiple kernels causing it to error
//#ifdef USE_CLUSTERED_LIGHTLIST
float4x4 g_mInvScrProjection;
float g_fClustScale;
float g_fClustBase;
float g_fNearPlane;

StructuredBuffer<float> g_logBaseBuffer; // don't support Buffer yet in unity
//#endif
struct LightingSettings
{
uint directionalLightCount;
uint punctualLightCount;
uint areaLightCount;
uint envLightCount;
uint numTileFtplX;
uint numTileFtplY;
uint pad0, pad1; // 16-byte alignment
// uint numTileClusteredX;
// uint numTileClusteredY;
// uint isLogBaseBufferEnabled;
// uint log2NumClusters;
// float clusterScale;
// float clusterBase;
// float nearPlane;
// float farPlane;
float4 dirShadowSplitSpheres[4]; // TODO: share this max between C# and hlsl
};
// We use a structured buffer instead of a constant buffer due to the delay between setting values via constant and other buffer types on PS4
StructuredBuffer<LightingSettings> _LightingSettings; // 1 element
StructuredBuffer<DirectionalLightData> _DirectionalLightDatas;
StructuredBuffer<LightData> _LightDatas;
StructuredBuffer<EnvLightData> _EnvLightDatas;
StructuredBuffer<ShadowData> _ShadowDatas;
StructuredBuffer<DirectionalLightData> _DirectionalLightDatas;
StructuredBuffer<LightData> _LightDatas;
StructuredBuffer<EnvLightData> _EnvLightDatas;
StructuredBuffer<ShadowData> _ShadowDatas;
// Use texture atlas for shadow map
//TEXTURE2D(_ShadowAtlas);

TEXTURECUBE(_SkyTexture);
SAMPLERCUBE(sampler_SkyTexture); // NOTE: Sampler could be share here with _EnvTextures. Don't know if the shader compiler will complain...
/*
// See _LightingSettings
uint _DirectionalLightCount;
uint _PunctualLightCount;
uint _AreaLightCount;
uint _EnvLightCount;
float4 _DirShadowSplitSpheres[4]; // TODO: share this max between C# and hlsl
int _EnvLightSkyEnabled; // TODO: make it a bool
*/
struct LightLoopContext
{

float GetDirectionalShadowAttenuation(LightLoopContext lightLoopContext, float3 positionWS, int index, float3 L, float2 unPositionSS)
{
// Note Index is 0 for now, but else we need to provide the correct index in _LightingSettings[0].dirShadowSplitSpheres and _ShadowDatas
int shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _LightingSettings[0].dirShadowSplitSpheres);
// Note Index is 0 for now, but else we need to provide the correct index in _DirShadowSplitSpheres and _ShadowDatas
int shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _DirShadowSplitSpheres);
if (shadowSplitIndex == -1)
return 1.0;

733
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePassLoop.hlsl


//-----------------------------------------------------------------------------
// LightLoop
// ----------------------------------------------------------------------------
void ApplyDebug(LightLoopContext lightLoopContext, float3 positionWS, inout float3 diffuseLighting, inout float3 specularLighting)
{
#ifdef LIGHTING_DEBUG
int lightDebugMode = (int)_DebugLightModeAndAlbedo.x;
if (lightDebugMode == LIGHTINGDEBUGMODE_DIFFUSE_LIGHTING)
{
specularLighting = float3(0.0, 0.0, 0.0);
}
else if (lightDebugMode == LIGHTINGDEBUGMODE_SPECULAR_LIGHTING)
{
diffuseLighting = float3(0.0, 0.0, 0.0);
}
else if (lightDebugMode == LIGHTINGDEBUGMODE_VISUALIZE_CASCADE)
{
specularLighting = float3(0.0, 0.0, 0.0);
const float3 s_CascadeColors[] = {
float3(1.0, 0.0, 0.0),
float3(0.0, 1.0, 0.0),
float3(0.0, 0.0, 1.0),
float3(1.0, 1.0, 0.0)
};
#ifdef SHADOWS_USE_SHADOWCTXT
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
#else
float shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
#endif
int shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _LightingSettings[0].dirShadowSplitSpheres);
if (shadowSplitIndex == -1)
diffuseLighting = float3(0.0, 0.0, 0.0);
else
{
diffuseLighting = s_CascadeColors[shadowSplitIndex] * shadow;
}
}
#endif
}
#ifdef LIGHTLOOP_TILE_PASS
// Calculate the offset in global light index light for current light category
int GetTileOffset(PositionInputs posInput, uint lightCategory)
{
uint2 tileIndex = posInput.unTileCoord;
return (tileIndex.y + lightCategory * _LightingSettings[0].numTileFtplY) * _LightingSettings[0].numTileFtplX + tileIndex.x;
}
void GetCountAndStartTile(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
const int tileOffset = GetTileOffset(posInput, lightCategory);
// The first entry inside a tile is the number of light for lightCategory (thus the +0)
lightCount = g_vLightListGlobal[DWORD_PER_TILE * tileOffset + 0] & 0xffff;
start = tileOffset;
}
uint FetchIndexTile(uint tileOffset, uint lightIndex)
{
const uint lightIndexPlusOne = lightIndex + 1; // Add +1 as first slot is reserved to store number of light
// Light index are store on 16bit
return (g_vLightListGlobal[DWORD_PER_TILE * tileOffset + (lightIndexPlusOne >> 1)] >> ((lightIndexPlusOne & 1) * DWORD_PER_TILE)) & 0xffff;
}
#ifdef USE_FPTL_LIGHTLIST
uint GetTileSize()
{
return TILE_SIZE_FPTL;
}
void GetCountAndStart(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
GetCountAndStartTile(posInput, lightCategory, start, lightCount);
}
uint FetchIndex(uint tileOffset, uint lightIndex)
{
return FetchIndexTile(tileOffset, lightIndex);
}
#elif defined(USE_CLUSTERED_LIGHTLIST)
#include "ClusteredUtils.hlsl"
uint GetTileSize()
{
return TILE_SIZE_CLUSTERED;
}
void GetCountAndStartCluster(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
uint2 tileIndex = posInput.unTileCoord;
float logBase = g_fClustBase;
if (g_isLogBaseBufferEnabled)
{
logBase = g_logBaseBuffer[tileIndex.y * _NumTileClusteredX + tileIndex.x];
}
int clustIdx = SnapToClusterIdxFlex(posInput.depthVS, logBase, g_isLogBaseBufferEnabled != 0);
int nrClusters = (1 << g_iLog2NumClusters);
const int idx = ((lightCategory * nrClusters + clustIdx) * _NumTileClusteredY + tileIndex.y) * _NumTileClusteredX + tileIndex.x;
uint dataPair = g_vLayeredOffsetsBuffer[idx];
start = dataPair & 0x7ffffff;
lightCount = (dataPair >> 27) & 31;
}
uint FetchIndexCluster(uint tileOffset, uint lightIndex)
{
return g_vLightListGlobal[tileOffset + lightIndex];
}
void GetCountAndStart(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
if (_UseTileLightList)
GetCountAndStartTile(posInput, lightCategory, start, lightCount);
else
GetCountAndStartCluster(posInput, lightCategory, start, lightCount);
}
uint FetchIndex(uint tileOffset, uint lightIndex)
{
if (_UseTileLightList)
return FetchIndexTile(tileOffset, lightIndex);
else
return FetchIndexCluster(tileOffset, lightIndex);
}
#endif
// bakeDiffuseLighting is part of the prototype so a user is able to implement a "base pass" with GI and multipass direct light (aka old unity rendering path)
void LightLoop( float3 V, PositionInputs posInput, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting,
out float3 diffuseLighting,
out float3 specularLighting)
{
LightLoopContext context;
#ifndef SHADOWS_USE_SHADOWCTXT
ZERO_INITIALIZE(LightLoopContext, context);
#else
context.sampleShadow = 0;
context.sampleReflection = 0;
context.shadowContext = InitShadowContext();
#endif
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
#ifdef PROCESS_DIRECTIONAL_LIGHT
for (i = 0; i < _LightingSettings[0].directionalLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional( context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
#endif
#ifdef PROCESS_PUNCTUAL_LIGHT
// TODO: Convert the for loop below to a while on each type as we know we are sorted!
uint punctualLightStart;
uint punctualLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, punctualLightStart, punctualLightCount);
for (i = 0; i < punctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, posInput, prelightData, _LightDatas[FetchIndex(punctualLightStart, i)], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
#endif
#ifdef PROCESS_AREA_LIGHT
// TODO: Convert the for loop below to a while on each type as we know we are sorted!
uint areaLightStart;
uint areaLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_AREA, areaLightStart, areaLightCount);
for (i = 0; i < areaLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
uint areaIndex = FetchIndex(areaLightStart, i);
if(_LightDatas[areaIndex].lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Line( context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
else
{
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
#endif
#ifdef PROCESS_ENV_LIGHT
float3 iblDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 iblSpecularLighting = float3(0.0, 0.0, 0.0);
// Only apply sky IBL if the sky texture is available.
#ifdef SKY_LIGHTING
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
// 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
EvaluateBSDF_Env(context, V, posInput, prelightData, envLightSky, bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
#endif
uint envLightStart;
uint envLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount);
for (i = 0; i < envLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
EvaluateBSDF_Env(context, V, posInput, prelightData, _EnvLightDatas[FetchIndex(envLightStart, i)], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
diffuseLighting += iblDiffuseLighting;
specularLighting += iblSpecularLighting;
#endif
// TODO: currently apply GI at the same time as reflection
#ifdef PROCESS_ENV_LIGHT
// Add indirect diffuse + emissive (if any)
diffuseLighting += bakeDiffuseLighting;
#endif
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);
}
#else // LIGHTLOOP_SINGLE_PASS
//-----------------------------------------------------------------------------
// LightLoop
// ----------------------------------------------------------------------------
void ApplyDebug(LightLoopContext lightLoopContext, float3 positionWS, inout float3 diffuseLighting, inout float3 specularLighting)
{
#ifdef LIGHTING_DEBUG
int lightDebugMode = (int)_DebugLightModeAndAlbedo.x;
if (lightDebugMode == LIGHTINGDEBUGMODE_DIFFUSE_LIGHTING)
{
specularLighting = float3(0.0, 0.0, 0.0);
}
else if (lightDebugMode == LIGHTINGDEBUGMODE_SPECULAR_LIGHTING)
{
diffuseLighting = float3(0.0, 0.0, 0.0);
}
else if (lightDebugMode == LIGHTINGDEBUGMODE_VISUALIZE_CASCADE)
{
specularLighting = float3(0.0, 0.0, 0.0);
const float3 s_CascadeColors[] = {
float3(1.0, 0.0, 0.0),
float3(0.0, 1.0, 0.0),
float3(0.0, 0.0, 1.0),
float3(1.0, 1.0, 0.0)
};
#ifdef SHADOWS_USE_SHADOWCTXT
float shadow = GetDirectionalShadowAttenuation(lightLoopContext.shadowContext, positionWS, 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
#else
float shadow = GetDirectionalShadowAttenuation(lightLoopContext, positionWS, 0, float3(0.0, 0.0, 0.0), float2(0.0, 0.0));
#endif
int shadowSplitIndex = GetSplitSphereIndexForDirshadows(positionWS, _DirShadowSplitSpheres);
if (shadowSplitIndex == -1)
diffuseLighting = float3(0.0, 0.0, 0.0);
else
{
diffuseLighting = s_CascadeColors[shadowSplitIndex] * shadow;
}
}
#endif
}
#ifdef LIGHTLOOP_TILE_PASS
// Calculate the offset in global light index light for current light category
int GetTileOffset(PositionInputs posInput, uint lightCategory)
{
uint2 tileIndex = posInput.unTileCoord;
return (tileIndex.y + lightCategory * _NumTileFtplY) * _NumTileFtplX + tileIndex.x;
}
void GetCountAndStartTile(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
const int tileOffset = GetTileOffset(posInput, lightCategory);
// The first entry inside a tile is the number of light for lightCategory (thus the +0)
lightCount = g_vLightListGlobal[DWORD_PER_TILE * tileOffset + 0] & 0xffff;
start = tileOffset;
}
uint FetchIndexTile(uint tileOffset, uint lightIndex)
{
const uint lightIndexPlusOne = lightIndex + 1; // Add +1 as first slot is reserved to store number of light
// Light index are store on 16bit
return (g_vLightListGlobal[DWORD_PER_TILE * tileOffset + (lightIndexPlusOne >> 1)] >> ((lightIndexPlusOne & 1) * DWORD_PER_TILE)) & 0xffff;
}
#ifdef USE_FPTL_LIGHTLIST
uint GetTileSize()
{
return TILE_SIZE_FPTL;
}
void GetCountAndStart(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
GetCountAndStartTile(posInput, lightCategory, start, lightCount);
}
uint FetchIndex(uint tileOffset, uint lightIndex)
{
return FetchIndexTile(tileOffset, lightIndex);
}
#elif defined(USE_CLUSTERED_LIGHTLIST)
#include "ClusteredUtils.hlsl"
uint GetTileSize()
{
return TILE_SIZE_CLUSTERED;
}
void GetCountAndStartCluster(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
uint2 tileIndex = posInput.unTileCoord;
float logBase = g_fClustBase;
if (g_isLogBaseBufferEnabled)
{
logBase = g_logBaseBuffer[tileIndex.y * _NumTileClusteredX + tileIndex.x];
}
int clustIdx = SnapToClusterIdxFlex(posInput.depthVS, logBase, g_isLogBaseBufferEnabled != 0);
int nrClusters = (1 << g_iLog2NumClusters);
const int idx = ((lightCategory * nrClusters + clustIdx) * _NumTileClusteredY + tileIndex.y) * _NumTileClusteredX + tileIndex.x;
uint dataPair = g_vLayeredOffsetsBuffer[idx];
start = dataPair & 0x7ffffff;
lightCount = (dataPair >> 27) & 31;
}
uint FetchIndexCluster(uint tileOffset, uint lightIndex)
{
return g_vLightListGlobal[tileOffset + lightIndex];
}
void GetCountAndStart(PositionInputs posInput, uint lightCategory, out uint start, out uint lightCount)
{
if (_UseTileLightList)
GetCountAndStartTile(posInput, lightCategory, start, lightCount);
else
GetCountAndStartCluster(posInput, lightCategory, start, lightCount);
}
uint FetchIndex(uint tileOffset, uint lightIndex)
{
if (_UseTileLightList)
return FetchIndexTile(tileOffset, lightIndex);
else
return FetchIndexCluster(tileOffset, lightIndex);
}
#endif
// bakeDiffuseLighting is part of the prototype so a user is able to implement a "base pass" with GI and multipass direct light (aka old unity rendering path)
void LightLoop( float3 V, PositionInputs posInput, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting,
out float3 diffuseLighting,
out float3 specularLighting)
{
LightLoopContext context;
#ifndef SHADOWS_USE_SHADOWCTXT
ZERO_INITIALIZE(LightLoopContext, context);
#else
context.sampleShadow = 0;
context.sampleReflection = 0;
context.shadowContext = InitShadowContext();
#endif
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
#ifdef PROCESS_DIRECTIONAL_LIGHT
for (i = 0; i < _DirectionalLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional( context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
#endif
#ifdef PROCESS_PUNCTUAL_LIGHT
// TODO: Convert the for loop below to a while on each type as we know we are sorted!
uint punctualLightStart;
uint punctualLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_PUNCTUAL, punctualLightStart, punctualLightCount);
for (i = 0; i < punctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, posInput, prelightData, _LightDatas[FetchIndex(punctualLightStart, i)], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
#endif
#ifdef PROCESS_AREA_LIGHT
// TODO: Convert the for loop below to a while on each type as we know we are sorted!
uint areaLightStart;
uint areaLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_AREA, areaLightStart, areaLightCount);
for (i = 0; i < areaLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
uint areaIndex = FetchIndex(areaLightStart, i);
if(_LightDatas[areaIndex].lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Line( context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
else
{
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[areaIndex], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
#endif
#ifdef PROCESS_ENV_LIGHT
float3 iblDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 iblSpecularLighting = float3(0.0, 0.0, 0.0);
// Only apply sky IBL if the sky texture is available.
if (_EnvLightSkyEnabled)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
// 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
EvaluateBSDF_Env(context, V, posInput, prelightData, envLightSky, bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
uint envLightStart;
uint envLightCount;
GetCountAndStart(posInput, LIGHTCATEGORY_ENV, envLightStart, envLightCount);
for (i = 0; i < envLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
EvaluateBSDF_Env(context, V, posInput, prelightData, _EnvLightDatas[FetchIndex(envLightStart, i)], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
diffuseLighting += iblDiffuseLighting;
specularLighting += iblSpecularLighting;
#endif
// TODO: currently apply GI at the same time as reflection
#ifdef PROCESS_ENV_LIGHT
// Add indirect diffuse + emissive (if any)
diffuseLighting += bakeDiffuseLighting;
#endif
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);
}
#else // LIGHTLOOP_SINGLE_PASS
// bakeDiffuseLighting is part of the prototype so a user is able to implement a "base pass" with GI and multipass direct light (aka old unity rendering path)
void LightLoop( float3 V, PositionInputs posInput, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting,
out float3 diffuseLighting,
out float3 specularLighting)
{
LightLoopContext context;
#ifndef SHADOWS_USE_SHADOWCTXT
ZERO_INITIALIZE(LightLoopContext, context);
#else
context.sampleShadow = 0;
context.sampleReflection = 0;
context.shadowContext = InitShadowContext();
#endif
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < _LightingSettings[0].directionalLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional( context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
for (i = 0; i < _LightingSettings[0].punctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
// Area are store with punctual, just offset the index
for (i = _LightingSettings[0].punctualLightCount; i < _LightingSettings[0].punctualLightCount + _LightingSettings[0].areaLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
if (_LightDatas[i].lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Line( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
else
{
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
// TODO: Check the reflection hierarchy, for the current system (matching legacy unity) we must sort from bigger solid angle to lower (lower override bigger). So begging by sky
// TODO: Change the way it is done by reversing the order, from smaller solid angle to bigger, so we can early out when the weight is 1.
float3 iblDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 iblSpecularLighting = float3(0.0, 0.0, 0.0);
// Only apply sky IBL if the sky texture is available.
#ifdef SKY_LIGHTING
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
// 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
EvaluateBSDF_Env(context, V, posInput, prelightData, envLightSky, bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
#endif
for (i = 0; i < _LightingSettings[0].envLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
EvaluateBSDF_Env(context, V, posInput, prelightData, _EnvLightDatas[i], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
diffuseLighting += iblDiffuseLighting;
specularLighting += iblSpecularLighting;
// Add indirect diffuse + emissive (if any)
diffuseLighting += bakeDiffuseLighting;
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);
}
#endif
// bakeDiffuseLighting is part of the prototype so a user is able to implement a "base pass" with GI and multipass direct light (aka old unity rendering path)
void LightLoop( float3 V, PositionInputs posInput, PreLightData prelightData, BSDFData bsdfData, float3 bakeDiffuseLighting,
out float3 diffuseLighting,
out float3 specularLighting)
{
LightLoopContext context;
#ifndef SHADOWS_USE_SHADOWCTXT
ZERO_INITIALIZE(LightLoopContext, context);
#else
context.sampleShadow = 0;
context.sampleReflection = 0;
context.shadowContext = InitShadowContext();
#endif
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < _DirectionalLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional( context, V, posInput, prelightData, _DirectionalLightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
for (i = 0; i < _PunctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Punctual( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
// Area are store with punctual, just offset the index
for (i = _PunctualLightCount; i < _AreaLightCount + _PunctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
if (_LightDatas[i].lightType == GPULIGHTTYPE_LINE)
{
EvaluateBSDF_Line( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
else
{
EvaluateBSDF_Area( context, V, posInput, prelightData, _LightDatas[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
}
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
// TODO: Check the reflection hierarchy, for the current system (matching legacy unity) we must sort from bigger solid angle to lower (lower override bigger). So begging by sky
// TODO: Change the way it is done by reversing the order, from smaller solid angle to bigger, so we can early out when the weight is 1.
float3 iblDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 iblSpecularLighting = float3(0.0, 0.0, 0.0);
// Only apply sky IBL if the sky texture is available.
if (_EnvLightSkyEnabled)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
// 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
EvaluateBSDF_Env(context, V, posInput, prelightData, envLightSky, bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
for (i = 0; i < _EnvLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
EvaluateBSDF_Env(context, V, posInput, prelightData, _EnvLightDatas[i], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
diffuseLighting += iblDiffuseLighting;
specularLighting += iblSpecularLighting;
// Add indirect diffuse + emissive (if any)
diffuseLighting += bakeDiffuseLighting;
ApplyDebug(context, posInput.positionWS, diffuseLighting, specularLighting);
}
#endif
正在加载...
取消
保存