浏览代码

[fptl] first pass at code cleanup and coding conventions compliance

/main
vlad-andreev 8 年前
当前提交
ef44a1f3
共有 13 个文件被更改,包括 962 次插入951 次删除
  1. 178
      Assets/ScriptableRenderLoop/ForwardRenderLoop/ForwardRenderLoop.cs
  2. 109
      Assets/ScriptableRenderLoop/common/SkyboxHelper.cs
  3. 184
      Assets/ScriptableRenderLoop/common/TextureCache.cs
  4. 2
      Assets/ScriptableRenderLoop/common/TextureSettings.cs
  5. 881
      Assets/ScriptableRenderLoop/fptl/FptlLighting.cs
  6. 64
      Assets/ScriptableRenderLoop/fptl/LightDefinitions.cs
  7. 202
      Assets/ScriptableRenderLoop/fptl/LightDefinitions.cs.hlsl
  8. 40
      Assets/ScriptableRenderLoop/fptl/LightingTemplate.hlsl
  9. 24
      Assets/ScriptableRenderLoop/fptl/ReflectionTemplate.hlsl
  10. 80
      Assets/ScriptableRenderLoop/fptl/lightlistbuild-clustered.compute
  11. 56
      Assets/ScriptableRenderLoop/fptl/lightlistbuild.compute
  12. 15
      Assets/ScriptableRenderLoop/fptl/renderloopfptl.asset
  13. 78
      Assets/ScriptableRenderLoop/fptl/scrbound.compute

178
Assets/ScriptableRenderLoop/ForwardRenderLoop/ForwardRenderLoop.cs


ShadowSettings m_ShadowSettings = ShadowSettings.Default;
ShadowRenderPass m_ShadowPass;
const int MAX_LIGHTS = 10;
const int MAX_SHADOWMAP_PER_LIGHTS = 6;
const int MAX_DIRECTIONAL_SPLIT = 4;
const int k_MaxLights = 10;
const int k_MaxShadowmapPerLights = 6;
const int k_MaxDirectionalSplit = 4;
const float DIRECTIONAL_LIGHT_PULLBACK_DISTANCE = 10000.0f;
const float k_DirectionalLightPullbackDistance = 10000.0f;
[NonSerialized] private int m_nWarnedTooManyLights = 0;
[NonSerialized] private int m_WarnedTooManyLights = 0;
void OnEnable()

//---------------------------------------------------------------------------------------------------------------------------------------------------
void UpdateLightConstants(VisibleLight[] visibleLights, ref ShadowOutput shadow)
{
int nNumLightsIncludingTooMany = 0;
var numLightsIncludingTooMany = 0;
int g_nNumLights = 0;
var numLights = 0;
Vector4[] g_vLightColor = new Vector4[MAX_LIGHTS];
Vector4[] g_vLightPosition_flInvRadius = new Vector4[MAX_LIGHTS];
Vector4[] g_vLightDirection = new Vector4[MAX_LIGHTS];
Vector4[] g_vLightShadowIndex_vLightParams = new Vector4[MAX_LIGHTS];
Vector4[] g_vLightFalloffParams = new Vector4[MAX_LIGHTS];
Vector4[] g_vSpotLightInnerOuterConeCosines = new Vector4[MAX_LIGHTS];
Matrix4x4[] g_matWorldToShadow = new Matrix4x4[MAX_LIGHTS * MAX_SHADOWMAP_PER_LIGHTS];
Vector4[] g_vDirShadowSplitSpheres = new Vector4[MAX_DIRECTIONAL_SPLIT];
var lightColor = new Vector4[k_MaxLights];
var lightPosition_invRadius = new Vector4[k_MaxLights];
var lightDirection = new Vector4[k_MaxLights];
var lightShadowIndex_lightParams = new Vector4[k_MaxLights];
var lightFalloffParams = new Vector4[k_MaxLights];
var spotLightInnerOuterConeCosines = new Vector4[k_MaxLights];
var matWorldToShadow = new Matrix4x4[k_MaxLights * k_MaxShadowmapPerLights];
var dirShadowSplitSpheres = new Vector4[k_MaxDirectionalSplit];
for (int nLight = 0; nLight < visibleLights.Length; nLight++)
for (var nLight = 0; nLight < visibleLights.Length; nLight++)
nNumLightsIncludingTooMany++;
if (nNumLightsIncludingTooMany > MAX_LIGHTS)
numLightsIncludingTooMany++;
if (numLightsIncludingTooMany > k_MaxLights)
VisibleLight light = visibleLights[nLight];
LightType lightType = light.lightType;
Vector3 position = light.light.transform.position;
Vector3 lightDir = light.light.transform.forward.normalized;
AdditionalLightData additionalLightData = light.light.GetComponent<AdditionalLightData>();
var light = visibleLights[nLight];
var lightType = light.lightType;
var position = light.light.transform.position;
var lightDir = light.light.transform.forward.normalized;
var additionalLightData = light.light.GetComponent<AdditionalLightData>();
bool hasShadows = shadow.GetShadowSliceCountLightIndex(nLight) != 0;
var hasShadows = shadow.GetShadowSliceCountLightIndex(nLight) != 0;
g_vLightColor[g_nNumLights] = light.finalColor;
g_vLightPosition_flInvRadius[g_nNumLights] = new Vector4(
position.x - (lightDir.x * DIRECTIONAL_LIGHT_PULLBACK_DISTANCE),
position.y - (lightDir.y * DIRECTIONAL_LIGHT_PULLBACK_DISTANCE),
position.z - (lightDir.z * DIRECTIONAL_LIGHT_PULLBACK_DISTANCE),
lightColor[numLights] = light.finalColor;
lightPosition_invRadius[numLights] = new Vector4(
position.x - (lightDir.x * k_DirectionalLightPullbackDistance),
position.y - (lightDir.y * k_DirectionalLightPullbackDistance),
position.z - (lightDir.z * k_DirectionalLightPullbackDistance),
g_vLightDirection[g_nNumLights] = new Vector4(lightDir.x, lightDir.y, lightDir.z);
g_vLightShadowIndex_vLightParams[g_nNumLights] = new Vector4(0, 0, 1, 1);
g_vLightFalloffParams[g_nNumLights] = new Vector4(0.0f, 0.0f, float.MaxValue, (float)lightType);
g_vSpotLightInnerOuterConeCosines[g_nNumLights] = new Vector4(0.0f, -1.0f, 1.0f);
lightDirection[numLights] = new Vector4(lightDir.x, lightDir.y, lightDir.z);
lightShadowIndex_lightParams[numLights] = new Vector4(0, 0, 1, 1);
lightFalloffParams[numLights] = new Vector4(0.0f, 0.0f, float.MaxValue, (float)lightType);
spotLightInnerOuterConeCosines[numLights] = new Vector4(0.0f, -1.0f, 1.0f);
for (int s = 0; s < MAX_DIRECTIONAL_SPLIT; ++s)
for (var s = 0; s < k_MaxDirectionalSplit; ++s)
g_vDirShadowSplitSpheres[s] = shadow.directionalShadowSplitSphereSqr[s];
dirShadowSplitSpheres[s] = shadow.directionalShadowSplitSphereSqr[s];
g_vLightColor[g_nNumLights] = light.finalColor;
lightColor[numLights] = light.finalColor;
g_vLightPosition_flInvRadius[g_nNumLights] = new Vector4(position.x, position.y, position.z, 1.0f / light.range);
g_vLightDirection[g_nNumLights] = new Vector4(0.0f, 0.0f, 0.0f);
g_vLightShadowIndex_vLightParams[g_nNumLights] = new Vector4(0, 0, 1, 1);
g_vLightFalloffParams[g_nNumLights] = new Vector4(1.0f, 0.0f, light.range * light.range, (float)lightType);
g_vSpotLightInnerOuterConeCosines[g_nNumLights] = new Vector4(0.0f, -1.0f, 1.0f);
lightPosition_invRadius[numLights] = new Vector4(position.x, position.y, position.z, 1.0f / light.range);
lightDirection[numLights] = new Vector4(0.0f, 0.0f, 0.0f);
lightShadowIndex_lightParams[numLights] = new Vector4(0, 0, 1, 1);
lightFalloffParams[numLights] = new Vector4(1.0f, 0.0f, light.range * light.range, (float)lightType);
spotLightInnerOuterConeCosines[numLights] = new Vector4(0.0f, -1.0f, 1.0f);
g_vLightColor[g_nNumLights] = light.finalColor;
g_vLightPosition_flInvRadius[g_nNumLights] = new Vector4(position.x, position.y, position.z, 1.0f / light.range);
g_vLightDirection[g_nNumLights] = new Vector4(lightDir.x, lightDir.y, lightDir.z);
g_vLightShadowIndex_vLightParams[g_nNumLights] = new Vector4(0, 0, 1, 1);
g_vLightFalloffParams[g_nNumLights] = new Vector4(1.0f, 0.0f, light.range * light.range, (float)lightType);
lightColor[numLights] = light.finalColor;
lightPosition_invRadius[numLights] = new Vector4(position.x, position.y, position.z, 1.0f / light.range);
lightDirection[numLights] = new Vector4(lightDir.x, lightDir.y, lightDir.z);
lightShadowIndex_lightParams[numLights] = new Vector4(0, 0, 1, 1);
lightFalloffParams[numLights] = new Vector4(1.0f, 0.0f, light.range * light.range, (float)lightType);
float flInnerConePercent = AdditionalLightData.GetInnerSpotPercent01(additionalLightData);
float spotAngle = light.light.spotAngle;
float flPhiDot = Mathf.Clamp(Mathf.Cos(spotAngle * 0.5f * Mathf.Deg2Rad), 0.0f, 1.0f); // outer cone
float flThetaDot = Mathf.Clamp(Mathf.Cos(spotAngle * 0.5f * flInnerConePercent * Mathf.Deg2Rad), 0.0f, 1.0f); // inner cone
g_vSpotLightInnerOuterConeCosines[g_nNumLights] = new Vector4(flThetaDot, flPhiDot, 1.0f / Mathf.Max(0.01f, flThetaDot - flPhiDot));
var flInnerConePercent = AdditionalLightData.GetInnerSpotPercent01(additionalLightData);
var spotAngle = light.light.spotAngle;
var flPhiDot = Mathf.Clamp(Mathf.Cos(spotAngle * 0.5f * Mathf.Deg2Rad), 0.0f, 1.0f); // outer cone
var flThetaDot = Mathf.Clamp(Mathf.Cos(spotAngle * 0.5f * flInnerConePercent * Mathf.Deg2Rad), 0.0f, 1.0f); // inner cone
spotLightInnerOuterConeCosines[numLights] = new Vector4(flThetaDot, flPhiDot, 1.0f / Mathf.Max(0.01f, flThetaDot - flPhiDot));
g_vLightShadowIndex_vLightParams[g_nNumLights].x = 1;
for (int s = 0; s < shadow.GetShadowSliceCountLightIndex(nLight); ++s)
lightShadowIndex_lightParams[numLights].x = 1;
for (var s = 0; s < shadow.GetShadowSliceCountLightIndex(nLight); ++s)
int shadowSliceIndex = shadow.GetShadowSliceIndex(nLight, s);
g_matWorldToShadow[g_nNumLights * MAX_SHADOWMAP_PER_LIGHTS + s] = shadow.shadowSlices[shadowSliceIndex].shadowTransform.transpose;
var shadowSliceIndex = shadow.GetShadowSliceIndex(nLight, s);
matWorldToShadow[numLights * k_MaxShadowmapPerLights + s] = shadow.shadowSlices[shadowSliceIndex].shadowTransform.transpose;
g_nNumLights++;
numLights++;
if (nNumLightsIncludingTooMany > MAX_LIGHTS)
if (numLightsIncludingTooMany > k_MaxLights)
if (nNumLightsIncludingTooMany > m_nWarnedTooManyLights)
if (numLightsIncludingTooMany > m_WarnedTooManyLights)
Debug.LogError("ERROR! Found " + nNumLightsIncludingTooMany + " runtime lights! Valve renderer supports up to " + MAX_LIGHTS +
" active runtime lights at a time!\nDisabling " + (nNumLightsIncludingTooMany - MAX_LIGHTS) + " runtime light" +
((nNumLightsIncludingTooMany - MAX_LIGHTS) > 1 ? "s" : "") + "!\n");
Debug.LogError("ERROR! Found " + numLightsIncludingTooMany + " runtime lights! Valve renderer supports up to " + k_MaxLights +
" active runtime lights at a time!\nDisabling " + (numLightsIncludingTooMany - k_MaxLights) + " runtime light" +
((numLightsIncludingTooMany - k_MaxLights) > 1 ? "s" : "") + "!\n");
m_nWarnedTooManyLights = nNumLightsIncludingTooMany;
m_WarnedTooManyLights = numLightsIncludingTooMany;
if (m_nWarnedTooManyLights > 0)
if (m_WarnedTooManyLights > 0)
m_nWarnedTooManyLights = 0;
Debug.Log("SUCCESS! Found " + nNumLightsIncludingTooMany + " runtime lights which is within the supported number of lights, " + MAX_LIGHTS + ".\n\n");
m_WarnedTooManyLights = 0;
Debug.Log("SUCCESS! Found " + numLightsIncludingTooMany + " runtime lights which is within the supported number of lights, " + k_MaxLights + ".\n\n");
Shader.SetGlobalInt("g_nNumLights", g_nNumLights);
Shader.SetGlobalInt("g_nNumLights", numLights);
Shader.SetGlobalVectorArray("g_vLightPosition_flInvRadius", g_vLightPosition_flInvRadius);
Shader.SetGlobalVectorArray("g_vLightColor", g_vLightColor);
Shader.SetGlobalVectorArray("g_vLightDirection", g_vLightDirection);
Shader.SetGlobalVectorArray("g_vLightShadowIndex_vLightParams", g_vLightShadowIndex_vLightParams);
Shader.SetGlobalVectorArray("g_vLightFalloffParams", g_vLightFalloffParams);
Shader.SetGlobalVectorArray("g_vSpotLightInnerOuterConeCosines", g_vSpotLightInnerOuterConeCosines);
Shader.SetGlobalMatrixArray("g_matWorldToShadow", g_matWorldToShadow);
Shader.SetGlobalVectorArray("g_vDirShadowSplitSpheres", g_vDirShadowSplitSpheres);
Shader.SetGlobalVectorArray("g_vLightPosition_flInvRadius", lightPosition_invRadius);
Shader.SetGlobalVectorArray("g_vLightColor", lightColor);
Shader.SetGlobalVectorArray("g_vLightDirection", lightDirection);
Shader.SetGlobalVectorArray("g_vLightShadowIndex_vLightParams", lightShadowIndex_lightParams);
Shader.SetGlobalVectorArray("g_vLightFalloffParams", lightFalloffParams);
Shader.SetGlobalVectorArray("g_vSpotLightInnerOuterConeCosines", spotLightInnerOuterConeCosines);
Shader.SetGlobalMatrixArray("g_matWorldToShadow", matWorldToShadow);
Shader.SetGlobalVectorArray("g_vDirShadowSplitSpheres", dirShadowSplitSpheres);
// Time
#if (UNITY_EDITOR)

#endif
// PCF 3x3 Shadows
float flTexelEpsilonX = 1.0f / m_ShadowSettings.shadowAtlasWidth;
float flTexelEpsilonY = 1.0f / m_ShadowSettings.shadowAtlasHeight;
Vector4 g_vShadow3x3PCFTerms0 = new Vector4(20.0f / 267.0f, 33.0f / 267.0f, 55.0f / 267.0f, 0.0f);
Vector4 g_vShadow3x3PCFTerms1 = new Vector4(flTexelEpsilonX, flTexelEpsilonY, -flTexelEpsilonX, -flTexelEpsilonY);
Vector4 g_vShadow3x3PCFTerms2 = new Vector4(flTexelEpsilonX, flTexelEpsilonY, 0.0f, 0.0f);
Vector4 g_vShadow3x3PCFTerms3 = new Vector4(-flTexelEpsilonX, -flTexelEpsilonY, 0.0f, 0.0f);
var texelEpsilonX = 1.0f / m_ShadowSettings.shadowAtlasWidth;
var texelEpsilonY = 1.0f / m_ShadowSettings.shadowAtlasHeight;
var shadow3x3PCFTerms0 = new Vector4(20.0f / 267.0f, 33.0f / 267.0f, 55.0f / 267.0f, 0.0f);
var shadow3x3PCFTerms1 = new Vector4(texelEpsilonX, texelEpsilonY, -texelEpsilonX, -texelEpsilonY);
var shadow3x3PCFTerms2 = new Vector4(texelEpsilonX, texelEpsilonY, 0.0f, 0.0f);
var shadow3x3PCFTerms3 = new Vector4(-texelEpsilonX, -texelEpsilonY, 0.0f, 0.0f);
Shader.SetGlobalVector("g_vShadow3x3PCFTerms0", g_vShadow3x3PCFTerms0);
Shader.SetGlobalVector("g_vShadow3x3PCFTerms1", g_vShadow3x3PCFTerms1);
Shader.SetGlobalVector("g_vShadow3x3PCFTerms2", g_vShadow3x3PCFTerms2);
Shader.SetGlobalVector("g_vShadow3x3PCFTerms3", g_vShadow3x3PCFTerms3);
Shader.SetGlobalVector("g_vShadow3x3PCFTerms0", shadow3x3PCFTerms0);
Shader.SetGlobalVector("g_vShadow3x3PCFTerms1", shadow3x3PCFTerms1);
Shader.SetGlobalVector("g_vShadow3x3PCFTerms2", shadow3x3PCFTerms2);
Shader.SetGlobalVector("g_vShadow3x3PCFTerms3", shadow3x3PCFTerms3);
}
public override void Render(Camera[] cameras, RenderLoop renderLoop)

UpdateLightConstants(cullResults.visibleLights, ref shadows);
DrawRendererSettings settings = new DrawRendererSettings(cullResults, camera, new ShaderPassName("ForwardBase"));
var settings = new DrawRendererSettings(cullResults, camera, new ShaderPassName("ForwardBase"));
settings.rendererConfiguration = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectReflectionProbes;
settings.sorting.sortOptions = SortOptions.SortByMaterialThenMesh;

#if UNITY_EDITOR
public override UnityEditor.SupportedRenderingFeatures GetSupportedRenderingFeatures()
{
var features = new UnityEditor.SupportedRenderingFeatures();
features.reflectionProbe = UnityEditor.SupportedRenderingFeatures.ReflectionProbe.Rotation;
var features = new UnityEditor.SupportedRenderingFeatures
{
reflectionProbe = UnityEditor.SupportedRenderingFeatures.ReflectionProbe.Rotation
};
return features;
}

109
Assets/ScriptableRenderLoop/common/SkyboxHelper.cs


{
}
const int NumFullSubdivisions = 3; // 3 subdivs == 2048 triangles
const int NumHorizonSubdivisions = 2;
const int k_NumFullSubdivisions = 3; // 3 subdivs == 2048 triangles
const int k_NumHorizonSubdivisions = 2;
Vector3[] vertData = new Vector3[8 * 3];
for (int i = 0; i < 8 * 3; i++)
var vertData = new Vector3[8 * 3];
for (var i = 0; i < 8 * 3; i++)
vertData[i] = octaVerts[i];
vertData[i] = m_OctaVerts[i];
for (int i = 0; i < NumFullSubdivisions; i++)
for (var i = 0; i < k_NumFullSubdivisions; i++)
Vector3[] srcData = vertData.Clone() as Vector3[];
List<Vector3> verts = new List<Vector3>();
var srcData = vertData.Clone() as Vector3[];
var verts = new List<Vector3>();
for (int k = 0; k < srcData.Length; k += 3)
for (var k = 0; k < srcData.Length; k += 3)
{
Subdivide(verts, srcData[k], srcData[k + 1], srcData[k + 2]);
}

// Horizon subdivisions
float horizonLimit = 1.0f;
for (int i = 0; i < NumHorizonSubdivisions; i++)
var horizonLimit = 1.0f;
for (var i = 0; i < k_NumHorizonSubdivisions; i++)
Vector3[] srcData = vertData.Clone() as Vector3[];
List<Vector3> verts = new List<Vector3>();
var srcData = vertData.Clone() as Vector3[];
var verts = new List<Vector3>();
for (int k = 0; k < srcData.Length; k += 3)
for (var k = 0; k < srcData.Length; k += 3)
float maxAbsY = Mathf.Max(Mathf.Abs(srcData[k].y), Mathf.Abs(srcData[k + 1].y), Mathf.Abs(srcData[k + 2].y));
var maxAbsY = Mathf.Max(Mathf.Abs(srcData[k].y), Mathf.Abs(srcData[k + 1].y), Mathf.Abs(srcData[k + 2].y));
if (maxAbsY > horizonLimit)
{
// Pass through existing triangle

}
// Write out the mesh
int vertexCount = vertData.Length;
var vertexCount = vertData.Length;
for (int i = 0; i < vertexCount; i++)
for (var i = 0; i < vertexCount; i++)
_mesh = new Mesh();
_mesh.vertices = vertData;
_mesh.triangles = triangles;
m_Mesh = new Mesh
{
vertices = vertData,
triangles = triangles
};
get { return _mesh; }
get { return m_Mesh; }
}
public void Draw(RenderLoop loop, Camera camera)

return;
}
Material mat = RenderSettings.skybox;
var mat = RenderSettings.skybox;
if (mat == null)
{

CommandBuffer cmd = new CommandBuffer();
cmd.name = "Skybox";
var cmd = new CommandBuffer { name = "Skybox" };
bool looksLikeSixSidedShader = true;
var looksLikeSixSidedShader = true;
looksLikeSixSidedShader &= (mat.passCount == 6); // should have six passes
//looksLikeSixSidedShader &= !mat.GetShader()->GetShaderLabShader()->HasLightingPasses();

CreateMesh();
}
float dist = camera.farClipPlane * 10.0f;
var dist = camera.farClipPlane * 10.0f;
Matrix4x4 world = Matrix4x4.TRS(camera.transform.position, Quaternion.identity, new Vector3(dist, dist, dist));
var world = Matrix4x4.TRS(camera.transform.position, Quaternion.identity, new Vector3(dist, dist, dist));
Matrix4x4 skyboxProj = SkyboxHelper.GetProjectionMatrix(camera);
var skyboxProj = SkyboxHelper.GetProjectionMatrix(camera);
cmd.SetProjectionAndViewMatrices(skyboxProj, camera.worldToCameraMatrix);
cmd.DrawMesh(mesh, world, mat);

cmd.Dispose();
}
static public Matrix4x4 GetProjectionMatrix(Camera camera)
public static Matrix4x4 GetProjectionMatrix(Camera camera)
Matrix4x4 skyboxProj = Matrix4x4.Perspective(camera.fieldOfView, camera.aspect, camera.nearClipPlane, camera.farClipPlane);
var skyboxProj = Matrix4x4.Perspective(camera.fieldOfView, camera.aspect, camera.nearClipPlane, camera.farClipPlane);
float nearPlane = camera.nearClipPlane * 0.01f;
var nearPlane = camera.nearClipPlane * 0.01f;
skyboxProj = AdjustDepthRange(skyboxProj, camera.nearClipPlane, nearPlane, camera.farClipPlane);
return MakeProjectionInfinite(skyboxProj, nearPlane);
}

const float epsilon = 1e-6f;
Matrix4x4 r = m;
var r = m;
r[2, 2] = -1.0f + epsilon;
r[2, 3] = (-2.0f + epsilon) * nearPlane;
r[3, 2] = -1.0f;

static Matrix4x4 AdjustDepthRange(Matrix4x4 mat, float origNear, float newNear, float newFar)
{
float x = mat[0, 0];
float y = mat[1, 1];
float w = mat[0, 2];
float z = mat[1, 2];
var x = mat[0, 0];
var y = mat[1, 1];
var w = mat[0, 2];
var z = mat[1, 2];
float r = ((2.0f * origNear) / x) * ((w + 1) * 0.5f);
float t = ((2.0f * origNear) / y) * ((z + 1) * 0.5f);
float l = ((2.0f * origNear) / x) * (((w + 1) * 0.5f) - 1);
float b = ((2.0f * origNear) / y) * (((z + 1) * 0.5f) - 1);
var r = ((2.0f * origNear) / x) * ((w + 1) * 0.5f);
var t = ((2.0f * origNear) / y) * ((z + 1) * 0.5f);
var l = ((2.0f * origNear) / x) * (((w + 1) * 0.5f) - 1);
var b = ((2.0f * origNear) / y) * (((z + 1) * 0.5f) - 1);
float ratio = (newNear / origNear);
var ratio = (newNear / origNear);
r *= ratio;
t *= ratio;

Matrix4x4 ret = new Matrix4x4();
var ret = new Matrix4x4();
ret[0, 0] = (2.0f * newNear) / (r - l); ret[0, 1] = 0; ret[0, 2] = (r + l) / (r - l); ret[0, 3] = 0;
ret[1, 0] = 0; ret[1, 1] = (2.0f * newNear) / (t - b); ret[1, 2] = (t + b) / (t - b); ret[1, 3] = 0;

}
// Octahedron vertices
Vector3[] octaVerts =
readonly Vector3[] m_OctaVerts =
{
new Vector3(0.0f, 1.0f, 0.0f), new Vector3(0.0f, 0.0f, -1.0f), new Vector3(1.0f, 0.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f), new Vector3(1.0f, 0.0f, 0.0f), new Vector3(0.0f, 0.0f, 1.0f),

return Vector3.Normalize(v1 + v2);
}
void Subdivide(List<Vector3> dest, Vector3 v1, Vector3 v2, Vector3 v3)
void Subdivide(ICollection<Vector3> dest, Vector3 v1, Vector3 v2, Vector3 v3)
Vector3 v12 = SubDivVert(v1, v2);
Vector3 v23 = SubDivVert(v2, v3);
Vector3 v13 = SubDivVert(v1, v3);
var v12 = SubDivVert(v1, v2);
var v23 = SubDivVert(v2, v3);
var v13 = SubDivVert(v1, v3);
dest.Add(v1);
dest.Add(v12);

dest.Add(v23);
}
void SubdivideYOnly(List<Vector3> dest, Vector3 v1, Vector3 v2, Vector3 v3)
void SubdivideYOnly(ICollection<Vector3> dest, Vector3 v1, Vector3 v2, Vector3 v3)
float d12 = Mathf.Abs(v2.y - v1.y);
float d23 = Mathf.Abs(v2.y - v3.y);
float d31 = Mathf.Abs(v3.y - v1.y);
var d12 = Mathf.Abs(v2.y - v1.y);
var d23 = Mathf.Abs(v2.y - v3.y);
var d31 = Mathf.Abs(v3.y - v1.y);
Vector3 top, va, vb;

vb = v1;
}
Vector3 v12 = SubDivVert(top, va);
Vector3 v13 = SubDivVert(top, vb);
var v12 = SubDivVert(top, va);
var v13 = SubDivVert(top, vb);
dest.Add(top);
dest.Add(v12);

}
}
Mesh _mesh;
Mesh m_Mesh;
}

184
Assets/ScriptableRenderLoop/common/TextureCache.cs


public override void TransferToSlice(int sliceIndex, Texture texture)
{
bool mismatch = (cache.width != texture.width) || (cache.height != texture.height);
var mismatch = (cache.width != texture.width) || (cache.height != texture.height);
if (texture is Texture2D)
{

public bool AllocTextureArray(int numTextures, int width, int height, TextureFormat format, bool isMipMapped)
{
bool res = AllocTextureArray(numTextures);
m_numMipLevels = GetNumMips(width, height);
var res = AllocTextureArray(numTextures);
m_NumMipLevels = GetNumMips(width, height);
cache = new Texture2DArray(width, height, numTextures, format, isMipMapped);
cache.hideFlags = HideFlags.HideAndDontSave;
cache.wrapMode = TextureWrapMode.Clamp;
cache = new Texture2DArray(width, height, numTextures, format, isMipMapped)
{
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Clamp
};
return res;
}

public class TextureCacheCubemap : TextureCache
{
private CubemapArray cache;
private CubemapArray m_Cache;
bool mismatch = (cache.width != texture.width) || (cache.height != texture.height);
var mismatch = (m_Cache.width != texture.width) || (m_Cache.height != texture.height);
mismatch |= (cache.format != (texture as Cubemap).format);
mismatch |= (m_Cache.format != (texture as Cubemap).format);
texture.name, cache.width, cache.height, cache.format);
texture.name, m_Cache.width, m_Cache.height, m_Cache.format);
for (int f = 0; f < 6; f++)
Graphics.CopyTexture(texture, f, cache, 6 * sliceIndex + f);
for (var f = 0; f < 6; f++)
Graphics.CopyTexture(texture, f, m_Cache, 6 * sliceIndex + f);
return cache;
return m_Cache;
bool res = AllocTextureArray(6 * numCubeMaps);
m_numMipLevels = GetNumMips(width, width);
var res = AllocTextureArray(6 * numCubeMaps);
m_NumMipLevels = GetNumMips(width, width);
cache = new CubemapArray(width, numCubeMaps, format, isMipMapped);
cache.hideFlags = HideFlags.HideAndDontSave;
cache.wrapMode = TextureWrapMode.Clamp;
m_Cache = new CubemapArray(width, numCubeMaps, format, isMipMapped)
{
hideFlags = HideFlags.HideAndDontSave,
wrapMode = TextureWrapMode.Clamp
};
return res;
}

Texture.DestroyImmediate(cache); // do I need this?
Texture.DestroyImmediate(m_Cache); // do I need this?
abstract public class TextureCache : Object
public abstract class TextureCache : Object
protected int m_numMipLevels;
protected int m_NumMipLevels;
public static int ms_GlobalTextureCacheVersion = 0;
public int m_TextureCacheVersion = 0;
static int s_GlobalTextureCacheVersion = 0;
int m_TextureCacheVersion = 0;
#if UNITY_EDITOR
internal class AssetReloader : UnityEditor.AssetPostprocessor

ms_GlobalTextureCacheVersion++;
s_GlobalTextureCacheVersion++;
private AssetReloader m_assetReloader;
public uint TexID;
public uint CountLRU;
public uint texId;
public uint countLRU;
private int m_numTextures;
private int m_NumTextures;
Dictionary<uint, int> m_locatorInSliceArray;
Dictionary<uint, int> m_LocatorInSliceArray;
private static uint g_MaxFrameCount = unchecked((uint)(-1));
private static uint g_InvalidTexID = (uint)0;

uint TexID = (uint)texture.GetInstanceID();
var texId = (uint)texture.GetInstanceID();
if (TexID == g_InvalidTexID) return 0;
if (texId == g_InvalidTexID) return 0;
bool bSwapSlice = false;
bool bFoundAvailOrExistingSlice = false;
int sliceIndex = -1;
var bSwapSlice = false;
var bFoundAvailOrExistingSlice = false;
var sliceIndex = -1;
if (m_locatorInSliceArray.ContainsKey(TexID))
if (m_LocatorInSliceArray.ContainsKey(texId))
if (m_TextureCacheVersion != ms_GlobalTextureCacheVersion)
if (m_TextureCacheVersion != s_GlobalTextureCacheVersion)
m_locatorInSliceArray.Remove(TexID);
m_LocatorInSliceArray.Remove(texId);
Debug.Assert(m_TextureCacheVersion <= ms_GlobalTextureCacheVersion);
Debug.Assert(m_TextureCacheVersion <= s_GlobalTextureCacheVersion);
sliceIndex = m_locatorInSliceArray[TexID];
sliceIndex = m_LocatorInSliceArray[texId];
bFoundAvailOrExistingSlice = true;
}
//assert(m_SliceArray[sliceIndex].TexID==TexID);

{
// look for first non zero entry. Will by the least recently used entry
// since the array was pre-sorted (in linear time) in NewFrame()
bool bFound = false;
var bFound = false;
while ((!bFound) && j < m_numTextures)
while ((!bFound) && j < m_NumTextures)
if (m_SliceArray[idx].CountLRU == 0) ++j; // if entry already snagged by a new texture in this frame then ++j
if (m_SliceArray[idx].countLRU == 0) ++j; // if entry already snagged by a new texture in this frame then ++j
else bFound = true;
}

if (m_SliceArray[idx].TexID != g_InvalidTexID)
if (m_SliceArray[idx].texId != g_InvalidTexID)
m_locatorInSliceArray.Remove(m_SliceArray[idx].TexID);
m_LocatorInSliceArray.Remove(m_SliceArray[idx].texId);
m_locatorInSliceArray.Add(TexID, idx);
m_SliceArray[idx].TexID = TexID;
m_LocatorInSliceArray.Add(texId, idx);
m_SliceArray[idx].texId = texId;
sliceIndex = idx;
bFoundAvailOrExistingSlice = true;

//assert(bFoundAvailOrExistingSlice);
if (bFoundAvailOrExistingSlice)
{
m_SliceArray[sliceIndex].CountLRU = 0; // mark slice as in use this frame
m_SliceArray[sliceIndex].countLRU = 0; // mark slice as in use this frame
if (bSwapSlice) // if this was a miss
{

public void NewFrame()
{
int numNonZeros = 0;
int[] tmpBuffer = new int[m_numTextures];
for (int i = 0; i < m_numTextures; i++)
var numNonZeros = 0;
var tmpBuffer = new int[m_NumTextures];
for (var i = 0; i < m_NumTextures; i++)
if (m_SliceArray[m_SortedIdxArray[i]].CountLRU != 0) ++numNonZeros;
if (m_SliceArray[m_SortedIdxArray[i]].countLRU != 0) ++numNonZeros;
for (int i = 0; i < m_numTextures; i++)
for (var i = 0; i < m_NumTextures; i++)
if (m_SliceArray[tmpBuffer[i]].CountLRU == 0)
if (m_SliceArray[tmpBuffer[i]].countLRU == 0)
{
m_SortedIdxArray[zerosBase + numNonZeros] = tmpBuffer[i];
++zerosBase;

}
}
for (int i = 0; i < m_numTextures; i++)
for (var i = 0; i < m_NumTextures; i++)
if (m_SliceArray[i].CountLRU < g_MaxFrameCount) ++m_SliceArray[i].CountLRU; // next frame
if (m_SliceArray[i].countLRU < g_MaxFrameCount) ++m_SliceArray[i].countLRU; // next frame
}
//for(int q=1; q<m_numTextures; q++)

public TextureCache()
protected TextureCache()
m_numTextures = 0;
m_numMipLevels = 0;
m_NumTextures = 0;
m_NumMipLevels = 0;
}
public virtual void TransferToSlice(int sliceIndex, Texture texture)

{
m_SliceArray = new SSliceEntry[numTextures];
m_SortedIdxArray = new int[numTextures];
m_locatorInSliceArray = new Dictionary<uint, int>();
m_LocatorInSliceArray = new Dictionary<uint, int>();
m_numTextures = numTextures;
for (int i = 0; i < m_numTextures; i++)
m_NumTextures = numTextures;
for (var i = 0; i < m_NumTextures; i++)
m_SliceArray[i].CountLRU = g_MaxFrameCount; // never used before
m_SliceArray[i].TexID = g_InvalidTexID;
m_SliceArray[i].countLRU = g_MaxFrameCount; // never used before
m_SliceArray[i].texId = g_InvalidTexID;
m_SortedIdxArray[i] = i;
}
}

// should not really be used in general. Assuming lights are culled properly entries will automatically be replaced efficiently.
public void RemoveEntryFromSlice(Texture texture)
{
uint TexID = (uint)texture.GetInstanceID();
var texId = (uint)texture.GetInstanceID();
if (TexID == g_InvalidTexID) return;
if (texId == g_InvalidTexID) return;
if (m_locatorInSliceArray.ContainsKey(TexID))
{
int sliceIndex = m_locatorInSliceArray[TexID];
if (!m_LocatorInSliceArray.ContainsKey(texId))
return;
//assert(m_SliceArray[sliceIndex].TexID==TexID);
var sliceIndex = m_LocatorInSliceArray[texId];
// locate entry sorted by uCountLRU in m_pSortedIdxArray
bool bFoundIdxSortLRU = false;
int i = 0;
while ((!bFoundIdxSortLRU) && i < m_numTextures)
{
if (m_SortedIdxArray[i] == sliceIndex) bFoundIdxSortLRU = true;
else ++i;
}
//assert(m_SliceArray[sliceIndex].TexID==TexID);
if (bFoundIdxSortLRU)
{
// relocate sliceIndex to front of m_pSortedIdxArray since uCountLRU will be set to maximum.
for (int j = 0; j < i; j++) { m_SortedIdxArray[j + 1] = m_SortedIdxArray[j]; }
m_SortedIdxArray[0] = sliceIndex;
// locate entry sorted by uCountLRU in m_pSortedIdxArray
var foundIdxSortLRU = false;
var i = 0;
while ((!foundIdxSortLRU) && i < m_NumTextures)
{
if (m_SortedIdxArray[i] == sliceIndex) foundIdxSortLRU = true;
else ++i;
}
// delete from m_locatorInSliceArray and m_pSliceArray.
m_locatorInSliceArray.Remove(TexID);
m_SliceArray[sliceIndex].CountLRU = g_MaxFrameCount; // never used before
m_SliceArray[sliceIndex].TexID = g_InvalidTexID;
}
if (!foundIdxSortLRU)
return;
// relocate sliceIndex to front of m_pSortedIdxArray since uCountLRU will be set to maximum.
for (var j = 0; j < i; j++)
{
m_SortedIdxArray[j + 1] = m_SortedIdxArray[j];
m_SortedIdxArray[0] = sliceIndex;
// delete from m_locatorInSliceArray and m_pSliceArray.
m_LocatorInSliceArray.Remove(texId);
m_SliceArray[sliceIndex].countLRU = g_MaxFrameCount; // never used before
m_SliceArray[sliceIndex].texId = g_InvalidTexID;
}
protected int GetNumMips(int width, int height)

protected int GetNumMips(int dim)
{
uint uDim = (uint)dim;
int iNumMips = 0;
var uDim = (uint)dim;
var iNumMips = 0;
while (uDim > 0)
{ ++iNumMips; uDim >>= 1; }
return iNumMips;

2
Assets/ScriptableRenderLoop/common/TextureSettings.cs


public uint pointCookieSize;
public uint reflectionCubemapSize;
static public TextureSettings Default
public static TextureSettings Default
{
get
{

881
Assets/ScriptableRenderLoop/fptl/FptlLighting.cs
文件差异内容过多而无法显示
查看文件

64
Assets/ScriptableRenderLoop/fptl/LightDefinitions.cs


public struct SFiniteLightData
{
// setup constant buffer
public float fPenumbra;
public float penumbra;
public uint uLightType;
public uint uLightModel; // DIRECT_LIGHT=0, REFLECTION_LIGHT=1
public uint lightType;
public uint lightModel; // DIRECT_LIGHT=0, REFLECTION_LIGHT=1
public Vector3 vLpos;
public float fLightIntensity;
public Vector3 lightPos;
public float lightIntensity;
public Vector3 vLaxisX;
public float fRecipRange;
public Vector3 lightAxisX;
public float recipRange;
public Vector3 vLaxisY;
public float fSphRadiusSq;
public Vector3 lightAxisY;
public float radiusSq;
public Vector3 vLaxisZ; // spot +Z axis
public Vector3 lightAxisZ; // spot +Z axis
public Vector3 vCol;
public int iSliceIndex;
public Vector3 color;
public int sliceIndex;
public Vector3 vBoxInnerDist;
public float fDecodeExp;
public Vector3 boxInnerDist;
public float decodeExp;
public Vector3 vBoxInvRange;
public uint uShadowLightIndex;
public Vector3 boxInvRange;
public uint shadowLightIndex;
public Vector3 vLocalCubeCapturePoint;
public float fProbeBlendDistance;
public Vector3 localCubeCapturePoint;
public float probeBlendDistance;
public Vector3 vBoxAxisX;
public Vector3 vBoxAxisY;
public Vector3 vBoxAxisZ;
public Vector3 vCen; // a center in camera space inside the bounding volume of the light source.
public Vector2 vScaleXY;
public float fRadius;
public Vector3 boxAxisX;
public Vector3 boxAxisY;
public Vector3 boxAxisZ;
public Vector3 center; // a center in camera space inside the bounding volume of the light source.
public Vector2 scaleXY;
public float radius;
public Vector3 vCol;
public float fLightIntensity;
public Vector3 color;
public float intensity;
public Vector3 vLaxisX;
public uint uShadowLightIndex;
public Vector3 lightAxisX;
public uint shadowLightIndex;
public Vector3 vLaxisY;
public float fPad0;
public Vector3 lightAxisY;
public float pad0;
public Vector3 vLaxisZ;
public float fPad1;
public Vector3 lightAxisZ;
public float pad1;
};
[UnityEngine.ScriptableRenderLoop.GenerateHLSL]

202
Assets/ScriptableRenderLoop/fptl/LightDefinitions.cs.hlsl


// PackingRules = Exact
struct SFiniteLightData
{
float fPenumbra;
int flags;
uint uLightType;
uint uLightModel;
float3 vLpos;
float fLightIntensity;
float3 vLaxisX;
float fRecipRange;
float3 vLaxisY;
float fSphRadiusSq;
float3 vLaxisZ;
float cotan;
float3 vCol;
int iSliceIndex;
float3 vBoxInnerDist;
float fDecodeExp;
float3 vBoxInvRange;
uint uShadowLightIndex;
float3 vLocalCubeCapturePoint;
float fProbeBlendDistance;
float penumbra;
int flags;
uint lightType;
uint lightModel;
float3 lightPos;
float lightIntensity;
float3 lightAxisX;
float recipRange;
float3 lightAxisY;
float radiusSq;
float3 lightAxisZ;
float cotan;
float3 color;
int sliceIndex;
float3 boxInnerDist;
float decodeExp;
float3 boxInvRange;
uint shadowLightIndex;
float3 localCubeCapturePoint;
float probeBlendDistance;
};
// Generated from SFiniteLightBound

float3 vBoxAxisX;
float3 vBoxAxisY;
float3 vBoxAxisZ;
float3 vCen;
float2 vScaleXY;
float fRadius;
float3 boxAxisX;
float3 boxAxisY;
float3 boxAxisZ;
float3 center;
float2 scaleXY;
float radius;
};
// Generated from DirectionalLight

float3 vCol;
float fLightIntensity;
float3 vLaxisX;
uint uShadowLightIndex;
float3 vLaxisY;
float fPad0;
float3 vLaxisZ;
float fPad1;
float3 color;
float intensity;
float3 lightAxisX;
uint shadowLightIndex;
float3 lightAxisY;
float pad0;
float3 lightAxisZ;
float pad1;
float GetFPenumbra(SFiniteLightData value)
float GetPenumbra(SFiniteLightData value)
return value.fPenumbra;
return value.penumbra;
return value.flags;
return value.flags;
uint GetULightType(SFiniteLightData value)
uint GetLightType(SFiniteLightData value)
return value.uLightType;
return value.lightType;
uint GetULightModel(SFiniteLightData value)
uint GetLightModel(SFiniteLightData value)
return value.uLightModel;
return value.lightModel;
float3 GetVLpos(SFiniteLightData value)
float3 GetLightPos(SFiniteLightData value)
return value.vLpos;
return value.lightPos;
float GetFLightIntensity(SFiniteLightData value)
float GetLightIntensity(SFiniteLightData value)
return value.fLightIntensity;
return value.lightIntensity;
float3 GetVLaxisX(SFiniteLightData value)
float3 GetLightAxisX(SFiniteLightData value)
return value.vLaxisX;
return value.lightAxisX;
float GetFRecipRange(SFiniteLightData value)
float GetRecipRange(SFiniteLightData value)
return value.fRecipRange;
return value.recipRange;
float3 GetVLaxisY(SFiniteLightData value)
float3 GetLightAxisY(SFiniteLightData value)
return value.vLaxisY;
return value.lightAxisY;
float GetFSphRadiusSq(SFiniteLightData value)
float GetRadiusSq(SFiniteLightData value)
return value.fSphRadiusSq;
return value.radiusSq;
float3 GetVLaxisZ(SFiniteLightData value)
float3 GetLightAxisZ(SFiniteLightData value)
return value.vLaxisZ;
return value.lightAxisZ;
return value.cotan;
return value.cotan;
float3 GetVCol(SFiniteLightData value)
float3 GetColor(SFiniteLightData value)
return value.vCol;
return value.color;
int GetISliceIndex(SFiniteLightData value)
int GetSliceIndex(SFiniteLightData value)
return value.iSliceIndex;
return value.sliceIndex;
float3 GetVBoxInnerDist(SFiniteLightData value)
float3 GetBoxInnerDist(SFiniteLightData value)
return value.vBoxInnerDist;
return value.boxInnerDist;
float GetFDecodeExp(SFiniteLightData value)
float GetDecodeExp(SFiniteLightData value)
return value.fDecodeExp;
return value.decodeExp;
float3 GetVBoxInvRange(SFiniteLightData value)
float3 GetBoxInvRange(SFiniteLightData value)
return value.vBoxInvRange;
return value.boxInvRange;
uint GetUShadowLightIndex(SFiniteLightData value)
uint GetShadowLightIndex(SFiniteLightData value)
return value.uShadowLightIndex;
return value.shadowLightIndex;
float3 GetVLocalCubeCapturePoint(SFiniteLightData value)
float3 GetLocalCubeCapturePoint(SFiniteLightData value)
return value.vLocalCubeCapturePoint;
return value.localCubeCapturePoint;
float GetFProbeBlendDistance(SFiniteLightData value)
float GetProbeBlendDistance(SFiniteLightData value)
return value.fProbeBlendDistance;
return value.probeBlendDistance;
float3 GetVBoxAxisX(SFiniteLightBound value)
float3 GetBoxAxisX(SFiniteLightBound value)
return value.vBoxAxisX;
return value.boxAxisX;
float3 GetVBoxAxisY(SFiniteLightBound value)
float3 GetBoxAxisY(SFiniteLightBound value)
return value.vBoxAxisY;
return value.boxAxisY;
float3 GetVBoxAxisZ(SFiniteLightBound value)
float3 GetBoxAxisZ(SFiniteLightBound value)
return value.vBoxAxisZ;
return value.boxAxisZ;
float3 GetVCen(SFiniteLightBound value)
float3 GetCenter(SFiniteLightBound value)
return value.vCen;
return value.center;
float2 GetVScaleXY(SFiniteLightBound value)
float2 GetScaleXY(SFiniteLightBound value)
return value.vScaleXY;
return value.scaleXY;
float GetFRadius(SFiniteLightBound value)
float GetRadius(SFiniteLightBound value)
return value.fRadius;
return value.radius;
float3 GetVCol(DirectionalLight value)
float3 GetColor(DirectionalLight value)
return value.vCol;
return value.color;
float GetFLightIntensity(DirectionalLight value)
float GetIntensity(DirectionalLight value)
return value.fLightIntensity;
return value.intensity;
float3 GetVLaxisX(DirectionalLight value)
float3 GetLightAxisX(DirectionalLight value)
return value.vLaxisX;
return value.lightAxisX;
uint GetUShadowLightIndex(DirectionalLight value)
uint GetShadowLightIndex(DirectionalLight value)
return value.uShadowLightIndex;
return value.shadowLightIndex;
float3 GetVLaxisY(DirectionalLight value)
float3 GetLightAxisY(DirectionalLight value)
return value.vLaxisY;
return value.lightAxisY;
float GetFPad0(DirectionalLight value)
float GetPad0(DirectionalLight value)
return value.fPad0;
return value.pad0;
float3 GetVLaxisZ(DirectionalLight value)
float3 GetLightAxisZ(DirectionalLight value)
return value.vLaxisZ;
return value.lightAxisZ;
float GetFPad1(DirectionalLight value)
float GetPad1(DirectionalLight value)
return value.fPad1;
return value.pad1;

40
Assets/ScriptableRenderLoop/fptl/LightingTemplate.hlsl


float atten = 1;
[branch]
if (lightData.uShadowLightIndex != 0xffffffff)
if (lightData.shadowLightIndex != 0xffffffff)
float shadowScalar = SampleShadow(DIRECTIONAL_LIGHT, vPw, 0, lightData.uShadowLightIndex);
float shadowScalar = SampleShadow(DIRECTIONAL_LIGHT, vPw, 0, lightData.shadowLightIndex);
light.color.xyz = lightData.vCol.xyz * atten;
light.dir.xyz = mul((float3x3) g_mViewToWorld, -lightData.vLaxisZ).xyz;
light.color.xyz = lightData.color.xyz * atten;
light.dir.xyz = mul((float3x3) g_mViewToWorld, -lightData.lightAxisZ).xyz;
ints += EvalMaterial(light, ind);
}

if(numLights>0)
{
uint uIndex = l<numLights ? FetchIndex(start, l) : 0;
uint uLgtType = l<numLights ? g_vLightData[uIndex].uLightType : 0;
uint uLgtType = l<numLights ? g_vLightData[uIndex].lightType : 0;
float3 vLp = lgtDat.vLpos.xyz;
float3 vLp = lgtDat.lightPos.xyz;
float attLookUp = dist*lgtDat.fRecipRange; attLookUp *= attLookUp;
float attLookUp = dist*lgtDat.recipRange; attLookUp *= attLookUp;
const float fProjVec = -dot(vL, lgtDat.vLaxisZ.xyz); // spotDir = lgtDat.vLaxisZ.xyz
float2 cookCoord = (-lgtDat.cotan)*float2( dot(vL, lgtDat.vLaxisX.xyz), dot(vL, lgtDat.vLaxisY.xyz) ) / fProjVec;
const float fProjVec = -dot(vL, lgtDat.lightAxisZ.xyz); // spotDir = lgtDat.lightAxisZ.xyz
float2 cookCoord = (-lgtDat.cotan)*float2( dot(vL, lgtDat.lightAxisX.xyz), dot(vL, lgtDat.lightAxisY.xyz) ) / fProjVec;
const bool bHasCookie = (lgtDat.flags&IS_CIRCULAR_SPOT_SHAPE)==0; // all square spots have cookies
float d0 = 0.65;

cookCoord = cookCoord*0.5 + 0.5;
angularAtt = UNITY_SAMPLE_TEX2DARRAY_LOD(_spotCookieTextures, float3(cookCoord, lgtDat.iSliceIndex), 0.0);
angularAtt = UNITY_SAMPLE_TEX2DARRAY_LOD(_spotCookieTextures, float3(cookCoord, lgtDat.sliceIndex), 0.0);
}
atten *= angularAtt.w*(fProjVec>0.0); // finally apply this to the dist att.

float shadowScalar = SampleShadow(SPOT_LIGHT, vPw, 0, lgtDat.uShadowLightIndex);
float shadowScalar = SampleShadow(SPOT_LIGHT, vPw, 0, lgtDat.shadowLightIndex);
light.color.xyz = lgtDat.vCol.xyz*atten*angularAtt.xyz;
light.color.xyz = lgtDat.color.xyz*atten*angularAtt.xyz;
uLgtType = l<numLights ? g_vLightData[uIndex].uLightType : 0;
uLgtType = l<numLights ? g_vLightData[uIndex].lightType : 0;
}
// specialized loop for sphere lights

float3 vLp = lgtDat.vLpos.xyz;
float3 vLp = lgtDat.lightPos.xyz;
float3 toLight = vLp - vP;
float dist = length(toLight);

float attLookUp = dist*lgtDat.fRecipRange; attLookUp *= attLookUp;
float attLookUp = dist*lgtDat.recipRange; attLookUp *= attLookUp;
float atten = tex2Dlod(_LightTextureB0, float4(attLookUp.rr, 0.0, 0.0)).UNITY_ATTEN_CHANNEL;
float4 cookieColor = float4(1,1,1,1);

{
float3 cookieCoord = -float3(dot(vL, lgtDat.vLaxisX.xyz), dot(vL, lgtDat.vLaxisY.xyz), dot(vL, lgtDat.vLaxisZ.xyz)); // negate to make vL a fromLight vector
cookieColor = UNITY_SAMPLE_TEXCUBEARRAY_LOD(_pointCookieTextures, float4(cookieCoord, lgtDat.iSliceIndex), 0.0);
float3 cookieCoord = -float3(dot(vL, lgtDat.lightAxisX.xyz), dot(vL, lgtDat.lightAxisY.xyz), dot(vL, lgtDat.lightAxisZ.xyz)); // negate to make vL a fromLight vector
cookieColor = UNITY_SAMPLE_TEXCUBEARRAY_LOD(_pointCookieTextures, float4(cookieCoord, lgtDat.sliceIndex), 0.0);
atten *= cookieColor.w;
}

float shadowScalar = SampleShadow(SPHERE_LIGHT, vPw, vLw, lgtDat.uShadowLightIndex);
float shadowScalar = SampleShadow(SPHERE_LIGHT, vPw, vLw, lgtDat.shadowLightIndex);
light.color.xyz = lgtDat.vCol.xyz*atten*cookieColor.xyz;
light.color.xyz = lgtDat.color.xyz*atten*cookieColor.xyz;
uLgtType = l<numLights ? g_vLightData[uIndex].uLightType : 0;
uLgtType = l<numLights ? g_vLightData[uIndex].lightType : 0;
}
//if(uLgtType!=SPOT_LIGHT && uLgtType!=SPHERE_LIGHT) ++l;

24
Assets/ScriptableRenderLoop/fptl/ReflectionTemplate.hlsl


if(numReflProbes>0)
{
uint uIndex = l<numReflProbes ? FetchIndex(start, l) : 0;
uint uLgtType = l<numReflProbes ? g_vLightData[uIndex].uLightType : 0;
uint uLgtType = l<numReflProbes ? g_vLightData[uIndex].lightType : 0;
float3 vLp = lgtDat.vLpos.xyz;
float3 vLp = lgtDat.lightPos.xyz;
float3 posInReflVolumeSpace = float3( dot(vecToSurfPos, lgtDat.vLaxisX), dot(vecToSurfPos, lgtDat.vLaxisY), dot(vecToSurfPos, lgtDat.vLaxisZ) );
float3 posInReflVolumeSpace = float3( dot(vecToSurfPos, lgtDat.lightAxisX), dot(vecToSurfPos, lgtDat.lightAxisY), dot(vecToSurfPos, lgtDat.lightAxisZ) );
float blendDistance = lgtDat.fProbeBlendDistance;//unity_SpecCube1_ProbePosition.w; // will be set to blend distance for this probe
float blendDistance = lgtDat.probeBlendDistance;//unity_SpecCube1_ProbePosition.w; // will be set to blend distance for this probe
float3 sampleDir;
if((lgtDat.flags&IS_BOX_PROJECTED)!=0)

//float4 boxMax = unity_SpecCube0_BoxMax + float4(blendDistance,blendDistance,blendDistance,0);
//sampleDir = BoxProjectedCubemapDirection (worldNormalRefl, worldPos, unity_SpecCube0_ProbePosition, boxMin, boxMax);
float4 vBoxOuterDistance = float4( lgtDat.vBoxInnerDist + float3(blendDistance, blendDistance, blendDistance), 0.0 );
float4 boxOuterDistance = float4( lgtDat.boxInnerDist + float3(blendDistance, blendDistance, blendDistance), 0.0 );
sampleDir = BoxProjectedCubemapDirection(worldNormalRefl, posInReflVolumeSpace, float4(lgtDat.vLocalCubeCapturePoint, 1.0), -vBoxOuterDistance, vBoxOuterDistance);
sampleDir = BoxProjectedCubemapDirection(worldNormalRefl, posInReflVolumeSpace, float4(lgtDat.localCubeCapturePoint, 1.0), -boxOuterDistance, boxOuterDistance);
float3 volumeSpaceRefl = float3( dot(vspaceRefl, lgtDat.vLaxisX), dot(vspaceRefl, lgtDat.vLaxisY), dot(vspaceRefl, lgtDat.vLaxisZ) );
float3 vPR = BoxProjectedCubemapDirection(volumeSpaceRefl, posInReflVolumeSpace, float4(lgtDat.vLocalCubeCapturePoint, 1.0), -vBoxOuterDistance, vBoxOuterDistance); // Volume space corrected reflection vector
sampleDir = mul( (float3x3) g_mViewToWorld, vPR.x*lgtDat.vLaxisX + vPR.y*lgtDat.vLaxisY + vPR.z*lgtDat.vLaxisZ );
float3 volumeSpaceRefl = float3( dot(vspaceRefl, lgtDat.lightAxisX), dot(vspaceRefl, lgtDat.lightAxisY), dot(vspaceRefl, lgtDat.lightAxisZ) );
float3 vPR = BoxProjectedCubemapDirection(volumeSpaceRefl, posInReflVolumeSpace, float4(lgtDat.localCubeCapturePoint, 1.0), -boxOuterDistance, boxOuterDistance); // Volume space corrected reflection vector
sampleDir = mul( (float3x3) g_mViewToWorld, vPR.x*lgtDat.lightAxisX + vPR.y*lgtDat.lightAxisY + vPR.z*lgtDat.lightAxisZ );
#endif
}
else

g.roughness = percRoughness;
g.reflUVW = sampleDir;
half3 env0 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBEARRAY(_reflCubeTextures), lgtDat.iSliceIndex, float4(lgtDat.fLightIntensity, lgtDat.fDecodeExp, 0.0, 0.0), g);
half3 env0 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBEARRAY(_reflCubeTextures), lgtDat.sliceIndex, float4(lgtDat.lightIntensity, lgtDat.decodeExp, 0.0, 0.0), g);
UnityIndirect ind;

// Also this ensures that pixels not located in the reflection Volume AABB won't
// accidentally pick up reflections from this Volume.
//half3 distance = distanceFromAABB(worldPos, unity_SpecCube0_BoxMin.xyz, unity_SpecCube0_BoxMax.xyz);
half3 distance = distanceFromAABB(posInReflVolumeSpace, -lgtDat.vBoxInnerDist, lgtDat.vBoxInnerDist);
half3 distance = distanceFromAABB(posInReflVolumeSpace, -lgtDat.boxInnerDist, lgtDat.boxInnerDist);
half falloff = saturate(1.0 - length(distance)/blendDistance);
ints = lerp(ints, rgb, falloff);

uLgtType = l<numReflProbes ? g_vLightData[uIndex].uLightType : 0;
uLgtType = l<numReflProbes ? g_vLightData[uIndex].lightType : 0;
}
//if(uLgtType!=BOX_LIGHT) ++l;

80
Assets/ScriptableRenderLoop/fptl/lightlistbuild-clustered.compute


// returns 1 for intersection and 0 for none
float4 GetPlaneEq(const float3 vBoxX, const float3 vBoxY, const float3 vBoxZ, const float3 vCen, const float2 vScaleXZ, const int sideIndex);
float4 GetPlaneEq(const float3 boxX, const float3 boxY, const float3 boxZ, const float3 center, const float2 vScaleXZ, const int sideIndex);
float4 FetchPlane(int l, int p);

{
if(offs<(start+iSpaceAvail) && i<nrClusters && CheckIntersection(l, i, viTilLL.xy, viTilUR.xy, suggestedBase) )
{
uint lightModel = g_vLightData[ coarseList[l] ].uLightModel;
uint lightModel = g_vLightData[ coarseList[l] ].lightModel;
++modelListCount[ lightModel==REFLECTION_LIGHT ? 1 : 0];
g_vLayeredLightList[offs++] = coarseList[l]; // reflection lights will be last since we sorted
}

float4 GetPlaneEq(const float3 vBoxX, const float3 vBoxY, const float3 vBoxZ, const float3 vCen, const float2 vScaleXY, const int sideIndex)
float4 GetPlaneEq(const float3 boxX, const float3 boxY, const float3 boxZ, const float3 center, const float2 scaleXY, const int sideIndex)
const int iAbsSide = (sideIndex == 0 || sideIndex == 1) ? 0 : ((sideIndex == 2 || sideIndex == 3) ? 1 : 2);
const int absSide = (sideIndex == 0 || sideIndex == 1) ? 0 : ((sideIndex == 2 || sideIndex == 3) ? 1 : 2);
float3 vA = fS*(iAbsSide == 0 ? vBoxX : (iAbsSide == 1 ? (-vBoxY) : vBoxZ));
float3 vB = fS*(iAbsSide == 0 ? (-vBoxY) : (iAbsSide == 1 ? (-vBoxX) : (-vBoxY)));
float3 vC = iAbsSide == 0 ? vBoxZ : (iAbsSide == 1 ? vBoxZ : (-vBoxX));
float3 vA = fS*(absSide == 0 ? boxX : (absSide == 1 ? (-boxY) : boxZ));
float3 vB = fS*(absSide == 0 ? (-boxY) : (absSide == 1 ? (-boxX) : (-boxY)));
float3 vC = absSide == 0 ? boxZ : (absSide == 1 ? boxZ : (-boxX));
bool bIsTopQuad = iAbsSide == 2 && (sideIndex & 1) != 0; // in this case all 4 verts get scaled.
bool bIsSideQuad = (iAbsSide == 0 || iAbsSide == 1); // if side quad only two verts get scaled (impacts q1 and q2)
bool bIsTopQuad = absSide == 2 && (sideIndex & 1) != 0; // in this case all 4 verts get scaled.
bool bIsSideQuad = (absSide == 0 || absSide == 1); // if side quad only two verts get scaled (impacts q1 and q2)
if (bIsTopQuad) { vB *= vScaleXY.y; vC *= vScaleXY.x; }
if (bIsTopQuad) { vB *= scaleXY.y; vC *= scaleXY.x; }
if (bIsSideQuad) { vA2 *= (iAbsSide == 0 ? vScaleXY.x : vScaleXY.y); vB2 *= (iAbsSide == 0 ? vScaleXY.y : vScaleXY.x); }
if (bIsSideQuad) { vA2 *= (absSide == 0 ? scaleXY.x : scaleXY.y); vB2 *= (absSide == 0 ? scaleXY.y : scaleXY.x); }
float3 p0 = vCen + (vA + vB - vC); // vCen + vA is center of face when vScaleXY is 1.0
float3 p0 = center + (vA + vB - vC); // center + vA is center of face when scaleXY is 1.0
float3 vN = cross( vB2, 0.5*(vA-vA2) - vC );
#ifdef LEFT_HAND_COORDINATES

{
SFiniteLightBound lgtDat = g_data[coarseList[l]];
const float3 vBoxX = lgtDat.vBoxAxisX.xyz;
const float3 vBoxY = lgtDat.vBoxAxisY.xyz;
const float3 vBoxZ = -lgtDat.vBoxAxisZ.xyz; // flip an axis to make it right handed since Determinant(worldToView)<0
const float3 vCen = lgtDat.vCen.xyz;
const float fRadius = lgtDat.fRadius;
const float2 vScaleXY = lgtDat.vScaleXY;
const float3 boxX = lgtDat.boxAxisX.xyz;
const float3 boxY = lgtDat.boxAxisY.xyz;
const float3 boxZ = -lgtDat.boxAxisZ.xyz; // flip an axis to make it right handed since Determinant(worldToView)<0
const float3 center = lgtDat.center.xyz;
const float radius = lgtDat.radius;
const float2 scaleXY = lgtDat.scaleXY;
return GetPlaneEq(vBoxX, vBoxY, vBoxZ, vCen, vScaleXY, p);
return GetPlaneEq(boxX, boxY, boxZ, center, scaleXY, p);
}

{
SFiniteLightBound lgtDat = g_data[coarseList[l]];
const float3 vCen = lgtDat.vCen.xyz;
float fRad = lgtDat.fRadius;
const float3 center = lgtDat.center.xyz;
float fRad = lgtDat.radius;
float3 maxZdir = float3(-vCen.z*vCen.x, -vCen.z*vCen.y, vCen.x*vCen.x + vCen.y*vCen.y); // cross(vCen,cross(Zaxis,vCen))
float3 maxZdir = float3(-center.z*center.x, -center.z*center.y, center.x*center.x + center.y*center.y); // cross(center,cross(Zaxis,center))
float len = length(maxZdir);
float scalarProj = len>0.0001 ? (maxZdir.z/len) : len; // since len>=(maxZdir.z/len) we can use len as an approximate value when len<=epsilon
float fOffs = scalarProj*fRad;

#ifdef LEFT_HAND_COORDINATES
fRad = fRad + (vCen.z+fOffs)*worldDistAtDepthOne;
fRad = fRad + (center.z+fOffs)*worldDistAtDepthOne;
fRad = fRad + (vCen.z-fOffs)*worldDistAtDepthOne;
fRad = fRad + (center.z-fOffs)*worldDistAtDepthOne;
float CdotV = dot(vCen,V);
float c = dot(vCen,vCen) - fRad*fRad;
float CdotV = dot(center,V);
float c = dot(center,center) - fRad*fRad;
float fDescDivFour = CdotV*CdotV - a*c;
if(!(c<0 || (fDescDivFour>0 && CdotV>0))) // if ray misses bounding sphere

#ifdef EXACT_EDGE_TESTS
float3 GetHullVertex(const float3 vBoxX, const float3 vBoxY, const float3 vBoxZ, const float3 vCen, const float2 vScaleXY, const int p)
float3 GetHullVertex(const float3 boxX, const float3 boxY, const float3 boxZ, const float3 center, const float2 scaleXY, const int p)
float3 vScales = float3( ((p&1)!=0 ? 1.0f : (-1.0f))*(bIsTopVertex ? vScaleXY.x : 1.0), ((p&2)!=0 ? 1.0f : (-1.0f))*(bIsTopVertex ? vScaleXY.y : 1.0), (p&4)!=0 ? 1.0f : (-1.0f) );
return (vScales.x*vBoxX + vScales.y*vBoxY + vScales.z*vBoxZ) + vCen;
float3 vScales = float3( ((p&1)!=0 ? 1.0f : (-1.0f))*(bIsTopVertex ? scaleXY.x : 1.0), ((p&2)!=0 ? 1.0f : (-1.0f))*(bIsTopVertex ? scaleXY.y : 1.0), (p&4)!=0 ? 1.0f : (-1.0f) );
return (vScales.x*boxX + vScales.y*boxY + vScales.z*boxZ) + center;
void GetHullEdge(out int idx0, out int idx_twin, out float3 vP0, out float3 vE0, const int e0, const float3 vBoxX, const float3 vBoxY, const float3 vBoxZ, const float3 vCen, const float2 vScaleXY)
void GetHullEdge(out int idx0, out int idx_twin, out float3 vP0, out float3 vE0, const int e0, const float3 boxX, const float3 boxY, const float3 boxZ, const float3 center, const float2 scaleXY)
{
int iAxis = e0>>2;
int iSwizzle = e0&0x3;

idx0 = bSwap ? i1 : i0;
idx_twin = bSwap ? i0 : i1;
float3 p0 = GetHullVertex(vBoxX, vBoxY, vBoxZ, vCen, vScaleXY, idx0);
float3 p1 = GetHullVertex(vBoxX, vBoxY, vBoxZ, vCen, vScaleXY, idx_twin);
float3 p0 = GetHullVertex(boxX, boxY, boxZ, center, scaleXY, idx0);
float3 p1 = GetHullVertex(boxX, boxY, boxZ, center, scaleXY, idx_twin);
vP0 = p0;
vE0 = p1-p0;

GroupMemoryBarrierWithGroupSync();
#endif
const int idxCoarse = coarseList[l];
[branch]if(g_vLightData[idxCoarse].uLightType!=SPHERE_LIGHT) // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
[branch]if(g_vLightData[idxCoarse].lightType!=SPHERE_LIGHT) // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
const float3 vBoxX = lgtDat.vBoxAxisX.xyz;
const float3 vBoxY = lgtDat.vBoxAxisY.xyz;
const float3 vBoxZ = -lgtDat.vBoxAxisZ.xyz; // flip an axis to make it right handed since Determinant(worldToView)<0
const float3 vCen = lgtDat.vCen.xyz;
const float2 vScaleXY = lgtDat.vScaleXY;
const float3 boxX = lgtDat.boxAxisX.xyz;
const float3 boxY = lgtDat.boxAxisY.xyz;
const float3 boxZ = -lgtDat.boxAxisZ.xyz; // flip an axis to make it right handed since Determinant(worldToView)<0
const float3 center = lgtDat.center.xyz;
const float2 scaleXY = lgtDat.scaleXY;
for(int i=threadID; i<totNrEdgePairs; i+=NR_THREADS)
{

int idx_cur=0, idx_twin=0;
float3 vP0, vE0;
GetHullEdge(idx_cur, idx_twin, vP0, vE0, e0, vBoxX, vBoxY, vBoxZ, vCen, vScaleXY);
GetHullEdge(idx_cur, idx_twin, vP0, vE0, e0, boxX, boxY, boxZ, center, scaleXY);
float3 vP1, vE1;

for(int k=1; k<8; k++) // only need to test 7 verts (technically just 6).
{
int j = (idx_cur+k)&0x7;
float3 vPh = GetHullVertex(vBoxX, vBoxY, vBoxZ, vCen, vScaleXY, j);
float3 vPh = GetHullVertex(boxX, boxY, boxZ, center, scaleXY, j);
float fSignDist = idx_twin==j ? 0.0 : dot(vN, vPh-vP0);
if(fSignDist>0) ++positive; else if(fSignDist<0) ++negative;
}

56
Assets/ScriptableRenderLoop/fptl/lightlistbuild.compute


{
// fetch light
int idxCoarse = l<iNrCoarseLights ? coarseList[l] : 0;
uint uLgtType = l<iNrCoarseLights ? g_vLightData[idxCoarse].uLightType : 0;
uint uLgtType = l<iNrCoarseLights ? g_vLightData[idxCoarse].lightType : 0;
SFiniteLightData lgtDat = g_vLightData[idxCoarse];
const bool bIsSpotDisc = (lgtDat.flags&IS_CIRCULAR_SPOT_SHAPE)!=0;
SFiniteLightData lightData = g_vLightData[idxCoarse];
const bool bIsSpotDisc = (lightData.flags&IS_CIRCULAR_SPOT_SHAPE)!=0;
// serially check 4 pixels
uint uVal = 0;

float3 vVPos = GetViewPosFromLinDepth(uPixLoc + float2(0.5,0.5), vLinDepths[i]);
// check pixel
float3 fromLight = vVPos-lgtDat.vLpos.xyz;
float3 fromLight = vVPos-lightData.lightPos.xyz;
const float fSclProj = dot(fromLight, lgtDat.vLaxisZ.xyz); // spotDir = lgtDat.vLaxisZ.xyz
const float fSclProj = dot(fromLight, lightData.lightAxisZ.xyz); // spotDir = lightData.lightAxisZ.xyz
float2 V = abs( float2( dot(fromLight, lgtDat.vLaxisX.xyz), dot(fromLight, lgtDat.vLaxisY.xyz) ) );
float2 V = abs( float2( dot(fromLight, lightData.lightAxisX.xyz), dot(fromLight, lightData.lightAxisY.xyz) ) );
if( all( float2(lgtDat.fSphRadiusSq, fSclProj) > float2(distSq, fDist2D*lgtDat.cotan) ) ) uVal = 1;
if( all( float2(lightData.radiusSq, fSclProj) > float2(distSq, fDist2D*lightData.cotan) ) ) uVal = 1;
uLgtType = l<iNrCoarseLights ? g_vLightData[idxCoarse].uLightType : 0;
uLgtType = l<iNrCoarseLights ? g_vLightData[idxCoarse].lightType : 0;
SFiniteLightData lgtDat = g_vLightData[idxCoarse];
SFiniteLightData lightData = g_vLightData[idxCoarse];
// serially check 4 pixels
uint uVal = 0;

float3 vVPos = GetViewPosFromLinDepth(uPixLoc + float2(0.5,0.5), vLinDepths[i]);
// check pixel
float3 vLp = lgtDat.vLpos.xyz;
float3 vLp = lightData.lightPos.xyz;
if(lgtDat.fSphRadiusSq>distSq) uVal = 1;
if(lightData.radiusSq>distSq) uVal = 1;
uLgtType = l<iNrCoarseLights ? g_vLightData[idxCoarse].uLightType : 0;
uLgtType = l<iNrCoarseLights ? g_vLightData[idxCoarse].lightType : 0;
SFiniteLightData lgtDat = g_vLightData[idxCoarse];
SFiniteLightData lightData = g_vLightData[idxCoarse];
// serially check 4 pixels
uint uVal = 0;

float3 vVPos = GetViewPosFromLinDepth(uPixLoc + float2(0.5,0.5), vLinDepths[i]);
// check pixel
float3 toLight = lgtDat.vLpos.xyz - vVPos;
float3 toLight = lightData.lightPos.xyz - vVPos;
float3 dist = float3( dot(toLight, lgtDat.vLaxisX), dot(toLight, lgtDat.vLaxisY), dot(toLight, lgtDat.vLaxisZ) );
dist = (abs(dist) - lgtDat.vBoxInnerDist) * lgtDat.vBoxInvRange; // not as efficient as it could be
float3 dist = float3( dot(toLight, lightData.lightAxisX), dot(toLight, lightData.lightAxisY), dot(toLight, lightData.lightAxisZ) );
dist = (abs(dist) - lightData.boxInnerDist) * lightData.boxInvRange; // not as efficient as it could be
uLgtType = l<iNrCoarseLights ? g_vLightData[idxCoarse].uLightType : 0;
uLgtType = l<iNrCoarseLights ? g_vLightData[idxCoarse].lightType : 0;
}
// in case we have some corrupt data make sure we terminate

int nrLightsCombinedList = ldsNrLightsFinal<MAX_NR_COARSE_ENTRIES ? ldsNrLightsFinal : MAX_NR_COARSE_ENTRIES;
for(int i=t; i<nrLightsCombinedList; i+=NR_THREADS)
{
InterlockedAdd(ldsModelListCount[ g_vLightData[ prunedList[i] ].uLightModel ], 1);
InterlockedAdd(ldsModelListCount[ g_vLightData[ prunedList[i] ].lightModel ], 1);
}

// original version
//float2 vRay2D = float2(max(V.x,V.y), fSclProj);
//float distSqB = bIsSpotDisc ? distSq : dot(vRay2D,vRay2D);
//if( all( float3(lgtDat.fSphRadiusSq, fSclProj, fSclProj) > float3(distSq, sqrt(distSqB)*lgtDat.fPenumbra, 0.0) ) ) uVal = 1;
//if( all( float3(lightData.radiusSq, fSclProj, fSclProj) > float3(distSq, sqrt(distSqB)*lightData.fPenumbra, 0.0) ) ) uVal = 1;
//if( all( float3(lgtDat.fSphRadiusSq, (fSclProj*fSclProj), fSclProj) > float3(distSq, fDist2DSqr*cotaSqr, fSpotNearPlane) ) ) uVal = 1;
//if( all( float3(lightData.radiusSq, (fSclProj*fSclProj), fSclProj) > float3(distSq, fDist2DSqr*cotaSqr, fSpotNearPlane) ) ) uVal = 1;
#if 0
void merge(int l, int m, int r);

int iNrVisib = 0;
for(int l=threadID; l<iNrCoarseLights; l+=NR_THREADS)
{
SFiniteLightBound lgtDat = g_data[coarseList[l]];
SFiniteLightBound lightData = g_data[coarseList[l]];
const float3 vCen = lgtDat.vCen.xyz;
float fRad = lgtDat.fRadius;
const float3 center = lightData.center.xyz;
float fRad = lightData.radius;
float3 maxZdir = float3(-vCen.z*vCen.x, -vCen.z*vCen.y, vCen.x*vCen.x + vCen.y*vCen.y); // cross(vCen,cross(Zaxis,vCen))
float3 maxZdir = float3(-center.z*center.x, -center.z*center.y, center.x*center.x + center.y*center.y); // cross(center,cross(Zaxis,center))
float len = length(maxZdir);
float scalarProj = len>0.0001 ? (maxZdir.z/len) : len; // since len>=(maxZdir.z/len) we can use len as an approximate value when len<=epsilon
float fOffs = scalarProj*fRad;

#ifdef LEFT_HAND_COORDINATES
fRad = fRad + (vCen.z+fOffs)*worldDistAtDepthOne;
fRad = fRad + (center.z+fOffs)*worldDistAtDepthOne;
fRad = fRad + (vCen.z-fOffs)*worldDistAtDepthOne;
fRad = fRad + (center.z-fOffs)*worldDistAtDepthOne;
float CdotV = dot(vCen,V);
float c = dot(vCen,vCen) - fRad*fRad;
float CdotV = dot(center,V);
float c = dot(center,center) - fRad*fRad;
float fDescDivFour = CdotV*CdotV - a*c;
if(c<0 || (fDescDivFour>0 && CdotV>0)) // if ray hit bounding sphere

15
Assets/ScriptableRenderLoop/fptl/renderloopfptl.asset


directionalLightCascades: {x: 0.05, y: 0.2, z: 0.3}
m_TextureSettings:
spotCookieSize: 512
pointCookieSize: 256
pointCookieSize: 128
m_DeferredShader: {fileID: 4800000, guid: 1c102a89f3460254a8c413dbdcd63a2a, type: 3}
m_DeferredReflectionShader: {fileID: 4800000, guid: 3899e06d641c2cb4cbff794df0da536b,
deferredShader: {fileID: 4800000, guid: 1c102a89f3460254a8c413dbdcd63a2a, type: 3}
deferredReflectionShader: {fileID: 4800000, guid: 3899e06d641c2cb4cbff794df0da536b,
m_FinalPassShader: {fileID: 4800000, guid: 5590f54ad211f594da4e687b698f2258, type: 3}
m_BuildScreenAABBShader: {fileID: 7200000, guid: e7a739144e735934b89a42a4b9d9e23c,
finalPassShader: {fileID: 4800000, guid: 5590f54ad211f594da4e687b698f2258, type: 3}
buildScreenAABBShader: {fileID: 7200000, guid: e7a739144e735934b89a42a4b9d9e23c,
m_BuildPerTileLightListShader: {fileID: 7200000, guid: f54ef7cb596a714488693ef9cdaf63fb,
buildPerTileLightListShader: {fileID: 7200000, guid: f54ef7cb596a714488693ef9cdaf63fb,
m_BuildPerVoxelLightListShader: {fileID: 7200000, guid: 4c2d6eb0553e2514bba3ea9a85d8c53c,
buildPerVoxelLightListShader: {fileID: 7200000, guid: 4c2d6eb0553e2514bba3ea9a85d8c53c,
EnableClustered: 0

78
Assets/ScriptableRenderLoop/fptl/scrbound.compute


unsigned int GetClip(const float4 P);
int ClipAgainstPlane(const int iSrcIndex, const int iNrSrcVerts, const int subLigt, const int p);
void CalcBound(out bool2 bIsMinValid, out bool2 bIsMaxValid, out float2 vMin, out float2 vMax, float4x4 InvProjection, float3 pos_view_space, float r);
void GetQuad(out float3 p0, out float3 p1, out float3 p2, out float3 p3, const float3 vBoxX, const float3 vBoxY, const float3 vBoxZ, const float3 vCen, const float2 vScaleXY, const int sideIndex);
void GetPlane(out float3 p0, out float3 vN, const float3 vBoxX, const float3 vBoxY, const float3 vBoxZ, const float3 vCen, const float2 vScaleXY, const int sideIndex);
void GetQuad(out float3 p0, out float3 p1, out float3 p2, out float3 p3, const float3 boxX, const float3 boxY, const float3 boxZ, const float3 center, const float2 scaleXY, const int sideIndex);
void GetPlane(out float3 p0, out float3 vN, const float3 boxX, const float3 boxY, const float3 boxZ, const float3 center, const float2 scaleXY, const int sideIndex);
[numthreads(NR_THREADS, 1, 1)]

SFiniteLightBound lgtDat = g_data[lgtIndex];
const float3 vBoxX = lgtDat.vBoxAxisX.xyz;
const float3 vBoxY = lgtDat.vBoxAxisY.xyz;
const float3 vBoxZ = -lgtDat.vBoxAxisZ.xyz; // flip an axis to make it right handed since Determinant(worldToView)<0
const float3 vCen = lgtDat.vCen.xyz;
const float fRadius = lgtDat.fRadius;
const float2 vScaleXY = lgtDat.vScaleXY;
const float3 boxX = lgtDat.boxAxisX.xyz;
const float3 boxY = lgtDat.boxAxisY.xyz;
const float3 boxZ = -lgtDat.boxAxisZ.xyz; // flip an axis to make it right handed since Determinant(worldToView)<0
const float3 center = lgtDat.center.xyz;
const float radius = lgtDat.radius;
const float2 scaleXY = lgtDat.scaleXY;
GetQuad(q0, q1, q2, q3, vBoxX, vBoxY, vBoxZ, vCen, vScaleXY, sideIndex);
GetQuad(q0, q1, q2, q3, boxX, boxY, boxZ, center, scaleXY, sideIndex);
const float4 vP0 = mul(g_mProjection, float4(q0, 1));

for(f=0; f<6; f++)
{
float3 q0, q1, q2, q3;
GetQuad(q0, q1, q2, q3, vBoxX, vBoxY, vBoxZ, vCen, vScaleXY, f);
GetQuad(q0, q1, q2, q3, boxX, boxY, boxZ, center, scaleXY, f);
// 4 vertices to a quad of the convex hull in post projection space
const float4 vP0 = mul(g_mProjection, float4(q0, 1));

for(f=0; f<6; f++)
{
float3 vP0, vN;
GetPlane(vP0, vN, vBoxX, vBoxY, vBoxZ, vCen, vScaleXY, f);
GetPlane(vP0, vN, boxX, boxY, boxZ, center, scaleXY, f);
for(i=0; i<8; i++)
{

}
else
{
//if((vCen.z+fRadius)<0.0)
if( length(vCen)>fRadius)
//if((center.z+radius)<0.0)
if( length(center)>radius)
CalcBound(bMi, bMa, vMi, vMa, g_mInvProjection, vCen, fRadius);
CalcBound(bMi, bMa, vMi, vMa, g_mInvProjection, center, radius);
vMin.xy = bMi ? max(vMin.xy, vMi) : vMin.xy;
vMax.xy = bMa ? min(vMax.xy, vMa) : vMax.xy;

if((vCen.z-fRadius)>0.0)
if((center.z-radius)>0.0)
float4 vPosF = mul(g_mProjection, float4(0,0,vCen.z-fRadius,1));
float4 vPosF = mul(g_mProjection, float4(0,0,center.z-radius,1));
if((vCen.z+fRadius)>0.0)
if((center.z+radius)>0.0)
float4 vPosB = mul(g_mProjection, float4(0,0,vCen.z+fRadius,1));
float4 vPosB = mul(g_mProjection, float4(0,0,center.z+radius,1));
if((vCen.z+fRadius)<0.0)
if((center.z+radius)<0.0)
float4 vPosF = mul(g_mProjection, float4(0,0,vCen.z+fRadius,1));
float4 vPosF = mul(g_mProjection, float4(0,0,center.z+radius,1));
if((vCen.z-fRadius)<0.0)
if((center.z-radius)<0.0)
float4 vPosB = mul(g_mProjection, float4(0,0,vCen.z-fRadius,1));
float4 vPosB = mul(g_mProjection, float4(0,0,center.z-radius,1));
vMax.z = min(vMax.z, vPosB.z/vPosB.w);
}
#endif

return vNew;
}
void GetQuad(out float3 p0, out float3 p1, out float3 p2, out float3 p3, const float3 vBoxX, const float3 vBoxY, const float3 vBoxZ, const float3 vCen, const float2 vScaleXY, const int sideIndex)
void GetQuad(out float3 p0, out float3 p1, out float3 p2, out float3 p3, const float3 boxX, const float3 boxY, const float3 boxZ, const float3 center, const float2 scaleXY, const int sideIndex)
float3 vA = fS*(iAbsSide == 0 ? vBoxX : (iAbsSide == 1 ? (-vBoxY) : vBoxZ));
float3 vB = fS*(iAbsSide == 0 ? (-vBoxY) : (iAbsSide == 1 ? (-vBoxX) : (-vBoxY)));
float3 vC = iAbsSide == 0 ? vBoxZ : (iAbsSide == 1 ? vBoxZ : (-vBoxX));
float3 vA = fS*(iAbsSide == 0 ? boxX : (iAbsSide == 1 ? (-boxY) : boxZ));
float3 vB = fS*(iAbsSide == 0 ? (-boxY) : (iAbsSide == 1 ? (-boxX) : (-boxY)));
float3 vC = iAbsSide == 0 ? boxZ : (iAbsSide == 1 ? boxZ : (-boxX));
if (bIsTopQuad) { vB *= vScaleXY.y; vC *= vScaleXY.x; }
if (bIsTopQuad) { vB *= scaleXY.y; vC *= scaleXY.x; }
if (bIsSideQuad) { vA2 *= (iAbsSide == 0 ? vScaleXY.x : vScaleXY.y); vB2 *= (iAbsSide == 0 ? vScaleXY.y : vScaleXY.x); }
if (bIsSideQuad) { vA2 *= (iAbsSide == 0 ? scaleXY.x : scaleXY.y); vB2 *= (iAbsSide == 0 ? scaleXY.y : scaleXY.x); }
p0 = vCen + (vA + vB - vC); // vCen + vA is center of face when vScaleXY is 1.0
p1 = vCen + (vA - vB - vC);
p2 = vCen + (vA2 - vB2 + vC);
p3 = vCen + (vA2 + vB2 + vC);
p0 = center + (vA + vB - vC); // center + vA is center of face when scaleXY is 1.0
p1 = center + (vA - vB - vC);
p2 = center + (vA2 - vB2 + vC);
p3 = center + (vA2 + vB2 + vC);
void GetPlane(out float3 p0, out float3 vN, const float3 vBoxX, const float3 vBoxY, const float3 vBoxZ, const float3 vCen, const float2 vScaleXY, const int sideIndex)
void GetPlane(out float3 p0, out float3 vN, const float3 boxX, const float3 boxY, const float3 boxZ, const float3 center, const float2 scaleXY, const int sideIndex)
float3 vA = fS*(iAbsSide == 0 ? vBoxX : (iAbsSide == 1 ? (-vBoxY) : vBoxZ));
float3 vB = fS*(iAbsSide == 0 ? (-vBoxY) : (iAbsSide == 1 ? (-vBoxX) : (-vBoxY)));
float3 vC = iAbsSide == 0 ? vBoxZ : (iAbsSide == 1 ? vBoxZ : (-vBoxX));
float3 vA = fS*(iAbsSide == 0 ? boxX : (iAbsSide == 1 ? (-boxY) : boxZ));
float3 vB = fS*(iAbsSide == 0 ? (-boxY) : (iAbsSide == 1 ? (-boxX) : (-boxY)));
float3 vC = iAbsSide == 0 ? boxZ : (iAbsSide == 1 ? boxZ : (-boxX));
if (bIsTopQuad) { vB *= vScaleXY.y; vC *= vScaleXY.x; }
if (bIsTopQuad) { vB *= scaleXY.y; vC *= scaleXY.x; }
if (bIsSideQuad) { vA2 *= (iAbsSide == 0 ? vScaleXY.x : vScaleXY.y); vB2 *= (iAbsSide == 0 ? vScaleXY.y : vScaleXY.x); }
if (bIsSideQuad) { vA2 *= (iAbsSide == 0 ? scaleXY.x : scaleXY.y); vB2 *= (iAbsSide == 0 ? scaleXY.y : scaleXY.x); }
p0 = vCen + (vA + vB - vC); // vCen + vA is center of face when vScaleXY is 1.0
p0 = center + (vA + vB - vC); // center + vA is center of face when scaleXY is 1.0
float3 vNout = cross( vB2, 0.5*(vA-vA2) - vC );
#ifdef LEFT_HAND_COORDINATES

正在加载...
取消
保存