浏览代码

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoopInspector.cs
/main
sebastienlagarde 8 年前
当前提交
ba4ec92e
共有 28 个文件被更改,包括 1312 次插入1294 次删除
  1. 3
      Assets/Editor/Tests/RenderloopTests/CullResultsTest.cs
  2. 8
      Assets/Editor/Tests/RenderloopTests/RenderloopTestFixture.cs
  3. 8
      Assets/ScriptableRenderLoop/AdditionalLightData.cs
  4. 177
      Assets/ScriptableRenderLoop/ForwardRenderLoop/ForwardRenderLoop.cs
  5. 221
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  6. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/LightDefinition.cs.hlsl
  7. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Builtin/BuiltinData.cs.hlsl
  8. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.cs.hlsl
  9. 106
      Assets/ScriptableRenderLoop/RenderPasses/ShadowRenderPass.cs
  10. 2
      Assets/ScriptableRenderLoop/ScriptableRenderLoop.cs
  11. 16
      Assets/ScriptableRenderLoop/ScriptableRenderLoopPicker.cs
  12. 102
      Assets/ScriptableRenderLoop/common/SkyboxHelper.cs
  13. 182
      Assets/ScriptableRenderLoop/common/TextureCache.cs
  14. 7
      Assets/ScriptableRenderLoop/common/TextureSettings.cs
  15. 873
      Assets/ScriptableRenderLoop/fptl/FptlLighting.cs
  16. 64
      Assets/ScriptableRenderLoop/fptl/LightDefinitions.cs
  17. 202
      Assets/ScriptableRenderLoop/fptl/LightDefinitions.cs.hlsl
  18. 40
      Assets/ScriptableRenderLoop/fptl/LightingTemplate.hlsl
  19. 24
      Assets/ScriptableRenderLoop/fptl/ReflectionTemplate.hlsl
  20. 80
      Assets/ScriptableRenderLoop/fptl/lightlistbuild-clustered.compute
  21. 56
      Assets/ScriptableRenderLoop/fptl/lightlistbuild.compute
  22. 15
      Assets/ScriptableRenderLoop/fptl/renderloopfptl.asset
  23. 78
      Assets/ScriptableRenderLoop/fptl/scrbound.compute
  24. 143
      Assets/ShaderGenerator/CSharpToHLSL.cs
  25. 8
      Assets/ShaderGenerator/ShaderGeneratorMenu.cs
  26. 139
      Assets/ShaderGenerator/ShaderTypeGeneration.cs
  27. 37
      .editorconfig
  28. 9
      Assets/ScriptableRenderLoop/fptl/LightingUtils.hlsl.meta

3
Assets/Editor/Tests/RenderloopTests/CullResultsTest.cs


using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
[TestFixture]

8
Assets/Editor/Tests/RenderloopTests/RenderloopTestFixture.cs


public class RenderLoopTestFixture : MonoBehaviour
{
public delegate void TestDelegate(Camera camera, CullResults cullResults, RenderLoop renderLoop);
private static TestDelegate callback;
private static TestDelegate s_Callback;
foreach (Camera camera in cameras)
foreach (var camera in cameras)
{
CullingParameters cullingParams;
bool gotCullingParams = CullResults.GetCullingParameters(camera, out cullingParams);

callback(camera, cullResults, renderLoop);
s_Callback(camera, cullResults, renderLoop);
}
renderLoop.Submit();

var instance = camObject.AddComponent<RenderLoopWrapper>();
instance.callback = Render;
callback = renderCallback;
s_Callback = renderCallback;
instance.enabled = true;
Transform t = camObject.transform;

8
Assets/ScriptableRenderLoop/AdditionalLightData.cs


using System;
namespace UnityEngine.ScriptableRenderLoop
{
//@TODO: We should continously move these values

{
public const int defaultShadowResolution = 512;
public const int DefaultShadowResolution = 512;
public int shadowResolution = defaultShadowResolution;
public int shadowResolution = DefaultShadowResolution;
[RangeAttribute(0.0F, 100.0F)]
public float innerSpotPercent = 0.0F;

if (lightData != null)
return lightData.shadowResolution;
else
return defaultShadowResolution;
return DefaultShadowResolution;
}
}
}

177
Assets/ScriptableRenderLoop/ForwardRenderLoop/ForwardRenderLoop.cs


using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace UnityEngine.ScriptableRenderLoop
{

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];
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 (int 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;
lightShadowIndex_lightParams[numLights].x = 1;
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;
}

221
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


using UnityEngine;
using System.Collections;
using UnityEngine.Rendering;
using System.Collections.Generic;
using System;

// This HDRenderLoop assume linear lighting. Don't work with gamma.
public class HDRenderLoop : ScriptableRenderLoop
{
private static string m_HDRenderLoopPath = "Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset";
private const string k_HDRenderLoopPath = "Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset";
// Must be in sync with DebugViewMaterial.hlsl
public enum DebugViewVaryingMode

static void CreateHDRenderLoop()
{
var instance = ScriptableObject.CreateInstance<HDRenderLoop>();
UnityEditor.AssetDatabase.CreateAsset(instance, m_HDRenderLoopPath);
UnityEditor.AssetDatabase.CreateAsset(instance, k_HDRenderLoopPath);
}
#endif

public const int MaxGbuffer = 8;
public void SetBufferDescription(int index, string stringID, RenderTextureFormat inFormat, RenderTextureReadWrite inSRGBWrite)
public void SetBufferDescription(int index, string stringId, RenderTextureFormat inFormat, RenderTextureReadWrite inSRGBWrite)
IDs[index] = Shader.PropertyToID(stringID);
IDs[index] = Shader.PropertyToID(stringId);
RTIDs[index] = new RenderTargetIdentifier(IDs[index]);
formats[index] = inFormat;
sRGBWrites[index] = inSRGBWrite;

Material m_FinalPassMaterial;
// TODO: Find a way to automatically create/iterate through these kind of class
Lit.RenderLoop m_litRenderLoop;
Lit.RenderLoop m_LitRenderLoop;
// Debug
Material m_DebugViewMaterialGBuffer;

Material CreateEngineMaterial(string shaderPath)
{
Material mat = new Material(Shader.Find(shaderPath) as Shader);
mat.hideFlags = HideFlags.HideAndDontSave;
var mat = new Material(Shader.Find(shaderPath) as Shader)
{
hideFlags = HideFlags.HideAndDontSave
};
return mat;
}

m_cubeReflTexArray.AllocTextureArray(32, (int)m_TextureSettings.reflectionCubemapSize, TextureFormat.BC6H, true);
// Init Lit material buffer - GBuffer and init
m_litRenderLoop = new Lit.RenderLoop(); // Our object can be garbacge collected, so need to be allocate here
m_LitRenderLoop = new Lit.RenderLoop(); // Our object can be garbacge collected, so need to be allocate here
m_gbufferManager.gbufferCount = m_litRenderLoop.GetGBufferCount();
m_gbufferManager.gbufferCount = m_LitRenderLoop.GetGBufferCount();
m_gbufferManager.SetBufferDescription(gbufferIndex, "_CameraGBufferTexture" + gbufferIndex, m_litRenderLoop.RTFormat[gbufferIndex], m_litRenderLoop.RTReadWrite[gbufferIndex]);
m_gbufferManager.SetBufferDescription(gbufferIndex, "_CameraGBufferTexture" + gbufferIndex, m_LitRenderLoop.RTFormat[gbufferIndex], m_LitRenderLoop.RTReadWrite[gbufferIndex]);
m_litRenderLoop.Rebuild();
m_LitRenderLoop.Rebuild();
m_litRenderLoop.OnDisable();
m_LitRenderLoop.OnDisable();
s_punctualLightList.Release();
s_envLightList.Release();

if (!debugParameters.displayTransparentObjects)
return;
DrawRendererSettings settings = new DrawRendererSettings(cull, camera, new ShaderPassName(passName));
settings.rendererConfiguration = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectReflectionProbes;
settings.sorting.sortOptions = SortOptions.SortByMaterialThenMesh;
var settings = new DrawRendererSettings(cull, camera, new ShaderPassName(passName))
{
rendererConfiguration = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectReflectionProbes,
sorting = { sortOptions = SortOptions.SortByMaterialThenMesh }
};
settings.inputCullingOptions.SetQueuesTransparent();
renderLoop.DrawRenderers(ref settings);
}

}
// setup GBuffer for rendering
var cmd = new CommandBuffer();
cmd.name = "GBuffer Pass";
var cmd = new CommandBuffer { name = "GBuffer Pass" };
cmd.SetRenderTarget(m_gbufferManager.GetGBuffers(cmd), new RenderTargetIdentifier(s_CameraDepthBuffer));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();

{
// Render Opaque forward
{
var cmd = new CommandBuffer();
cmd.name = "DebugView Material Mode Pass";
var cmd = new CommandBuffer { name = "DebugView Material Mode Pass" };
cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
cmd.ClearRenderTarget(true, true, new Color(0, 0, 0, 0));
renderLoop.ExecuteCommandBuffer(cmd);

// m_gbufferManager.BindBuffers(m_DeferredMaterial);
// TODO: Bind depth textures
var cmd = new CommandBuffer();
cmd.name = "GBuffer Debug Pass";
var cmd = new CommandBuffer { name = "GBuffer Debug Pass" };
cmd.Blit(null, new RenderTargetIdentifier(s_CameraColorBuffer), m_DebugViewMaterialGBuffer, 0);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();

// Last blit
{
var cmd = new CommandBuffer();
cmd.name = "Blit DebugView Material Debug";
var cmd = new CommandBuffer { name = "Blit DebugView Material Debug" };
cmd.Blit(s_CameraColorBuffer, BuiltinRenderTextureType.CameraTarget);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();

{
// The actual projection matrix used in shaders is actually massaged a bit to work across all platforms
// (different Z value ranges etc.)
Matrix4x4 gpuProj = GL.GetGPUProjectionMatrix(camera.projectionMatrix, false);
Matrix4x4 gpuVP = gpuProj * camera.worldToCameraMatrix;
var gpuProj = GL.GetGPUProjectionMatrix(camera.projectionMatrix, false);
var gpuVP = gpuProj * camera.worldToCameraMatrix;
return gpuVP;
}

Vector4 screenSize = new Vector4();
screenSize.x = camera.pixelWidth;
screenSize.y = camera.pixelHeight;
screenSize.z = 1.0f / camera.pixelWidth;
screenSize.w = 1.0f / camera.pixelHeight;
return screenSize;
return new Vector4(camera.pixelWidth, camera.pixelHeight, 1.0f / camera.pixelWidth, 1.0f / camera.pixelHeight);
}
void RenderDeferredLighting(Camera camera, RenderLoop renderLoop)

}
// Bind material data
m_litRenderLoop.Bind();
m_LitRenderLoop.Bind();
Matrix4x4 invViewProj = GetViewProjectionMatrix(camera).inverse;
var invViewProj = GetViewProjectionMatrix(camera).inverse;
Vector4 screenSize = ComputeScreenSize(camera);
var screenSize = ComputeScreenSize(camera);
var cmd = new CommandBuffer();
cmd.name = "Deferred Ligthing Pass";
var cmd = new CommandBuffer { name = "Deferred Ligthing Pass" };
cmd.Blit(null, new RenderTargetIdentifier(s_CameraColorBuffer), m_DeferredMaterial, 0);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();

{
// Bind material data
m_litRenderLoop.Bind();
m_LitRenderLoop.Bind();
var cmd = new CommandBuffer();
cmd.name = "Forward Pass";
var cmd = new CommandBuffer { name = "Forward Pass" };
cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();

void FinalPass(RenderLoop renderLoop)
{
// Those could be tweakable for the neutral tonemapper, but in the case of the LookDev we don't need that
const float BlackIn = 0.02f;
const float WhiteIn = 10.0f;
const float BlackOut = 0.0f;
const float WhiteOut = 10.0f;
const float WhiteLevel = 5.3f;
const float WhiteClip = 10.0f;
const float DialUnits = 20.0f;
const float HalfDialUnits = DialUnits * 0.5f;
const float blackIn = 0.02f;
const float whiteIn = 10.0f;
const float blackOut = 0.0f;
const float whiteOut = 10.0f;
const float whiteLevel = 5.3f;
const float whiteClip = 10.0f;
const float dialUnits = 20.0f;
const float halfDialUnits = dialUnits * 0.5f;
Vector4 tonemapCoeff1 = new Vector4((BlackIn * DialUnits) + 1.0f, (BlackOut * HalfDialUnits) + 1.0f, (WhiteIn / DialUnits), (1.0f - (WhiteOut / DialUnits)));
Vector4 tonemapCoeff2 = new Vector4(0.0f, 0.0f, WhiteLevel, WhiteClip / HalfDialUnits);
var tonemapCoeff1 = new Vector4((blackIn * dialUnits) + 1.0f, (blackOut * halfDialUnits) + 1.0f, (whiteIn / dialUnits), (1.0f - (whiteOut / dialUnits)));
var tonemapCoeff2 = new Vector4(0.0f, 0.0f, whiteLevel, whiteClip / halfDialUnits);
m_FinalPassMaterial.SetVector("_ToneMapCoeffs1", tonemapCoeff1);
m_FinalPassMaterial.SetVector("_ToneMapCoeffs2", tonemapCoeff2);

CommandBuffer cmd = new CommandBuffer();
cmd.name = "FinalPass";
var cmd = new CommandBuffer { name = "FinalPass" };
// Resolve our HDR texture to CameraTarget.
cmd.Blit(s_CameraColorBuffer, BuiltinRenderTextureType.CameraTarget, m_FinalPassMaterial, 0);
renderLoop.ExecuteCommandBuffer(cmd);

void UpdatePunctualLights(VisibleLight[] visibleLights)
{
List<PunctualLightData> lights = new List<PunctualLightData>();
var lights = new List<PunctualLightData>();
VisibleLight light = visibleLights[lightIndex];
if (light.lightType == LightType.Spot || light.lightType == LightType.Point || light.lightType == LightType.Directional)
{
PunctualLightData l = new PunctualLightData();
var light = visibleLights[lightIndex];
if (light.lightType != LightType.Spot && light.lightType != LightType.Point && light.lightType != LightType.Directional)
continue;
if (light.lightType == LightType.Directional)
{
l.useDistanceAttenuation = 0.0f;
// positionWS store Light direction for directional and is opposite to the forward direction
l.positionWS = -light.light.transform.forward;
l.invSqrAttenuationRadius = 0.0f;
}
else
{
l.useDistanceAttenuation = 1.0f;
l.positionWS = light.light.transform.position;
l.invSqrAttenuationRadius = 1.0f / (light.range * light.range);
}
var l = new PunctualLightData();
// Correct intensity calculation (Different from Unity)
float lightColorR = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.r);
float lightColorG = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.g);
float lightColorB = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.b);
if (light.lightType == LightType.Directional)
{
l.useDistanceAttenuation = 0.0f;
// positionWS store Light direction for directional and is opposite to the forward direction
l.positionWS = -light.light.transform.forward;
l.invSqrAttenuationRadius = 0.0f;
}
else
{
l.useDistanceAttenuation = 1.0f;
l.positionWS = light.light.transform.position;
l.invSqrAttenuationRadius = 1.0f / (light.range * light.range);
}
l.color.Set(lightColorR, lightColorG, lightColorB);
// Correct intensity calculation (Different from Unity)
var lightColorR = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.r);
var lightColorG = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.g);
var lightColorB = light.light.intensity * Mathf.GammaToLinearSpace(light.light.color.b);
// Light direction is opposite to the forward direction
l.forward = -light.light.transform.forward;
// CAUTION: For IES as we inverse forward maybe this will need rotation.
l.up = light.light.transform.up;
l.right = light.light.transform.right;
l.color.Set(lightColorR, lightColorG, lightColorB);
l.diffuseScale = 1.0f;
l.specularScale = 1.0f;
l.shadowDimmer = 1.0f;
// Light direction is opposite to the forward direction
l.forward = -light.light.transform.forward;
// CAUTION: For IES as we inverse forward maybe this will need rotation.
l.up = light.light.transform.up;
l.right = light.light.transform.right;
if (light.lightType == LightType.Spot)
{
float spotAngle = light.light.spotAngle;
AdditionalLightData additionalLightData = light.light.GetComponent<AdditionalLightData>();
float innerConePercent = AdditionalLightData.GetInnerSpotPercent01(additionalLightData);
float cosSpotOuterHalfAngle = Mathf.Clamp(Mathf.Cos(spotAngle * 0.5f * Mathf.Deg2Rad), 0.0f, 1.0f);
float cosSpotInnerHalfAngle = Mathf.Clamp(Mathf.Cos(spotAngle * 0.5f * innerConePercent * Mathf.Deg2Rad), 0.0f, 1.0f); // inner cone
l.diffuseScale = 1.0f;
l.specularScale = 1.0f;
l.shadowDimmer = 1.0f;
float val = Mathf.Max(0.001f, (cosSpotInnerHalfAngle - cosSpotOuterHalfAngle));
l.angleScale = 1.0f / val;
l.angleOffset = -cosSpotOuterHalfAngle * l.angleScale;
}
else
{
// 1.0f, 2.0f are neutral value allowing GetAngleAnttenuation in shader code to return 1.0
l.angleScale = 1.0f;
l.angleOffset = 2.0f;
}
if (light.lightType == LightType.Spot)
{
var spotAngle = light.light.spotAngle;
var additionalLightData = light.light.GetComponent<AdditionalLightData>();
var innerConePercent = AdditionalLightData.GetInnerSpotPercent01(additionalLightData);
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
lights.Add(l);
var val = Mathf.Max(0.001f, (cosSpotInnerHalfAngle - cosSpotOuterHalfAngle));
l.angleScale = 1.0f / val;
l.angleOffset = -cosSpotOuterHalfAngle * l.angleScale;
else
{
// 1.0f, 2.0f are neutral value allowing GetAngleAnttenuation in shader code to return 1.0
l.angleScale = 1.0f;
l.angleOffset = 2.0f;
}
lights.Add(l);
}
s_punctualLightList.SetData(lights.ToArray());

void UpdateReflectionProbes(VisibleReflectionProbe[] activeReflectionProbes)
{
List<EnvLightData> lights = new List<EnvLightData>();
var lights = new List<EnvLightData>();
VisibleReflectionProbe probe = activeReflectionProbes[lightIndex];
var probe = activeReflectionProbes[lightIndex];
EnvLightData l = new EnvLightData();
var l = new EnvLightData
{
positionWS = probe.localToWorld.GetColumn(3),
shapeType = EnvShapeType.None
};
l.positionWS = probe.localToWorld.GetColumn(3);
l.shapeType = EnvShapeType.None;
if (probe.boxProjection != 0)
{
l.shapeType = EnvShapeType.Box;

public override void Render(Camera[] cameras, RenderLoop renderLoop)
{
if (!m_litRenderLoop.isInit)
if (!m_LitRenderLoop.isInit)
m_litRenderLoop.RenderInit(renderLoop);
m_LitRenderLoop.RenderInit(renderLoop);
}
// Do anything we need to do upon a new frame.

// Set camera constant buffer
// TODO...
CullResults cullResults;
CullingParameters cullingParams;
if (!CullResults.GetCullingParameters(camera, out cullingParams))
continue;

cullResults = CullResults.Cull(ref cullingParams, renderLoop);
var cullResults = CullResults.Cull(ref cullingParams, renderLoop);
//ShadowOutput shadows;
//m_ShadowPass.Render (renderLoop, cullResults, out shadows);

#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;
}

2
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/LightDefinition.cs.hlsl


//
// This file was automatically generated from Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/LightDefinition.cs. Please don't edit by hand.
// This file was automatically generated from Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/LightDefinition.cs. Please don't edit by hand.
//
//

2
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Builtin/BuiltinData.cs.hlsl


//
// This file was automatically generated from Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/BuiltinData.cs. Please don't edit by hand.
// This file was automatically generated from Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Builtin/BuiltinData.cs. Please don't edit by hand.
//
//

2
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.cs.hlsl


//
// This file was automatically generated from Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit.cs. Please don't edit by hand.
// This file was automatically generated from Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.cs. Please don't edit by hand.
//
//

106
Assets/ScriptableRenderLoop/RenderPasses/ShadowRenderPass.cs


using UnityEngine;
using System.Collections;
using UnityEngine.Rendering;
using UnityEngine.Profiling;
using System.Collections.Generic;

ShadowSettings m_Settings;
[NonSerialized]
bool m_bFailedToPackLastTime;
bool m_FailedToPackLastTime;
const int kDepthBuffer = 24;
const int k_DepthBuffer = 24;
m_bFailedToPackLastTime = false;
m_FailedToPackLastTime = false;
m_ShadowTexName = Shader.PropertyToID("g_tShadowBuffer");
}

this.lightIndex = lightIndex;
}
public int splitIndex;
public int lightIndex;
public readonly int splitIndex;
public readonly int lightIndex;
LightType lightType = lights[index].lightType;
if (lightType == LightType.Spot)
return 1;
var lightType = lights[index].lightType;
switch (lightType)
{
case LightType.Spot:
return 1;
if (lightType == LightType.Directional)
return m_Settings.directionalLightCascadeCount;
case LightType.Directional:
return m_Settings.directionalLightCascadeCount;
return 6;
default:
return 6;
}
static public void ClearPackedShadows(VisibleLight[] lights, out ShadowOutput packedShadows)
public static void ClearPackedShadows(VisibleLight[] lights, out ShadowOutput packedShadows)
{
packedShadows.directionalShadowSplitSphereSqr = null;
packedShadows.shadowSlices = null;

//---------------------------------------------------------------------------------------------------------------------------------------------------
bool AutoPackLightsIntoShadowTexture(List<InputShadowLightData> shadowLights, VisibleLight[] lights, out ShadowOutput packedShadows)
{
Dictionary<int, InputShadowLightData> activeShadowLights = new Dictionary<int, InputShadowLightData>();
List<int> shadowIndices = new List<int>();
var activeShadowLights = new Dictionary<int, InputShadowLightData>();
var shadowIndices = new List<int>();
//@TODO: Disallow multiple directional lights

shadowIndices.Sort(
delegate(int l1, int l2)
{
int nCompare = 0;
var nCompare = 0;
// Sort shadow-casting lights by shadow resolution
nCompare = activeShadowLights[l1].shadowResolution.CompareTo(activeShadowLights[l2].shadowResolution); // Sort by shadow size

);
// Start filling lights into texture
List<AtlasEntry> requestedPages = new List<AtlasEntry>();
var requestedPages = new List<AtlasEntry>();
int numShadowSplits = CalculateNumShadowSplits(shadowIndices[i], lights);
var numShadowSplits = CalculateNumShadowSplits(shadowIndices[i], lights);
packedShadows.shadowLights[shadowIndices[i]].shadowSliceCount = numShadowSplits;
packedShadows.shadowLights[shadowIndices[i]].shadowSliceIndex = requestedPages.Count;

}
int nCurrentX = 0;
int nCurrentY = -1;
int nNextY = 0;
var nCurrentX = 0;
var nCurrentY = -1;
var nNextY = 0;
foreach (AtlasEntry entry in requestedPages)
foreach (var entry in requestedPages)
int shadowResolution = activeShadowLights[entry.lightIndex].shadowResolution;
var shadowResolution = activeShadowLights[entry.lightIndex].shadowResolution;
// Check if first texture is too wide
if (nCurrentY == -1)

Debug.LogError("ERROR! Shadow packer ran out of space in the " + m_Settings.shadowAtlasWidth + "x" + m_Settings.shadowAtlasHeight + " texture!\n\n");
m_bFailedToPackLastTime = true;
m_FailedToPackLastTime = true;
ClearPackedShadows(lights, out packedShadows);
return false;
}

if ((nCurrentY + shadowResolution) > m_Settings.shadowAtlasHeight)
{
Debug.LogError("ERROR! Shadow packer ran out of space in the " + m_Settings.shadowAtlasWidth + "x" + m_Settings.shadowAtlasHeight + " texture!\n\n");
m_bFailedToPackLastTime = true;
m_FailedToPackLastTime = true;
ClearPackedShadows(lights, out packedShadows);
return false;
}

//Debug.Log( "Sheet packer: " + vl.m_cachedLight.name + " ( " + vl.m_shadowX + ", " + vl.m_shadowY + " ) " + vl.m_shadowResolution + "\n\n" );
}
if (m_bFailedToPackLastTime)
if (m_FailedToPackLastTime)
m_bFailedToPackLastTime = false;
m_FailedToPackLastTime = false;
Debug.Log("SUCCESS! Shadow packer can now fit all lights into the " + m_Settings.shadowAtlasWidth + "x" + m_Settings.shadowAtlasHeight + " texture!\n\n");
}

static List<InputShadowLightData> GetInputShadowLightData(CullResults cullResults)
{
var shadowCasters = new List<InputShadowLightData>();
VisibleLight[] lights = cullResults.visibleLights;
var lights = cullResults.visibleLights;
if (lights[i].light.shadows != LightShadows.None)
if (lights[i].light.shadows == LightShadows.None)
continue;
// Only a single directional shadow casting light is supported
if (lights[i].lightType == LightType.Directional)
// Only a single directional shadow casting light is supported
if (lights[i].lightType == LightType.Directional)
{
directionalLightCount++;
if (directionalLightCount != 1)
continue;
}
directionalLightCount++;
if (directionalLightCount != 1)
continue;
}
AdditionalLightData additionalLight = lights[i].light.GetComponent<AdditionalLightData>();
AdditionalLightData additionalLight = lights[i].light.GetComponent<AdditionalLightData>();
InputShadowLightData light;
light.lightIndex = i;
light.shadowResolution = AdditionalLightData.GetShadowResolution(additionalLight);
InputShadowLightData light;
light.lightIndex = i;
light.shadowResolution = AdditionalLightData.GetShadowResolution(additionalLight);
shadowCasters.Add(light);
}
shadowCasters.Add(light);
}
return shadowCasters;
}

var setRenderTargetCommandBuffer = new CommandBuffer();
setRenderTargetCommandBuffer.name = "Render packed shadows";
setRenderTargetCommandBuffer.GetTemporaryRT(m_ShadowTexName, m_Settings.shadowAtlasWidth, m_Settings.shadowAtlasHeight, kDepthBuffer, FilterMode.Bilinear, RenderTextureFormat.Shadowmap, RenderTextureReadWrite.Linear);
setRenderTargetCommandBuffer.GetTemporaryRT(m_ShadowTexName, m_Settings.shadowAtlasWidth, m_Settings.shadowAtlasHeight, k_DepthBuffer, FilterMode.Bilinear, RenderTextureFormat.Shadowmap, RenderTextureReadWrite.Linear);
setRenderTargetCommandBuffer.SetRenderTarget(new RenderTargetIdentifier(m_ShadowTexName));
setRenderTargetCommandBuffer.ClearRenderTarget(true, true, Color.green);

Matrix4x4 proj;
Matrix4x4 view;
LightType lightType = visibleLights[lightIndex].lightType;
Vector3 lightDirection = visibleLights[lightIndex].light.transform.forward;
var lightType = visibleLights[lightIndex].lightType;
var lightDirection = visibleLights[lightIndex].light.transform.forward;
var shadowNearClip = visibleLights[lightIndex].light.shadowNearPlane;
int shadowSliceIndex = packedShadows.GetShadowSliceIndex(lightIndex, 0);

DrawShadowsSettings settings = new DrawShadowsSettings(cullResults, lightIndex);
var settings = new DrawShadowsSettings(cullResults, lightIndex);
bool needRendering = cullResults.ComputeSpotShadowsMatricesAndCullingPrimitives(lightIndex, out view, out proj, out settings.splitData);
SetupShadowSplitMatrices(ref packedShadows.shadowSlices[shadowSliceIndex], proj, view);
if (needRendering)

{
for (int s = 0; s < shadowSliceCount; ++s, shadowSliceIndex++)
{
DrawShadowsSettings settings = new DrawShadowsSettings(cullResults, lightIndex);
var settings = new DrawShadowsSettings(cullResults, lightIndex);
bool needRendering = cullResults.ComputePointShadowsMatricesAndCullingPrimitives(lightIndex, (CubemapFace)s, 2.0f, out view, out proj, out settings.splitData);
SetupShadowSplitMatrices(ref shadowSlices[shadowSliceIndex], proj, view);

private void SetupShadowSplitMatrices(ref ShadowSliceData lightData, Matrix4x4 proj, Matrix4x4 view)
{
Matrix4x4 matScaleBias = Matrix4x4.identity;
var matScaleBias = Matrix4x4.identity;
matScaleBias.m00 = 0.5f;
matScaleBias.m11 = 0.5f;
matScaleBias.m22 = 0.5f;

Matrix4x4 matTile = Matrix4x4.identity;
var matTile = Matrix4x4.identity;
matTile.m00 = (float)lightData.shadowResolution / (float)m_Settings.shadowAtlasWidth;
matTile.m11 = (float)lightData.shadowResolution / (float)m_Settings.shadowAtlasHeight;
matTile.m03 = (float)lightData.atlasX / (float)m_Settings.shadowAtlasWidth;

//---------------------------------------------------------------------------------------------------------------------------------------------------
private void RenderShadowSplit(ref ShadowSliceData slice, Vector3 lightDirection, Matrix4x4 proj, Matrix4x4 view, ref RenderLoop loop, DrawShadowsSettings settings)
{
var commandBuffer = new CommandBuffer();
commandBuffer.name = "ShadowSetup";
var commandBuffer = new CommandBuffer { name = "ShadowSetup" };
// Set viewport / matrices etc
commandBuffer.SetViewport(new Rect(slice.atlasX, slice.atlasY, slice.shadowResolution, slice.shadowResolution));

2
Assets/ScriptableRenderLoop/ScriptableRenderLoop.cs


using UnityEngine;
using System.Collections;
using UnityEngine.Rendering;
namespace UnityEngine.ScriptableRenderLoop

16
Assets/ScriptableRenderLoop/ScriptableRenderLoopPicker.cs


using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace UnityEngine.ScriptableRenderLoop
{

return false;
#if UNITY_EDITOR
if (m_AssetVersion != ms_GlobalAssetVersion)
if (m_AssetVersion != s_GlobalAssetVersion)
m_AssetVersion = ms_GlobalAssetVersion;
m_AssetVersion = s_GlobalAssetVersion;
m_RenderLoop.Rebuild();
}
#endif

{
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
foreach (string str in importedAssets)
foreach (var str in importedAssets)
ms_GlobalAssetVersion++;
s_GlobalAssetVersion++;
public static int ms_GlobalAssetVersion = 0;
public int m_AssetVersion = 0;
static int s_GlobalAssetVersion = 0;
int m_AssetVersion = 0;
#endif
}
}

102
Assets/ScriptableRenderLoop/common/SkyboxHelper.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine.Rendering;
using UnityEngine;

{
}
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];
var vertData = new Vector3[8 * 3];
vertData[i] = octaVerts[i];
vertData[i] = m_OctaVerts[i];
for (int i = 0; i < NumFullSubdivisions; i++)
for (int 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)
{

}
// Horizon subdivisions
float horizonLimit = 1.0f;
for (int i = 0; i < NumHorizonSubdivisions; i++)
var horizonLimit = 1.0f;
for (int 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>();
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;
var triangles = new int[vertexCount];
for (int 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;
}

182
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);
Graphics.CopyTexture(texture, f, cache, 6 * sliceIndex + 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 (int 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 (int 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 (int 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 (int 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;
var sliceIndex = m_LocatorInSliceArray[texId];
//assert(m_SliceArray[sliceIndex].TexID==TexID);
//assert(m_SliceArray[sliceIndex].TexID==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;
}
// 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;
}
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;
if (!foundIdxSortLRU)
return;
// 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;
}
// 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;
// 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;

7
Assets/ScriptableRenderLoop/common/TextureSettings.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
[System.Serializable]
public struct TextureSettings
{

static public TextureSettings Default
public static TextureSettings Default
{
get
{

873
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

143
Assets/ShaderGenerator/CSharpToHLSL.cs


using System;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Visitors;
using ICSharpCode.NRefactory.Ast;

public static void GenerateAll()
{
m_typeName = new Dictionary<string, ShaderTypeGenerator>();
s_TypeName = new Dictionary<string, ShaderTypeGenerator>();
// Iterate over assemblyList, discover all applicable types with fully qualified names
var assemblyList = AssemblyEnumerator.EnumerateReferencedAssemblies(Assembly.GetCallingAssembly());

Type[] types = assembly.GetExportedTypes();
var types = assembly.GetExportedTypes();
object[] attributes = type.GetCustomAttributes(true);
var attributes = type.GetCustomAttributes(true);
Type parent = type.DeclaringType;
var parent = type.DeclaringType;
if (parent != null)
{
Debug.LogError("The GenerateHLSL attribute not supported on nested classes (" + type.FullName + "), skipping.");

ShaderTypeGenerator gen;
if (m_typeName.TryGetValue(type.FullName, out gen))
if (s_TypeName.TryGetValue(type.FullName, out gen))
m_typeName[type.FullName] = new ShaderTypeGenerator(type, attr as GenerateHLSL);
s_TypeName[type.FullName] = new ShaderTypeGenerator(type, attr as GenerateHLSL);
}
}
}

// Now that we have extracted all the typenames that we care about, parse all .cs files in all asset
// paths and figure out in which files those types are actually declared.
m_sourceGenerators = new Dictionary<string, List<ShaderTypeGenerator>>();
s_SourceGenerators = new Dictionary<string, List<ShaderTypeGenerator>>();
var assetPaths = AssetDatabase.GetAllAssetPaths().Where(s => s.EndsWith(".cs")).ToList();
foreach (var assetPath in assetPaths)

// Finally, write out the generated code
foreach (var it in m_sourceGenerators)
foreach (var it in s_SourceGenerators)
{
string fileName = it.Key + ".hlsl";
bool skipFile = false;

}
}
if (!skipFile)
if (skipFile)
continue;
using (var writer = File.CreateText(fileName))
using (System.IO.StreamWriter writer = File.CreateText(fileName))
{
writer.Write("//\n");
writer.Write("// This file was automatically generated from " + it.Key + ". Please don't edit by hand.\n");
writer.Write("//\n\n");
writer.Write("//\n");
writer.Write("// This file was automatically generated from " + it.Key + ". Please don't edit by hand.\n");
writer.Write("//\n\n");
foreach (var gen in it.Value)
foreach (var gen in it.Value)
{
if (gen.hasStatics)
if (gen.hasStatics)
{
writer.Write(gen.EmitDefines() + "\n");
}
writer.Write(gen.EmitDefines() + "\n");
}
foreach (var gen in it.Value)
foreach (var gen in it.Value)
{
if (gen.hasFields)
if (gen.hasFields)
{
writer.Write(gen.EmitTypeDecl() + "\n");
}
writer.Write(gen.EmitTypeDecl() + "\n");
}
foreach (var gen in it.Value)
foreach (var gen in it.Value)
{
if (gen.hasFields && gen.needAccessors)
if (gen.hasFields && gen.needAccessors())
{
writer.Write(gen.EmitAccessors() + "\n");
}
writer.Write(gen.EmitAccessors() + "\n");
writer.Write("\n");
writer.Write("\n");
static Dictionary<string, ShaderTypeGenerator> m_typeName;
static Dictionary<string, ShaderTypeGenerator> s_TypeName;
static void LoadTypes(string fileName)
{

try
{
var visitor = new NamespaceVisitor();
VisitorData data = new VisitorData();
data.m_typeName = m_typeName;
var data = new VisitorData { typeName = s_TypeName };
m_sourceGenerators[fileName] = data.generators;
s_SourceGenerators[fileName] = data.generators;
}
catch
{

}
}
static Dictionary<string, List<ShaderTypeGenerator>> m_sourceGenerators;
static Dictionary<string, List<ShaderTypeGenerator>> s_SourceGenerators;
class VisitorData
{

public string GetTypePrefix()
{
string fullNamespace = string.Empty;
var fullNamespace = string.Empty;
string separator = "";
foreach (string ns in currentClasses)
{
fullNamespace = ns + "+" + fullNamespace;
}
var separator = "";
foreach (string ns in currentNamespaces)
fullNamespace = currentClasses.Aggregate(fullNamespace, (current, ns) => ns + "+" + current);
foreach (var ns in currentNamespaces)
{
if (fullNamespace == string.Empty)
{

fullNamespace = ns + "." + fullNamespace;
}
string name = "";
var name = "";
if (fullNamespace != string.Empty)
{
name = fullNamespace + separator + name;

public Stack<string> currentNamespaces;
public Stack<string> currentClasses;
public List<ShaderTypeGenerator> generators;
public Dictionary<string, ShaderTypeGenerator> m_typeName;
public readonly Stack<string> currentNamespaces;
public readonly Stack<string> currentClasses;
public readonly List<ShaderTypeGenerator> generators;
public Dictionary<string, ShaderTypeGenerator> typeName;
}
class NamespaceVisitor : AbstractAstVisitor

VisitorData visitorData = (VisitorData)data;
var visitorData = (VisitorData)data;
visitorData.currentNamespaces.Push(namespaceDeclaration.Name);
namespaceDeclaration.AcceptChildren(this, visitorData);
visitorData.currentNamespaces.Pop();

// Structured types only
if (typeDeclaration.Type == ClassType.Class || typeDeclaration.Type == ClassType.Struct || typeDeclaration.Type == ClassType.Enum)
{
VisitorData visitorData = (VisitorData)data;
var visitorData = (VisitorData)data;
string name = visitorData.GetTypePrefix() + typeDeclaration.Name;
var name = visitorData.GetTypePrefix() + typeDeclaration.Name;
if (visitorData.m_typeName.TryGetValue(name, out gen))
if (visitorData.typeName.TryGetValue(name, out gen))
{
visitorData.generators.Add(gen);
}

{
public static List<Assembly> EnumerateReferencedAssemblies(Assembly assembly)
{
Dictionary<string, Assembly> assemblies = assembly.GetReferencedAssembliesRecursive();
assemblies[GetName(assembly.FullName)] = assembly;
return assemblies.Values.ToList();
Dictionary<string, Assembly> referenced = assembly.GetReferencedAssembliesRecursive();
referenced[GetName(assembly.FullName)] = assembly;
return referenced.Values.ToList();
assemblies = new Dictionary<string, Assembly>();
s_Assemblies = new Dictionary<string, Assembly>();
var keysToRemove = assemblies.Values.Where(
var keysToRemove = s_Assemblies.Values.Where(
assemblies.Remove(GetName(k.FullName));
s_Assemblies.Remove(GetName(k.FullName));
return assemblies;
return s_Assemblies;
}
private static void InternalGetDependentAssembliesRecursive(Assembly assembly)

foreach (var r in referencedAssemblies)
{
if (String.IsNullOrEmpty(assembly.FullName))
if (string.IsNullOrEmpty(assembly.FullName))
if (assemblies.ContainsKey(GetName(r.FullName)) == false)
if (s_Assemblies.ContainsKey(GetName(r.FullName)))
continue;
try
{
// Ensure that the assembly is loaded
var a = Assembly.Load(r.FullName);
s_Assemblies[GetName(a.FullName)] = a;
InternalGetDependentAssembliesRecursive(a);
}
catch
try
{
// Ensure that the assembly is loaded
var a = Assembly.Load(r.FullName);
assemblies[GetName(a.FullName)] = a;
InternalGetDependentAssembliesRecursive(a);
}
catch
{
// Missing dll, ignore.
}
// Missing dll, ignore.
}
}
}

return name.Split(',')[0];
}
static Dictionary<string, Assembly> assemblies;
static Dictionary<string, Assembly> s_Assemblies;
}
}

8
Assets/ShaderGenerator/ShaderGeneratorMenu.cs


using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEditor;
namespace UnityEngine.ScriptableRenderLoop
{
public class ShaderGeneratorMenu

139
Assets/ShaderGenerator/ShaderTypeGeneration.cs


using System;
using System.Collections;
using UnityEngine;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Visitors;
namespace UnityEngine.ScriptableRenderLoop
{

return info;
}
public PrimitiveType type;
public readonly PrimitiveType type;
public string originalName;
public string comment;
public readonly string originalName;
public readonly string comment;
public int rows;
public int cols;
public int swizzleOffset;

bool ExtractComplex(FieldInfo field, List<ShaderFieldInfo> shaderFields)
{
List<FieldInfo> floatFields = new List<FieldInfo>();
List<FieldInfo> intFields = new List<FieldInfo>();
List<FieldInfo> uintFields = new List<FieldInfo>();
string[] descs = new string[4] { "x: ", "y: ", "z: ", "w: " };
var floatFields = new List<FieldInfo>();
var intFields = new List<FieldInfo>();
var uintFields = new List<FieldInfo>();
var descs = new string[4] { "x: ", "y: ", "z: ", "w: " };
foreach (FieldInfo subField in field.FieldType.GetFields())
foreach (var subField in field.FieldType.GetFields())
{
if (subField.IsStatic)
continue;

{
List<ShaderFieldInfo> mergedFields = new List<ShaderFieldInfo>();
List<ShaderFieldInfo>.Enumerator e = shaderFields.GetEnumerator();
if (!e.MoveNext())
using (var e = shaderFields.GetEnumerator())
// Empty shader struct definition.
return shaderFields;
}
if (!e.MoveNext())
{
// Empty shader struct definition.
return shaderFields;
}
ShaderFieldInfo current = e.Current.Clone() as ShaderFieldInfo;
ShaderFieldInfo current = e.Current.Clone() as ShaderFieldInfo;
while (e.MoveNext())
{
while (true)
while (e.MoveNext())
int offset = current.elementCount;
MergeResult result = PackFields(e.Current, ref current);
while (true)
{
int offset = current.elementCount;
var result = PackFields(e.Current, ref current);
if (result == MergeResult.Failed)
{
return null;
}
else if (result == MergeResult.Full)
{
break;
}
if (result == MergeResult.Failed)
{
return null;
}
else if (result == MergeResult.Full)
{
break;
}
// merge accessors
Accessor acc = current.accessor;
// merge accessors
var acc = current.accessor;
acc.name = current.name;
e.Current.accessor = acc;
e.Current.swizzleOffset += offset;
acc.name = current.name;
e.Current.accessor = acc;
e.Current.swizzleOffset += offset;
current.packed = e.Current.packed = true;
current.packed = e.Current.packed = true;
if (!e.MoveNext())
{
mergedFields.Add(current);
return mergedFields;
if (!e.MoveNext())
{
mergedFields.Add(current);
return mergedFields;
}
mergedFields.Add(current);
current = e.Current.Clone() as ShaderFieldInfo;
mergedFields.Add(current);
current = e.Current.Clone() as ShaderFieldInfo;
}
}
return mergedFields;
}

shaderText += "// PackingRules = " + attr.packingRules.ToString() + "\n";
shaderText += "struct " + type.Name + "\n";
shaderText += "{\n";
foreach (ShaderFieldInfo shaderFieldInfo in packedFields)
foreach (var shaderFieldInfo in m_PackedFields)
{
shaderText += "\t" + shaderFieldInfo.ToString() + "\n";
}

shaderText += "//\n";
shaderText += "// Accessors for " + type.FullName + "\n";
shaderText += "//\n";
foreach (var shaderField in shaderFields)
foreach (var shaderField in m_ShaderFields)
{
Accessor acc = shaderField.accessor;
string accessorName = shaderField.originalName;

shaderText += "//\n";
shaderText += "// " + type.FullName + ": static fields\n";
shaderText += "//\n";
foreach (var def in statics)
foreach (var def in m_Statics)
{
shaderText += "#define " + def.Key + " (" + def.Value + ")\n";
}

public bool Generate()
{
statics = new Dictionary<string, string>();
m_Statics = new Dictionary<string, string>();
shaderFields = new List<ShaderFieldInfo>();
m_ShaderFields = new List<ShaderFieldInfo>();
if (type.IsEnum)
{

{
string name = field.Name;
name = InsertUnderscore(name);
statics[(type.Name + "_" + name).ToUpper()] = field.GetRawConstantValue().ToString();
m_Statics[(type.Name + "_" + name).ToUpper()] = field.GetRawConstantValue().ToString();
}
}
errors = null;

{
if (field.FieldType.IsPrimitive)
{
statics[field.Name] = field.GetValue(null).ToString();
m_Statics[field.Name] = field.GetValue(null).ToString();
}
continue;
}

string subNamespace = type.Namespace.Substring(type.Namespace.LastIndexOf((".")) + 1);
string name = InsertUnderscore(field.Name);
statics[("DEBUGVIEW_" + subNamespace + "_" + type.Name + "_" + name).ToUpper()] = Convert.ToString(attr.paramDefinesStart + debugCounter++);
m_Statics[("DEBUGVIEW_" + subNamespace + "_" + type.Name + "_" + name).ToUpper()] = Convert.ToString(attr.paramDefinesStart + debugCounter++);
EmitPrimitiveType(PrimitiveType.Float, 1, field.Name, "", shaderFields);
EmitPrimitiveType(PrimitiveType.Float, 1, field.Name, "", m_ShaderFields);
EmitPrimitiveType(PrimitiveType.Int, 1, field.Name, "", shaderFields);
EmitPrimitiveType(PrimitiveType.Int, 1, field.Name, "", m_ShaderFields);
EmitPrimitiveType(PrimitiveType.UInt, 1, field.Name, "", shaderFields);
EmitPrimitiveType(PrimitiveType.UInt, 1, field.Name, "", m_ShaderFields);
else
{
Error("unsupported field type '" + field.FieldType + "'");

{
// handle special types, otherwise try parsing the struct
if (field.FieldType == typeof(Vector2))
EmitPrimitiveType(PrimitiveType.Float, 2, field.Name, "", shaderFields);
EmitPrimitiveType(PrimitiveType.Float, 2, field.Name, "", m_ShaderFields);
EmitPrimitiveType(PrimitiveType.Float, 3, field.Name, "", shaderFields);
EmitPrimitiveType(PrimitiveType.Float, 3, field.Name, "", m_ShaderFields);
EmitPrimitiveType(PrimitiveType.Float, 4, field.Name, "", shaderFields);
EmitPrimitiveType(PrimitiveType.Float, 4, field.Name, "", m_ShaderFields);
EmitMatrixType(PrimitiveType.Float, 4, 4, field.Name, "", shaderFields);
else if (!ExtractComplex(field, shaderFields))
EmitMatrixType(PrimitiveType.Float, 4, 4, field.Name, "", m_ShaderFields);
else if (!ExtractComplex(field, m_ShaderFields))
{
// Error reporting done in ExtractComplex()
return false;

packedFields = shaderFields;
m_PackedFields = m_ShaderFields;
packedFields = Pack(shaderFields);
m_PackedFields = Pack(m_ShaderFields);
if (packedFields == null)
if (m_PackedFields == null)
{
return false;
}

public bool hasFields
{
get { return shaderFields.Count > 0; }
get { return m_ShaderFields.Count > 0; }
get { return statics.Count > 0; }
get { return m_Statics.Count > 0; }
public bool needAccessors()
public bool needAccessors
return attr.needAccessors;
get { return attr.needAccessors; }
}
public Type type;

Dictionary<string, string> statics;
List<ShaderFieldInfo> shaderFields;
List<ShaderFieldInfo> packedFields;
Dictionary<string, string> m_Statics;
List<ShaderFieldInfo> m_ShaderFields;
List<ShaderFieldInfo> m_PackedFields;
}
}

37
.editorconfig


# see http://editorconfig.org/ for docs on this file
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf ; help with sharing files across os's (i.e. network share or through local vm)
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
# trailing whitespace is significant in markdown (bad choice, bad!)
[*.{md,markdown}]
trim_trailing_whitespace = false
# keep these and the VS stuff below in sync with .hgeol's CRLF extensions
[*.{vcproj,bat,cmd,xaml,tt,t4,ttinclude}]
end_of_line = crlf
# this VS-specific stuff is based on experiments to see how VS will modify a file after it has been manually edited.
# the settings are meant to closely match what VS does to minimize unnecessary diffs. this duplicates some settings in *
# but let's be explicit here to be safe (in case someone wants to copy-paste this out to another .editorconfig).
[*.{vcxproj,vcxproj.filters,csproj,props,targets}]
indent_style = space
indent_size = 2
end_of_line = crlf
charset = utf-8-bom
trim_trailing_whitespace = true
insert_final_newline = false
[*.{sln,sln.template}]
indent_style = tab
indent_size = 4
end_of_line = crlf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = false

9
Assets/ScriptableRenderLoop/fptl/LightingUtils.hlsl.meta


fileFormatVersion: 2
guid: 0f0336214df2a1845afb1ce1b72075f5
timeCreated: 1476376272
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存