Julien Ignace 8 年前
当前提交
900253f2
共有 12 个文件被更改,包括 366 次插入344 次删除
  1. 2
      Assets/ScriptableRenderLoop/AdditionalLightData.cs
  2. 206
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  3. 91
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs
  4. 198
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs.hlsl
  5. 71
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.cs
  6. 13
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.hlsl
  7. 11
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePassLoop.hlsl
  8. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs
  9. 86
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.hlsl
  10. 10
      Assets/ScriptableRenderLoop/ShaderLibrary/AreaLighting.hlsl
  11. 8
      Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl
  12. 12
      Assets/ScriptableRenderLoop/ShaderLibrary/CommonLighting.hlsl

2
Assets/ScriptableRenderLoop/AdditionalLightData.cs


}
[RangeAttribute(0.0F, 1.0F)]
public float shadowDimmer = 1.0F;
public float shadowDimmer = 1.0f;
public bool affectDiffuse = true;
public bool affectSpecular = true;

206
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


ShadowRenderPass m_ShadowPass;
public const int k_MaxDirectionalLightsOnSCreen = 2;
public const int k_MaxPunctualLightsOnSCreen = 512;
public const int k_MaxAreaLightsOnSCreen = 128;
public const int k_MaxEnvLightsOnSCreen = 64;

public class LightList
{
public List<PunctualLightData> punctualLights;
public List<AreaLightData> areaLights;
public List<DirectionalLightData> directionalLights;
public List<LightData> punctualLights;
public List<LightData> areaLights;
public List<EnvLightData> envLights;
public List<PunctualShadowData> punctualShadows;
}

{
// Init light list
lightList = new LightList();
lightList.punctualLights = new List<PunctualLightData>();
lightList.areaLights = new List<AreaLightData>();
lightList.directionalLights = new List<DirectionalLightData>();
lightList.punctualLights = new List<LightData>();
lightList.areaLights = new List<LightData>();
lightList.envLights = new List<EnvLightData>();
lightList.punctualShadows = new List<PunctualShadowData>();

continue;
}
// Note: LightType.Area is offline only, use for baking, no need to test it
// Test whether we should treat this punctual light as an area light.
// It's a temporary hack until the proper UI support is added.
if (additionalData.treatAsAreaLight)
if (light.lightType == LightType.Directional)
if (lightList.areaLights.Count >= k_MaxAreaLightsOnSCreen)
if (lightList.areaLights.Count >= k_MaxDirectionalLightsOnSCreen)
var lightData = new AreaLightData();
var directionalLightData = new DirectionalLightData();
// Light direction for directional and is opposite to the forward direction
directionalLightData.direction = -light.light.transform.forward;
directionalLightData.color = new Vector3(lightColorR, lightColorG, lightColorB);
directionalLightData.diffuseScale = additionalData.affectDiffuse ? 1.0f : 0.0f;
directionalLightData.specularScale = additionalData.affectSpecular ? 1.0f : 0.0f;
directionalLightData.cosAngle = 0.0f;
directionalLightData.sinAngle = 0.0f;
directionalLightData.shadowIndex = -1;
// TODO: add AreaShapeType.Line support for small widths.
lightData.shapeType = AreaShapeType.Rectangle;
lightData.size = new Vector2(additionalData.areaLightLength, additionalData.areaLightWidth);
lightData.twoSided = additionalData.isDoubleSided;
// TODO: shadow
lightData.positionWS = light.light.transform.position;
lightData.forward = light.light.transform.forward; // Note: Light direction is oriented backward (-Z)
lightData.up = light.light.transform.up;
lightData.right = light.light.transform.right;
lightList.directionalLights.Add(directionalLightData);
lightData.color = new Vector3(lightColorR, lightColorG, lightColorB);
lightData.diffuseScale = additionalData.affectDiffuse ? 1.0f : 0.0f;
lightData.specularScale = additionalData.affectSpecular ? 1.0f : 0.0f;
lightData.shadowDimmer = additionalData.shadowDimmer;
continue;
}
lightData.invSqrAttenuationRadius = 1.0f / (light.range * light.range);
// Note: LightType.Area is offline only, use for baking, no need to test it
var lightData = new LightData();
lightList.areaLights.Add(lightData);
// Early out if we reach the maximum
// Test whether we should treat this punctual light as an area light.
// It's a temporary hack until the proper UI support is added.
if (additionalData.treatAsAreaLight)
{
if (lightList.areaLights.Count >= k_MaxAreaLightsOnSCreen)
continue;
// TODO: shadows.
lightData.lightType = GPULightType.Rectangle;
}
else
{

var punctualLightData = new PunctualLightData();
if (light.lightType == LightType.Directional)
switch (light.lightType)
punctualLightData.useDistanceAttenuation = 0.0f;
// positionWS store Light direction for directional and is opposite to the forward direction
punctualLightData.positionWS = -light.light.transform.forward;
punctualLightData.invSqrAttenuationRadius = 0.0f;
case LightType.Directional: lightData.lightType = GPULightType.Directional; break;
case LightType.Spot: lightData.lightType = GPULightType.Spot; break;
case LightType.Point: lightData.lightType = GPULightType.Point; break;
else
{
punctualLightData.useDistanceAttenuation = 1.0f;
punctualLightData.positionWS = light.light.transform.position;
punctualLightData.invSqrAttenuationRadius = 1.0f / (light.range * light.range);
}
}
punctualLightData.color = new Vector3(lightColorR, lightColorG, lightColorB);
lightData.positionWS = light.light.transform.position;
lightData.invSqrAttenuationRadius = 1.0f / (light.range * light.range);
punctualLightData.forward = light.light.transform.forward; // Note: Light direction is oriented backward (-Z)
punctualLightData.up = light.light.transform.up;
punctualLightData.right = light.light.transform.right;
lightData.color = new Vector3(lightColorR, lightColorG, lightColorB);
lightData.forward = light.light.transform.forward; // Note: Light direction is oriented backward (-Z)
lightData.up = light.light.transform.up;
lightData.right = light.light.transform.right;
if (light.lightType == LightType.Spot)
{
var spotAngle = light.spotAngle;
if (lightData.lightType == GPULightType.Spot)
{
var spotAngle = light.spotAngle;
var innerConePercent = additionalData.GetInnerSpotPercent01();
var cosSpotOuterHalfAngle = Mathf.Clamp(Mathf.Cos(spotAngle * 0.5f * Mathf.Deg2Rad), 0.0f, 1.0f);
var cosSpotInnerHalfAngle = Mathf.Clamp(Mathf.Cos(spotAngle * 0.5f * innerConePercent * Mathf.Deg2Rad), 0.0f, 1.0f); // inner cone
var innerConePercent = additionalData.GetInnerSpotPercent01();
var cosSpotOuterHalfAngle = Mathf.Clamp(Mathf.Cos(spotAngle * 0.5f * Mathf.Deg2Rad), 0.0f, 1.0f);
var cosSpotInnerHalfAngle = Mathf.Clamp(Mathf.Cos(spotAngle * 0.5f * innerConePercent * Mathf.Deg2Rad), 0.0f, 1.0f); // inner cone
var val = Mathf.Max(0.001f, (cosSpotInnerHalfAngle - cosSpotOuterHalfAngle));
punctualLightData.angleScale = 1.0f / val;
punctualLightData.angleOffset = -cosSpotOuterHalfAngle * punctualLightData.angleScale;
}
else
{
// 1.0f, 2.0f are neutral value allowing GetAngleAnttenuation in shader code to return 1.0
punctualLightData.angleScale = 1.0f;
punctualLightData.angleOffset = 2.0f;
}
var val = Mathf.Max(0.001f, (cosSpotInnerHalfAngle - cosSpotOuterHalfAngle));
lightData.angleScale = 1.0f / val;
lightData.angleOffset = -cosSpotOuterHalfAngle * lightData.angleScale;
}
else
{
// 1.0f, 2.0f are neutral value allowing GetAngleAnttenuation in shader code to return 1.0
lightData.angleScale = 1.0f;
lightData.angleOffset = 2.0f;
}
punctualLightData.diffuseScale = additionalData.affectDiffuse ? 1.0f : 0.0f;
punctualLightData.specularScale = additionalData.affectSpecular ? 1.0f : 0.0f;
punctualLightData.shadowDimmer = additionalData.shadowDimmer;
lightData.diffuseScale = additionalData.affectDiffuse ? 1.0f : 0.0f;
lightData.specularScale = additionalData.affectSpecular ? 1.0f : 0.0f;
lightData.shadowDimmer = additionalData.shadowDimmer;
punctualLightData.IESIndex = -1;
punctualLightData.cookieIndex = -1;
punctualLightData.shadowIndex = -1;
lightData.IESIndex = -1;
lightData.cookieIndex = -1;
lightData.shadowIndex = -1;
bool hasCookie = light.light.cookie != null;
if (hasCookie)
bool hasCookie = light.light.cookie != null;
if (hasCookie)
{
if (light.lightType == LightType.Point)
if (light.lightType == LightType.Point)
{
punctualLightData.cookieIndex = m_CubeCookieTexArray.FetchSlice(light.light.cookie);
}
else if (light.lightType == LightType.Spot)
{
punctualLightData.cookieIndex = m_CookieTexArray.FetchSlice(light.light.cookie);
}
lightData.cookieIndex = m_CubeCookieTexArray.FetchSlice(light.light.cookie);
// Setup shadow data arrays
bool hasShadows = light.light.shadows != LightShadows.None && shadowOutput.GetShadowSliceCountLightIndex(lightIndex) != 0;
bool hasNotReachMaxLimit = lightList.punctualShadows.Count + (light.lightType == LightType.Point ? 6 : 1) <= k_MaxShadowOnScreen;
if (hasShadows && hasNotReachMaxLimit) // Note < MaxShadows should be check at shadowOutput creation
else if (light.lightType == LightType.Spot)
// When we have a point light, we assumed that there is 6 consecutive PunctualShadowData
punctualLightData.shadowIndex = lightList.punctualShadows.Count;
lightData.cookieIndex = m_CookieTexArray.FetchSlice(light.light.cookie);
}
}
for (int sliceIndex = 0; sliceIndex < shadowOutput.GetShadowSliceCountLightIndex(lightIndex); ++sliceIndex)
{
PunctualShadowData punctualShadowData = new PunctualShadowData();
// Setup shadow data arrays
bool hasShadows = light.light.shadows != LightShadows.None && shadowOutput.GetShadowSliceCountLightIndex(lightIndex) != 0;
bool hasNotReachMaxLimit = lightList.punctualShadows.Count + (lightData.lightType == GPULightType.Point ? 6 : 1) <= k_MaxShadowOnScreen;
int shadowSliceIndex = shadowOutput.GetShadowSliceIndex(lightIndex, sliceIndex);
punctualShadowData.worldToShadow = shadowOutput.shadowSlices[shadowSliceIndex].shadowTransform.transpose; // Transpose for hlsl reading ?
if (hasShadows && hasNotReachMaxLimit) // Note < MaxShadows should be check at shadowOutput creation
{
// When we have a point light, we assumed that there is 6 consecutive PunctualShadowData
lightData.shadowIndex = lightList.punctualShadows.Count;
if (light.lightType == LightType.Spot)
{
punctualShadowData.shadowType = ShadowType.Spot;
}
else if (light.lightType == LightType.Point)
{
punctualShadowData.shadowType = ShadowType.Point;
}
else
{
punctualShadowData.shadowType = ShadowType.Directional;
}
for (int sliceIndex = 0; sliceIndex < shadowOutput.GetShadowSliceCountLightIndex(lightIndex); ++sliceIndex)
{
PunctualShadowData punctualShadowData = new PunctualShadowData();
int shadowSliceIndex = shadowOutput.GetShadowSliceIndex(lightIndex, sliceIndex);
punctualShadowData.worldToShadow = shadowOutput.shadowSlices[shadowSliceIndex].shadowTransform.transpose; // Transpose for hlsl reading ?
punctualShadowData.lightType = lightData.lightType;
punctualShadowData.bias = light.light.shadowBias;
punctualShadowData.bias = light.light.shadowBias;
lightList.punctualShadows.Add(punctualShadowData);
}
lightList.punctualShadows.Add(punctualShadowData);
}
lightList.punctualLights.Add(punctualLightData);
lightData.size = new Vector2(additionalData.areaLightLength, additionalData.areaLightWidth);
lightData.twoSided = additionalData.isDoubleSided;
if (additionalData.treatAsAreaLight)
{
lightList.areaLights.Add(lightData);
}
else
{
lightList.punctualLights.Add(lightData);
}
}

91
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs


// structure definition
//-----------------------------------------------------------------------------
[GenerateHLSL]
public enum GPULightType
{
Directional,
Spot,
Point,
ProjectorOrtho,
ProjectorPyramid,
// AreaLight
Rectangle,
Line,
// Currently not supported in real time (just use for reference)
Sphere,
Disk,
Hemisphere,
Cylinder
};
public struct PunctualLightData
public struct LightData
public float useDistanceAttenuation;
public float angleScale; // Spot light
public float angleScale;
public float angleOffset;
public float angleOffset;
public float diffuseScale; // Spot light
public float diffuseScale;
public int cookieIndex;
public int cookieIndex;
public Vector3 unused;
public GPULightType lightType;
// Area Light specific
public Vector2 size;
public bool twoSided;
public enum ShadowType
public struct DirectionalLightData
Spot,
Directional,
Point
public Vector3 direction;
public float diffuseScale;
public Vector3 color;
public float specularScale;
// Sun disc size
public float cosAngle; // Distance to disk
public float sinAngle; // Disk radius
public int shadowIndex;
public float unsued;
// TODO: we may have to add various parameters here for shadow - was suppose to be coupled with a light loop
// A point light is 6x PunctualShadowData

// Include scale and bias for shadow atlas if any
public Matrix4x4 worldToShadow;
public ShadowType shadowType;
public GPULightType lightType;
public Vector2 unused;
};
[GenerateHLSL]
public enum AreaShapeType
{
Rectangle,
Line,
// Currently not supported in real time (just use for reference)
Sphere,
Disk,
Hemisphere,
Cylinder
};
[GenerateHLSL]
public struct AreaLightData
{
public Vector3 positionWS;
public float invSqrAttenuationRadius;
public Vector3 color;
public AreaShapeType shapeType;
public Vector3 forward;
public float diffuseScale;
public Vector3 up;
public float specularScale;
public Vector3 right;
public float shadowDimmer;
public Vector2 size;
public bool twoSided;
public float unused;
};

198
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs.hlsl


#ifndef LIGHTDEFINITION_CS_HLSL
#define LIGHTDEFINITION_CS_HLSL
//
// UnityEngine.Experimental.ScriptableRenderLoop.ShadowType: static fields
// UnityEngine.Experimental.ScriptableRenderLoop.GPULightType: static fields
#define SHADOWTYPE_SPOT (0)
#define SHADOWTYPE_DIRECTIONAL (1)
#define SHADOWTYPE_POINT (2)
//
// UnityEngine.Experimental.ScriptableRenderLoop.AreaShapeType: static fields
//
#define AREASHAPETYPE_RECTANGLE (0)
#define AREASHAPETYPE_LINE (1)
#define AREASHAPETYPE_SPHERE (2)
#define AREASHAPETYPE_DISK (3)
#define AREASHAPETYPE_HEMISPHERE (4)
#define AREASHAPETYPE_CYLINDER (5)
#define GPULIGHTTYPE_DIRECTIONAL (0)
#define GPULIGHTTYPE_SPOT (1)
#define GPULIGHTTYPE_POINT (2)
#define GPULIGHTTYPE_PROJECTOR_ORTHO (3)
#define GPULIGHTTYPE_PROJECTOR_PYRAMID (4)
#define GPULIGHTTYPE_RECTANGLE (5)
#define GPULIGHTTYPE_LINE (6)
#define GPULIGHTTYPE_SPHERE (7)
#define GPULIGHTTYPE_DISK (8)
#define GPULIGHTTYPE_HEMISPHERE (9)
#define GPULIGHTTYPE_CYLINDER (10)
//
// UnityEngine.Experimental.ScriptableRenderLoop.EnvShapeType: static fields

#define ENVSHAPETYPE_SPHERE (2)
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.PunctualLightData
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.LightData
struct PunctualLightData
struct LightData
float useDistanceAttenuation;
float angleScale;
float angleScale;
float angleOffset;
float angleOffset;
float diffuseScale;
float diffuseScale;
float3 unused;
int lightType;
float2 size;
bool twoSided;
};
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.DirectionalLightData
// PackingRules = Exact
struct DirectionalLightData
{
float3 direction;
float diffuseScale;
float3 color;
float specularScale;
float cosAngle;
float sinAngle;
int shadowIndex;
float unsued;
};
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.PunctualShadowData

float4x4 worldToShadow;
int shadowType;
int lightType;
float2 unused;
};
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.AreaLightData
// PackingRules = Exact
struct AreaLightData
{
float3 positionWS;
float invSqrAttenuationRadius;
float3 color;
int shapeType;
float3 forward;
float diffuseScale;
float3 up;
float specularScale;
float3 right;
float shadowDimmer;
float2 size;
bool twoSided;
float unused;
};

};
//
// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.PunctualLightData
// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.LightData
float3 GetPositionWS(PunctualLightData value)
float3 GetPositionWS(LightData value)
float GetInvSqrAttenuationRadius(PunctualLightData value)
float GetInvSqrAttenuationRadius(LightData value)
float3 GetColor(PunctualLightData value)
float3 GetColor(LightData value)
float GetUseDistanceAttenuation(PunctualLightData value)
float GetAngleScale(LightData value)
return value.useDistanceAttenuation;
return value.angleScale;
float3 GetForward(PunctualLightData value)
float3 GetForward(LightData value)
float GetAngleScale(PunctualLightData value)
float GetAngleOffset(LightData value)
return value.angleScale;
return value.angleOffset;
float3 GetUp(PunctualLightData value)
float3 GetUp(LightData value)
float GetAngleOffset(PunctualLightData value)
float GetDiffuseScale(LightData value)
return value.angleOffset;
return value.diffuseScale;
float3 GetRight(PunctualLightData value)
float3 GetRight(LightData value)
float GetDiffuseScale(PunctualLightData value)
{
return value.diffuseScale;
}
float GetSpecularScale(PunctualLightData value)
float GetSpecularScale(LightData value)
float GetShadowDimmer(PunctualLightData value)
float GetShadowDimmer(LightData value)
int GetShadowIndex(PunctualLightData value)
int GetShadowIndex(LightData value)
int GetIESIndex(PunctualLightData value)
int GetIESIndex(LightData value)
int GetCookieIndex(PunctualLightData value)
int GetCookieIndex(LightData value)
float3 GetUnused(PunctualLightData value)
{
return value.unused;
}
//
// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.PunctualShadowData
//
float4x4 GetWorldToShadow(PunctualShadowData value)
int GetLightType(LightData value)
return value.worldToShadow;
return value.lightType;
int GetShadowType(PunctualShadowData value)
float2 GetSize(LightData value)
return value.shadowType;
return value.size;
float GetBias(PunctualShadowData value)
bool GetTwoSided(LightData value)
return value.bias;
}
float GetQuality(PunctualShadowData value)
{
return value.quality;
}
float2 GetUnused(PunctualShadowData value)
{
return value.unused;
return value.twoSided;
// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.AreaLightData
// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.DirectionalLightData
float3 GetPositionWS(AreaLightData value)
float3 GetDirection(DirectionalLightData value)
return value.positionWS;
return value.direction;
float GetInvSqrAttenuationRadius(AreaLightData value)
float GetDiffuseScale(DirectionalLightData value)
return value.invSqrAttenuationRadius;
return value.diffuseScale;
float3 GetColor(AreaLightData value)
float3 GetColor(DirectionalLightData value)
int GetShapeType(AreaLightData value)
float GetSpecularScale(DirectionalLightData value)
return value.shapeType;
return value.specularScale;
float3 GetForward(AreaLightData value)
float GetCosAngle(DirectionalLightData value)
return value.forward;
return value.cosAngle;
float GetDiffuseScale(AreaLightData value)
float GetSinAngle(DirectionalLightData value)
return value.diffuseScale;
return value.sinAngle;
float3 GetUp(AreaLightData value)
int GetShadowIndex(DirectionalLightData value)
return value.up;
return value.shadowIndex;
float GetSpecularScale(AreaLightData value)
float GetUnsued(DirectionalLightData value)
return value.specularScale;
return value.unsued;
float3 GetRight(AreaLightData value)
//
// Accessors for UnityEngine.Experimental.ScriptableRenderLoop.PunctualShadowData
//
float4x4 GetWorldToShadow(PunctualShadowData value)
return value.right;
return value.worldToShadow;
float GetShadowDimmer(AreaLightData value)
int GetLightType(PunctualShadowData value)
return value.shadowDimmer;
return value.lightType;
float2 GetSize(AreaLightData value)
float GetBias(PunctualShadowData value)
return value.size;
return value.bias;
bool GetTwoSided(AreaLightData value)
float GetQuality(PunctualShadowData value)
return value.twoSided;
return value.quality;
float GetUnused(AreaLightData value)
float GetUnused(PunctualShadowData value)
{
return value.unused;
}

71
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.cs


return "LIGHTLOOP_SINGLE_PASS";
}
ComputeBuffer m_punctualLightList;
ComputeBuffer m_envLightList;
ComputeBuffer m_areaLightList;
ComputeBuffer m_punctualShadowList;
// Static keyword is required here else we get a "DestroyBuffer can only be call in main thread"
static ComputeBuffer s_DirectionalLights;
static ComputeBuffer s_PunctualLightList;
static ComputeBuffer s_EnvLightList;
static ComputeBuffer s_AreaLightList;
static ComputeBuffer s_PunctualShadowList;
if (m_punctualLightList != null)
m_punctualLightList.Release();
if (s_DirectionalLights != null)
s_DirectionalLights.Release();
if (m_areaLightList != null)
m_areaLightList.Release();
if (s_PunctualLightList != null)
s_PunctualLightList.Release();
if (m_punctualShadowList != null)
m_punctualShadowList.Release();
if (s_AreaLightList != null)
s_AreaLightList.Release();
if (s_PunctualShadowList != null)
s_PunctualShadowList.Release();
if (m_envLightList != null)
m_envLightList.Release();
if (s_EnvLightList != null)
s_EnvLightList.Release();
}
public void Rebuild()

m_punctualLightList = new ComputeBuffer(HDRenderLoop.k_MaxPunctualLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(PunctualLightData)));
m_areaLightList = new ComputeBuffer(HDRenderLoop.k_MaxAreaLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(AreaLightData)));
m_envLightList = new ComputeBuffer(HDRenderLoop.k_MaxEnvLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
m_punctualShadowList = new ComputeBuffer(HDRenderLoop.k_MaxShadowOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(PunctualShadowData)));
s_DirectionalLights = new ComputeBuffer(HDRenderLoop.k_MaxDirectionalLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DirectionalLightData)));
s_PunctualLightList = new ComputeBuffer(HDRenderLoop.k_MaxPunctualLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_AreaLightList = new ComputeBuffer(HDRenderLoop.k_MaxAreaLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_EnvLightList = new ComputeBuffer(HDRenderLoop.k_MaxEnvLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
s_PunctualShadowList = new ComputeBuffer(HDRenderLoop.k_MaxShadowOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(PunctualShadowData)));
m_punctualLightList.Release();
m_areaLightList.Release();
m_envLightList.Release();
m_punctualShadowList.Release();
s_DirectionalLights.Release();
s_DirectionalLights = null;
s_PunctualLightList.Release();
s_PunctualLightList = null;
s_AreaLightList.Release();
s_AreaLightList = null;
s_EnvLightList.Release();
s_EnvLightList = null;
s_PunctualShadowList.Release();
s_PunctualShadowList = null;
m_punctualLightList.SetData(lightList.punctualLights.ToArray());
m_areaLightList.SetData(lightList.areaLights.ToArray());
m_envLightList.SetData(lightList.envLights.ToArray());
m_punctualShadowList.SetData(lightList.punctualShadows.ToArray());
s_DirectionalLights.SetData(lightList.directionalLights.ToArray());
s_PunctualLightList.SetData(lightList.punctualLights.ToArray());
s_AreaLightList.SetData(lightList.areaLights.ToArray());
s_EnvLightList.SetData(lightList.envLights.ToArray());
s_PunctualShadowList.SetData(lightList.punctualShadows.ToArray());
Shader.SetGlobalBuffer("_PunctualLightList", m_punctualLightList);
Shader.SetGlobalBuffer("_DirectionalLightList", s_DirectionalLights);
Shader.SetGlobalInt("_DirectionalLightCount", lightList.directionalLights.Count);
Shader.SetGlobalBuffer("_PunctualLightList", s_PunctualLightList);
Shader.SetGlobalBuffer("_AreaLightList", m_areaLightList);
Shader.SetGlobalBuffer("_AreaLightList", s_AreaLightList);
Shader.SetGlobalBuffer("_PunctualShadowList", m_punctualShadowList);
Shader.SetGlobalBuffer("_EnvLightList", m_envLightList);
Shader.SetGlobalBuffer("_PunctualShadowList", s_PunctualShadowList);
Shader.SetGlobalBuffer("_EnvLightList", s_EnvLightList);
Shader.SetGlobalInt("_EnvLightCount", lightList.envLights.Count);
}
}

13
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.hlsl


// Constant and structure declaration
// ----------------------------------------------------------------------------
StructuredBuffer<PunctualLightData> _PunctualLightList;
StructuredBuffer<AreaLightData> _AreaLightList;
StructuredBuffer<EnvLightData> _EnvLightList;
StructuredBuffer<PunctualShadowData> _PunctualShadowList;
StructuredBuffer<DirectionalLightData> _DirectionalLightList;
StructuredBuffer<LightData> _PunctualLightList;
StructuredBuffer<LightData> _AreaLightList;
StructuredBuffer<EnvLightData> _EnvLightList;
StructuredBuffer<PunctualShadowData> _PunctualShadowList;
//TEXTURE2D_ARRAY(_ShadowArray);
//SAMPLER2D_SHADOW(sampler_ShadowArray);

SAMPLERCUBE(sampler_SkyTexture); // NOTE: Sampler could be share here with _EnvTextures. Don't know if the shader compiler will complain...
CBUFFER_START(UnityPerLightLoop)
int _DirectionalLightCount;
int _PunctualLightCount;
int _AreaLightCount;
int _EnvLightCount;

float GetPunctualShadowAttenuation(LightLoopContext lightLoopContext, float3 positionWS, int index, float3 L, float2 unPositionSS)
{
int faceIndex = 0;
if (_PunctualShadowList[index].shadowType == SHADOWTYPE_POINT)
if (_PunctualShadowList[index].lightType == GPULIGHTTYPE_POINT)
{
GetCubeFaceID(L, faceIndex);
}

11
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePassLoop.hlsl


int i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < _DirectionalLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;
EvaluateBSDF_Directional( context, V, positionWS, prelightData, _DirectionalLightList[i], bsdfData,
localDiffuseLighting, localSpecularLighting);
diffuseLighting += localDiffuseLighting;
specularLighting += localSpecularLighting;
}
for (i = 0; i < _PunctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;

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


/*
ClearComputeBuffers();
buildScreenAABBShader = Resources.Load<ComputeShader>("srcbound");
buildScreenAABBShader = Resources.Load<ComputeShader>("scrbound");
buildPerTileLightListShader = Resources.Load<ComputeShader>("lightlistbuild");
buildPerBigTileLightListShader = Resources.Load<ComputeShader>("lightlistbuild-bigtile");
buildPerVoxelLightListShader = Resources.Load<ComputeShader>("lightlistbuild-clustered");

86
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.hlsl


// Area light specific
// UVs for sampling the LUTs
// TODO: Test with fastAcos
float theta = acos(dot(bsdfData.normalWS, V));
float theta = FastACos(dot(bsdfData.normalWS, V));
// Scale and bias for the current precomputed table - the constant use here are the one that have been use when the table in LtcData.DisneyDiffuse.cs and LtcData.GGX.cs was use
float2 uv = 0.0078125 + 0.984375 * float2(bsdfData.perceptualRoughness, theta * INV_HALF_PI);

#ifdef HAS_LIGHTLOOP
//-----------------------------------------------------------------------------
// BSDF share between area light (reference) and punctual light
// BSDF share between directional light, punctual light and area light (reference)
//-----------------------------------------------------------------------------
void BSDF( float3 V, float3 L, float3 positionWS, PreLightData preLightData, BSDFData bsdfData,

}
//-----------------------------------------------------------------------------
// EvaluateBSDF_Directional
//-----------------------------------------------------------------------------
void EvaluateBSDF_Directional( LightLoopContext lightLoopContext,
float3 V, float3 positionWS, PreLightData preLightData, DirectionalLightData lightData, BSDFData bsdfData,
out float3 diffuseLighting,
out float3 specularLighting)
{
float3 L = lightData.direction;
float illuminance = saturate(dot(bsdfData.normalWS, L));
diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
[branch] if (lightData.shadowIndex >= 0 && illuminance > 0.0f)
{
float shadowAttenuation = GetPunctualShadowAttenuation(lightLoopContext, positionWS, lightData.shadowIndex, L, preLightData.unPositionSS);
illuminance *= shadowAttenuation;
}
[branch] if (illuminance > 0.0f)
{
BSDF(V, L, positionWS, preLightData, bsdfData, diffuseLighting, specularLighting);
diffuseLighting *= lightData.color * illuminance * lightData.diffuseScale;
specularLighting *= lightData.color * illuminance * lightData.specularScale;
}
}
//-----------------------------------------------------------------------------
float3 V, float3 positionWS, PreLightData preLightData, PunctualLightData lightData, BSDFData bsdfData,
float3 V, float3 positionWS, PreLightData preLightData, LightData lightData, BSDFData bsdfData,
out float3 diffuseLighting,
out float3 specularLighting)
{

// For point light and directional GetAngleAttenuation() return 1
float3 unL = lightData.positionWS - positionWS * lightData.useDistanceAttenuation;
float3 unL = lightData.positionWS - positionWS;
float3 L = normalize(unL);
float attenuation = GetDistanceAttenuation(unL, lightData.invSqrAttenuationRadius);

// EvaluateBSDF_Area - Reference
//-----------------------------------------------------------------------------
void IntegrateGGXAreaRef( float3 V, float3 positionWS, PreLightData preLightData, AreaLightData lightData, BSDFData bsdfData,
void IntegrateGGXAreaRef( float3 V, float3 positionWS, PreLightData preLightData, LightData lightData, BSDFData bsdfData,
out float3 diffuseLighting,
out float3 specularLighting,
uint sampleCount = 512)

float4x4 localToWorld = float4x4(float4(lightData.right, 0.0), float4(lightData.up, 0.0), float4(lightData.forward, 0.0), float4(lightData.positionWS, 1.0));
if (lightData.shapeType == AREASHAPETYPE_SPHERE)
if (lightData.lightType == GPULIGHTTYPE_SPHERE)
else if (lightData.shapeType == AREASHAPETYPE_HEMISPHERE)
else if (lightData.lightType == GPULIGHTTYPE_HEMISPHERE)
else if (lightData.shapeType == AREASHAPETYPE_CYLINDER)
else if (lightData.lightType == GPULIGHTTYPE_CYLINDER)
else if (lightData.shapeType == AREASHAPETYPE_RECTANGLE)
else if (lightData.lightType == GPULIGHTTYPE_RECTANGLE)
else if (lightData.shapeType == AREASHAPETYPE_DISK)
else if (lightData.lightType == GPULIGHTTYPE_DISK)
else if (lightData.shapeType == AREASHAPETYPE_LINE)
else if (lightData.lightType == GPULIGHTTYPE_LINE)
// SampleLine(u, localToWorld, areaLight.lightRadius0, lightPdf, P, Ns);
; // TODO

//-----------------------------------------------------------------------------
void EvaluateBSDF_Area( LightLoopContext lightLoopContext,
float3 V, float3 positionWS, PreLightData preLightData, AreaLightData lightData, BSDFData bsdfData,
float3 V, float3 positionWS, PreLightData preLightData, LightData lightData, BSDFData bsdfData,
out float3 diffuseLighting,
out float3 specularLighting)
{

}
#ifndef DIFFUSE_LAMBERT_BRDF
// TODO: verify that we do not need to multiply by PI.
ltcValue *= preLightData.ltcDisneyDiffuseMagnitude;
#endif

ltcValue *= lightData.specularScale;
specularLighting = fresnelTerm * lightData.color * ltcValue;
}
// TODO: current area light code doesn't take into account artist attenuation radius!
#endif
}

uint sampleCount = 2048)
{
float3 N = bsdfData.normalWS;
float3 tangentX = bsdfData.tangentWS;
float3 tangentY = bsdfData.bitangentWS;
float3 tangentX, tangentY;
GetLocalFrame(N, tangentX, tangentY);
for (uint i = 0; i < sampleCount; ++i)
{

float3 V, EnvLightData lightData, BSDFData bsdfData,
uint sampleCount = 2048)
{
float3 N = bsdfData.normalWS;
float NdotV = dot(N, V);
float3 acc = float3(0.0, 0.0, 0.0);
float3 N = bsdfData.normalWS;
float3 tangentX = bsdfData.tangentWS;
float3 tangentY = bsdfData.bitangentWS;
float NdotV = saturate(dot(N, V));
float3 acc = float3(0.0, 0.0, 0.0);
float3 tangentX, tangentY;
GetLocalFrame(N, tangentX, tangentY);
for (uint i = 0; i < sampleCount; ++i)
{

uint sampleCount = 2048)
{
float3 N = bsdfData.normalWS;
float NdotV = saturate(dot(N, V));
float3 tangentX = bsdfData.tangentWS;
float3 tangentY = bsdfData.bitangentWS;
float NdotV = saturate(dot(N, V));
float3 tangentX, tangentY;
GetLocalFrame(N, tangentX, tangentY);
for (uint i = 0; i < sampleCount; ++i)
{

*/
diffuseLighting = float3(0.0, 0.0, 0.0);
weight = float2(0.0, 0.0);
weight = float2(0.0, 1.0);
#else
// TODO: factor this code in common, so other material authoring don't require to rewrite everything,

10
Assets/ScriptableRenderLoop/ShaderLibrary/AreaLighting.hlsl


float IntegrateEdge(float3 v1, float3 v2)
{
float cosTheta = dot(v1, v2);
// TODO: Explain the 0.9999 <= precision is important!
cosTheta = Clamp(cosTheta, -0.9999, 0.9999);
// TODO: Experiment with fastAcos
float theta = acos(cosTheta);
float res = cross(v1, v2).z * theta / sin(theta);
// Clamp to avoid artifacts. This particular constant gives the best results.
cosTheta = Clamp(cosTheta, -0.9999, 0.9999);
float theta = FastACos(cosTheta);
float res = cross(v1, v2).z * theta / sin(theta);
return res;
}

8
Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl


#define MERGE_NAME(X, Y) X##Y
// Acos in 14 cycles.
float res = -0.156583 * x + HALF_PI;
res *= sqrt(1.0 - x);
return (inX >= 0) ? res : PI - res;
float res = (0.0468878 * x + -0.203471) * x + 1.570796; // p(x)
res *= sqrt(1.0f - x);
return (inX >= 0) ? res : PI - res; // Undo range reduction
}
// Same cost as Acos + 1 FR

12
Assets/ScriptableRenderLoop/ShaderLibrary/CommonLighting.hlsl


return v * sqrt((float3)r2 - 0.5 * v2.yzx - 0.5 * v2.zxy + vr3.yxx * v2.zzy);
}
// Computes the squared magnitude of the vector 'v' after mapping it
// to a vector within the sphere of radius 'r', where r = sqrt(r2).
// The vector is originally defined within the cube of dimensions [-r, r]^3.
// The mapping is performed as per MapCubeToSphere().
// 'dotV' is dot(v, v) (often calculated when calling such a function)
float ComputeCubeToSphereMapSqMagnitude(float3 v, float dotV, float r2)
// Computes the squared magnitude of the vector computed by MapCubeToSphere().
float ComputeCubeToSphereMapSqMagnitude(float3 v, float r2)
return r2 * dotV - v2.x * v2.y - v2.y * v2.z - v2.z * v2.x + v2.x * v2.y * v2.z * rcp(r2);
// Note: dot(v, v) is often computed before this function is called,
// so the compiler should optimize and use the precomputed result here.
return r2 * dot(v, v) - v2.x * v2.y - v2.y * v2.z - v2.z * v2.x + v2.x * v2.y * v2.z * rcp(r2);
}
#endif // UNITY_COMMON_LIGHTING_INCLUDED
正在加载...
取消
保存