浏览代码

code cleanup part deux

/main
vlad-andreev 8 年前
当前提交
3e91c5e0
共有 19 个文件被更改,包括 405 次插入443 次删除
  1. 3
      Assets/Editor/Tests/RenderloopTests/CullResultsTest.cs
  2. 8
      Assets/Editor/Tests/RenderloopTests/RenderloopTestFixture.cs
  3. 8
      Assets/ScriptableRenderLoop/AdditionalLightData.cs
  4. 9
      Assets/ScriptableRenderLoop/ForwardRenderLoop/ForwardRenderLoop.cs
  5. 221
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  6. 135
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoopInspector.cs
  7. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Lighting/LightDefinition.cs.hlsl
  8. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Builtin/BuiltinData.cs.hlsl
  9. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.cs.hlsl
  10. 106
      Assets/ScriptableRenderLoop/RenderPasses/ShadowRenderPass.cs
  11. 2
      Assets/ScriptableRenderLoop/ScriptableRenderLoop.cs
  12. 16
      Assets/ScriptableRenderLoop/ScriptableRenderLoopPicker.cs
  13. 13
      Assets/ScriptableRenderLoop/common/SkyboxHelper.cs
  14. 12
      Assets/ScriptableRenderLoop/common/TextureCache.cs
  15. 5
      Assets/ScriptableRenderLoop/common/TextureSettings.cs
  16. 14
      Assets/ScriptableRenderLoop/fptl/FptlLighting.cs
  17. 143
      Assets/ShaderGenerator/CSharpToHLSL.cs
  18. 8
      Assets/ShaderGenerator/ShaderGeneratorMenu.cs
  19. 139
      Assets/ShaderGenerator/ShaderTypeGeneration.cs

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

9
Assets/ScriptableRenderLoop/ForwardRenderLoop/ForwardRenderLoop.cs


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

var matWorldToShadow = new Matrix4x4[k_MaxLights * k_MaxShadowmapPerLights];
var dirShadowSplitSpheres = new Vector4[k_MaxDirectionalSplit];
for (var nLight = 0; nLight < visibleLights.Length; nLight++)
for (int nLight = 0; nLight < visibleLights.Length; nLight++)
{
numLightsIncludingTooMany++;
if (numLightsIncludingTooMany > k_MaxLights)

if (hasShadows)
{
for (var s = 0; s < k_MaxDirectionalSplit; ++s)
for (int s = 0; s < k_MaxDirectionalSplit; ++s)
{
dirShadowSplitSpheres[s] = shadow.directionalShadowSplitSphereSqr[s];
}

{
// Enable shadows
lightShadowIndex_lightParams[numLights].x = 1;
for (var s = 0; s < shadow.GetShadowSliceCountLightIndex(nLight); ++s)
for (int s = 0; s < shadow.GetShadowSliceCountLightIndex(nLight); ++s)
{
var shadowSliceIndex = shadow.GetShadowSliceIndex(nLight, s);
matWorldToShadow[numLights * k_MaxShadowmapPerLights + s] = shadow.shadowSlices[shadowSliceIndex].shadowTransform.transpose;

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

135
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoopInspector.cs


using UnityEngine;
using System.Collections;
using UnityEngine.Rendering;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
//using EditorGUIUtility=UnityEditor.EditorGUIUtility;

}
private static Styles s_Styles = null;
private static Styles styles { get { if (s_Styles == null) s_Styles = new Styles(); return s_Styles; } }
const float kMaxExposure = 32.0f;
private static Styles styles
{
get
{
if (s_Styles == null)
s_Styles = new Styles();
return s_Styles;
}
}
const float k_MaxExposure = 32.0f;
object[] attributes = type.GetCustomAttributes(true);
var attributes = type.GetCustomAttributes(true);
GenerateHLSL attr = attributes[0] as GenerateHLSL;
var attr = attributes[0] as GenerateHLSL;
if (!attr.needParamDefines)
{

FieldInfo[] fields = type.GetFields();
var fields = type.GetFields();
string subNamespace = type.Namespace.Substring(type.Namespace.LastIndexOf((".")) + 1);
var subNamespace = type.Namespace.Substring(type.Namespace.LastIndexOf((".")) + 1);
int localIndex = 0;
var localIndex = 0;
string name = field.Name;
var fieldName = field.Name;
// Check if the display name have been override by the users
if (Attribute.IsDefined(field, typeof(SurfaceDataAttributes)))
{

name = propertyAttr[0].displayName;
fieldName = propertyAttr[0].displayName;
name = (isBSDFData ? "Engine/" : "") + subNamespace + "/" + name;
fieldName = (isBSDFData ? "Engine/" : "") + subNamespace + "/" + fieldName;
debugViewMaterialStrings[index] = new GUIContent(name);
debugViewMaterialStrings[index] = new GUIContent(fieldName);
debugViewMaterialValues[index] = attr.paramDefinesStart + (int)localIndex;
index++;
localIndex++;

void FillWithPropertiesEnum(Type type, GUIContent[] debugViewMaterialStrings, int[] debugViewMaterialValues, bool isBSDFData, ref int index)
{
String[] names = Enum.GetNames(type);
var names = Enum.GetNames(type);
int localIndex = 0;
var localIndex = 0;
string name = (isBSDFData ? "Engine/" : "") + names[localIndex];
var valueName = (isBSDFData ? "Engine/" : "") + names[localIndex];
debugViewMaterialStrings[index] = new GUIContent(name);
debugViewMaterialStrings[index] = new GUIContent(valueName);
debugViewMaterialValues[index] = (int)value;
index++;
localIndex++;

public override void OnInspectorGUI()
{
HDRenderLoop renderLoop = target as HDRenderLoop;
if (renderLoop)
{
HDRenderLoop.DebugParameters debugParameters = renderLoop.debugParameters;
var renderLoop = target as HDRenderLoop;
EditorGUILayout.LabelField(styles.debugParameters);
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
if (!renderLoop)
return;
var debugParameters = renderLoop.debugParameters;
EditorGUILayout.LabelField(styles.debugParameters);
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
if (!styles.isDebugViewMaterialInit)
{
String[] varyingNames = Enum.GetNames(typeof(HDRenderLoop.DebugViewVaryingMode));
String[] GBufferNames = Enum.GetNames(typeof(HDRenderLoop.DebugViewGbufferMode));
if (!styles.isDebugViewMaterialInit)
{
var varyingNames = Enum.GetNames(typeof(HDRenderLoop.DebugViewVaryingMode));
var gbufferNames = Enum.GetNames(typeof(HDRenderLoop.DebugViewGbufferMode));
// +1 for the zero case
int num = 1 + varyingNames.Length
+ GBufferNames.Length
+ typeof(Builtin.BuiltinData).GetFields().Length
+ typeof(Lit.SurfaceData).GetFields().Length
+ typeof(Lit.BSDFData).GetFields().Length;
// +1 for the zero case
var num = 1 + varyingNames.Length
+ gbufferNames.Length
+ typeof(Builtin.BuiltinData).GetFields().Length
+ typeof(Lit.SurfaceData).GetFields().Length
+ typeof(Lit.BSDFData).GetFields().Length;
styles.debugViewMaterialStrings = new GUIContent[num];
styles.debugViewMaterialValues = new int[num];
styles.debugViewMaterialStrings = new GUIContent[num];
styles.debugViewMaterialValues = new int[num];
int index = 0;
var index = 0;
// 0 is a reserved number
styles.debugViewMaterialStrings[0] = new GUIContent("None");
styles.debugViewMaterialValues[0] = 0;
index++;
// 0 is a reserved number
styles.debugViewMaterialStrings[0] = new GUIContent("None");
styles.debugViewMaterialValues[0] = 0;
index++;
FillWithPropertiesEnum(typeof(HDRenderLoop.DebugViewVaryingMode), styles.debugViewMaterialStrings, styles.debugViewMaterialValues, false, ref index);
FillWithProperties(typeof(Builtin.BuiltinData), styles.debugViewMaterialStrings, styles.debugViewMaterialValues, false, ref index);
FillWithProperties(typeof(Lit.SurfaceData), styles.debugViewMaterialStrings, styles.debugViewMaterialValues, false, ref index);
FillWithPropertiesEnum(typeof(HDRenderLoop.DebugViewVaryingMode), styles.debugViewMaterialStrings, styles.debugViewMaterialValues, false, ref index);
FillWithProperties(typeof(Builtin.BuiltinData), styles.debugViewMaterialStrings, styles.debugViewMaterialValues, false, ref index);
FillWithProperties(typeof(Lit.SurfaceData), styles.debugViewMaterialStrings, styles.debugViewMaterialValues, false, ref index);
// Engine
FillWithPropertiesEnum(typeof(HDRenderLoop.DebugViewGbufferMode), styles.debugViewMaterialStrings, styles.debugViewMaterialValues, true, ref index);
FillWithProperties(typeof(Lit.BSDFData), styles.debugViewMaterialStrings, styles.debugViewMaterialValues, true, ref index);
// Engine
FillWithPropertiesEnum(typeof(HDRenderLoop.DebugViewGbufferMode), styles.debugViewMaterialStrings, styles.debugViewMaterialValues, true, ref index);
FillWithProperties(typeof(Lit.BSDFData), styles.debugViewMaterialStrings, styles.debugViewMaterialValues, true, ref index);
styles.isDebugViewMaterialInit = true;
}
styles.isDebugViewMaterialInit = true;
}
debugParameters.debugViewMaterial = EditorGUILayout.IntPopup(styles.debugViewMaterial, (int)debugParameters.debugViewMaterial, styles.debugViewMaterialStrings, styles.debugViewMaterialValues);
debugParameters.debugViewMaterial = EditorGUILayout.IntPopup(styles.debugViewMaterial, (int)debugParameters.debugViewMaterial, styles.debugViewMaterialStrings, styles.debugViewMaterialValues);
EditorGUILayout.Space();
debugParameters.enableTonemap = EditorGUILayout.Toggle(styles.enableTonemap, debugParameters.enableTonemap);
debugParameters.exposure = Mathf.Max(Mathf.Min(EditorGUILayout.FloatField(styles.exposure, debugParameters.exposure), kMaxExposure), -kMaxExposure);
EditorGUILayout.Space();
debugParameters.enableTonemap = EditorGUILayout.Toggle(styles.enableTonemap, debugParameters.enableTonemap);
debugParameters.exposure = Mathf.Max(Mathf.Min(EditorGUILayout.FloatField(styles.exposure, debugParameters.exposure), k_MaxExposure), -k_MaxExposure);
EditorGUILayout.Space();
debugParameters.displayOpaqueObjects = EditorGUILayout.Toggle(styles.displayOpaqueObjects, debugParameters.displayOpaqueObjects);
debugParameters.displayTransparentObjects = EditorGUILayout.Toggle(styles.displayTransparentObjects, debugParameters.displayTransparentObjects);
EditorGUILayout.Space();
debugParameters.displayOpaqueObjects = EditorGUILayout.Toggle(styles.displayOpaqueObjects, debugParameters.displayOpaqueObjects);
debugParameters.displayTransparentObjects = EditorGUILayout.Toggle(styles.displayTransparentObjects, debugParameters.displayTransparentObjects);
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(renderLoop); // Repaint
}
EditorGUI.indentLevel--;
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(renderLoop); // Repaint
EditorGUI.indentLevel--;
}
}
}

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

13
Assets/ScriptableRenderLoop/common/SkyboxHelper.cs


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

public void CreateMesh()
{
var vertData = new Vector3[8 * 3];
for (var i = 0; i < 8 * 3; i++)
for (int i = 0; i < 8 * 3; i++)
for (var i = 0; i < k_NumFullSubdivisions; i++)
for (int i = 0; i < k_NumFullSubdivisions; i++)
for (var k = 0; k < srcData.Length; k += 3)
for (int k = 0; k < srcData.Length; k += 3)
{
Subdivide(verts, srcData[k], srcData[k + 1], srcData[k + 2]);
}

// Horizon subdivisions
var horizonLimit = 1.0f;
for (var i = 0; i < k_NumHorizonSubdivisions; i++)
for (int i = 0; i < k_NumHorizonSubdivisions; i++)
for (var k = 0; k < srcData.Length; k += 3)
for (int k = 0; k < srcData.Length; k += 3)
{
var maxAbsY = Mathf.Max(Mathf.Abs(srcData[k].y), Mathf.Abs(srcData[k + 1].y), Mathf.Abs(srcData[k + 2].y));
if (maxAbsY > horizonLimit)

// Write out the mesh
var vertexCount = vertData.Length;
var triangles = new int[vertexCount];
for (var i = 0; i < vertexCount; i++)
for (int i = 0; i < vertexCount; i++)
{
triangles[i] = i;
}

12
Assets/ScriptableRenderLoop/common/TextureCache.cs


return;
}
for (var f = 0; f < 6; f++)
for (int f = 0; f < 6; f++)
Graphics.CopyTexture(texture, f, m_Cache, 6 * sliceIndex + f);
}

{
var numNonZeros = 0;
var tmpBuffer = new int[m_NumTextures];
for (var i = 0; i < m_NumTextures; i++)
for (int i = 0; i < m_NumTextures; i++)
for (var i = 0; i < m_NumTextures; i++)
for (int i = 0; i < m_NumTextures; i++)
{
if (m_SliceArray[tmpBuffer[i]].countLRU == 0)
{

}
}
for (var 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
}

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

return;
// relocate sliceIndex to front of m_pSortedIdxArray since uCountLRU will be set to maximum.
for (var j = 0; j < i; j++)
for (int j = 0; j < i; j++)
{
m_SortedIdxArray[j + 1] = m_SortedIdxArray[j];
}

5
Assets/ScriptableRenderLoop/common/TextureSettings.cs


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

14
Assets/ScriptableRenderLoop/fptl/FptlLighting.cs


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

{
var data = new float[16];
for (var c = 0; c < 4; c++)
for (var r = 0; r < 4; r++)
for (int c = 0; c < 4; c++)
for (int r = 0; r < 4; r++)
data[4 * c + r] = mat[r, c];
cmd.SetComputeFloatParams(shadercs, name, data);

var lights = new List<DirectionalLight>();
var worldToView = camera.worldToCameraMatrix;
for (var nLight = 0; nLight < visibleLights.Count; nLight++)
for (int nLight = 0; nLight < visibleLights.Count; nLight++)
{
var light = visibleLights[nLight];
if (light.lightType == LightType.Directional)

var lightShadowIndex_LightParams = new Vector4[k_MaxLights];
var lightFalloffParams = new Vector4[k_MaxLights];
for (var nLight = 0; nLight < visibleLights.Count; nLight++)
for (int nLight = 0; nLight < visibleLights.Count; nLight++)
{
nNumLightsIncludingTooMany++;
if (nNumLightsIncludingTooMany > k_MaxLights)

if (hasShadows)
{
for (var s = 0; s < k_MaxDirectionalSplit; ++s)
for (int s = 0; s < k_MaxDirectionalSplit; ++s)
{
m_DirShadowSplitSpheres[s] = shadow.directionalShadowSplitSphereSqr[s];
}

{
// Enable shadows
lightShadowIndex_LightParams[numLights].x = 1;
for (var s = 0; s < shadow.GetShadowSliceCountLightIndex(nLight); ++s)
for (int s = 0; s < shadow.GetShadowSliceCountLightIndex(nLight); ++s)
{
var shadowSliceIndex = shadow.GetShadowSliceIndex(nLight, s);
m_MatWorldToShadow[numLights * k_MaxShadowmapPerLights + s] = shadow.shadowSlices[shadowSliceIndex].shadowTransform.transpose;

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;
}
}
正在加载...
取消
保存