浏览代码

Merge remote-tracking branch 'origin/master' into scriptablerenderloop-materialgraph

/scriptablerenderloop-materialgraph
Paul Demeulenaere 8 年前
当前提交
ab48557b
共有 71 个文件被更改,包括 2708 次插入816 次删除
  1. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Debug.meta
  2. 28
      Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopInspector.cs
  3. 5
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset
  4. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset.meta
  5. 53
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  6. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting.meta
  7. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Forward.hlsl
  8. 5
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs.hlsl
  9. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Lighting.hlsl
  10. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Resources/Deferred.shader
  11. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass.meta
  12. 7
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.cs
  13. 10
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.hlsl
  14. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePassLoop.hlsl
  15. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/ClusteredUtils.hlsl
  16. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-bigtile.compute
  17. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-clustered.compute
  18. 17
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild.compute
  19. 130
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs
  20. 6
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs.hlsl
  21. 3
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.hlsl
  22. 17
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePassLoop.hlsl
  23. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Builtin.meta
  24. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit.meta
  25. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/Editor/LayeredLitUI.cs
  26. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/LayeredLit.shader
  27. 331
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/LitUI.cs
  28. 3
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.shader
  29. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit.meta
  30. 278
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Editor/UnlitUI.cs
  31. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Unlit.shader
  32. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/PostProcess.meta
  33. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass.meta
  34. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Shadow.meta
  35. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Shadow/FixedSizePCF.meta
  36. 53
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/SkyHDRI.shader
  37. 1
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs
  38. 8
      Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs
  39. 9
      Assets/ScriptableRenderLoop/ScriptableRenderLoopPicker.cs
  40. 12
      Assets/ScriptableRenderLoop/ShaderLibrary/API/D3D11.hlsl
  41. 23
      Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl
  42. 6
      Assets/ScriptableRenderLoop/ShaderLibrary/CommonMaterial.hlsl
  43. 39
      Assets/ScriptableRenderLoop/ShaderLibrary/Debug.hlsl
  44. 6
      Assets/ScriptableRenderLoop/fptl/FptlLighting.cs
  45. 152
      Assets/ScriptableRenderLoop/fptl/LightingUtils.hlsl
  46. 147
      Assets/TestScenes/HDTest/HDRenderLoopTest.unity
  47. 9
      Assets/ScriptableRenderLoop/Editor.meta
  48. 130
      Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewTiles.shader
  49. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewTiles.shader.meta
  50. 42
      Assets/ScriptableRenderLoop/HDRenderLoop/Editor/UpgradeStandardShaderMaterials.cs
  51. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Editor/UpgradeStandardShaderMaterials.cs.meta
  52. 334
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/BaseLitUI.cs
  53. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/BaseLitUI.cs.meta
  54. 63
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/StandardSpecularToHDLitMaterialUpgrader.cs
  55. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/StandardSpecularToHDLitMaterialUpgrader.cs.meta
  56. 69
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/StandardToHDLitMaterialUpgrader.cs
  57. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/StandardToHDLitMaterialUpgrader.cs.meta
  58. 20
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/PatchStandardShaderToNewNamingConvention.cginc
  59. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/PatchStandardShaderToNewNamingConvention.cginc.meta
  60. 279
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Editor/BaseUnlitUI.cs
  61. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Editor/BaseUnlitUI.cs.meta
  62. 390
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/AtmosphericParameters.cs
  63. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/AtmosphericParameters.cs.meta
  64. 113
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/README.txt
  65. 354
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/AtmosphericScattering.hlsl
  66. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/AtmosphericScattering.hlsl.meta
  67. 12
      Assets/ScriptableRenderLoop/Editor/MaterialUpgrader.cs.meta
  68. 173
      Assets/ScriptableRenderLoop/Editor/MaterialUpgrader.cs
  69. 20
      Assets/forwardrenderloop.asset
  70. 8
      Assets/forwardrenderloop.asset.meta

2
Assets/ScriptableRenderLoop/HDRenderLoop/Debug.meta


fileFormatVersion: 2
guid: ee4b12281385a0a4791e3128dd34eae4
guid: 10d6f30f9ddaa5f47b910603925654fb
folderAsset: yes
timeCreated: 1475748186
licenseType: Pro

28
Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopInspector.cs


public readonly GUIContent useForwardRenderingOnly = new GUIContent("Use Forward Rendering Only");
public readonly GUIContent useDepthPrepass = new GUIContent("Use Depth Prepass");
public readonly GUIContent useSinglePassLightLoop = new GUIContent("Use single Pass light loop");
public bool isDebugViewMaterialInit = false;
public GUIContent[] debugViewMaterialStrings = null;

public readonly GUIContent[] shadowsCascadeCounts = new GUIContent[] { new GUIContent("1"), new GUIContent("2"), new GUIContent("3"), new GUIContent("4") };
public readonly int[] shadowsCascadeCountValues = new int[] { 1, 2, 3, 4 };
public readonly GUIContent shadowsCascades = new GUIContent("Cascade values");
public readonly GUIContent tileLightLoopSettings = new GUIContent("Tile Light Loop settings");
public readonly GUIContent tileLightLoopDebugMode = new GUIContent("Enable Debug mode", "Toggle overheat map mode");
public readonly GUIContent directIndirectSinglePass = new GUIContent("Enable direct and indirect lighting in single pass", "Toggle");
public readonly GUIContent bigTilePrepass = new GUIContent("Enable big tile prepass", "Toggle");
public readonly GUIContent clustered = new GUIContent("Enable clusted", "Toggle");
}
private static Styles s_Styles = null;

debugParameters.displayOpaqueObjects = EditorGUILayout.Toggle(styles.displayOpaqueObjects, debugParameters.displayOpaqueObjects);
debugParameters.displayTransparentObjects = EditorGUILayout.Toggle(styles.displayTransparentObjects, debugParameters.displayTransparentObjects);
debugParameters.useForwardRenderingOnly = EditorGUILayout.Toggle(styles.useForwardRenderingOnly, debugParameters.useForwardRenderingOnly);
debugParameters.useDepthPrepass = EditorGUILayout.Toggle(styles.useDepthPrepass, debugParameters.useDepthPrepass);
debugParameters.useDepthPrepass = EditorGUILayout.Toggle(styles.useDepthPrepass, debugParameters.useDepthPrepass);
debugParameters.useSinglePassLightLoop = EditorGUILayout.Toggle(styles.useSinglePassLightLoop, debugParameters.useSinglePassLightLoop);
if (EditorGUI.EndChangeCheck())
{

EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
/*
*/
if (EditorGUI.EndChangeCheck())
{

}
EditorGUI.indentLevel--;
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(renderLoop); // Repaint
}
EditorGUI.indentLevel--;
EditorGUILayout.Space();
EditorGUILayout.LabelField(styles.tileLightLoopSettings);
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
renderLoop.tilePassLightLoop.debugViewTilesFlags = (TilePass.DebugViewTilesFlags)EditorGUILayout.EnumMaskField("DebugView Tiles", renderLoop.tilePassLightLoop.debugViewTilesFlags);
renderLoop.tilePassLightLoop.enableDirectIndirectSinglePass = EditorGUILayout.Toggle(styles.directIndirectSinglePass, renderLoop.tilePassLightLoop.enableDirectIndirectSinglePass);
renderLoop.tilePassLightLoop.enableBigTilePrepass = EditorGUILayout.Toggle(styles.bigTilePrepass, renderLoop.tilePassLightLoop.enableBigTilePrepass);
renderLoop.tilePassLightLoop.enableClustered = EditorGUILayout.Toggle(styles.clustered, renderLoop.tilePassLightLoop.enableClustered);
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(renderLoop); // Repaint

5
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset


m_Script: {fileID: 11500000, guid: 558064ecdbf6b6742892d699acb39aed, type: 3}
m_Name: HDRenderLoop
m_EditorClassIdentifier:
m_SkyParameters:
skyHDRI: {fileID: 0}
rotation: 0
exposure: 0
multiplier: 1
m_ShadowSettings:
enabled: 1
shadowAtlasWidth: 4096

2
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset.meta


fileFormatVersion: 2
guid: 2400b74f5ce370c4481e5dc417d03703
timeCreated: 1479691644
timeCreated: 1480265826
licenseType: Pro
NativeFormatImporter:
userData:

53
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


public bool enableTonemap = true;
public float exposure = 0;
public bool useSinglePassLightLoop = true;
}
DebugParameters m_DebugParameters = new DebugParameters();

// TODO: Find a way to automatically create/iterate through lightloop
SinglePass.LightLoop m_SinglePassLightLoop;
TilePass.LightLoop m_TilePassLightLoop;
TilePass.LightLoop m_TilePassLightLoop = null;
public TilePass.LightLoop tilePassLightLoop
{
get { return m_TilePassLightLoop; }
}
// TODO: Find a way to automatically create/iterate through deferred material
Lit.RenderLoop m_LitRenderLoop;

m_SinglePassLightLoop = new SinglePass.LightLoop();
m_SinglePassLightLoop.Rebuild();
m_TilePassLightLoop = new TilePass.LightLoop();
m_TilePassLightLoop.Rebuild();
tilePassLightLoop.Rebuild();
m_lightList = new LightList();
m_lightList.Allocate();

{
m_LitRenderLoop.OnDisable();
m_SinglePassLightLoop.OnDisable();
m_TilePassLightLoop.OnDisable();
tilePassLightLoop.OnDisable();
Utilities.Destroy(m_FinalPassMaterial);
Utilities.Destroy(m_DebugViewMaterialGBuffer);

{
// Bind material data
m_LitRenderLoop.Bind();
m_SinglePassLightLoop.RenderDeferredLighting(camera, renderLoop, m_CameraColorBuffer);
// m_TilePassLightLoop.RenderDeferredLighting(camera, renderLoop, m_CameraColorBuffer);
if (debugParameters.useSinglePassLightLoop)
{
m_SinglePassLightLoop.RenderDeferredLighting(camera, renderLoop, m_CameraColorBuffer);
}
else
{
tilePassLightLoop.RenderDeferredLighting(camera, renderLoop, m_CameraColorBufferRT);
}
}
}

lightList.envCullIndices.Add(probeIndex);
}
// build per tile light lists
m_SinglePassLightLoop.PrepareLightsForGPU(cullResults, camera, m_lightList);
//m_TilePassLightLoop.PrepareLightsForGPU(cullResults, camera, m_lightList);
// build per tile light lists
if (debugParameters.useSinglePassLightLoop)
{
m_SinglePassLightLoop.PrepareLightsForGPU(cullResults, camera, m_lightList);
}
else
{
tilePassLightLoop.PrepareLightsForGPU(cullResults, camera, m_lightList);
}
if (camera.pixelWidth != m_WidthOnRecord || camera.pixelHeight != m_HeightOnRecord || m_TilePassLightLoop.NeedResize())
if (camera.pixelWidth != m_WidthOnRecord || camera.pixelHeight != m_HeightOnRecord || tilePassLightLoop.NeedResize())
m_TilePassLightLoop.ReleaseResolutionDependentBuffers();
tilePassLightLoop.ReleaseResolutionDependentBuffers();
m_TilePassLightLoop.AllocResolutionDependentBuffers(camera.pixelWidth, camera.pixelHeight);
tilePassLightLoop.AllocResolutionDependentBuffers(camera.pixelWidth, camera.pixelHeight);
// update recorded window resolution
m_WidthOnRecord = camera.pixelWidth;

//Shader.SetGlobalTexture("_CubeCookieTextures", m_CubeCookieTexArray.GetTexCache());
Shader.SetGlobalTexture("_EnvTextures", m_CubeReflTexArray.GetTexCache());
m_SinglePassLightLoop.PushGlobalParams(camera, renderLoop, lightList);
m_TilePassLightLoop.PushGlobalParams(camera, renderLoop, lightList);
if (debugParameters.useSinglePassLightLoop)
{
m_SinglePassLightLoop.PushGlobalParams(camera, renderLoop, lightList);
}
else
{
tilePassLightLoop.PushGlobalParams(camera, renderLoop, lightList);
}
}
public override void Render(Camera[] cameras, RenderLoop renderLoop)

using (new Utilities.ProfilingSample("Build Light list", renderLoop))
{
PrepareLightsForGPU(cullResults, camera, ref shadows, ref m_lightList);
//m_TilePassLightLoop.BuildGPULightLists(camera, renderLoop, m_lightList, m_CameraDepthBuffer);
if (!debugParameters.useSinglePassLightLoop)
tilePassLightLoop.BuildGPULightLists(camera, renderLoop, m_lightList, m_CameraDepthBufferRT);
PushGlobalParams(camera, renderLoop, m_lightList);
}

2
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting.meta


fileFormatVersion: 2
guid: b8bec6e2ba5850349bc2827fbe25b071
guid: 7dc18395c5211d44bbe417b8b8b2e81a
folderAsset: yes
timeCreated: 1474297943
licenseType: Pro

2
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Forward.hlsl


// If only one keyword is present it mean that only one type of forward lighting architecture is supported.
// Must match name in GetKeyword() method of forward lighting architecture .cs file
// #pragma multi_compile LIGHTLOOP_SINGLE_PASS -> can't use a pragma from include... (for now)
// #pragma multi_compile LIGHTLOOP_SINGLE_PASS LIGHTLOOP_TILE_PASS -> can't use a pragma from include... (for now)
// #pragma multi_compile SHADOWFILTERING_FIXED_SIZE_PCF -> can't use a pragma from include... (for now)

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


#define ENVSHAPETYPE_BOX (1)
#define ENVSHAPETYPE_SPHERE (2)
//
// UnityEngine.Experimental.ScriptableRenderLoop.EnvConstants: static fields
//
#define ENVCONSTANTS_SPEC_CUBE_LOD_STEP (6)
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.LightData
// PackingRules = Exact
struct LightData

4
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Lighting.hlsl


#ifdef LIGHTLOOP_SINGLE_PASS
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePass.hlsl"
#elif LIGHTLOOP_TILED_PASS
#elif defined(LIGHTLOOP_TILE_PASS)
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.hlsl"
#endif

// LightLoop use evaluation BSDF function for light type define in Material.hlsl
#ifdef LIGHTLOOP_SINGLE_PASS
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass/SinglePassLoop.hlsl"
#elif LIGHTLOOP_TILED_PASS
#elif defined(LIGHTLOOP_TILE_PASS)
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePassLoop.hlsl"
#endif

9
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Resources/Deferred.shader


Shader "Hidden/HDRenderLoop/Deferred"
{
Properties
{
// We need to be able to control the blend mode for deferred shader in case we do multiple pass
_SrcBlend("", Float) = 1
_DstBlend("", Float) = 1
}
SubShader
{

Blend Off
Blend[_SrcBlend][_DstBlend]
HLSLPROGRAM
#pragma target 5.0

// TODO: Workflow problem here, I would like to only generate variant for the LIGHTLOOP_TILE_PASS case, not the LIGHTLOOP_SINGLE_PASS case. This must be on lightloop side and include here.... (Can we codition
#pragma multi_compile LIGHTLOOP_TILE_DIRECT LIGHTLOOP_TILE_INDIRECT LIGHTLOOP_TILE_ALL
#pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
#pragma multi_compile _ ENABLE_DEBUG
//-------------------------------------------------------------------------------------
// Include

2
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/SinglePass.meta


fileFormatVersion: 2
guid: 16efe1cc514ae594993f6705dacbf97d
guid: dfb6e7f2aee22e147834de3e01b7c03c
folderAsset: yes
timeCreated: 1477266406
licenseType: Pro

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


Shader.SetGlobalVectorArray("_DirShadowSplitSpheres", lightList.directionalShadowSplitSphereSqr);
}
public void RenderDeferredLighting(Camera camera, RenderLoop renderLoop, RenderTargetIdentifier colorBuffer)
public void RenderDeferredLighting(Camera camera, RenderLoop renderLoop, RenderTargetIdentifier cameraColorBufferRT)
{
var invViewProj = Utilities.GetViewProjectionMatrix(camera).inverse;
m_DeferredMaterial.SetMatrix("_InvViewProjMatrix", invViewProj);

m_DeferredMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m_DeferredMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
cmd.Blit(null, colorBuffer, m_DeferredMaterial, 0);
cmd.Blit(null, cameraColorBufferRT, m_DeferredMaterial, 0);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}

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


SAMPLERCUBE(sampler_SkyTexture); // NOTE: Sampler could be share here with _EnvTextures. Don't know if the shader compiler will complain...
CBUFFER_START(UnityPerLightLoop)
int _DirectionalLightCount;
int _PunctualLightCount;
int _AreaLightCount;
int _EnvLightCount;
uint _DirectionalLightCount;
uint _PunctualLightCount;
uint _AreaLightCount;
uint _EnvLightCount;
EnvLightData _EnvLightSky;
float4 _ShadowMapSize;
float4 _DirShadowSplitSpheres[4]; // TODO share this max between C# and hlsl

// This code will be inlined as lightLoopContext is hardcoded in the light loop
if (lightLoopContext.sampleReflection == SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES)
{
return SAMPLE_TEXTURECUBE_ARRAY_LOD(_EnvTextures, sampler_EnvTextures, float4(texCoord, index), lod);
return SAMPLE_TEXTURECUBE_ARRAY_LOD(_EnvTextures, sampler_EnvTextures, texCoord, index, lod);
}
else // SINGLE_PASS_SAMPLE_SKY
{

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


diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
int i = 0; // Declare once to avoid the D3D11 compiler warning.
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
for (i = 0; i < _DirectionalLightCount; ++i)
{

2
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/ClusteredUtils.hlsl


float GetScaleFromBase(float base)
{
const float C = (float)(1 << g_iLog2NumClusters);
const float geomSeries = (1.0 - pow(base, C)) / (1 - base); // geometric series: sum_k=0^{C-1} base^k
const float geomSeries = (1.0 - pow(abs(base), C)) / (1 - base); // geometric series: sum_k=0^{C-1} base^k
return geomSeries / (g_fFarPlane - g_fNearPlane);
}

9
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-bigtile.compute


lightOffs = 0;
GroupMemoryBarrierWithGroupSync();
for(int i=t; i<iNrCoarseLights; i+=NR_THREADS) if(lightsListLDS[i]<g_iNrVisibLights) InterlockedAdd(lightOffs, 1);
int i;
for(i=t; i<iNrCoarseLights; i+=NR_THREADS) if(lightsListLDS[i]<g_iNrVisibLights) InterlockedAdd(lightOffs, 1);
for(int i=t; i<(iNrCoarseLights+1); i+=NR_THREADS)
for(i=t; i<(iNrCoarseLights+1); i+=NR_THREADS)
g_vLightList[MAX_NR_BIGTILE_LIGHTS_PLUSONE*offs + i] = t==0 ? iNrCoarseLights : lightsListLDS[i-1];
}

const int totNrEdgePairs = 12*nrFrustEdges;
for(int l=0; l<iNrCoarseLights; l++)
{
const int idxCoarse = lightsListLDS[l];
const uint idxCoarse = lightsListLDS[l];
[branch]if(idxCoarse<(uint) g_iNrVisibLights && g_vLightData[idxCoarse].lightType!=SPHERE_LIGHT) // don't bother doing edge tests for sphere lights since these have camera aligned bboxes.
{
SFiniteLightBound lgtDat = g_data[idxCoarse];

GroupMemoryBarrierWithGroupSync();
#endif
}
#endif
#endif

4
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild-clustered.compute


{
uint2 uPixCrd = min( uint2(viTilLL.x+(idx&0xf), viTilLL.y+(idx>>4)), uint2(iWidth-1, iHeight-1) );
#ifdef MSAA_ENABLED
for(int i=0; i<iNumSamplesMSAA; i++)
for(uint i=0; i<iNumSamplesMSAA; i++)
{
const float fDpth = FetchDepthMSAA(g_depth_tex, uPixCrd, i);
#else

void ClearAtomic(uint threadID : SV_GroupIndex, uint3 u3GroupID : SV_GroupID)
{
g_LayeredSingleIdxBuffer[0]=0;
}
}

17
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/Resources/lightlistbuild.compute


uniform int g_iNrVisibLights;
uniform int _PunctualLightCount;
uniform uint2 g_viDimensions;
uniform float4x4 g_mInvScrProjection;
uniform float4x4 g_mScrProjection;

// write lights to global buffers
int localOffs=0;
int offs = tileIDX.y*nrTilesX + tileIDX.x;
// This should thow a warning if NR_LIGHT_MODELS change
int indicesShift[NR_LIGHT_MODELS] = {0, _PunctualLightCount};
for(int m=0; m<NR_LIGHT_MODELS; m++)
{
int nrLightsFinal = ldsModelListCount[ m ];

const int nrDWords = ((nrLightsFinalClamped+1)+1)>>1;
for(int l=(int) t; l<(int) nrDWords; l += NR_THREADS)
{
uint uLow = l==0 ? nrLightsFinalClamped : prunedList[2*l-1+localOffs];
uint uHigh = prunedList[2*l+0+localOffs];
uint uLow = l==0 ? nrLightsFinalClamped : prunedList[2*l-1+localOffs] - indicesShift[m];
uint uHigh = prunedList[2*l+0+localOffs] - indicesShift[m];
g_vLightList[16*offs + l] = (uLow&0xffff) | (uHigh<<16);
}

}
}

lightOffsSph = 0;
// make a copy of coarseList in prunedList.
for(int l=threadID; l<iNrCoarseLights; l+=NR_THREADS)
int l;
for(l=threadID; l<iNrCoarseLights; l+=NR_THREADS)
prunedList[l]=coarseList[l];
#if !defined(SHADER_API_XBOXONE) && !defined(SHADER_API_PSSL)

float onePixDiagDist = GetOnePixDiagWorldDistAtDepthOne();
float halfTileSizeAtZDistOne = 8*onePixDiagDist; // scale by half a tile
for(int l=threadID; l<iNrCoarseLights; l+=NR_THREADS)
for(l=threadID; l<iNrCoarseLights; l+=NR_THREADS)
{
SFiniteLightBound lightData = g_data[coarseList[l]];

if(uIndex<MAX_NR_COARSE_ENTRIES) prunedList[uIndex] = coarseList[t]; // we allow up to 64 pruned lights while stored in LDS.
}
}
#endif
#endif

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


}
[GenerateHLSL]
public enum DebugViewTilesFlags
{
DirectLighting = 1,
Reflection = 2
};
[GenerateHLSL]
public struct SFiniteLightBound
{
public Vector3 boxAxisX;

private static int s_GenListPerBigTileKernel;
// clustered light list specific buffers and data begin
public DebugViewTilesFlags debugViewTilesFlags = 0;
public bool enableBigTilePrepass = false; // SebL - TODO: I get a crash when enabling this
public bool enableBigTilePrepass = true;
public bool enableDrawTileDebug = false;
public bool enableDirectIndirectSinglePass = false;
public bool enableComputeLightEvaluation = false;
const bool k_UseDepthBuffer = true; // only has an impact when EnableClustered is true (requires a depth-prepass)
const bool k_UseAsyncCompute = true; // should not use on mobile

static ComputeBuffer s_PunctualShadowList;
static ComputeBuffer s_DirectionalShadowList;
Material m_DeferredMaterial;
Material m_DeferredReflectionMaterial;
Material m_DeferredDirectMaterial;
Material m_DeferredIndirectMaterial;
Material m_DeferredAllMaterial;
Material m_DebugViewTilesMaterial;
const int k_TileSize = 16;

int GetNumTileY(Camera camera)
{
return (camera.pixelWidth + (k_TileSize - 1)) / k_TileSize;
return (camera.pixelHeight + (k_TileSize - 1)) / k_TileSize;
}
// Local function

buildPerBigTileLightListShader.SetBuffer(s_GenListPerBigTileKernel, "g_data", s_ConvexBoundsBuffer);
}
s_LightList = null;
m_boundData = new SFiniteLightBound[MaxNumLights];
m_lightData = new SFiniteLightData[MaxNumLights];
m_lightCount = 0;

s_EnvLightList = new ComputeBuffer(HDRenderLoop.k_MaxEnvLightsOnSCreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
s_PunctualShadowList = new ComputeBuffer(HDRenderLoop.k_MaxShadowOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(PunctualShadowData)));
m_DeferredMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/Deferred");
m_DeferredMaterial.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredMaterial.EnableKeyword("LIGHTLOOP_TILE_DIRECT");
m_DeferredReflectionMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/Deferred");
m_DeferredReflectionMaterial.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredReflectionMaterial.EnableKeyword("LIGHTLOOP_TILE_INDIRECT");
m_DeferredDirectMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/Deferred");
m_DeferredDirectMaterial.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredDirectMaterial.EnableKeyword("LIGHTLOOP_TILE_DIRECT");
m_DeferredDirectMaterial.DisableKeyword("LIGHTLOOP_TILE_INDIRECT");
m_DeferredDirectMaterial.DisableKeyword("LIGHTLOOP_TILE_ALL");
m_DeferredIndirectMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/Deferred");
m_DeferredIndirectMaterial.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredIndirectMaterial.DisableKeyword("LIGHTLOOP_TILE_DIRECT");
m_DeferredIndirectMaterial.EnableKeyword("LIGHTLOOP_TILE_INDIRECT");
m_DeferredIndirectMaterial.DisableKeyword("LIGHTLOOP_TILE_ALL");
m_DeferredAllMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/Deferred");
m_DeferredAllMaterial.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredAllMaterial.DisableKeyword("LIGHTLOOP_TILE_DIRECT");
m_DeferredAllMaterial.DisableKeyword("LIGHTLOOP_TILE_INDIRECT");
m_DeferredAllMaterial.EnableKeyword("LIGHTLOOP_TILE_ALL");
m_DebugViewTilesMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/DebugViewTiles");
}
public void OnDisable()

s_PunctualShadowList.Release();
s_PunctualShadowList = null;
Utilities.Destroy(m_DeferredMaterial);
Utilities.Destroy(m_DeferredReflectionMaterial);
Utilities.Destroy(m_DeferredDirectMaterial);
Utilities.Destroy(m_DeferredIndirectMaterial);
Utilities.Destroy(m_DeferredAllMaterial);
Utilities.Destroy(m_DebugViewTilesMaterial);
}
public bool NeedResize()

lightData.boxInnerDist = e;
lightData.boxInvRange.Set(1.0f / delta.x, 1.0f / delta.y, 1.0f / delta.z);
lightData.lightType = (uint)LightDefinitions.BOX_LIGHT;
lightData.lightModel = (uint)LightDefinitions.REFLECTION_LIGHT;
m_lightData[index] = lightData;
}
// Sanity check

m_lightCount = lightList.punctualLights.Count + lightList.envLights.Count;
s_ConvexBoundsBuffer.SetData(m_boundData); // TODO: check with Vlad what is happening here, do we copy 1024 element always ? Could we setup the size we want to copy ?
s_LightDataBuffer.SetData(m_lightData);
void VoxelLightListGeneration(CommandBuffer cmd, Camera camera, Matrix4x4 projscr, Matrix4x4 invProjscr, int cameraDepthBuffer)
void VoxelLightListGeneration(CommandBuffer cmd, Camera camera, Matrix4x4 projscr, Matrix4x4 invProjscr, RenderTargetIdentifier cameraDepthBufferRT)
{
// clear atomic offset index
cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_ClearVoxelAtomicKernel, "g_LayeredSingleIdxBuffer", s_GlobalLightListAtomic);

cmd.SetComputeFloatParam(buildPerVoxelLightListShader, "g_fClustScale", m_ClustScale);
cmd.SetComputeFloatParam(buildPerVoxelLightListShader, "g_fClustBase", k_ClustLogBase);
cmd.SetComputeTextureParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_depth_tex", new RenderTargetIdentifier(cameraDepthBuffer));
cmd.SetComputeTextureParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_depth_tex", cameraDepthBufferRT);
if (enableBigTilePrepass) cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_vBigTileLightList", s_BigTileLightList);
if (enableBigTilePrepass)
cmd.SetComputeBufferParam(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, "g_vBigTileLightList", s_BigTileLightList);
if (k_UseDepthBuffer)
{

cmd.DispatchCompute(buildPerVoxelLightListShader, s_GenListPerVoxelKernel, numTilesX, numTilesY, 1);
}
public void BuildGPULightLists(Camera camera, RenderLoop loop, HDRenderLoop.LightList lightList, int cameraDepthBuffer)
public void BuildGPULightLists(Camera camera, RenderLoop loop, HDRenderLoop.LightList lightList, RenderTargetIdentifier cameraDepthBufferRT)
{
var w = camera.pixelWidth;
var h = camera.pixelHeight;

{
cmd.SetComputeIntParams(buildPerTileLightListShader, "g_viDimensions", new int[2] { w, h });
cmd.SetComputeIntParam(buildPerTileLightListShader, "g_iNrVisibLights", m_lightCount);
cmd.SetComputeIntParam(buildPerTileLightListShader, "_PunctualLightCount", lightList.punctualLights.Count);
cmd.SetComputeTextureParam(buildPerTileLightListShader, s_GenListPerTileKernel, "g_depth_tex", new RenderTargetIdentifier(cameraDepthBuffer));
cmd.SetComputeTextureParam(buildPerTileLightListShader, s_GenListPerTileKernel, "g_depth_tex", cameraDepthBufferRT);
if (enableBigTilePrepass) cmd.SetComputeBufferParam(buildPerTileLightListShader, s_GenListPerTileKernel, "g_vBigTileLightList", s_BigTileLightList);
if (enableBigTilePrepass)
cmd.SetComputeBufferParam(buildPerTileLightListShader, s_GenListPerTileKernel, "g_vBigTileLightList", s_BigTileLightList);
VoxelLightListGeneration(cmd, camera, projscr, invProjscr, cameraDepthBuffer);
VoxelLightListGeneration(cmd, camera, projscr, invProjscr, cameraDepthBufferRT);
}
loop.ExecuteCommandBuffer(cmd);

cmd.Dispose();
}
public void RenderDeferredLighting(Camera camera, RenderLoop renderLoop, RenderTargetIdentifier colorBuffer)
public void RenderDeferredLighting(Camera camera, RenderLoop renderLoop, RenderTargetIdentifier cameraColorBufferRT)
var cmd = new CommandBuffer();
var invViewProj = Utilities.GetViewProjectionMatrix(camera).inverse;
var screenSize = Utilities.ComputeScreenSize(camera);
m_DeferredMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DeferredReflectionMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
if (enableDrawTileDebug)
m_DeferredMaterial.EnableKeyword("ENABLE_DEBUG");
else
m_DeferredMaterial.DisableKeyword("ENABLE_DEBUG");
m_DeferredDirectMaterial.SetMatrix("_InvViewProjMatrix", invViewProj);
m_DeferredDirectMaterial.SetVector("_ScreenSize", screenSize);
m_DeferredDirectMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m_DeferredDirectMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
m_DeferredDirectMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DeferredDirectMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DeferredIndirectMaterial.SetMatrix("_InvViewProjMatrix", invViewProj);
m_DeferredIndirectMaterial.SetVector("_ScreenSize", screenSize);
m_DeferredIndirectMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m_DeferredIndirectMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); // Additive
m_DeferredIndirectMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DeferredIndirectMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DeferredAllMaterial.SetMatrix("_InvViewProjMatrix", invViewProj);
m_DeferredAllMaterial.SetVector("_ScreenSize", screenSize);
m_DeferredAllMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m_DeferredAllMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
m_DeferredAllMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DeferredAllMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DebugViewTilesMaterial.SetVector("_ScreenSize", screenSize);
m_DebugViewTilesMaterial.SetInt("_ViewTilesFlags", (int)debugViewTilesFlags);
var cmd = new CommandBuffer();
cmd.SetGlobalBuffer("g_vLightListGlobal", bUseClusteredForDeferred ? s_PerVoxelLightLists : s_LightList); // opaques list (unless MSAA possibly)
// In case of bUseClusteredForDeferred disable toggle option since we're using m_perVoxelLightLists as opposed to lightList

}
else
{*/
cmd.Blit(0, colorBuffer, m_DeferredMaterial, 0);
cmd.Blit(0, colorBuffer, m_DeferredReflectionMaterial, 0);
if (enableDirectIndirectSinglePass)
{
cmd.Blit(null, cameraColorBufferRT, m_DeferredAllMaterial, 0);
}
else
{
cmd.Blit(null, cameraColorBufferRT, m_DeferredDirectMaterial, 0);
cmd.Blit(null, cameraColorBufferRT, m_DeferredIndirectMaterial, 0);
}
if(debugViewTilesFlags != 0)
{
cmd.Blit(null, cameraColorBufferRT, m_DebugViewTilesMaterial, 0);
}
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();

6
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.cs.hlsl


#define DIRECT_LIGHT (0)
#define REFLECTION_LIGHT (1)
//
// UnityEngine.Experimental.ScriptableRenderLoop.TilePass.DebugViewTilesFlags: static fields
//
#define DEBUGVIEWTILESFLAGS_DIRECT_LIGHTING (1)
#define DEBUGVIEWTILESFLAGS_REFLECTION (2)
// Generated from UnityEngine.Experimental.ScriptableRenderLoop.TilePass.SFiniteLightBound
// PackingRules = Exact
struct SFiniteLightBound

3
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePass.hlsl


#define PROCESS_ENV_LIGHT
#endif
#include "TilePass.cs.hlsl"
Buffer<uint> g_vLightListGlobal;
#define TILE_SIZE 16 // This is fixed
#define DWORD_PER_TILE 16 // See dwordsPerTile in TilePass.cs, we have roomm for 31 lights and a number of light value all store on 16 bit (ushort)

17
Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePassLoop.hlsl


const int tileOffset = GetTileOffset(coord, lightCategory);
// The first entry inside a tile is the number of light for lightCategory (thus the +0)
lightCount = g_vLightListGlobal[DWORD_PER_TILE * tileOffs + 0] & 0xffff;
lightCount = g_vLightListGlobal[DWORD_PER_TILE * tileOffset + 0] & 0xffff;
start = tileOffset;
}

uint FetchIndex(uint tileOffset, uint lightIndex)
{
return FetchIndexOpaque(tileOffs, lightIndex);
return FetchIndexOpaque(tileOffset, lightIndex);
}
#else

diffuseLighting = float3(0.0, 0.0, 0.0);
specularLighting = float3(0.0, 0.0, 0.0);
int i = 0; // Declare once to avoid the D3D11 compiler warning.
uint i = 0; // Declare once to avoid the D3D11 compiler warning.
#ifdef PROCESS_DIRECTIONAL_LIGHT
for (i = 0; i < _DirectionalLightCount; ++i)

iblDiffuseLighting = lerp(iblDiffuseLighting, localDiffuseLighting, weight.x); // Should be remove by the compiler if it is smart as all is constant 0
iblSpecularLighting = lerp(iblSpecularLighting, localSpecularLighting, weight.y);
}
diffuseLighting += iblDiffuseLighting;
specularLighting += iblSpecularLighting;
// TODO
#if ENABLE_DEBUG
// c = OverlayHeatMap(pixCoord & 15, numLightsProcessed, c);
// Currently do lightmap with indirect specula
// TODO: test what is the most appropriate here...
#ifdef PROCESS_ENV_LIGHT
// Add indirect diffuse + emissive (if any)
diffuseLighting += bakeDiffuseLighting;
#endif
}

2
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Builtin.meta


fileFormatVersion: 2
guid: af4ee1f6f88b039449ba02003b0f332d
guid: d67cc60b4fdba994cb837067ccdc352a
folderAsset: yes
timeCreated: 1476653183
licenseType: Pro

2
Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit.meta


fileFormatVersion: 2
guid: cebd0ba54432759488065d1592e05692
guid: d43c06a2afd9f2f4ab88a7a94c43e1a6
folderAsset: yes
timeCreated: 1476653183
licenseType: Pro

2
Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/Editor/LayeredLitUI.cs


using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor
namespace UnityEditor.Experimental.ScriptableRenderLoop
{
internal class LayeredLitGUI : LitGUI
{

2
Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/LayeredLit.shader


}
}
CustomEditor "LayeredLitGUI"
CustomEditor "Experimental.ScriptableRenderLoop.LayeredLitGUI"
}

331
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/LitUI.cs


using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor
namespace UnityEditor.Experimental.ScriptableRenderLoop
public abstract class BaseLitGUI : ShaderGUI
{
protected static class Styles
{
public static string OptionText = "Options";
public static string SurfaceTypeText = "Surface Type";
public static string BlendModeText = "Blend Mode";
public static string detailText = "Inputs Detail";
public static string lightingText = "Inputs Lighting";
public static GUIContent alphaCutoffEnableText = new GUIContent("Alpha Cutoff Enable", "Threshold for alpha cutoff");
public static GUIContent alphaCutoffText = new GUIContent("Alpha Cutoff", "Threshold for alpha cutoff");
public static GUIContent doubleSidedModeText = new GUIContent("Double Sided", "This will render the two face of the objects (disable backface culling)");
public static readonly string[] surfaceTypeNames = Enum.GetNames(typeof(SurfaceType));
public static readonly string[] blendModeNames = Enum.GetNames(typeof(BlendMode));
public static string InputsOptionsText = "Inputs options";
public static GUIContent smoothnessMapChannelText = new GUIContent("Smoothness Source", "Smoothness texture and channel");
public static GUIContent UVBaseMappingText = new GUIContent("UV set for Base", "");
public static GUIContent texWorldScaleText = new GUIContent("Scale to apply on world coordinate in case of Planar/Triplanar", "");
public static GUIContent UVBaseDetailMappingText = new GUIContent("UV set for Base and Detail", "");
public static GUIContent normalMapSpaceText = new GUIContent("Normal/Tangent Map space", "");
public static GUIContent heightMapModeText = new GUIContent("Height Map Mode", "");
public static GUIContent detailMapModeText = new GUIContent("Detail Map with Normal", "Detail Map with AO / Height");
public static GUIContent UVDetailMappingText = new GUIContent("UV set for Detail", "");
public static GUIContent emissiveColorModeText = new GUIContent("Emissive Color Usage", "Use emissive color or emissive mask");
public static string InputsText = "Inputs";
public static string InputsMapText = "";
public static GUIContent baseColorText = new GUIContent("Base Color + Opacity", "Albedo (RGB) and Opacity (A)");
public static GUIContent baseColorSmoothnessText = new GUIContent("Base Color + Smoothness", "Albedo (RGB) and Smoothness (A)");
public static GUIContent metallicText = new GUIContent("Metallic", "Metallic scale factor");
public static GUIContent smoothnessText = new GUIContent("Smoothness", "Smoothness scale factor");
public static GUIContent maskMapESText = new GUIContent("Mask Map - M(R), AO(G), E(B), S(A)", "Mask map");
public static GUIContent maskMapEText = new GUIContent("Mask Map - M(R), AO(G), E(B)", "Mask map");
public static GUIContent maskMapText = new GUIContent("Mask Map - M(R), AO(G)", "Mask map");
public static GUIContent maskMapSText = new GUIContent("Mask Map - M(R), AO(G), S(A)", "Mask map");
public static GUIContent specularOcclusionMapText = new GUIContent("Specular Occlusion Map (RGBA)", "Specular Occlusion Map");
public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map (DXT5) - Need to implement BC5");
public static GUIContent heightMapText = new GUIContent("Height Map (R)", "Height Map");
public static GUIContent tangentMapText = new GUIContent("Tangent Map", "Tangent Map (BC5) - DXT5 for test");
public static GUIContent anisotropyText = new GUIContent("Anisotropy", "Anisotropy scale factor");
public static GUIContent anisotropyMapText = new GUIContent("Anisotropy Map (G)", "Anisotropy");
public static GUIContent detailMapNormalText = new GUIContent("Detail Map A(R) Ny(G) S(B) Nx(A)", "Detail Map");
public static GUIContent detailMapAOHeightText = new GUIContent("Detail Map A(R) AO(G) S(B) H(A)", "Detail Map");
public static GUIContent detailMaskText = new GUIContent("Detail Mask (B)", "Mask for detailMap");
public static GUIContent detailAlbedoScaleText = new GUIContent("Detail AlbedoScale", "Detail Albedo Scale factor");
public static GUIContent detailNormalScaleText = new GUIContent("Detail NormalScale", "Normal Scale factor");
public static GUIContent detailSmoothnessScaleText = new GUIContent("Detail SmoothnessScale", "Smoothness Scale factor");
public static GUIContent detailHeightScaleText = new GUIContent("Detail HeightScale", "Height Scale factor");
public static GUIContent detailAOScaleText = new GUIContent("Detail AOScale", "AO Scale factor");
public static GUIContent emissiveText = new GUIContent("Emissive Color", "Emissive");
public static GUIContent emissiveIntensityText = new GUIContent("Emissive Intensity", "Emissive");
public static GUIContent emissiveWarning = new GUIContent("Emissive value is animated but the material has not been configured to support emissive. Please make sure the material itself has some amount of emissive.");
public static GUIContent emissiveColorWarning = new GUIContent("Ensure emissive color is non-black for emission to have effect.");
}
public enum SurfaceType
{
Opaque,
Transparent
}
public enum BlendMode
{
Lerp,
Add,
SoftAdd,
Multiply,
Premultiply
}
public enum DoubleSidedMode
{
None,
DoubleSided,
DoubleSidedLightingFlip,
DoubleSidedLightingMirror,
}
void SurfaceTypePopup()
{
EditorGUI.showMixedValue = surfaceType.hasMixedValue;
var mode = (SurfaceType)surfaceType.floatValue;
EditorGUI.BeginChangeCheck();
mode = (SurfaceType)EditorGUILayout.Popup(Styles.SurfaceTypeText, (int)mode, Styles.surfaceTypeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Surface Type");
surfaceType.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
}
protected void ShaderOptionsGUI()
{
EditorGUI.indentLevel++;
GUILayout.Label(Styles.OptionText, EditorStyles.boldLabel);
SurfaceTypePopup();
if ((SurfaceType)surfaceType.floatValue == SurfaceType.Transparent)
{
BlendModePopup();
}
m_MaterialEditor.ShaderProperty(alphaCutoffEnable, Styles.alphaCutoffEnableText.text);
if (alphaCutoffEnable.floatValue == 1.0)
{
m_MaterialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoffText.text);
}
m_MaterialEditor.ShaderProperty(doubleSidedMode, Styles.doubleSidedModeText.text);
EditorGUI.indentLevel--;
}
private void BlendModePopup()
{
EditorGUI.showMixedValue = blendMode.hasMixedValue;
var mode = (BlendMode)blendMode.floatValue;
EditorGUI.BeginChangeCheck();
mode = (BlendMode)EditorGUILayout.Popup(Styles.BlendModeText, (int)mode, Styles.blendModeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Blend Mode");
blendMode.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
}
protected void FindOptionProperties(MaterialProperty[] props)
{
surfaceType = FindProperty(kSurfaceType, props);
blendMode = FindProperty(kBlendMode, props);
alphaCutoff = FindProperty(kAlphaCutoff, props);
alphaCutoffEnable = FindProperty(kAlphaCutoffEnabled, props);
doubleSidedMode = FindProperty(kDoubleSidedMode, props);
FindInputOptionProperties(props);
}
protected void SetupMaterial(Material material)
{
bool alphaTestEnable = material.GetFloat(kAlphaCutoffEnabled) == 1.0;
SurfaceType surfaceType = (SurfaceType)material.GetFloat(kSurfaceType);
BlendMode blendMode = (BlendMode)material.GetFloat(kBlendMode);
DoubleSidedMode doubleSidedMode = (DoubleSidedMode)material.GetFloat(kDoubleSidedMode);
if (surfaceType == SurfaceType.Opaque)
{
material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : "");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.renderQueue = alphaTestEnable ? (int)UnityEngine.Rendering.RenderQueue.AlphaTest : -1;
}
else
{
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_ZWrite", 0);
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
switch (blendMode)
{
case BlendMode.Lerp:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
break;
case BlendMode.Add:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
break;
case BlendMode.SoftAdd:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusDstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
break;
case BlendMode.Multiply:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
break;
case BlendMode.Premultiply:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
break;
}
}
if (doubleSidedMode == DoubleSidedMode.None)
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Back);
}
else
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Off);
}
if (doubleSidedMode == DoubleSidedMode.DoubleSidedLightingFlip)
{
material.EnableKeyword("_DOUBLESIDED_LIGHTING_FLIP");
material.DisableKeyword("_DOUBLESIDED_LIGHTING_MIRROR");
}
else if (doubleSidedMode == DoubleSidedMode.DoubleSidedLightingMirror)
{
material.DisableKeyword("_DOUBLESIDED_LIGHTING_FLIP");
material.EnableKeyword("_DOUBLESIDED_LIGHTING_MIRROR");
}
else
{
material.DisableKeyword("_DOUBLESIDED_LIGHTING_FLIP");
material.DisableKeyword("_DOUBLESIDED_LIGHTING_MIRROR");
}
SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable);
SetupInputMaterial(material);
}
protected void SetKeyword(Material m, string keyword, bool state)
{
if (state)
m.EnableKeyword(keyword);
else
m.DisableKeyword(keyword);
}
public void ShaderPropertiesGUI(Material material)
{
// Use default labelWidth
EditorGUIUtility.labelWidth = 0f;
// Detect any changes to the material
EditorGUI.BeginChangeCheck();
{
ShaderOptionsGUI();
EditorGUILayout.Space();
ShaderInputOptionsGUI();
EditorGUILayout.Space();
ShaderInputGUI();
}
if (EditorGUI.EndChangeCheck())
{
foreach (var obj in m_MaterialEditor.targets)
SetupMaterial((Material)obj);
}
}
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
{
FindOptionProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
FindInputProperties(props);
m_MaterialEditor = materialEditor;
Material material = materialEditor.target as Material;
ShaderPropertiesGUI(material);
}
protected MaterialEditor m_MaterialEditor;
MaterialProperty surfaceType = null;
MaterialProperty alphaCutoffEnable = null;
MaterialProperty blendMode = null;
MaterialProperty alphaCutoff = null;
MaterialProperty doubleSidedMode = null;
const string kSurfaceType = "_SurfaceType";
const string kBlendMode = "_BlendMode";
const string kAlphaCutoff = "_AlphaCutoff";
const string kAlphaCutoffEnabled = "_AlphaCutoffEnable";
const string kDoubleSidedMode = "_DoubleSidedMode";
protected static string[] reservedProperties = new string[] { kSurfaceType, kBlendMode, kAlphaCutoff, kAlphaCutoffEnabled, kDoubleSidedMode };
protected abstract void FindInputProperties(MaterialProperty[] props);
protected abstract void ShaderInputGUI();
protected abstract void ShaderInputOptionsGUI();
protected abstract void FindInputOptionProperties(MaterialProperty[] props);
protected abstract void SetupInputMaterial(Material material);
}
class LitGUI : BaseLitGUI
{
public enum SmoothnessMapChannel

SetKeyword(material, "_DETAIL_MAP", material.GetTexture(kDetailMap));
}
public static bool ShouldEmissionBeEnabled(Material mat)
protected override bool ShouldEmissionBeEnabled(Material mat)
{
float emissiveIntensity = mat.GetFloat(kEmissiveIntensity);
var realtimeEmission = (mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.RealtimeEmissive) > 0;

protected virtual void SetupEmissionGIFlags(Material material)
{
// Setup lightmap emissive flags
MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags;
if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0)
{
if (ShouldEmissionBeEnabled(material))
flags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
else
flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack;
material.globalIlluminationFlags = flags;
}
}
override protected void SetupInputMaterial(Material material)
{
// Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation

SetKeyword(material, "_EMISSIVE_COLOR", ((EmissiveColorMode)material.GetFloat(kEmissiveColorMode)) == EmissiveColorMode.UseEmissiveColor);
SetupKeywordsForInputMaps(material);
SetupEmissionGIFlags(material);
}
// TODO: ? or remove
bool HasValidEmissiveKeyword(Material material)
{
/*
// Material animation might be out of sync with the material keyword.
// So if the emission support is disabled on the material, but the property blocks have a value that requires it, then we need to show a warning.
// (note: (Renderer MaterialPropertyBlock applies its values to emissionColorForRendering))
bool hasEmissionKeyword = material.IsKeywordEnabled ("_EMISSION");
if (!hasEmissionKeyword && ShouldEmissionBeEnabled (material, emissionColorForRendering.colorValue))
return false;
else
return true;
*/
return true;
}
}
} // namespace UnityEditor

3
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.shader


#define SHADERPASS SHADERPASS_FORWARD
// TEMP until pragma work in include
// #include "../../Lighting/Forward.hlsl"
// LIGHTLOOP_TILE_PASS
#pragma multi_compile LIGHTLOOP_SINGLE_PASS
//#pragma multi_compile SHADOWFILTERING_FIXED_SIZE_PCF

}
}
CustomEditor "LitGUI"
CustomEditor "Experimental.ScriptableRenderLoop.LitGUI"
}

2
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit.meta


fileFormatVersion: 2
guid: 355ba1f7a06cc7a4abe51689715bb1e7
guid: 5ebb7166783e16a42807309c93c63fad
folderAsset: yes
timeCreated: 1476653182
licenseType: Pro

278
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Editor/UnlitUI.cs


using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor
namespace UnityEditor.Experimental.ScriptableRenderLoop
internal class UnlitGUI : ShaderGUI
class UnlitGUI : BaseUnlitGUI
public enum SurfaceType
{
Opaque,
Transparent
}
public enum BlendMode
{
Lerp,
Add,
SoftAdd,
Multiply,
Premultiply
}
public enum DoubleSidedMode
{
None,
DoubleSided
}
private static class Styles
{
public static string OptionText = "Options";
public static string SurfaceTypeText = "Surface Type";
public static string BlendModeText = "Blend Mode";
public static GUIContent alphaCutoffEnableText = new GUIContent("Alpha Cutoff Enable", "Threshold for alpha cutoff");
public static GUIContent alphaCutoffText = new GUIContent("Alpha Cutoff", "Threshold for alpha cutoff");
public static GUIContent doubleSidedModeText = new GUIContent("Double Sided", "This will render the two face of the objects (disable backface culling)");
public static readonly string[] surfaceTypeNames = Enum.GetNames(typeof(SurfaceType));
public static readonly string[] blendModeNames = Enum.GetNames(typeof(BlendMode));
public static string InputsOptionsText = "Inputs options";
public static string InputsText = "Inputs";
public static string InputsMapText = "";
public static GUIContent colorText = new GUIContent("Color + Opacity", "Albedo (RGB) and Opacity (A)");
public static GUIContent emissiveText = new GUIContent("Emissive Color", "Emissive");
public static GUIContent emissiveIntensityText = new GUIContent("Emissive Intensity", "Emissive");
}
MaterialProperty surfaceType = null;
MaterialProperty blendMode = null;
MaterialProperty alphaCutoff = null;
MaterialProperty alphaCutoffEnable = null;
MaterialProperty doubleSidedMode = null;
protected MaterialEditor m_MaterialEditor;
protected const string kSurfaceType = "_SurfaceType";
protected const string kBlendMode = "_BlendMode";
protected const string kAlphaCutoff = "_AlphaCutoff";
protected const string kAlphaCutoffEnabled = "_AlphaCutoffEnable";
protected const string kDoubleSidedMode = "_DoubleSidedMode";
public void FindOptionProperties(MaterialProperty[] props)
{
surfaceType = FindProperty(kSurfaceType, props);
blendMode = FindProperty(kBlendMode, props);
alphaCutoff = FindProperty(kAlphaCutoff, props);
alphaCutoffEnable = FindProperty(kAlphaCutoffEnabled, props);
doubleSidedMode = FindProperty(kDoubleSidedMode, props);
}
protected const string kEmissiveIntensity = "_EmissiveIntensity";
public void FindInputProperties(MaterialProperty[] props)
override protected void FindInputProperties(MaterialProperty[] props)
{
color = FindProperty("_Color", props);
colorMap = FindProperty("_ColorMap", props);

}
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
{
FindOptionProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
FindInputProperties(props);
m_MaterialEditor = materialEditor;
Material material = materialEditor.target as Material;
ShaderPropertiesGUI(material);
}
protected void ShaderOptionsGUI()
{
EditorGUI.indentLevel++;
GUILayout.Label(Styles.OptionText, EditorStyles.boldLabel);
SurfaceTypePopup();
if ((SurfaceType)surfaceType.floatValue == SurfaceType.Transparent)
{
BlendModePopup();
}
m_MaterialEditor.ShaderProperty(alphaCutoffEnable, Styles.alphaCutoffEnableText.text);
if (alphaCutoffEnable.floatValue == 1.0)
{
m_MaterialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoffText.text);
}
m_MaterialEditor.ShaderProperty(doubleSidedMode, Styles.doubleSidedModeText.text);
EditorGUI.indentLevel--;
}
protected void ShaderInputOptionsGUI()
{
EditorGUI.indentLevel++;
EditorGUI.indentLevel--;
}
protected void ShaderInputGUI()
override protected void ShaderInputGUI()
{
EditorGUI.indentLevel++;

EditorGUI.indentLevel--;
}
public void ShaderPropertiesGUI(Material material)
{
// Use default labelWidth
EditorGUIUtility.labelWidth = 0f;
// Detect any changes to the material
EditorGUI.BeginChangeCheck();
{
ShaderOptionsGUI();
EditorGUILayout.Space();
ShaderInputOptionsGUI();
EditorGUILayout.Space();
ShaderInputGUI();
}
if (EditorGUI.EndChangeCheck())
{
foreach (var obj in m_MaterialEditor.targets)
SetupMaterial((Material)obj);
}
}
// TODO: try to setup minimun value to fall back to standard shaders and reverse
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
override protected void ShaderInputOptionsGUI()
base.AssignNewShaderToMaterial(material, oldShader, newShader);
void SurfaceTypePopup()
protected override void FindInputOptionProperties(MaterialProperty[] props)
EditorGUI.showMixedValue = surfaceType.hasMixedValue;
var mode = (SurfaceType)surfaceType.floatValue;
EditorGUI.BeginChangeCheck();
mode = (SurfaceType)EditorGUILayout.Popup(Styles.SurfaceTypeText, (int)mode, Styles.surfaceTypeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Surface Type");
surfaceType.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
void BlendModePopup()
{
EditorGUI.showMixedValue = blendMode.hasMixedValue;
var mode = (BlendMode)blendMode.floatValue;
EditorGUI.BeginChangeCheck();
mode = (BlendMode)EditorGUILayout.Popup(Styles.BlendModeText, (int)mode, Styles.blendModeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Blend Mode");
blendMode.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
}
protected virtual void SetupKeywordsForInputMaps(Material material)
protected override void SetupInputMaterial(Material material)
protected void SetupMaterial(Material material)
protected override bool ShouldEmissionBeEnabled(Material mat)
// Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
// (MaterialProperty value might come from renderer material property block)
bool alphaTestEnable = material.GetFloat(kAlphaCutoffEnabled) == 1.0;
SurfaceType surfaceType = (SurfaceType)material.GetFloat(kSurfaceType);
BlendMode blendMode = (BlendMode)material.GetFloat(kBlendMode);
DoubleSidedMode doubleSidedMode = (DoubleSidedMode)material.GetFloat(kDoubleSidedMode);
if (surfaceType == SurfaceType.Opaque)
{
material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : "");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.renderQueue = alphaTestEnable ? (int)UnityEngine.Rendering.RenderQueue.AlphaTest : -1;
}
else
{
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_ZWrite", 0);
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
switch (blendMode)
{
case BlendMode.Lerp:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
break;
case BlendMode.Add:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
break;
case BlendMode.SoftAdd:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusDstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
break;
case BlendMode.Multiply:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
break;
case BlendMode.Premultiply:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
break;
}
}
if (doubleSidedMode == DoubleSidedMode.None)
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Back);
}
else
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Off);
}
SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable);
SetupKeywordsForInputMaps(material);
// Setup lightmap emissive flags
MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags;
if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0)
{
if (LitGUI.ShouldEmissionBeEnabled(material))
flags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
else
flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack;
material.globalIlluminationFlags = flags;
}
float emissiveIntensity = mat.GetFloat(kEmissiveIntensity);
var realtimeEmission = (mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.RealtimeEmissive) > 0;
return emissiveIntensity > 0.0f || realtimeEmission;
bool HasValidEmissiveKeyword(Material material)
{
/*
// Material animation might be out of sync with the material keyword.
// So if the emission support is disabled on the material, but the property blocks have a value that requires it, then we need to show a warning.
// (note: (Renderer MaterialPropertyBlock applies its values to emissionColorForRendering))
bool hasEmissionKeyword = material.IsKeywordEnabled ("_EMISSION");
if (!hasEmissionKeyword && ShouldEmissionBeEnabled (material, emissionColorForRendering.colorValue))
return false;
else
return true;
*/
return true;
}
}
protected void SetKeyword(Material m, string keyword, bool state)
{
if (state)
m.EnableKeyword(keyword);
else
m.DisableKeyword(keyword);
}
}
} // namespace UnityEditor

2
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Unlit.shader


}
}
CustomEditor "UnlitGUI"
CustomEditor "Experimental.ScriptableRenderLoop.UnlitGUI"
}

2
Assets/ScriptableRenderLoop/HDRenderLoop/PostProcess.meta


fileFormatVersion: 2
guid: 8a352e0cb2a42fd4ba968b628ec4bc10
guid: 838933a8561a8704e9d537270132e500
folderAsset: yes
timeCreated: 1474641822
licenseType: Pro

2
Assets/ScriptableRenderLoop/HDRenderLoop/ShaderPass.meta


fileFormatVersion: 2
guid: 86e1905991f44ab49baa68fc4d0570e4
guid: e3b3ad4462341ec4b86566ec1fd82c7c
folderAsset: yes
timeCreated: 1476885561
licenseType: Pro

2
Assets/ScriptableRenderLoop/HDRenderLoop/Shadow.meta


fileFormatVersion: 2
guid: 90ecdcec65552154d89b8e03c90039d4
guid: 74dbe7f252951f340bb1038a738db89e
folderAsset: yes
timeCreated: 1477395055
licenseType: Pro

2
Assets/ScriptableRenderLoop/HDRenderLoop/Shadow/FixedSizePCF.meta


fileFormatVersion: 2
guid: bf62af062defe384f9e1e45ef3cb4169
guid: b7ba3daf73a727d4a851bd2c904c04dd
folderAsset: yes
timeCreated: 1477395055
licenseType: Pro

53
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/SkyHDRI.shader


#pragma vertex Vert
#pragma fragment Frag
#pragma multi_compile _ ATMOSPHERICS_OCCLUSION_FULLSKY
#pragma multi_compile _ ATMOSPHERICS_DEBUG
#include "Color.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/ShaderVariables.hlsl"
#define IS_RENDERING_SKY
#include "AtmosphericScattering.hlsl"
float4 _SkyParam; // x exposure, y multiplier, z rotation
float4x4 _InvViewProjMatrix;
float4 _SkyParam; // x exposure, y multiplier, z rotation
struct Attributes
{

float3 rotDirY = float3(sinPhi, 0, cosPhi);
dir = float3(dot(rotDirX, dir), dir.y, dot(rotDirY, dir));
return ClampToFloat16Max(SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir, 0) * exp2(_SkyParam.x) * _SkyParam.y);
float3 skyDome = ClampToFloat16Max(SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, dir, 0).rgb * exp2(_SkyParam.x) * _SkyParam.y);
Coordinate coord = GetCoordinate(input.positionCS.xy, _ScreenSize.zw);
// Get the depth value of the scene, or use 0.01 otherwise.
float rawDepth = max(LOAD_TEXTURE2D(_CameraDepthTexture, coord.unPositionSS).r, 0.01);
float3 positionWS = UnprojectToWorld(rawDepth, coord.positionSS, _InvViewProjMatrix);
// Do not perform blending with the environment map if the sky is occluded.
float skyDomeWeight = (rawDepth > 0.01) ? 0.0 : 1.0;
float4 c1, c2, c3;
VolundTransferScatter(positionWS, c1, c2, c3);
float4 coord1 = float4(c1.rgb + c3.rgb, max(0.f, 1.f - c1.a - c3.a));
float3 coord2 = c2.rgb;
float sunCos = dot(normalize(dir), _SunDirection);
float miePh = MiePhase(sunCos, _MiePhaseAnisotropy);
float2 occlusion = float2(1.0, 1.0); // TODO.
float extinction = coord1.a;
float3 scatter = coord1.rgb * occlusion.x + coord2 * miePh * occlusion.y;
#ifdef ATMOSPHERICS_DEBUG
switch (_AtmosphericsDebugMode)
{
case ATMOSPHERICS_DBG_RAYLEIGH: return c1;
case ATMOSPHERICS_DBG_MIE: return c2 * miePh;
case ATMOSPHERICS_DBG_HEIGHT: return c3;
case ATMOSPHERICS_DBG_SCATTERING: return float4(scatter, 0.0);
case ATMOSPHERICS_DBG_OCCLUSION: return float4(occlusion.xy, 0.0, 0.0);
case ATMOSPHERICS_DBG_OCCLUDEDSCATTERING: return float4(scatter, 0.0);
}
#endif
// Blend with the color of the scene.
return float4(skyDome * (skyDomeWeight * extinction) + scatter, 0.0);
}
ENDHLSL

1
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs


m_RenderSkyPropertyBlock.SetTexture("_Cubemap", skyParameters.skyHDRI);
m_RenderSkyPropertyBlock.SetVector("_SkyParam", new Vector4(skyParameters.exposure, skyParameters.multiplier, skyParameters.rotation, 0.0f));
m_RenderSkyPropertyBlock.SetMatrix("_InvViewProjMatrix", Utilities.GetViewProjectionMatrix(camera).inverse);
var cmd = new CommandBuffer { name = "" };
cmd.DrawMesh(skyMesh, Matrix4x4.identity, m_SkyHDRIMaterial, 0, 0, m_RenderSkyPropertyBlock);

8
Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs


cmd.SetComputeFloatParams(shadercs, name, data);
}
public static void SetKeyword(Material m, string keyword, bool state)
{
if (state)
m.EnableKeyword(keyword);
else
m.DisableKeyword(keyword);
}
}
}

9
Assets/ScriptableRenderLoop/ScriptableRenderLoopPicker.cs


[SerializeField]
private ScriptableRenderLoop m_RenderLoop;
// TEMPORARY
public int legacyRenderLoopMaxShaderLOD = int.MaxValue;
void OnEnable()
{
RenderLoop.renderLoopDelegate += Render;

void SyncRenderingFeatures()
{
if (m_RenderLoop != null && isActiveAndEnabled)
Shader.globalMaximumLOD = int.MaxValue;
#if UNITY_EDITOR
if (m_RenderLoop != null && isActiveAndEnabled)
UnityEditor.SupportedRenderingFeatures.active = m_RenderLoop.GetSupportedRenderingFeatures();

void OnDisable()
{
RenderLoop.renderLoopDelegate -= Render;
Shader.globalMaximumLOD = legacyRenderLoopMaxShaderLOD;
#if UNITY_EDITOR
#if UNITY_EDITOR
UnityEditor.SupportedRenderingFeatures.active = UnityEditor.SupportedRenderingFeatures.Default;
#endif
}

12
Assets/ScriptableRenderLoop/ShaderLibrary/API/D3D11.hlsl


#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3((coord2).xy, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3((coord2).xy, index), lod)
#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3) textureName.Sample(samplerName, float4((coord3).xyz, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, float4((coord3).xyz, index), lod)
#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)
#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)

#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))

23
Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl


0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0 };
// Using pow often result to a warning like this
// "pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them"
// PositivePow remove this warning when you know the value is positive and avoid inf/NAN.
float PositivePow(float base, float power)
{
return pow(max(abs(base), float(FLT_EPSILON)), power);
}
float2 PositivePow(float2 base, float2 power)
{
return pow(max(abs(base), float2(FLT_EPSILON, FLT_EPSILON)), power);
}
float3 PositivePow(float3 base, float3 power)
{
return pow(max(abs(base), float3(FLT_EPSILON, FLT_EPSILON, FLT_EPSILON)), power);
}
float4 PositivePow(float4 base, float4 power)
{
return pow(max(abs(base), float4(FLT_EPSILON, FLT_EPSILON, FLT_EPSILON, FLT_EPSILON)), power);
}
// ----------------------------------------------------------------------------
// World position reconstruction / transformation
// ----------------------------------------------------------------------------

6
Assets/ScriptableRenderLoop/ShaderLibrary/CommonMaterial.hlsl


return blendWeights;
}
float LerpWhiteTo(float b, float t)
{
float oneMinusT = 1.0 - t;
return oneMinusT + b * t;
}
float3 LerpWhiteTo(float3 b, float t)
{
float oneMinusT = 1.0 - t;

39
Assets/ScriptableRenderLoop/ShaderLibrary/Debug.hlsl


return outColor;
}
bool SampleDebugFont(int2 pixCoord, uint digit)
{
if (pixCoord.x < 0 || pixCoord.y < 0 || pixCoord.x >= 5 || pixCoord.y >= 9 || digit > 9)
return false;
#define PACK_BITS25(_x0,_x1,_x2,_x3,_x4,_x5,_x6,_x7,_x8,_x9,_x10,_x11,_x12,_x13,_x14,_x15,_x16,_x17,_x18,_x19,_x20,_x21,_x22,_x23,_x24) (_x0|(_x1<<1)|(_x2<<2)|(_x3<<3)|(_x4<<4)|(_x5<<5)|(_x6<<6)|(_x7<<7)|(_x8<<8)|(_x9<<9)|(_x10<<10)|(_x11<<11)|(_x12<<12)|(_x13<<13)|(_x14<<14)|(_x15<<15)|(_x16<<16)|(_x17<<17)|(_x18<<18)|(_x19<<19)|(_x20<<20)|(_x21<<21)|(_x22<<22)|(_x23<<23)|(_x24<<24))
#define _ 0
#define x 1
uint fontData[9][2] = {
{ PACK_BITS25(_,_,x,_,_, _,_,x,_,_, _,x,x,x,_, x,x,x,x,x, _,_,_,x,_), PACK_BITS25(x,x,x,x,x, _,x,x,x,_, x,x,x,x,x, _,x,x,x,_, _,x,x,x,_) },
{ PACK_BITS25(_,x,_,x,_, _,x,x,_,_, x,_,_,_,x, _,_,_,_,x, _,_,_,x,_), PACK_BITS25(x,_,_,_,_, x,_,_,_,x, _,_,_,_,x, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, x,_,x,_,_, x,_,_,_,x, _,_,_,x,_, _,_,x,x,_), PACK_BITS25(x,_,_,_,_, x,_,_,_,_, _,_,_,x,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,_,_,x, _,_,x,_,_, _,x,_,x,_), PACK_BITS25(x,_,x,x,_, x,_,_,_,_, _,_,_,x,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,_,x,_, _,x,x,x,_, _,x,_,x,_), PACK_BITS25(x,x,_,_,x, x,x,x,x,_, _,_,x,_,_, _,x,x,x,_, _,x,x,x,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,x,_,_, _,_,_,_,x, x,_,_,x,_), PACK_BITS25(_,_,_,_,x, x,_,_,_,x, _,_,x,_,_, x,_,_,_,x, _,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,x,_,_,_, _,_,_,_,x, x,x,x,x,x), PACK_BITS25(_,_,_,_,x, x,_,_,_,x, _,x,_,_,_, x,_,_,_,x, _,_,_,_,x) },
{ PACK_BITS25(_,x,_,x,_, _,_,x,_,_, x,_,_,_,_, x,_,_,_,x, _,_,_,x,_), PACK_BITS25(x,_,_,_,x, x,_,_,_,x, _,x,_,_,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(_,_,x,_,_, x,x,x,x,x, x,x,x,x,x, _,x,x,x,_, _,_,_,x,_), PACK_BITS25(_,x,x,x,_, _,x,x,x,_, _,x,_,_,_, _,x,x,x,_, _,x,x,x,_) }
};
#undef _
#undef x
#undef PACK_BITS25
return (fontData[8 - pixCoord.y][digit >= 5] >> ((digit % 5) * 5 + pixCoord.x)) & 1;
}
bool SampleDebugFontNumber(int2 pixCoord, uint number)
{
pixCoord.y -= 4;
if (number <= 9)
{
return SampleDebugFont(pixCoord - int2(6, 0), number);
}
else
{
return (SampleDebugFont(pixCoord, number / 10) | SampleDebugFont(pixCoord - int2(6, 0), number % 10));
}
}
#endif // UNITY_DEBUG_INCLUDED

6
Assets/ScriptableRenderLoop/fptl/FptlLighting.cs


var bnds = rl.bounds;
var boxOffset = rl.center; // reflection volume offset relative to cube map capture point
var blendDistance = rl.blendDistance;
float imp = rl.importance;
//Matrix4x4 mat = rl.transform.localToWorldMatrix;
Vector3 cubeCapturePos = mat.GetColumn(3); // cube map capture position in world space
// implicit in CalculateHDRDecodeValues() --> float ints = rl.intensity;
var boxProj = (rl.boxProjection != 0);

//Vector3 C = bnds.center; // P + boxOffset;
var C = mat.MultiplyPoint(boxOffset); // same as commented out line above when rot is identity
//Vector3 posForShaderParam = bnds.center - boxOffset; // gives same as rl.GetComponent<Transform>().position;
var posForShaderParam = cubeCapturePos; // same as commented out line above when rot is identity
var combinedExtent = e + new Vector3(blendDistance, blendDistance, blendDistance);
Vector3 vx = mat.GetColumn(0);

152
Assets/ScriptableRenderLoop/fptl/LightingUtils.hlsl


//return v4Pres.z / v4Pres.w;
}
bool SampleDebugFont(int2 pixCoord, uint digit)
{
if (pixCoord.x < 0 || pixCoord.y < 0 || pixCoord.x >= 5 || pixCoord.y >= 9 || digit > 9)
return false;
#define PACK_BITS25(_x0,_x1,_x2,_x3,_x4,_x5,_x6,_x7,_x8,_x9,_x10,_x11,_x12,_x13,_x14,_x15,_x16,_x17,_x18,_x19,_x20,_x21,_x22,_x23,_x24) (_x0|(_x1<<1)|(_x2<<2)|(_x3<<3)|(_x4<<4)|(_x5<<5)|(_x6<<6)|(_x7<<7)|(_x8<<8)|(_x9<<9)|(_x10<<10)|(_x11<<11)|(_x12<<12)|(_x13<<13)|(_x14<<14)|(_x15<<15)|(_x16<<16)|(_x17<<17)|(_x18<<18)|(_x19<<19)|(_x20<<20)|(_x21<<21)|(_x22<<22)|(_x23<<23)|(_x24<<24))
#define _ 0
#define x 1
uint fontData[9][2] = {
{ PACK_BITS25(_,_,x,_,_, _,_,x,_,_, _,x,x,x,_, x,x,x,x,x, _,_,_,x,_), PACK_BITS25(x,x,x,x,x, _,x,x,x,_, x,x,x,x,x, _,x,x,x,_, _,x,x,x,_) },
{ PACK_BITS25(_,x,_,x,_, _,x,x,_,_, x,_,_,_,x, _,_,_,_,x, _,_,_,x,_), PACK_BITS25(x,_,_,_,_, x,_,_,_,x, _,_,_,_,x, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, x,_,x,_,_, x,_,_,_,x, _,_,_,x,_, _,_,x,x,_), PACK_BITS25(x,_,_,_,_, x,_,_,_,_, _,_,_,x,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,_,_,x, _,_,x,_,_, _,x,_,x,_), PACK_BITS25(x,_,x,x,_, x,_,_,_,_, _,_,_,x,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,_,x,_, _,x,x,x,_, _,x,_,x,_), PACK_BITS25(x,x,_,_,x, x,x,x,x,_, _,_,x,_,_, _,x,x,x,_, _,x,x,x,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,x,_,_, _,_,_,_,x, x,_,_,x,_), PACK_BITS25(_,_,_,_,x, x,_,_,_,x, _,_,x,_,_, x,_,_,_,x, _,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,x,_,_,_, _,_,_,_,x, x,x,x,x,x), PACK_BITS25(_,_,_,_,x, x,_,_,_,x, _,x,_,_,_, x,_,_,_,x, _,_,_,_,x) },
{ PACK_BITS25(_,x,_,x,_, _,_,x,_,_, x,_,_,_,_, x,_,_,_,x, _,_,_,x,_), PACK_BITS25(x,_,_,_,x, x,_,_,_,x, _,x,_,_,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(_,_,x,_,_, x,x,x,x,x, x,x,x,x,x, _,x,x,x,_, _,_,_,x,_), PACK_BITS25(_,x,x,x,_, _,x,x,x,_, _,x,_,_,_, _,x,x,x,_, _,x,x,x,_) }
};
#undef _
#undef x
#undef PACK_BITS25
return (fontData[8 - pixCoord.y][digit >= 5] >> ((digit % 5) * 5 + pixCoord.x)) & 1;
}
bool SampleDebugFontNumber(int2 coord, uint number)
{
coord.y -= 4;
if (number <= 9)
{
return SampleDebugFont(coord - int2(6, 0), number);
}
else
{
return (SampleDebugFont(coord, number / 10) | SampleDebugFont(coord - int2(6, 0), number % 10));
}
}
float3 OverlayHeatMap(uint2 pixCoord, uint numLights, float3 c)
{
/////////////////////////////////////////////////////////////////////
//
const float4 kRadarColors[12] =
{
float4(0.0,0.0,0.0,0.0), // black
float4(0.0,0.0,0.6,0.5), // dark blue
float4(0.0,0.0,0.9,0.5), // blue
float4(0.0,0.6,0.9,0.5), // light blue
float4(0.0,0.9,0.9,0.5), // cyan
float4(0.0,0.9,0.6,0.5), // blueish green
float4(0.0,0.9,0.0,0.5), // green
float4(0.6,0.9,0.0,0.5), // yellowish green
float4(0.9,0.9,0.0,0.5), // yellow
float4(0.9,0.6,0.0,0.5), // orange
float4(0.9,0.0,0.0,0.5), // red
float4(1.0,0.0,0.0,0.9) // strong red
};
float maxNrLightsPerTile = 31;
int nColorIndex = numLights == 0 ? 0 : (1 + (int)floor(10 * (log2((float)numLights) / log2(maxNrLightsPerTile))));
nColorIndex = nColorIndex<0 ? 0 : nColorIndex;
float4 col = nColorIndex>11 ? float4(1.0, 1.0, 1.0, 1.0) : kRadarColors[nColorIndex];
int2 coord = pixCoord - int2(1, 1);
float3 color = lerp(c, pow(col.xyz, 2.2), 0.3*col.w);
if(numLights > 0)
{
if (SampleDebugFontNumber(coord, numLights)) // Shadow
color = 0.0f;
if (SampleDebugFontNumber(coord + 1, numLights)) // Text
color = 1.0f;
}
return color;
bool SampleDebugFont(int2 pixCoord, uint digit)
{
if (pixCoord.x < 0 || pixCoord.y < 0 || pixCoord.x >= 5 || pixCoord.y >= 9 || digit > 9)
return false;
#define PACK_BITS25(_x0,_x1,_x2,_x3,_x4,_x5,_x6,_x7,_x8,_x9,_x10,_x11,_x12,_x13,_x14,_x15,_x16,_x17,_x18,_x19,_x20,_x21,_x22,_x23,_x24) (_x0|(_x1<<1)|(_x2<<2)|(_x3<<3)|(_x4<<4)|(_x5<<5)|(_x6<<6)|(_x7<<7)|(_x8<<8)|(_x9<<9)|(_x10<<10)|(_x11<<11)|(_x12<<12)|(_x13<<13)|(_x14<<14)|(_x15<<15)|(_x16<<16)|(_x17<<17)|(_x18<<18)|(_x19<<19)|(_x20<<20)|(_x21<<21)|(_x22<<22)|(_x23<<23)|(_x24<<24))
#define _ 0
#define x 1
uint fontData[9][2] = {
{ PACK_BITS25(_,_,x,_,_, _,_,x,_,_, _,x,x,x,_, x,x,x,x,x, _,_,_,x,_), PACK_BITS25(x,x,x,x,x, _,x,x,x,_, x,x,x,x,x, _,x,x,x,_, _,x,x,x,_) },
{ PACK_BITS25(_,x,_,x,_, _,x,x,_,_, x,_,_,_,x, _,_,_,_,x, _,_,_,x,_), PACK_BITS25(x,_,_,_,_, x,_,_,_,x, _,_,_,_,x, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, x,_,x,_,_, x,_,_,_,x, _,_,_,x,_, _,_,x,x,_), PACK_BITS25(x,_,_,_,_, x,_,_,_,_, _,_,_,x,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,_,_,x, _,_,x,_,_, _,x,_,x,_), PACK_BITS25(x,_,x,x,_, x,_,_,_,_, _,_,_,x,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,_,x,_, _,x,x,x,_, _,x,_,x,_), PACK_BITS25(x,x,_,_,x, x,x,x,x,_, _,_,x,_,_, _,x,x,x,_, _,x,x,x,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,_,x,_,_, _,_,_,_,x, x,_,_,x,_), PACK_BITS25(_,_,_,_,x, x,_,_,_,x, _,_,x,_,_, x,_,_,_,x, _,_,_,_,x) },
{ PACK_BITS25(x,_,_,_,x, _,_,x,_,_, _,x,_,_,_, _,_,_,_,x, x,x,x,x,x), PACK_BITS25(_,_,_,_,x, x,_,_,_,x, _,x,_,_,_, x,_,_,_,x, _,_,_,_,x) },
{ PACK_BITS25(_,x,_,x,_, _,_,x,_,_, x,_,_,_,_, x,_,_,_,x, _,_,_,x,_), PACK_BITS25(x,_,_,_,x, x,_,_,_,x, _,x,_,_,_, x,_,_,_,x, x,_,_,_,x) },
{ PACK_BITS25(_,_,x,_,_, x,x,x,x,x, x,x,x,x,x, _,x,x,x,_, _,_,_,x,_), PACK_BITS25(_,x,x,x,_, _,x,x,x,_, _,x,_,_,_, _,x,x,x,_, _,x,x,x,_) }
};
#undef _
#undef x
#undef PACK_BITS25
return (fontData[8 - pixCoord.y][digit >= 5] >> ((digit % 5) * 5 + pixCoord.x)) & 1;
}
bool SampleDebugFontNumber(int2 coord, uint number)
{
coord.y -= 4;
if (number <= 9)
{
return SampleDebugFont(coord - int2(6, 0), number);
}
else
{
return (SampleDebugFont(coord, number / 10) | SampleDebugFont(coord - int2(6, 0), number % 10));
}
}
float3 OverlayHeatMap(uint2 pixCoord, uint numLights, float3 c)
{
/////////////////////////////////////////////////////////////////////
//
const float4 kRadarColors[12] =
{
float4(0.0,0.0,0.0,0.0), // black
float4(0.0,0.0,0.6,0.5), // dark blue
float4(0.0,0.0,0.9,0.5), // blue
float4(0.0,0.6,0.9,0.5), // light blue
float4(0.0,0.9,0.9,0.5), // cyan
float4(0.0,0.9,0.6,0.5), // blueish green
float4(0.0,0.9,0.0,0.5), // green
float4(0.6,0.9,0.0,0.5), // yellowish green
float4(0.9,0.9,0.0,0.5), // yellow
float4(0.9,0.6,0.0,0.5), // orange
float4(0.9,0.0,0.0,0.5), // red
float4(1.0,0.0,0.0,0.9) // strong red
};
float maxNrLightsPerTile = 31;
int nColorIndex = numLights == 0 ? 0 : (1 + (int)floor(10 * (log2((float)numLights) / log2(maxNrLightsPerTile))));
nColorIndex = nColorIndex<0 ? 0 : nColorIndex;
float4 col = nColorIndex>11 ? float4(1.0, 1.0, 1.0, 1.0) : kRadarColors[nColorIndex];
int2 coord = pixCoord - int2(1, 1);
float3 color = lerp(c, pow(col.xyz, 2.2), 0.3*col.w);
if(numLights > 0)
{
if (SampleDebugFontNumber(coord, numLights)) // Shadow
color = 0.0f;
if (SampleDebugFontNumber(coord + 1, numLights)) // Text
color = 1.0f;
}
return color;
}

147
Assets/TestScenes/HDTest/HDRenderLoopTest.unity


objectReference: {fileID: 0}
- target: {fileID: 485392, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_RootOrder
value: 3
value: 4
objectReference: {fileID: 0}
- target: {fileID: 115764, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_Name

objectReference: {fileID: 0}
- target: {fileID: 400000, guid: 646b4ac0331f8e447bd20f06eba916a3, type: 3}
propertyPath: m_RootOrder
value: 1
value: 2
objectReference: {fileID: 0}
- target: {fileID: 400000, guid: 646b4ac0331f8e447bd20f06eba916a3, type: 3}
propertyPath: m_LocalEulerAnglesHint.x

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 9
m_RootOrder: 10
m_LocalEulerAnglesHint: {x: 37.039, y: 0, z: 0}
--- !u!114 &580932148
MonoBehaviour:

- component: {fileID: 605581071}
- component: {fileID: 605581070}
- component: {fileID: 605581072}
- component: {fileID: 605581073}
m_Name: Directional light
m_Name: Sun (directional light)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 11
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 142.28, y: 106.256996, z: -160.70999}
--- !u!114 &605581072
MonoBehaviour:

isDoubleSided: 0
areaLightLength: 0
areaLightWidth: 0
--- !u!114 &605581073
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 605581069}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 97f65a78ace4fbf4187144e9fe724009, type: 3}
m_Name:
m_EditorClassIdentifier:
worldRayleighColorRamp:
key0:
serializedVersion: 2
rgba: 4288243277
key1:
serializedVersion: 2
rgba: 4291598720
key2:
serializedVersion: 2
rgba: 0
key3:
serializedVersion: 2
rgba: 0
key4:
serializedVersion: 2
rgba: 0
key5:
serializedVersion: 2
rgba: 0
key6:
serializedVersion: 2
rgba: 0
key7:
serializedVersion: 2
rgba: 0
ctime0: 0
ctime1: 65535
ctime2: 0
ctime3: 0
ctime4: 0
ctime5: 0
ctime6: 0
ctime7: 0
atime0: 0
atime1: 65535
atime2: 0
atime3: 0
atime4: 0
atime5: 0
atime6: 0
atime7: 0
m_Mode: 0
m_NumColorKeys: 2
m_NumAlphaKeys: 2
worldRayleighColorIntensity: 1
worldRayleighDensity: 10
worldRayleighExtinctionFactor: 1.1
worldRayleighIndirectScatter: 0.33
worldMieColorRamp:
key0:
serializedVersion: 2
rgba: 4286627826
key1:
serializedVersion: 2
rgba: 4294960895
key2:
serializedVersion: 2
rgba: 0
key3:
serializedVersion: 2
rgba: 0
key4:
serializedVersion: 2
rgba: 0
key5:
serializedVersion: 2
rgba: 0
key6:
serializedVersion: 2
rgba: 0
key7:
serializedVersion: 2
rgba: 0
ctime0: 0
ctime1: 65535
ctime2: 0
ctime3: 0
ctime4: 0
ctime5: 0
ctime6: 0
ctime7: 0
atime0: 0
atime1: 65535
atime2: 0
atime3: 0
atime4: 0
atime5: 0
atime6: 0
atime7: 0
m_Mode: 0
m_NumColorKeys: 2
m_NumAlphaKeys: 2
worldMieColorIntensity: 1
worldMieDensity: 15
worldMieExtinctionFactor: 0
worldMiePhaseAnisotropy: 0.9
worldNearScatterPush: 0
worldNormalDistance: 1000
heightRayleighColor: {r: 1, g: 1, b: 1, a: 1}
heightRayleighIntensity: 1
heightRayleighDensity: 10
heightMieDensity: 0
heightExtinctionFactor: 1.1
heightSeaLevel: 0
heightDistance: 50
heightPlaneShift: {x: 0, y: 0, z: 0}
heightNearScatterPush: 0
heightNormalDistance: 1000
worldScaleExponent: 1
atmosphericShader: {fileID: 0}
debugMode: 0
--- !u!1 &609148480
GameObject:
m_ObjectHideFlags: 0

objectReference: {fileID: 0}
- target: {fileID: 485392, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_RootOrder
value: 2
value: 3
objectReference: {fileID: 0}
- target: {fileID: 115764, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_Name

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 10
m_RootOrder: 11
m_LocalEulerAnglesHint: {x: 37.039, y: 0, z: 0}
--- !u!114 &970745598
MonoBehaviour:

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 7
m_RootOrder: 8
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1175446862
GameObject:

m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 8
m_RootOrder: 9
m_LocalEulerAnglesHint: {x: -0.39200002, y: 1.033, z: -0.92}
--- !u!114 &1220024536
MonoBehaviour:

objectReference: {fileID: 0}
- target: {fileID: 485392, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_RootOrder
value: 5
value: 6
objectReference: {fileID: 0}
- target: {fileID: 115764, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_Name

objectReference: {fileID: 0}
- target: {fileID: 485392, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_RootOrder
value: 6
value: 7
objectReference: {fileID: 0}
- target: {fileID: 2374582, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_Materials.Array.data[0]

objectReference: {fileID: 0}
- target: {fileID: 485392, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_RootOrder
value: 4
value: 5
objectReference: {fileID: 0}
- target: {fileID: 115764, guid: e641a36bceddbf24a89656e94dafb3e5, type: 2}
propertyPath: m_Name

9
Assets/ScriptableRenderLoop/Editor.meta


fileFormatVersion: 2
guid: 74ae8146f4a01491ba1306f3db78139d
folderAsset: yes
timeCreated: 1479851675
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

130
Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewTiles.shader


Shader "Hidden/HDRenderLoop/DebugViewTiles"
{
SubShader
{
Pass
{
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
HLSLPROGRAM
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev
#pragma vertex VertViewTiles
#pragma fragment FragViewTiles
#define LIGHTLOOP_TILE_PASS 1
#define USE_FPTL_LIGHTLIST 1 //TODO: make it also work with clustered
#define LIGHTLOOP_TILE_ALL 1
//-------------------------------------------------------------------------------------
// Include
//-------------------------------------------------------------------------------------
#include "Common.hlsl"
// Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new
// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
// the deferred shader will require to use multicompile.
#define UNITY_MATERIAL_LIT // Need to be define before including Material.hlsl
#include "Assets/ScriptableRenderLoop/HDRenderLoop/ShaderConfig.cs.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/ShaderVariables.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/Lighting.hlsl" // This include Material.hlsl
//-------------------------------------------------------------------------------------
// variable declaration
//-------------------------------------------------------------------------------------
uint _ViewTilesFlags;
TEXTURE2D(_CameraDepthTexture);
SAMPLER2D(sampler_CameraDepthTexture);
float4 VertViewTiles(float3 positionOS : POSITION): SV_POSITION
{
return TransformWorldToHClip(TransformObjectToWorld(positionOS));
}
float4 OverlayHeatMap(uint2 pixCoord, uint numLights)
{
const float4 kRadarColors[12] =
{
float4(0.0, 0.0, 0.0, 0.0), // black
float4(0.0, 0.0, 0.6, 0.5), // dark blue
float4(0.0, 0.0, 0.9, 0.5), // blue
float4(0.0, 0.6, 0.9, 0.5), // light blue
float4(0.0, 0.9, 0.9, 0.5), // cyan
float4(0.0, 0.9, 0.6, 0.5), // blueish green
float4(0.0, 0.9, 0.0, 0.5), // green
float4(0.6, 0.9, 0.0, 0.5), // yellowish green
float4(0.9, 0.9, 0.0, 0.5), // yellow
float4(0.9, 0.6, 0.0, 0.5), // orange
float4(0.9, 0.0, 0.0, 0.5), // red
float4(1.0, 0.0, 0.0, 0.9) // strong red
};
float maxNrLightsPerTile = 31;
int nColorIndex = numLights == 0 ? 0 : (1 + (int)floor(10 * (log2((float)numLights) / log2(maxNrLightsPerTile))));
nColorIndex = nColorIndex<0 ? 0 : nColorIndex;
float4 col = nColorIndex>11 ? float4(1.0, 1.0, 1.0, 1.0) : kRadarColors[nColorIndex];
int2 coord = pixCoord - int2(1, 1);
float4 color = float4(pow(col.xyz, 2.2), 0.3*col.w);
if (numLights > 0)
{
if (SampleDebugFontNumber(coord, numLights)) // Shadow
color = float4(0, 0, 0, 1);
if (SampleDebugFontNumber(coord + 1, numLights)) // Text
color = float4(1, 1, 1, 1);
}
return color;
}
float4 FragViewTiles(float4 positionCS : SV_POSITION) : SV_Target
{
Coordinate coord = GetCoordinate(positionCS.xy, _ScreenSize.zw);
#if USE_FPTL_LIGHTLIST
float linearDepth = 0.0;
#else
float depth = LOAD_TEXTURE2D(_CameraDepthTexture, coord.unPositionSS).x;
float linearDepth = GetLinearDepth(depth);
#endif
int n = 0;
if (_ViewTilesFlags & DEBUGVIEWTILESFLAGS_DIRECT_LIGHTING)
{
uint punctualLightStart;
uint punctualLightCount;
GetCountAndStart(coord, DIRECT_LIGHT, linearDepth, punctualLightStart, punctualLightCount);
n += punctualLightCount;
}
if (_ViewTilesFlags & DEBUGVIEWTILESFLAGS_REFLECTION)
{
uint envLightStart;
uint envLightCount;
GetCountAndStart(coord, REFLECTION_LIGHT, linearDepth, envLightStart, envLightCount);
n += envLightCount;
}
if (n > 0)
{
return OverlayHeatMap(int2(coord.unPositionSS.xy) & 15, n);
}
else
{
return 0.0;
}
}
ENDHLSL
}
}
Fallback Off
}

9
Assets/ScriptableRenderLoop/HDRenderLoop/Debug/Resources/DebugViewTiles.shader.meta


fileFormatVersion: 2
guid: c7c2bd17b06ceb4468e14081aaf1b96f
timeCreated: 1480329456
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

42
Assets/ScriptableRenderLoop/HDRenderLoop/Editor/UpgradeStandardShaderMaterials.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using NUnit.Framework;
namespace UnityEditor.Experimental.ScriptableRenderLoop
{
public class UpgradeStandardShaderMaterials
{
static List<MaterialUpgrader> GetHDUpgraders()
{
var upgraders = new List<MaterialUpgrader>();
upgraders.Add(new StandardToHDLitMaterialUpgrader());
upgraders.Add(new StandardSpecularToHDLitMaterialUpgrader());
return upgraders;
}
[MenuItem("HDRenderLoop/Upgrade Materials - Project")]
static void UpgradeMaterialsProject()
{
MaterialUpgrader.UpgradeProjectFolder(GetHDUpgraders(), "Upgrade to HD Material");
}
[MenuItem("HDRenderLoop/Upgrade Materials - Selection")]
static void UpgradeMaterialsSelection()
{
MaterialUpgrader.UpgradeSelection(GetHDUpgraders(), "Upgrade to HD Material");
}
[MenuItem("HDRenderLoop/Modify Light Intensity for Upgrade - Scene Only")]
static void UpgradeLights()
{
Light[] lights = Light.GetLights(LightType.Directional, 0);
foreach (var l in lights)
{
l.intensity *= Mathf.PI;
}
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Editor/UpgradeStandardShaderMaterials.cs.meta


fileFormatVersion: 2
guid: 9384735d0665f47539990919bf72504e
timeCreated: 1479839793
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

334
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/BaseLitUI.cs


using System;
using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor.Experimental.ScriptableRenderLoop
{
public abstract class BaseLitGUI : ShaderGUI
{
protected static class Styles
{
public static string OptionText = "Options";
public static string SurfaceTypeText = "Surface Type";
public static string BlendModeText = "Blend Mode";
public static string detailText = "Inputs Detail";
public static string lightingText = "Inputs Lighting";
public static GUIContent alphaCutoffEnableText = new GUIContent("Alpha Cutoff Enable", "Threshold for alpha cutoff");
public static GUIContent alphaCutoffText = new GUIContent("Alpha Cutoff", "Threshold for alpha cutoff");
public static GUIContent doubleSidedModeText = new GUIContent("Double Sided", "This will render the two face of the objects (disable backface culling)");
public static readonly string[] surfaceTypeNames = Enum.GetNames(typeof(SurfaceType));
public static readonly string[] blendModeNames = Enum.GetNames(typeof(BlendMode));
public static string InputsOptionsText = "Inputs options";
public static GUIContent smoothnessMapChannelText = new GUIContent("Smoothness Source", "Smoothness texture and channel");
public static GUIContent UVBaseMappingText = new GUIContent("UV set for Base", "");
public static GUIContent texWorldScaleText = new GUIContent("Scale to apply on world coordinate in case of Planar/Triplanar", "");
public static GUIContent UVBaseDetailMappingText = new GUIContent("UV set for Base and Detail", "");
public static GUIContent normalMapSpaceText = new GUIContent("Normal/Tangent Map space", "");
public static GUIContent heightMapModeText = new GUIContent("Height Map Mode", "");
public static GUIContent detailMapModeText = new GUIContent("Detail Map with Normal", "Detail Map with AO / Height");
public static GUIContent UVDetailMappingText = new GUIContent("UV set for Detail", "");
public static GUIContent emissiveColorModeText = new GUIContent("Emissive Color Usage", "Use emissive color or emissive mask");
public static string InputsText = "Inputs";
public static string InputsMapText = "";
public static GUIContent baseColorText = new GUIContent("Base Color + Opacity", "Albedo (RGB) and Opacity (A)");
public static GUIContent baseColorSmoothnessText = new GUIContent("Base Color + Smoothness", "Albedo (RGB) and Smoothness (A)");
public static GUIContent metallicText = new GUIContent("Metallic", "Metallic scale factor");
public static GUIContent smoothnessText = new GUIContent("Smoothness", "Smoothness scale factor");
public static GUIContent maskMapESText = new GUIContent("Mask Map - M(R), AO(G), E(B), S(A)", "Mask map");
public static GUIContent maskMapEText = new GUIContent("Mask Map - M(R), AO(G), E(B)", "Mask map");
public static GUIContent maskMapText = new GUIContent("Mask Map - M(R), AO(G)", "Mask map");
public static GUIContent maskMapSText = new GUIContent("Mask Map - M(R), AO(G), S(A)", "Mask map");
public static GUIContent specularOcclusionMapText = new GUIContent("Specular Occlusion Map (RGBA)", "Specular Occlusion Map");
public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map (DXT5) - Need to implement BC5");
public static GUIContent heightMapText = new GUIContent("Height Map (R)", "Height Map");
public static GUIContent tangentMapText = new GUIContent("Tangent Map", "Tangent Map (BC5) - DXT5 for test");
public static GUIContent anisotropyText = new GUIContent("Anisotropy", "Anisotropy scale factor");
public static GUIContent anisotropyMapText = new GUIContent("Anisotropy Map (G)", "Anisotropy");
public static GUIContent detailMapNormalText = new GUIContent("Detail Map A(R) Ny(G) S(B) Nx(A)", "Detail Map");
public static GUIContent detailMapAOHeightText = new GUIContent("Detail Map A(R) AO(G) S(B) H(A)", "Detail Map");
public static GUIContent detailMaskText = new GUIContent("Detail Mask (B)", "Mask for detailMap");
public static GUIContent detailAlbedoScaleText = new GUIContent("Detail AlbedoScale", "Detail Albedo Scale factor");
public static GUIContent detailNormalScaleText = new GUIContent("Detail NormalScale", "Normal Scale factor");
public static GUIContent detailSmoothnessScaleText = new GUIContent("Detail SmoothnessScale", "Smoothness Scale factor");
public static GUIContent detailHeightScaleText = new GUIContent("Detail HeightScale", "Height Scale factor");
public static GUIContent detailAOScaleText = new GUIContent("Detail AOScale", "AO Scale factor");
public static GUIContent emissiveText = new GUIContent("Emissive Color", "Emissive");
public static GUIContent emissiveIntensityText = new GUIContent("Emissive Intensity", "Emissive");
public static GUIContent emissiveWarning = new GUIContent("Emissive value is animated but the material has not been configured to support emissive. Please make sure the material itself has some amount of emissive.");
public static GUIContent emissiveColorWarning = new GUIContent("Ensure emissive color is non-black for emission to have effect.");
}
public enum SurfaceType
{
Opaque,
Transparent
}
public enum BlendMode
{
Lerp,
Add,
SoftAdd,
Multiply,
Premultiply
}
public enum DoubleSidedMode
{
None,
DoubleSided,
DoubleSidedLightingFlip,
DoubleSidedLightingMirror,
}
void SurfaceTypePopup()
{
EditorGUI.showMixedValue = surfaceType.hasMixedValue;
var mode = (SurfaceType)surfaceType.floatValue;
EditorGUI.BeginChangeCheck();
mode = (SurfaceType)EditorGUILayout.Popup(Styles.SurfaceTypeText, (int)mode, Styles.surfaceTypeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Surface Type");
surfaceType.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
}
protected void ShaderOptionsGUI()
{
EditorGUI.indentLevel++;
GUILayout.Label(Styles.OptionText, EditorStyles.boldLabel);
SurfaceTypePopup();
if ((SurfaceType)surfaceType.floatValue == SurfaceType.Transparent)
{
BlendModePopup();
}
m_MaterialEditor.ShaderProperty(alphaCutoffEnable, Styles.alphaCutoffEnableText.text);
if (alphaCutoffEnable.floatValue == 1.0)
{
m_MaterialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoffText.text);
}
m_MaterialEditor.ShaderProperty(doubleSidedMode, Styles.doubleSidedModeText.text);
EditorGUI.indentLevel--;
}
private void BlendModePopup()
{
EditorGUI.showMixedValue = blendMode.hasMixedValue;
var mode = (BlendMode)blendMode.floatValue;
EditorGUI.BeginChangeCheck();
mode = (BlendMode)EditorGUILayout.Popup(Styles.BlendModeText, (int)mode, Styles.blendModeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Blend Mode");
blendMode.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
}
protected void FindOptionProperties(MaterialProperty[] props)
{
surfaceType = FindProperty(kSurfaceType, props);
blendMode = FindProperty(kBlendMode, props);
alphaCutoff = FindProperty(kAlphaCutoff, props);
alphaCutoffEnable = FindProperty(kAlphaCutoffEnabled, props);
doubleSidedMode = FindProperty(kDoubleSidedMode, props);
FindInputOptionProperties(props);
}
protected void SetupMaterial(Material material)
{
bool alphaTestEnable = material.GetFloat(kAlphaCutoffEnabled) == 1.0;
SurfaceType surfaceType = (SurfaceType)material.GetFloat(kSurfaceType);
BlendMode blendMode = (BlendMode)material.GetFloat(kBlendMode);
DoubleSidedMode doubleSidedMode = (DoubleSidedMode)material.GetFloat(kDoubleSidedMode);
if (surfaceType == SurfaceType.Opaque)
{
material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : "");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.renderQueue = alphaTestEnable ? (int)UnityEngine.Rendering.RenderQueue.AlphaTest : -1;
}
else
{
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_ZWrite", 0);
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
switch (blendMode)
{
case BlendMode.Lerp:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
break;
case BlendMode.Add:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
break;
case BlendMode.SoftAdd:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusDstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
break;
case BlendMode.Multiply:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
break;
case BlendMode.Premultiply:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
break;
}
}
if (doubleSidedMode == DoubleSidedMode.None)
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Back);
}
else
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Off);
}
if (doubleSidedMode == DoubleSidedMode.DoubleSidedLightingFlip)
{
material.EnableKeyword("_DOUBLESIDED_LIGHTING_FLIP");
material.DisableKeyword("_DOUBLESIDED_LIGHTING_MIRROR");
}
else if (doubleSidedMode == DoubleSidedMode.DoubleSidedLightingMirror)
{
material.DisableKeyword("_DOUBLESIDED_LIGHTING_FLIP");
material.EnableKeyword("_DOUBLESIDED_LIGHTING_MIRROR");
}
else
{
material.DisableKeyword("_DOUBLESIDED_LIGHTING_FLIP");
material.DisableKeyword("_DOUBLESIDED_LIGHTING_MIRROR");
}
SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable);
SetupInputMaterial(material);
SetupEmissionGIFlags(material);
}
protected void SetKeyword(Material m, string keyword, bool state)
{
if (state)
m.EnableKeyword(keyword);
else
m.DisableKeyword(keyword);
}
public void ShaderPropertiesGUI(Material material)
{
// Use default labelWidth
EditorGUIUtility.labelWidth = 0f;
// Detect any changes to the material
EditorGUI.BeginChangeCheck();
{
ShaderOptionsGUI();
EditorGUILayout.Space();
ShaderInputOptionsGUI();
EditorGUILayout.Space();
ShaderInputGUI();
}
if (EditorGUI.EndChangeCheck())
{
foreach (var obj in m_MaterialEditor.targets)
SetupMaterial((Material)obj);
}
}
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
{
FindOptionProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
FindInputProperties(props);
m_MaterialEditor = materialEditor;
Material material = materialEditor.target as Material;
ShaderPropertiesGUI(material);
}
// TODO: ? or remove
bool HasValidEmissiveKeyword(Material material)
{
/*
// Material animation might be out of sync with the material keyword.
// So if the emission support is disabled on the material, but the property blocks have a value that requires it, then we need to show a warning.
// (note: (Renderer MaterialPropertyBlock applies its values to emissionColorForRendering))
bool hasEmissionKeyword = material.IsKeywordEnabled ("_EMISSION");
if (!hasEmissionKeyword && ShouldEmissionBeEnabled (material, emissionColorForRendering.colorValue))
return false;
else
return true;
*/
return true;
}
protected virtual void SetupEmissionGIFlags(Material material)
{
// Setup lightmap emissive flags
MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags;
if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0)
{
if (ShouldEmissionBeEnabled(material))
flags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
else
flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack;
material.globalIlluminationFlags = flags;
}
}
protected MaterialEditor m_MaterialEditor;
MaterialProperty surfaceType = null;
MaterialProperty alphaCutoffEnable = null;
MaterialProperty blendMode = null;
MaterialProperty alphaCutoff = null;
MaterialProperty doubleSidedMode = null;
const string kSurfaceType = "_SurfaceType";
const string kBlendMode = "_BlendMode";
const string kAlphaCutoff = "_AlphaCutoff";
const string kAlphaCutoffEnabled = "_AlphaCutoffEnable";
const string kDoubleSidedMode = "_DoubleSidedMode";
protected static string[] reservedProperties = new string[] { kSurfaceType, kBlendMode, kAlphaCutoff, kAlphaCutoffEnabled, kDoubleSidedMode };
protected abstract void FindInputProperties(MaterialProperty[] props);
protected abstract void ShaderInputGUI();
protected abstract void ShaderInputOptionsGUI();
protected abstract void FindInputOptionProperties(MaterialProperty[] props);
protected abstract void SetupInputMaterial(Material material);
protected abstract bool ShouldEmissionBeEnabled(Material material);
}
} // namespace UnityEditor

12
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/BaseLitUI.cs.meta


fileFormatVersion: 2
guid: d35c4b8ec5d49e4438d0b0ba2655c495
timeCreated: 1480349253
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

63
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/StandardSpecularToHDLitMaterialUpgrader.cs


using System;
using NUnit.Framework;
using UnityEngine;
namespace UnityEditor.Experimental.ScriptableRenderLoop
{
class StandardSpecularToHDLitMaterialUpgrader : MaterialUpgrader
{
public StandardSpecularToHDLitMaterialUpgrader()
{
RenameShader("Standard (Specular setup)", "HDRenderLoop/LitLegacySupport");
RenameTexture("_MainTex", "_BaseColorMap");
RenameColor("_Color", "_BaseColor");
RenameFloat("_Glossiness", "_Smoothness");
RenameTexture("_BumpMap", "_NormalMap");
RenameColor("_EmissionColor", "_EmissiveColor");
RenameFloat("_DetailNormalMapScale", "_DetailNormalScale");
RenameTexture("_DetailNormalMap", "_DetailMap");
//@Seb: Bumpmap scale doesn't exist in new shader
//_BumpScale("Scale", Float) = 1.0
// Anything reasonable that can be done here?
//RenameFloat("_SpecColor", ...);
//@TODO: Seb. Why do we multiply color by intensity
// in shader when we can just store a color?
// builtinData.emissiveColor * builtinData.emissiveIntensity
}
public override void Convert(Material srcMaterial, Material dstMaterial)
{
base.Convert(srcMaterial, dstMaterial);
//@TODO: Find a good way of setting up keywords etc from properties.
// Code should be shared with material UI code.
}
[Test]
public void UpgradeMaterial()
{
var newShader = Shader.Find("HDRenderLoop/LitLegacySupport");
var mat = new Material(Shader.Find("Standard (Specular setup)"));
var albedo = new Texture2D(1, 1);
var normals = new Texture2D(1, 1);
var baseScale = new Vector2(1, 1);
var color = Color.red;
mat.mainTexture = albedo;
mat.SetTexture("_BumpMap", normals);
mat.color = color;
mat.SetTextureScale("_MainTex", baseScale);
MaterialUpgrader.Upgrade(mat, new StandardSpecularToHDLitMaterialUpgrader(), MaterialUpgrader.UpgradeFlags.CleanupNonUpgradedProperties);
Assert.AreEqual(newShader, mat.shader);
Assert.AreEqual(albedo, mat.GetTexture("_BaseColorMap"));
Assert.AreEqual(color, mat.GetColor("_BaseColor"));
Assert.AreEqual(baseScale, mat.GetTextureScale("_BaseColorMap"));
Assert.AreEqual(normals, mat.GetTexture("_NormalMap"));
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/StandardSpecularToHDLitMaterialUpgrader.cs.meta


fileFormatVersion: 2
guid: 775bef174b1e2ed47972a143845e1191
timeCreated: 1479911618
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

69
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/StandardToHDLitMaterialUpgrader.cs


using System;
using NUnit.Framework;
using UnityEngine;
namespace UnityEditor.Experimental.ScriptableRenderLoop
{
class StandardToHDLitMaterialUpgrader : MaterialUpgrader
{
public StandardToHDLitMaterialUpgrader()
{
RenameShader("Standard", "HDRenderLoop/LitLegacySupport");
RenameTexture("_MainTex", "_BaseColorMap");
RenameColor("_Color", "_BaseColor");
RenameFloat("_Glossiness", "_Smoothness");
RenameTexture("_BumpMap", "_NormalMap");
RenameColor("_EmissionColor", "_EmissiveColor");
RenameFloat("_DetailNormalMapScale", "_DetailNormalScale");
// the HD renderloop packs detail albedo and detail normals into a single texture.
// mapping the detail normal map, if any, to the detail map, should do the right thing if
// there is no detail albedo.
RenameTexture("_DetailNormalMap", "_DetailMap");
//@Seb: Bumpmap scale doesn't exist in new shader
//_BumpScale("Scale", Float) = 1.0
// Metallic uses [Gamma] attribute in standard shader but not in Lit.
// @Seb: Should we convert?
RenameFloat("_Metallic", "_Metallic");
//@TODO: Seb. Why do we multiply color by intensity
// in shader when we can just store a color?
// builtinData.emissiveColor * builtinData.emissiveIntensity
}
public override void Convert(Material srcMaterial, Material dstMaterial)
{
base.Convert(srcMaterial, dstMaterial);
//@TODO: Find a good way of setting up keywords etc from properties.
// Code should be shared with material UI code.
}
[Test]
public void UpgradeMaterial()
{
var newShader = Shader.Find("HDRenderLoop/LitLegacySupport");
var mat = new Material(Shader.Find("Standard"));
var albedo = new Texture2D(1, 1);
var normals = new Texture2D(1, 1);
var baseScale = new Vector2(1, 1);
var color = Color.red;
mat.mainTexture = albedo;
mat.SetTexture("_BumpMap", normals);
mat.color = color;
mat.SetTextureScale("_MainTex", baseScale);
MaterialUpgrader.Upgrade(mat, new StandardToHDLitMaterialUpgrader(), MaterialUpgrader.UpgradeFlags.CleanupNonUpgradedProperties);
Assert.AreEqual(newShader, mat.shader);
Assert.AreEqual(albedo, mat.GetTexture("_BaseColorMap"));
Assert.AreEqual(color, mat.GetColor("_BaseColor"));
Assert.AreEqual(baseScale, mat.GetTextureScale("_BaseColorMap"));
Assert.AreEqual(normals, mat.GetTexture("_NormalMap"));
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/StandardToHDLitMaterialUpgrader.cs.meta


fileFormatVersion: 2
guid: fedbd6bc5d95f4d768cb8077e8454b4e
timeCreated: 1479851295
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

20
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/PatchStandardShaderToNewNamingConvention.cginc


// NOTE: For performing a project upgrade where you temporarily support both old and new renderloops
// in the same sahder
//
// The basic approach is:
// Upgrade all your shaders to the new naming convention, using a SubShader that also contains the legacy // renderloop code.
//
// 1. Copy HDRenderloop Lit.shader into your project
// 2. Add a SubShader and copy old Standard shader passes into it.
// 2. Set LOD on subshader to make Unity pick at runtime to use new renderloop shaders or
// legacy standard shaders based on if SRL is enabled or not.
// In the legacy standard shader section add
// #include "PatchStandardShaderToNewNamingConvention.cginc"
// List of name remaps
#define _MainTex _BaseColorMap
#define _MainTex_ST _BaseColorMap_ST
#define _BumpMap _NormalMap
#define _ParallaxMap _HeightMap
#define _Parallax _HeightScale
#define _Glossiness _Smoothness

9
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/PatchStandardShaderToNewNamingConvention.cginc.meta


fileFormatVersion: 2
guid: a9b4e2b7ef9a45f49834b052e7722acb
timeCreated: 1480085057
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

279
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Editor/BaseUnlitUI.cs


using System;
using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEditor.Experimental.ScriptableRenderLoop
{
public abstract class BaseUnlitGUI : ShaderGUI
{
public enum SurfaceType
{
Opaque,
Transparent
}
public enum BlendMode
{
Lerp,
Add,
SoftAdd,
Multiply,
Premultiply
}
public enum DoubleSidedMode
{
None,
DoubleSided
}
protected static class Styles
{
public static string OptionText = "Options";
public static string SurfaceTypeText = "Surface Type";
public static string BlendModeText = "Blend Mode";
public static GUIContent alphaCutoffEnableText = new GUIContent("Alpha Cutoff Enable", "Threshold for alpha cutoff");
public static GUIContent alphaCutoffText = new GUIContent("Alpha Cutoff", "Threshold for alpha cutoff");
public static GUIContent doubleSidedModeText = new GUIContent("Double Sided", "This will render the two face of the objects (disable backface culling)");
public static readonly string[] surfaceTypeNames = Enum.GetNames(typeof(SurfaceType));
public static readonly string[] blendModeNames = Enum.GetNames(typeof(BlendMode));
public static string InputsOptionsText = "Inputs options";
public static string InputsText = "Inputs";
public static string InputsMapText = "";
public static GUIContent colorText = new GUIContent("Color + Opacity", "Albedo (RGB) and Opacity (A)");
public static GUIContent emissiveText = new GUIContent("Emissive Color", "Emissive");
public static GUIContent emissiveIntensityText = new GUIContent("Emissive Intensity", "Emissive");
}
MaterialProperty surfaceType = null;
MaterialProperty blendMode = null;
MaterialProperty alphaCutoff = null;
MaterialProperty alphaCutoffEnable = null;
MaterialProperty doubleSidedMode = null;
protected const string kSurfaceType = "_SurfaceType";
protected const string kBlendMode = "_BlendMode";
protected const string kAlphaCutoff = "_AlphaCutoff";
protected const string kAlphaCutoffEnabled = "_AlphaCutoffEnable";
protected const string kDoubleSidedMode = "_DoubleSidedMode";
protected MaterialEditor m_MaterialEditor;
public void FindOptionProperties(MaterialProperty[] props)
{
surfaceType = FindProperty(kSurfaceType, props);
blendMode = FindProperty(kBlendMode, props);
alphaCutoff = FindProperty(kAlphaCutoff, props);
alphaCutoffEnable = FindProperty(kAlphaCutoffEnabled, props);
doubleSidedMode = FindProperty(kDoubleSidedMode, props);
FindInputOptionProperties(props);
}
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
{
FindOptionProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
FindInputProperties(props);
m_MaterialEditor = materialEditor;
Material material = materialEditor.target as Material;
ShaderPropertiesGUI(material);
}
protected void ShaderOptionsGUI()
{
EditorGUI.indentLevel++;
GUILayout.Label(Styles.OptionText, EditorStyles.boldLabel);
SurfaceTypePopup();
if ((SurfaceType)surfaceType.floatValue == SurfaceType.Transparent)
{
BlendModePopup();
}
m_MaterialEditor.ShaderProperty(alphaCutoffEnable, Styles.alphaCutoffEnableText.text);
if (alphaCutoffEnable.floatValue == 1.0)
{
m_MaterialEditor.ShaderProperty(alphaCutoff, Styles.alphaCutoffText.text);
}
m_MaterialEditor.ShaderProperty(doubleSidedMode, Styles.doubleSidedModeText.text);
EditorGUI.indentLevel--;
}
public void ShaderPropertiesGUI(Material material)
{
// Use default labelWidth
EditorGUIUtility.labelWidth = 0f;
// Detect any changes to the material
EditorGUI.BeginChangeCheck();
{
ShaderOptionsGUI();
EditorGUILayout.Space();
ShaderInputOptionsGUI();
EditorGUILayout.Space();
ShaderInputGUI();
}
if (EditorGUI.EndChangeCheck())
{
foreach (var obj in m_MaterialEditor.targets)
SetupMaterial((Material)obj);
}
}
// TODO: try to setup minimun value to fall back to standard shaders and reverse
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
{
base.AssignNewShaderToMaterial(material, oldShader, newShader);
}
void SurfaceTypePopup()
{
EditorGUI.showMixedValue = surfaceType.hasMixedValue;
var mode = (SurfaceType)surfaceType.floatValue;
EditorGUI.BeginChangeCheck();
mode = (SurfaceType)EditorGUILayout.Popup(Styles.SurfaceTypeText, (int)mode, Styles.surfaceTypeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Surface Type");
surfaceType.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
}
void BlendModePopup()
{
EditorGUI.showMixedValue = blendMode.hasMixedValue;
var mode = (BlendMode)blendMode.floatValue;
EditorGUI.BeginChangeCheck();
mode = (BlendMode)EditorGUILayout.Popup(Styles.BlendModeText, (int)mode, Styles.blendModeNames);
if (EditorGUI.EndChangeCheck())
{
m_MaterialEditor.RegisterPropertyChangeUndo("Blend Mode");
blendMode.floatValue = (float)mode;
}
EditorGUI.showMixedValue = false;
}
protected void SetupMaterial(Material material)
{
// Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
// (MaterialProperty value might come from renderer material property block)
bool alphaTestEnable = material.GetFloat(kAlphaCutoffEnabled) == 1.0;
SurfaceType surfaceType = (SurfaceType)material.GetFloat(kSurfaceType);
BlendMode blendMode = (BlendMode)material.GetFloat(kBlendMode);
DoubleSidedMode doubleSidedMode = (DoubleSidedMode)material.GetFloat(kDoubleSidedMode);
if (surfaceType == SurfaceType.Opaque)
{
material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : "");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.renderQueue = alphaTestEnable ? (int)UnityEngine.Rendering.RenderQueue.AlphaTest : -1;
}
else
{
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_ZWrite", 0);
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
switch (blendMode)
{
case BlendMode.Lerp:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
break;
case BlendMode.Add:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
break;
case BlendMode.SoftAdd:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusDstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
break;
case BlendMode.Multiply:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
break;
case BlendMode.Premultiply:
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
break;
}
}
if (doubleSidedMode == DoubleSidedMode.None)
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Back);
}
else
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Off);
}
SetKeyword(material, "_ALPHATEST_ON", alphaTestEnable);
SetupInputMaterial(material);
// Setup lightmap emissive flags
MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags;
if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0)
{
if (ShouldEmissionBeEnabled(material))
flags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
else
flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack;
material.globalIlluminationFlags = flags;
}
}
bool HasValidEmissiveKeyword(Material material)
{
/*
// Material animation might be out of sync with the material keyword.
// So if the emission support is disabled on the material, but the property blocks have a value that requires it, then we need to show a warning.
// (note: (Renderer MaterialPropertyBlock applies its values to emissionColorForRendering))
bool hasEmissionKeyword = material.IsKeywordEnabled ("_EMISSION");
if (!hasEmissionKeyword && ShouldEmissionBeEnabled (material, emissionColorForRendering.colorValue))
return false;
else
return true;
*/
return true;
}
protected void SetKeyword(Material m, string keyword, bool state)
{
if (state)
m.EnableKeyword(keyword);
else
m.DisableKeyword(keyword);
}
protected abstract void FindInputProperties(MaterialProperty[] props);
protected abstract void ShaderInputGUI();
protected abstract void ShaderInputOptionsGUI();
protected abstract void FindInputOptionProperties(MaterialProperty[] props);
protected abstract void SetupInputMaterial(Material material);
protected abstract bool ShouldEmissionBeEnabled(Material material);
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Unlit/Editor/BaseUnlitUI.cs.meta


fileFormatVersion: 2
guid: 11fd029bb88b2c04092b1e4d71b919c6
timeCreated: 1480351138
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

390
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/AtmosphericParameters.cs


using UnityEngine;
[ExecuteInEditMode]
public class AtmosphericParameters : MonoBehaviour
{
public enum OcclusionDownscale { x1 = 1, x2 = 2, x4 = 4 }
public enum OcclusionSamples { x64 = 0, x164 = 1, x244 = 2 }
public enum DepthTexture { Enable, Disable/*, Ignore*/ } // 'Ignore' appears to be currently unused.
public enum ScatterDebugMode { None, Scattering, Occlusion, OccludedScattering, Rayleigh, Mie, Height }
[Header("Global Settings")]
public Gradient worldRayleighColorRamp = null;
public float worldRayleighColorIntensity = 1f;
public float worldRayleighDensity = 10f;
public float worldRayleighExtinctionFactor = 1.1f;
public float worldRayleighIndirectScatter = 0.33f;
public Gradient worldMieColorRamp = null;
public float worldMieColorIntensity = 1f;
public float worldMieDensity = 15f;
public float worldMieExtinctionFactor = 0f;
public float worldMiePhaseAnisotropy = 0.9f;
public float worldNearScatterPush = 0f;
public float worldNormalDistance = 1000f;
[Header("Height Settings")]
public Color heightRayleighColor = Color.white;
public float heightRayleighIntensity = 1f;
public float heightRayleighDensity = 10f;
public float heightMieDensity = 0f;
public float heightExtinctionFactor = 1.1f;
public float heightSeaLevel = 0f;
public float heightDistance = 50f;
public Vector3 heightPlaneShift = Vector3.zero;
public float heightNearScatterPush = 0f;
public float heightNormalDistance = 1000f;
[Header("Sky Dome")]
/*public*/ Vector3 skyDomeScale = new Vector3(1f, 1f, 1f);
/*public*/ Vector3 skyDomeRotation = Vector3.zero;
/*public*/ Transform skyDomeTrackedYawRotation = null;
/*public*/ bool skyDomeVerticalFlip = false;
/*public*/ Cubemap skyDomeCube = null;
/*public*/ float skyDomeExposure = 1f;
/*public*/ Color skyDomeTint = Color.white;
/*public*/ Vector3 skyDomeOffset = Vector3.zero;
/*
[Header("Scatter Occlusion")]
public bool useOcclusion = false;
public float occlusionBias = 0f;
public float occlusionBiasIndirect = 0.6f;
public float occlusionBiasClouds = 0.3f;
public OcclusionDownscale occlusionDownscale = OcclusionDownscale.x2;
public OcclusionSamples occlusionSamples = OcclusionSamples.x64;
public bool occlusionDepthFixup = true;
public float occlusionDepthThreshold = 25f;
public bool occlusionFullSky = false;
public float occlusionBiasSkyRayleigh = 0.2f;
public float occlusionBiasSkyMie = 0.4f;
*/
[Header("Other")]
public Shader atmosphericShaderOverride = null;
// public Shader occlusionShaderOverride = null;
public float worldScaleExponent = 1.0f;
// public bool forcePerPixel = true;
// public bool forcePostEffect = true;
[Tooltip("Soft clouds need depth values. Ignore means externally controlled.")]
public DepthTexture depthTexture = DepthTexture.Enable;
public ScatterDebugMode debugMode = ScatterDebugMode.None;
// [HideInInspector] public Shader occlusionShaderOverride;
// Camera m_currentCamera;
// UnityEngine.Rendering.CommandBuffer m_occlusionCmdAfterShadows, m_occlusionCmdBeforeScreen;
Material m_atmosphericMaterial = null;
// Material m_occlusionMaterial = null;
bool m_isAwake = false;
public static AtmosphericParameters instance { get; private set; }
void Awake()
{
if (worldRayleighColorRamp == null)
{
worldRayleighColorRamp = new Gradient();
worldRayleighColorRamp.SetKeys(
new[] { new GradientColorKey(new Color(0.3f, 0.4f, 0.6f), 0f),
new GradientColorKey(new Color(0.5f, 0.6f, 0.8f), 1f) },
new[] { new GradientAlphaKey(1f, 0f),
new GradientAlphaKey(1f, 1f) }
);
}
if (worldMieColorRamp == null)
{
worldMieColorRamp = new Gradient();
worldMieColorRamp.SetKeys(
new[] { new GradientColorKey(new Color(0.95f, 0.75f, 0.5f), 0f),
new GradientColorKey(new Color(1f, 0.9f, 8.0f), 1f) },
new[] { new GradientAlphaKey(1f, 0f),
new GradientAlphaKey(1f, 1f) }
);
}
if (atmosphericShaderOverride != null)
{
// Override the default shader.
m_atmosphericMaterial = new Material(atmosphericShaderOverride);
m_atmosphericMaterial.hideFlags = HideFlags.HideAndDontSave;
}
/*
if (occlusionShaderOverride != null)
{
// Override the default shader.
m_occlusionMaterial = new Material(occlusionShaderOverride);
m_occlusionMaterial.hideFlags = HideFlags.HideAndDontSave;
}
*/
m_isAwake = true;
}
public void OnValidate()
{
if (!m_isAwake) return;
Light light = gameObject.GetComponentInParent<Light>();
if (light == null || light.type != LightType.Directional)
{
Debug.LogErrorFormat("Unexpected: AtmosphericParameters is not attached to a directional light.");
return;
}
worldScaleExponent = Mathf.Clamp(worldScaleExponent, 1f, 2f);
worldNormalDistance = Mathf.Clamp(worldNormalDistance, 1f, 10000f);
worldNearScatterPush = Mathf.Clamp(worldNearScatterPush, -200f, 300f);
worldRayleighDensity = Mathf.Clamp(worldRayleighDensity, 0, 1000f);
worldMieDensity = Mathf.Clamp(worldMieDensity, 0f, 1000f);
worldRayleighIndirectScatter = Mathf.Clamp(worldRayleighIndirectScatter, 0f, 1f);
worldMiePhaseAnisotropy = Mathf.Clamp01(worldMiePhaseAnisotropy);
heightNormalDistance = Mathf.Clamp(heightNormalDistance, 1f, 10000f);
heightNearScatterPush = Mathf.Clamp(heightNearScatterPush, -200f, 300f);
heightRayleighDensity = Mathf.Clamp(heightRayleighDensity, 0, 1000f);
heightMieDensity = Mathf.Clamp(heightMieDensity, 0, 1000f);
/*
occlusionBias = Mathf.Clamp01(occlusionBias);
occlusionBiasIndirect = Mathf.Clamp01(occlusionBiasIndirect);
occlusionBiasClouds = Mathf.Clamp01(occlusionBiasClouds);
occlusionBiasSkyRayleigh = Mathf.Clamp01(occlusionBiasSkyRayleigh);
occlusionBiasSkyMie = Mathf.Clamp01(occlusionBiasSkyMie);
*/
skyDomeExposure = Mathf.Clamp(skyDomeExposure, 0f, 8f);
if (instance == this)
{
// TODO: what's the point of doing this?
OnDisable();
OnEnable();
}
// TODO: why would I want to do that here?
// #if UNITY_EDITOR
// UnityEditor.SceneView.RepaintAll();
// #endif
}
void OnEnable()
{
if (!m_isAwake) return;
// Define select preprocessor symbols.
UpdateKeywords(true);
if (depthTexture == DepthTexture.Disable)
{
// Disable depth texture rendering.
Camera.current.depthTextureMode = DepthTextureMode.None;
}
// Set shader constants.
UpdateStaticUniforms();
UpdateDynamicUniforms();
if (instance && instance != this)
{
Debug.LogErrorFormat("Unexpected: AtmosphericParameters.instance already set (to: {0}). Still overriding with: {1}.", instance.name, name);
}
instance = this;
}
void OnDisable()
{
// Undefine all preprocessor symbols.
UpdateKeywords(false);
if (instance && instance != this)
{
Debug.LogErrorFormat("Unexpected: AtmosphericParameters.instance set to: {0}, not to: {1}. Leaving alone.", instance.name, name);
}
else
{
instance = null;
}
}
void UpdateKeywords(bool enable)
{
Shader.DisableKeyword("ATMOSPHERICS_OCCLUSION");
Shader.DisableKeyword("ATMOSPHERICS_OCCLUSION_FULLSKY");
Shader.DisableKeyword("ATMOSPHERICS_OCCLUSION_EDGE_FIXUP");
Shader.DisableKeyword("ATMOSPHERICS_SUNRAYS");
Shader.DisableKeyword("ATMOSPHERICS_DEBUG");
if (enable)
{
/*
if (useOcclusion)
{
Shader.EnableKeyword("ATMOSPHERICS_OCCLUSION");
if(occlusionDepthFixup && occlusionDownscale != OcclusionDownscale.x1)
Shader.EnableKeyword("ATMOSPHERICS_OCCLUSION_EDGE_FIXUP");
if(occlusionFullSky)
Shader.EnableKeyword("ATMOSPHERICS_OCCLUSION_FULLSKY");
}
*/
if (debugMode != ScatterDebugMode.None)
{
Shader.EnableKeyword("ATMOSPHERICS_DEBUG");
}
}
}
void UpdateStaticUniforms()
{
Shader.SetGlobalVector("_SkyDomeOffset", skyDomeOffset);
Shader.SetGlobalVector("_SkyDomeScale", skyDomeScale);
Shader.SetGlobalTexture("_SkyDomeCube", skyDomeCube);
Shader.SetGlobalFloat("_SkyDomeExposure", skyDomeExposure);
Shader.SetGlobalColor("_SkyDomeTint", skyDomeTint);
/*
Shader.SetGlobalFloat("_ShadowBias", useOcclusion ? occlusionBias : 1f);
Shader.SetGlobalFloat("_ShadowBiasIndirect", useOcclusion ? occlusionBiasIndirect : 1f);
Shader.SetGlobalFloat("_ShadowBiasClouds", useOcclusion ? occlusionBiasClouds : 1f);
Shader.SetGlobalVector("_ShadowBiasSkyRayleighMie", useOcclusion ? new Vector4(occlusionBiasSkyRayleigh, occlusionBiasSkyMie, 0f, 0f) : Vector4.zero);
Shader.SetGlobalFloat("_OcclusionDepthThreshold", occlusionDepthThreshold);
*/
Shader.SetGlobalFloat("_WorldScaleExponent", worldScaleExponent);
Shader.SetGlobalFloat("_WorldNormalDistanceRcp", 1f/worldNormalDistance);
Shader.SetGlobalFloat("_WorldNearScatterPush", -Mathf.Pow(Mathf.Abs(worldNearScatterPush), worldScaleExponent) * Mathf.Sign(worldNearScatterPush));
Shader.SetGlobalFloat("_WorldRayleighDensity", -worldRayleighDensity / 100000f);
Shader.SetGlobalFloat("_MiePhaseAnisotropy", worldMiePhaseAnisotropy);
Shader.SetGlobalVector("_RayleighInScatterPct", new Vector4(1f - worldRayleighIndirectScatter, worldRayleighIndirectScatter, 0f, 0f));
Shader.SetGlobalFloat("_HeightNormalDistanceRcp", 1f/heightNormalDistance);
Shader.SetGlobalFloat("_HeightNearScatterPush", -Mathf.Pow(Mathf.Abs(heightNearScatterPush), worldScaleExponent) * Mathf.Sign(heightNearScatterPush));
Shader.SetGlobalFloat("_HeightRayleighDensity", -heightRayleighDensity / 100000f);
Shader.SetGlobalFloat("_HeightSeaLevel", heightSeaLevel);
Shader.SetGlobalFloat("_HeightDistanceRcp", 1f/heightDistance);
Shader.SetGlobalVector("_HeightPlaneShift", heightPlaneShift);
Shader.SetGlobalVector("_HeightRayleighColor", (Vector4)heightRayleighColor * heightRayleighIntensity);
Shader.SetGlobalFloat("_HeightExtinctionFactor", heightExtinctionFactor);
Shader.SetGlobalFloat("_RayleighExtinctionFactor", worldRayleighExtinctionFactor);
Shader.SetGlobalFloat("_MieExtinctionFactor", worldMieExtinctionFactor);
var rayleighColorM20 = worldRayleighColorRamp.Evaluate(0.00f);
var rayleighColorM10 = worldRayleighColorRamp.Evaluate(0.25f);
var rayleighColorO00 = worldRayleighColorRamp.Evaluate(0.50f);
var rayleighColorP10 = worldRayleighColorRamp.Evaluate(0.75f);
var rayleighColorP20 = worldRayleighColorRamp.Evaluate(1.00f);
var mieColorM20 = worldMieColorRamp.Evaluate(0.00f);
var mieColorO00 = worldMieColorRamp.Evaluate(0.50f);
var mieColorP20 = worldMieColorRamp.Evaluate(1.00f);
Shader.SetGlobalVector("_RayleighColorM20", (Vector4)rayleighColorM20 * worldRayleighColorIntensity);
Shader.SetGlobalVector("_RayleighColorM10", (Vector4)rayleighColorM10 * worldRayleighColorIntensity);
Shader.SetGlobalVector("_RayleighColorO00", (Vector4)rayleighColorO00 * worldRayleighColorIntensity);
Shader.SetGlobalVector("_RayleighColorP10", (Vector4)rayleighColorP10 * worldRayleighColorIntensity);
Shader.SetGlobalVector("_RayleighColorP20", (Vector4)rayleighColorP20 * worldRayleighColorIntensity);
Shader.SetGlobalVector("_MieColorM20", (Vector4)mieColorM20 * worldMieColorIntensity);
Shader.SetGlobalVector("_MieColorO00", (Vector4)mieColorO00 * worldMieColorIntensity);
Shader.SetGlobalVector("_MieColorP20", (Vector4)mieColorP20 * worldMieColorIntensity);
Shader.SetGlobalInt("_AtmosphericsDebugMode", (int)debugMode);
}
void OnWillRenderObject()
{
/*
if (!m_isAwake) return;
// For now, we only use the directional light we are attached to, and the current camera.
if (depthTexture == DepthTexture.Disable)
{
// Disable depth texture rendering.
Camera.current.depthTextureMode = DepthTextureMode.None;
}
// Set shader constants.
UpdateDynamicUniforms();
if (useOcclusion) {
var camRgt = m_currentCamera.transform.right;
var camUp = m_currentCamera.transform.up;
var camFwd = m_currentCamera.transform.forward;
var dy = Mathf.Tan(m_currentCamera.fieldOfView * 0.5f * Mathf.Deg2Rad);
var dx = dy * m_currentCamera.aspect;
var vpCenter = camFwd * m_currentCamera.farClipPlane;
var vpRight = camRgt * dx * m_currentCamera.farClipPlane;
var vpUp = camUp * dy * m_currentCamera.farClipPlane;
m_occlusionMaterial.SetVector("_CameraPosition", m_currentCamera.transform.position);
m_occlusionMaterial.SetVector("_ViewportCorner", vpCenter - vpRight - vpUp);
m_occlusionMaterial.SetVector("_ViewportRight", vpRight * 2f);
m_occlusionMaterial.SetVector("_ViewportUp", vpUp * 2f);
var farDist = m_currentCamera ? m_currentCamera.farClipPlane : 1000f;
var refDist = (Mathf.Min(farDist, QualitySettings.shadowDistance) - 1f) / farDist;
m_occlusionMaterial.SetFloat("_OcclusionSkyRefDistance", refDist);
var srcRect = m_currentCamera.pixelRect;
var downscale = 1f / (float)(int)occlusionDownscale;
var occWidth = Mathf.RoundToInt(srcRect.width * downscale);
var occHeight = Mathf.RoundToInt(srcRect.height * downscale);
var occlusionId = Shader.PropertyToID("_OcclusionTexture");
m_occlusionCmdBeforeScreen.Clear();
m_occlusionCmdBeforeScreen.GetTemporaryRT(occlusionId, occWidth, occHeight, 0, FilterMode.Bilinear, RenderTextureFormat.R8, RenderTextureReadWrite.sRGB);
m_occlusionCmdBeforeScreen.Blit(
null,
occlusionId,
m_occlusionMaterial,
(int)occlusionSamples
);
m_occlusionCmdBeforeScreen.SetGlobalTexture(occlusionId, occlusionId);
}
*/
}
void UpdateDynamicUniforms()
{
/* For now, we only use the directional light we are attached to, and the current camera. */
var trackedYaw = skyDomeTrackedYawRotation ? skyDomeTrackedYawRotation.eulerAngles.y : 0f;
Shader.SetGlobalMatrix("_SkyDomeRotation",
Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(skyDomeRotation.x, 0f, 0f), Vector3.one)
* Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0f, skyDomeRotation.y - trackedYaw, 0f), Vector3.one)
* Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(1f, skyDomeVerticalFlip ? -1f : 1f, 1f))
);
Shader.SetGlobalVector("_SunDirection", -transform.forward);
Shader.SetGlobalFloat("_WorldMieDensity", -worldMieDensity / 100000f);
Shader.SetGlobalFloat("_HeightMieDensity", -heightMieDensity / 100000f);
var pixelRect = Camera.current ? Camera.current.pixelRect
: new Rect(0f, 0f, Screen.width, Screen.height);
var scale = 1.0f; //(float)(int)occlusionDownscale;
var depthTextureScaledTexelSize = new Vector4(scale / pixelRect.width,
scale / pixelRect.height,
-scale / pixelRect.width,
-scale / pixelRect.height);
Shader.SetGlobalVector("_DepthTextureScaledTexelSize", depthTextureScaledTexelSize);
}
void OnRenderObject()
{
/* This component is not rendered directly. */
}
}

12
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/AtmosphericParameters.cs.meta


fileFormatVersion: 2
guid: 97f65a78ace4fbf4187144e9fe724009
timeCreated: 1479992550
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

113
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/README.txt


# Atmospheric Scattering
Atmospheric scattering is a solution developed for nicer aerial perspective in The Blacksmith. It provides a model emulating atmospheric Rayleigh, Mie and height scattering (and also takes a lot of shortcuts in the name of performance and artistic control). Take a look at the blog post at this address http://blogs.unity3d.com/?p=27218 to get a high-level overview of the components making up the final composition.
### Options description
This component comes with quite a lot of options - but you normally don't have to tweak more than a handful of them to get good results - start with the densities and colors and that will get you started nicely.
#### World Components
**World Rayleigh Color Ramp**: The color or colors used for rayleigh scattering. It's a ramp instead of a single color because you can have different scattering colors depending on the angle to the unit being shaded. Values to the left in the ramp are mapped to angles below horizon, whereas values to the right are mapped to angles above the horizon.
**World Rayleigh Color Intensity**: An HDR color scale for the rayleigh color ramp.
**World Rayleigh Density**: The density of the rayleigh component.
**World Rayleigh Extinction Factor**: How much light is out-scattered or absorbed on its way to the eye. Basically how much to darken the shaded pixel.
**World Rayleigh Indirect Scatter**: Which percentage of the rayleigh scattering should be considered 'indirect' scattering. (relevant for occlusion only)
**World Mie Color Ramp**: The color or colors used for mie scattering. It's a ramp instead of a single color because you can have different scattering colors depending on the angle to the unit being shaded. Values to the left in the ramp are mapped to angles below horizon, whereas values to the right are mapped to angles above the horizon.
**World Mie Color Intensity**: An HDR color scale for the mie color ramp.
**World Mie Density**: The density of the mie component.
**World Mie Extinction Factor**: How much light is out-scattered or absorbed on its way to the eye. Basically how much to darken the shaded pixel.
**World Mie Phase Anisotropy**: How focused the forward directionality of the mie scattering is. Values close to 1 produce a small, very sharp mie component, whereas values below 0.5 creates a very large and unfocused mie component.
**World Near Scatter Push**: Allows the scattering to be pushed out to have no scattering directly in front of the camera, or pulled in to have more scattering close to the camera.
**World Normal Distance**: A measure of the scale of the scene. Essentially this desaturates the scattering near the camera, and interpolates into full color ramp at the edge of the specified distance.
#### Height Components
**Height Rayleigh Color**: The general global scattering color for height fog.
**Height Rayleigh Intensity**: An HDR color scale for the height global fog color.
**Height Rayleigh Density**: The density of the global height fog.
**Height Mie Density**: The density of the mie scattering being added to the global height fog.
**Height Extinction Factor**: How much light is out-scattered or absorbed on its way to the eye. Basically how much to darken the shaded pixel.
**Height Sea Level**: Sea level height offset from origin.
**Height Distance**: Falloff distance from sea level
**Height Plane Shift**: An optional plane vector for a tilted sea level.
**Height Near Scatter Push**: Allows the scattering to be pushed out to have no scattering directly in front of the camera, or pulled in to have more scattering close to the camera.
**Height Normal Distance**: A measure of the scale of the scene. Essentially this desaturates the scattering near the camera, and interpolates into full color at the edge of the specified distance.
#### Sky Dome
**Sky Dome Scale**: The scale of the skydome. We use this to virtually squash the sky sphere into behaving like a dome. The xz-dimensions affect how much scattering the horizon picks up, whereas the y-dimension dictates how far up on the sky the scattering is blended.
**Sky Dome Rotation**: An optional rotation of the skydome. Usually, only Y-rotation makes sense.
**Sky Dome Tracked Yaw Rotation**: Optionally have the skydome rotate to track a transform, typically a light source. Use in combination with rotation to perfectly align and track the sun to the skydome.
**Sky Dome Vertical Flip**: We have the option of putting two skybox textures into the same cubemap. This flags flips the UV projection to show the bottom half instead of the top half.
**Sky Dome Cube**: An HDR cubemap to use as sky dome.
**Sky Dome Exposure**: The exposure of the sky cubemap.
**Sky Dome Tint**: Tint color for the cubemap.
#### Scatter Occlusion
**Use Occlusion**: This flag enables scatter occlusion.
**Occlusion Bias**: Controls how strongly occlusion affects direct scattering.
**Occlusion BiasIndirect**: Controls how strongly occlusion affects indirect scattering.
**Occlusion BiasClouds**: Controls how strongly occlusion affects placed clouds.
**Occlusion Downscale**: Controls the downscale factor for occlusion gathering.
**Occlusion Samples**: The number of samples to use in gathering.
**Occlusion DepthFixup**: Whether to attempt to fix upsampling across depth discontinuities (currently d3d11 only).
**Occlusion DepthThreshold**: The threshold defining discontinuous depth.
**Occlusion FullSky**: Whether to gather occlusion even for skydome pixels.
**Occlusion BiasSkyRayleigh **: Controls how strongly occlusion affects rayleigh scattering on the skydome.
**Occlusion BiasSkyMie **: Controls how strongly occlusion affects mie scattering on the skydome.
#### Other
**World ScaleExponent**: An option to exponentially scale the world for scattering calculations (fake aerial perspective in small scenes).
**Force Per Pixel**: Force all scatter calculations to run at per-pixel frequency.
**Force Post Effect**: Force all scatter calculations to run in a post-process (requires the AtmosphericScatteringDeferred component on the camera, and doesn't apply to transparent object)
**Depth Texture**: Whether to enable, disable or leave alone the camera depth texture settings. (required for depth fixup and soft cloud planes)
**Debug Mode**: Various debug visualizations of the different rendering components.

354
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/AtmosphericScattering.hlsl


#ifndef FILE_ATMOSPHERICSCATTERING
#define FILE_ATMOSPHERICSCATTERING
#define ATMOSPHERICS_DBG_NONE 0
#define ATMOSPHERICS_DBG_SCATTERING 1
#define ATMOSPHERICS_DBG_OCCLUSION 2
#define ATMOSPHERICS_DBG_OCCLUDEDSCATTERING 3
#define ATMOSPHERICS_DBG_RAYLEIGH 4
#define ATMOSPHERICS_DBG_MIE 5
#define ATMOSPHERICS_DBG_HEIGHT 6
uniform int _AtmosphericsDebugMode;
uniform float3 _SunDirection;
uniform float _ShadowBias;
uniform float _ShadowBiasIndirect;
uniform float _ShadowBiasClouds;
uniform float _OcclusionDepthThreshold;
uniform float4 _OcclusionTexture_TexelSize;
uniform float4 _DepthTextureScaledTexelSize;
uniform float _WorldScaleExponent;
uniform float _WorldNormalDistanceRcp;
uniform float _WorldNearScatterPush;
uniform float _WorldRayleighDensity;
uniform float _WorldMieDensity;
uniform float3 _RayleighColorM20;
uniform float3 _RayleighColorM10;
uniform float3 _RayleighColorO00;
uniform float3 _RayleighColorP10;
uniform float3 _RayleighColorP20;
uniform float3 _RayleighColorP45;
uniform float3 _MieColorM20;
uniform float3 _MieColorO00;
uniform float3 _MieColorP20;
uniform float3 _MieColorP45;
uniform float _HeightNormalDistanceRcp;
uniform float _HeightNearScatterPush;
uniform float _HeightRayleighDensity;
uniform float _HeightMieDensity;
uniform float _HeightSeaLevel;
uniform float3 _HeightPlaneShift;
uniform float _HeightDistanceRcp;
uniform float _RayleighCoeffScale;
uniform float3 _RayleighSunTintIntensity;
uniform float2 _RayleighInScatterPct;
uniform float _MieCoeffScale;
uniform float3 _MieSunTintIntensity;
uniform float _MiePhaseAnisotropy;
uniform float _HeightExtinctionFactor;
uniform float _RayleighExtinctionFactor;
uniform float _MieExtinctionFactor;
uniform float4 _HeightRayleighColor;
SAMPLER2D(sampler_CameraDepthTexture)
#define SRL_BilinearSampler sampler_CameraDepthTexture // Used for all textures
TEXTURE2D(_CameraDepthTexture);
TEXTURE2D(_OcclusionTexture);
float HenyeyGreensteinPhase(float g, float cosTheta) {
float gSqr = g * g;
float a1 = (1.f - gSqr);
float a2 = (2.f + gSqr);
float b1 = 1.f + cosTheta * cosTheta;
float b2 = pow(abs(1.f + gSqr - 2.f * g * cosTheta), 1.5f);
return (a1 / a2) * (b1 / b2);
}
float RayleighPhase(float cosTheta) {
const float f = 3.f / (16.f * PI);
return f + f * cosTheta * cosTheta;
}
float MiePhase(float cosTheta, float anisotropy) {
const float f = 3.f / (8.f * PI);
return f * HenyeyGreensteinPhase(anisotropy, cosTheta);
}
float HeightDensity(float h, float H) {
return exp(-h/H);
}
float3 WorldScale(float3 p) {
p.xz = sign(p.xz) * pow(abs(p.xz), _WorldScaleExponent);
return p;
}
void VolundTransferScatter(float3 worldPos, out float4 coords1, out float4 coords2, out float4 coords3) {
const float3 scaledWorldPos = WorldScale(worldPos);
const float3 worldCamPos = WorldScale(_WorldSpaceCameraPos.xyz);
const float c_MieScaleHeight = 1200.f;
const float worldRayleighDensity = 1.f;
const float worldMieDensity = HeightDensity(scaledWorldPos.y, c_MieScaleHeight);
const float3 worldVec = scaledWorldPos.xyz - worldCamPos.xyz;
const float worldVecLen = length(worldVec);
const float3 worldDir = worldVec / worldVecLen;
const float3 worldDirUnscaled = normalize(worldPos - _WorldSpaceCameraPos.xyz);
const float viewSunCos = dot(worldDirUnscaled, _SunDirection);
const float rayleighPh = min(1.f, RayleighPhase(viewSunCos) * 12.f);
const float miePh = MiePhase(viewSunCos, _MiePhaseAnisotropy);
const float angle20 = 0.324f / 1.5f;
const float angle10 = 0.174f / 1.5f;
const float angleY = worldDir.y * saturate(worldVecLen / 250.0);
float3 rayleighColor;
if(angleY >= angle10) rayleighColor = lerp(_RayleighColorP10, _RayleighColorP20, saturate((angleY - angle10) / (angle20 - angle10)));
else if(angleY >= 0.f) rayleighColor = lerp(_RayleighColorO00, _RayleighColorP10, angleY / angle10);
else if(angleY >= -angle10) rayleighColor = lerp(_RayleighColorM10, _RayleighColorO00, (angleY + angle10) / angle10);
else rayleighColor = lerp(_RayleighColorM20, _RayleighColorM10, saturate((angleY + angle20) / (angle20 - angle10)));
float3 mieColor;
if(angleY >= 0.f) mieColor = lerp(_MieColorO00, _MieColorP20, saturate(angleY / angle20));
else mieColor = lerp(_MieColorM20, _MieColorO00, saturate((angleY + angle20) / angle20));
const float pushedDistance = max(0.f, worldVecLen + _WorldNearScatterPush);
const float pushedDensity = /*HeightDensity **/ pushedDistance /** exp(-scaledWorldPos.y / 8000.f)*/;
const float rayleighScatter = (1.f - exp(_WorldRayleighDensity * pushedDensity)) * rayleighPh;
#ifdef IS_RENDERING_SKY
const float mieScatter = (1.f - exp(_WorldMieDensity * pushedDensity));
#else
const float mieScatter = (1.f - exp(_WorldMieDensity * pushedDensity)) * miePh;
#endif
const float heightShift = dot(worldVec, _HeightPlaneShift);
const float heightScaledOffset = (scaledWorldPos.y - heightShift - _HeightSeaLevel) * _HeightDistanceRcp;
const float HeightDensity = exp(-heightScaledOffset);
const float pushedHeightDistance = max(0.f, worldVecLen + _HeightNearScatterPush);
const float heightScatter = (1.f - exp(_HeightRayleighDensity * pushedHeightDistance)) * HeightDensity;
#ifdef IS_RENDERING_SKY
const float heightMieScatter = (1.f - exp(_HeightMieDensity * pushedHeightDistance)) * HeightDensity;
#else
const float heightMieScatter = (1.f - exp(_HeightMieDensity * pushedHeightDistance)) * HeightDensity * miePh;
#endif
rayleighColor = lerp(Luminance(rayleighColor).rrr, rayleighColor, saturate(pushedDistance * _WorldNormalDistanceRcp));
float3 heightRayleighColor = lerp(Luminance(_HeightRayleighColor.xyz).rrr, _HeightRayleighColor.xyz, saturate(pushedHeightDistance * _HeightNormalDistanceRcp));
coords1.rgb = rayleighScatter * rayleighColor;
coords1.a = rayleighScatter;
coords3.rgb = saturate(heightScatter) * heightRayleighColor;
coords3.a = heightScatter;
coords2.rgb = mieScatter * mieColor + saturate(heightMieScatter) * mieColor;
coords2.a = mieScatter;
}
void VolundTransferScatter(float3 scaledWorldPos, out float4 coords1) {
float4 c1, c2, c3;
VolundTransferScatter(scaledWorldPos, c1, c2, c3);
#ifdef IS_RENDERING_SKY
coords1.rgb = c3.rgb;
coords1.a = max(0.f, 1.f - c3.a * _HeightExtinctionFactor);
#else
coords1.rgb = c1.rgb;
coords1.rgb += c3.rgb;
coords1.a = max(0.f, 1.f - c1.a * _RayleighExtinctionFactor - c3.a * _HeightExtinctionFactor);
#endif
coords1.rgb += c2.rgb;
coords1.a *= max(0.f, 1.f - c2.a * _MieExtinctionFactor);
#ifdef ATMOSPHERICS_DEBUG
if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_RAYLEIGH)
coords1.rgb = c1.rgb;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_MIE)
coords1.rgb = c2.rgb;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_HEIGHT)
coords1.rgb = c3.rgb;
#endif
}
float2 UVFromPos(float2 pos) {
return pos / _ScreenParams.xy;
}
float3 VolundApplyScatter(float4 coords1, float2 pos, float3 color) {
#ifdef ATMOSPHERICS_DEBUG
if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_OCCLUSION)
return 1;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_SCATTERING || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_OCCLUDEDSCATTERING)
return coords1.rgb;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_RAYLEIGH || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_MIE || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_HEIGHT)
return coords1.rgb;
#endif
return color * coords1.a + coords1.rgb;
}
float3 VolundApplyScatterAdd(float coords1, float3 color) {
return color * coords1;
}
void VolundTransferScatterOcclusion(float3 scaledWorldPos, out float4 coords1, out float3 coords2) {
float4 c1, c2, c3;
VolundTransferScatter(scaledWorldPos, c1, c2, c3);
coords1.rgb = c1.rgb * _RayleighInScatterPct.x;
coords1.a = max(0.f, 1.f - c1.a * _RayleighExtinctionFactor - c3.a * _HeightExtinctionFactor);
coords1.rgb += c2.rgb;
coords1.a *= max(0.f, 1.f - c2.a * _MieExtinctionFactor);
coords2.rgb = c3.rgb + c1.rgb * _RayleighInScatterPct.y;
#ifdef ATMOSPHERICS_DEBUG
if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_RAYLEIGH)
coords1.rgb = c1.rgb;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_MIE)
coords1.rgb = c2.rgb;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_HEIGHT)
coords1.rgb = c3.rgb;
#endif
}
float VolundSampleScatterOcclusion(float2 pos) {
#if defined(ATMOSPHERICS_OCCLUSION)
float2 uv = UVFromPos(pos);
#if defined(ATMOSPHERICS_OCCLUSION_EDGE_FIXUP)
float4 baseUV = float4(uv.x, uv.y, 0.f, 0.f);
float cDepth = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV, 0.f).r;
cDepth = LinearEyeDepth(cDepth);
float4 xDepth;
baseUV.xy = uv + _DepthTextureScaledTexelSize.zy; xDepth.x = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV);
baseUV.xy = uv + _DepthTextureScaledTexelSize.xy; xDepth.y = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV);
baseUV.xy = uv + _DepthTextureScaledTexelSize.xw; xDepth.z = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV);
baseUV.xy = uv + _DepthTextureScaledTexelSize.zw; xDepth.w = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, SRL_BilinearSampler, baseUV);
xDepth.x = LinearEyeDepth4(xDepth.x);
xDepth.y = LinearEyeDepth4(xDepth.y);
xDepth.z = LinearEyeDepth4(xDepth.z);
xDepth.w = LinearEyeDepth4(xDepth.w);
float4 diffDepth = xDepth - cDepth.rrrr;
float4 maskDepth = abs(diffDepth) < _OcclusionDepthThreshold;
float maskWeight = dot(maskDepth, maskDepth);
UNITY_BRANCH
if(maskWeight == 4.f || maskWeight == 0.f) {
return SAMPLE_TEXTURE2D_LOD(_OcclusionTexture, SRL_BilinearSampler, uv, 0.f).r;
} else {
float4 occ = GATHER_TEXTURE2D(_OcclusionTexture, SRL_BilinearSampler, uv);
float4 fWeights;
fWeights.xy = frac(uv * _OcclusionTexture_TexelSize.zw - 0.5f);
fWeights.zw = float2(1.f, 1.f) - fWeights.xy;
float4 mfWeights = float4(fWeights.z * fWeights.y, fWeights.x * fWeights.y, fWeights.x * fWeights.w, fWeights.z * fWeights.w);
return dot(occ, mfWeights * maskDepth) / dot(mfWeights, maskDepth);
}
#endif //defined(ATMOSPHERICS_OCCLUSION_EDGE_FIXUP)
#else //defined(ATMOSPHERICS_OCCLUSION)
return 1.f;
#endif //defined(ATMOSPHERICS_OCCLUSION)
}
float3 VolundApplyScatterOcclusion(float4 coords1, float3 coords2, float2 pos, float3 color) {
float occlusion = VolundSampleScatterOcclusion(pos);
#ifdef ATMOSPHERICS_DEBUG
if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_SCATTERING)
return coords1.rgb + coords2.rgb;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_OCCLUSION)
return occlusion;
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_OCCLUDEDSCATTERING)
return coords1.rgb * min(1.f, occlusion + _ShadowBias) + coords2.rgb * min(1.f, occlusion + _ShadowBiasIndirect);
else if(_AtmosphericsDebugMode == ATMOSPHERICS_DBG_RAYLEIGH || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_MIE || _AtmosphericsDebugMode == ATMOSPHERICS_DBG_HEIGHT)
return coords1.rgb;
#endif
return
color * coords1.a
+ coords1.rgb * min(1.f, occlusion + _ShadowBias) + coords2.rgb * min(1.f, occlusion + _ShadowBiasIndirect);
;
}
float VolundCloudOcclusion(float2 pos) {
#if defined(ATMOSPHERICS_OCCLUSION)
return min(1.f, VolundSampleScatterOcclusion(pos) + _ShadowBiasClouds);
#else
return 1.f;
#endif
}
float4 VolundApplyCloudScatter(float4 coords1, float4 color) {
#if defined(DBG_ATMOSPHERICS_SCATTERING) || defined(DBG_ATMOSPHERICS_OCCLUDEDSCATTERING)
return float4(coords1.rgb, color.a);
#elif defined(DBG_ATMOSPHERICS_OCCLUSION)
return 1;
#endif
color.rgb = color.rgb * coords1.a + coords1.rgb;
return color;
}
float4 VolundApplyCloudScatterOcclusion(float4 coords1, float3 coords2, float2 pos, float4 color) {
float occlusion = VolundSampleScatterOcclusion(pos);
#ifdef ATMOSPHERICS_OCCLUSION_DEBUG2
color.rgb = coords1.rgb * min(1.f, occlusion + _ShadowBias) + coords2.rgb * min(1.f, occlusion + _ShadowBiasIndirect);
return color;
#endif
#ifdef ATMOSPHERICS_OCCLUSION_DEBUG
return occlusion;
#endif
color.rgb = color.rgb * coords1.a + coords1.rgb * min(1.f, occlusion + _ShadowBias) + coords2.rgb * min(1.f, occlusion + _ShadowBiasIndirect);
float cloudOcclusion = min(1.f, occlusion + _ShadowBiasClouds);
color.a *= cloudOcclusion;
return color;
}
// Original vert/frag macros
#if defined(ATMOSPHERICS_OCCLUSION)
#define VOLUND_SCATTER_COORDS(idx1, idx2) float4 scatterCoords1 : TEXCOORD##idx1; float3 scatterCoords2 : TEXCOORD##idx2;
#define VOLUND_TRANSFER_SCATTER(pos, o) o.scatterCoords1 = pos.xyzz; o.scatterCoords2 = pos.xyz;
#define VOLUND_APPLY_SCATTER(i, color) VolundTransferScatterOcclusion(i.scatterCoords1.xyz, i.scatterCoords1, i.scatterCoords2); color = VolundApplyScatterOcclusion(i.scatterCoords1, i.scatterCoords2, i.pos.xy, color)
#define VOLUND_CLOUD_SCATTER(i, color) VolundTransferScatterOcclusion(i.scatterCoords1.xyz, i.scatterCoords1, i.scatterCoords2); color = VolundApplyCloudScatterOcclusion(i.scatterCoords1, i.scatterCoords2, i.pos.xy, color)
#else
#define VOLUND_SCATTER_COORDS(idx1, idx2) float4 scatterCoords1 : TEXCOORD##idx1;
#define VOLUND_TRANSFER_SCATTER(pos, o) o.scatterCoords1 = pos.xyzz;
#define VOLUND_APPLY_SCATTER(i, color) VolundTransferScatter(i.scatterCoords1.xyz, i.scatterCoords1); color = VolundApplyScatter(i.scatterCoords1, i.pos.xy, color);
#define VOLUND_CLOUD_SCATTER(i, color) VolundTransferScatter(i.scatterCoords1.xyz, i.scatterCoords1); color = VolundApplyCloudScatter(i.scatterCoords1, color);
#endif
#if !defined(SURFACE_SCATTER_COORDS)
/* surface shader analysis currently forces us to include stuff even when unused */
/* we also have to convince the analyzer to not optimize out stuff we need */
#define SURFACE_SCATTER_COORDS float3 scaledWorldPos; float4 scatterCoords1; float3 scatterCoords2;
#define SURFACE_SCATTER_TRANSFER(pos, o) o.scatterCoords1.r = o.scatterCoords2.r = pos.x;
#define SURFACE_SCATTER_APPLY(i, color) color += (i.scaledWorldPos + i.scatterCoords1.xyz + i.scatterCoords2.xyz) * 0.000001f
#endif
#endif //FILE_ATMOSPHERICSCATTERING

9
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/AtmosphericScattering.hlsl.meta


fileFormatVersion: 2
guid: b0be9dce952dbb9479a5eb30e49c07a3
timeCreated: 1480068393
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderLoop/Editor/MaterialUpgrader.cs.meta


fileFormatVersion: 2
guid: 67b996d0727a74b029aff1545143be17
timeCreated: 1479851694
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

173
Assets/ScriptableRenderLoop/Editor/MaterialUpgrader.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
namespace UnityEditor.Experimental.ScriptableRenderLoop
{
public class MaterialUpgrader
{
string m_OldShader;
string m_NewShader;
Dictionary<string, string> m_TextureRename = new Dictionary<string, string>();
Dictionary<string, string> m_FloatRename = new Dictionary<string, string>();
Dictionary<string, string> m_ColorRename = new Dictionary<string, string>();
[Flags]
public enum UpgradeFlags
{
None = 0,
LogErrorOnNonExistingProperty = 1,
CleanupNonUpgradedProperties = 2,
}
public void Upgrade(Material material, UpgradeFlags flags)
{
Material newMaterial;
if ((flags & UpgradeFlags.CleanupNonUpgradedProperties) != 0)
{
newMaterial = new Material(Shader.Find(m_NewShader));
}
else
{
newMaterial = UnityEngine.Object.Instantiate(material) as Material;
newMaterial.shader = Shader.Find(m_NewShader);
}
Convert(material, newMaterial);
material.shader = Shader.Find(m_NewShader);
material.CopyPropertiesFromMaterial(newMaterial);
UnityEngine.Object.DestroyImmediate(newMaterial);
}
// Overridable function to implement custom material upgrading functionality
public virtual void Convert(Material srcMaterial, Material dstMaterial)
{
foreach (var t in m_TextureRename)
{
dstMaterial.SetTextureScale(t.Value, srcMaterial.GetTextureScale(t.Key));
dstMaterial.SetTextureOffset(t.Value, srcMaterial.GetTextureOffset(t.Key));
dstMaterial.SetTexture(t.Value, srcMaterial.GetTexture(t.Key));
}
foreach (var t in m_FloatRename)
dstMaterial.SetFloat(t.Value, srcMaterial.GetFloat(t.Key));
foreach (var t in m_ColorRename)
dstMaterial.SetColor(t.Value, srcMaterial.GetColor(t.Key));
}
public void RenameShader(string oldName, string newName)
{
m_OldShader = oldName;
m_NewShader = newName;
}
public void RenameTexture(string oldName, string newName)
{
m_TextureRename[oldName] = newName;
}
public void RenameFloat(string oldName, string newName)
{
m_FloatRename[oldName] = newName;
}
public void RenameColor(string oldName, string newName)
{
m_ColorRename[oldName] = newName;
}
static bool IsMaterialPath(string path)
{
return path.EndsWith(".mat", StringComparison.OrdinalIgnoreCase);
}
static MaterialUpgrader GetUpgrader(List<MaterialUpgrader> upgraders, Material material)
{
if (material == null || material.shader == null)
return null;
string shaderName = material.shader.name;
for (int i = 0; i != upgraders.Count; i++)
{
if (upgraders[i].m_OldShader == shaderName)
return upgraders[i];
}
return null;
}
//@TODO: Only do this when it exceeds memory consumption...
static void SaveAssetsAndFreeMemory()
{
AssetDatabase.SaveAssets();
GC.Collect();
EditorUtility.UnloadUnusedAssetsImmediate();
AssetDatabase.Refresh();
}
public static void UpgradeProjectFolder(List<MaterialUpgrader> upgraders, string progressBarName)
{
int totalMaterialCount = 0;
foreach (string s in UnityEditor.AssetDatabase.GetAllAssetPaths())
{
if (IsMaterialPath(s))
totalMaterialCount++;
}
int materialIndex = 0;
foreach (string path in UnityEditor.AssetDatabase.GetAllAssetPaths())
{
if (IsMaterialPath(path))
{
materialIndex++;
if (UnityEditor.EditorUtility.DisplayCancelableProgressBar(progressBarName, string.Format("({0} of {1}) {2}", materialIndex, totalMaterialCount, path), (float)materialIndex / (float)totalMaterialCount))
break;
Material m = UnityEditor.AssetDatabase.LoadMainAssetAtPath(path) as Material;
Upgrade(m, upgraders, UpgradeFlags.None);
//SaveAssetsAndFreeMemory();
}
}
UnityEditor.EditorUtility.ClearProgressBar();
}
public static void Upgrade(Material material, MaterialUpgrader upgrader, UpgradeFlags flags)
{
var upgraders = new List<MaterialUpgrader>();
upgraders.Add(upgrader);
Upgrade(material, upgraders, flags);
}
public static void Upgrade(Material material, List<MaterialUpgrader> upgraders, UpgradeFlags flags)
{
var upgrader = GetUpgrader(upgraders, material);
if (upgrader != null)
upgrader.Upgrade(material, flags);
}
public static void UpgradeSelection(List<MaterialUpgrader> upgraders, string progressBarName)
{
string lastMaterialName = "";
var selection = Selection.objects;
for (int i = 0; i < selection.Length; i++)
{
if (UnityEditor.EditorUtility.DisplayCancelableProgressBar(progressBarName, string.Format("({0} of {1}) {2}", i, selection.Length, lastMaterialName), (float)i / (float)selection.Length))
break;
var material = selection[i] as Material;
Upgrade(material, upgraders, UpgradeFlags.None);
if (material != null)
lastMaterialName = material.name;
}
UnityEditor.EditorUtility.ClearProgressBar();
}
}
}

20
Assets/forwardrenderloop.asset


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 98fe12104b04e43dd9a963f3f7b26e8e, type: 3}
m_Name: forwardrenderloop
m_EditorClassIdentifier:
m_ShadowSettings:
enabled: 1
shadowAtlasWidth: 4096
shadowAtlasHeight: 4096
maxShadowDistance: 1000
directionalLightCascadeCount: 4
directionalLightCascades: {x: 0.05, y: 0.2, z: 0.3}

8
Assets/forwardrenderloop.asset.meta


fileFormatVersion: 2
guid: bfc231f294556ca4799e7f7feddee50d
timeCreated: 1475076344
licenseType: Pro
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存