Evgenii Golubev 8 年前
当前提交
b2ff5346
共有 23 个文件被更改,包括 1538 次插入896 次删除
  1. 226
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  2. 7
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/LightDefinition.cs
  3. 8
      Assets/ScriptableRenderLoop/HDRenderLoop/Lighting/TilePass/TilePassLoop.hlsl
  4. 287
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/Editor/LayeredLitUI.cs
  5. 215
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/LayeredLit/LayeredLit.shader
  6. 272
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Editor/LitUI.cs
  7. 66
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/Lit.shader
  8. 636
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitData.hlsl
  9. 24
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSharePass.hlsl
  10. 5
      Assets/ScriptableRenderLoop/HDRenderLoop/ShaderVariables.hlsl
  11. 150
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/SkyRenderer.cs
  12. 4
      Assets/ScriptableRenderLoop/RenderPasses/ShadowRenderPass.cs
  13. 2
      Assets/ScriptableRenderLoop/ShaderLibrary/AreaLighting.hlsl
  14. 23
      Assets/ScriptableRenderLoop/ShaderLibrary/CommonMaterial.hlsl
  15. 5
      Assets/ScriptableRenderLoop/ShaderLibrary/ImageBasedLighting.hlsl
  16. 2
      ProjectSettings/ProjectVersion.txt
  17. 35
      .collabignore
  18. 232
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSurfaceData.hlsl
  19. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSurfaceData.hlsl.meta
  20. 68
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/GGXConvolve.shader
  21. 9
      Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/GGXConvolve.shader.meta
  22. 141
      Assets/TestScenes/HDTest/Material/HDRenderLoopMaterials/Chrome.mat
  23. 8
      Assets/TestScenes/HDTest/Material/HDRenderLoopMaterials/Chrome.mat.meta

226
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


int m_VelocityBuffer;
int m_DistortionBuffer;
bool m_Dirty = false;
RenderTargetIdentifier m_CameraColorBufferRT;
RenderTargetIdentifier m_CameraDepthBufferRT;
RenderTargetIdentifier m_VelocityBufferRT;

void OnValidate()
{
Rebuild();
m_Dirty = true;
}
public override void Rebuild()

m_lightList = new LightList();
m_lightList.Allocate();
m_Dirty = false;
}
void OnDisable()

// We clear only the depth buffer, no need to clear the various color buffer as we overwrite them.
// Clear depth/stencil and init buffers
using (new Utilities.ProfilingSample("InitGBuffers and clear Depth/Stencil", renderLoop))
{
var cmd = new CommandBuffer();
cmd.name = "";
{
var cmd = new CommandBuffer();
cmd.name = "";
// Init buffer
// With scriptable render loop we must allocate ourself depth and color buffer (We must be independent of backbuffer for now, hope to fix that later).
// Also we manage ourself the HDR format, here allocating fp16 directly.
// With scriptable render loop we can allocate temporary RT in a command buffer, they will not be release with ExecuteCommandBuffer
// These temporary surface are release automatically at the end of the scriptable renderloop if not release explicitly
int w = camera.pixelWidth;
int h = camera.pixelHeight;
// Init buffer
// With scriptable render loop we must allocate ourself depth and color buffer (We must be independent of backbuffer for now, hope to fix that later).
// Also we manage ourself the HDR format, here allocating fp16 directly.
// With scriptable render loop we can allocate temporary RT in a command buffer, they will not be release with ExecuteCommandBuffer
// These temporary surface are release automatically at the end of the scriptable renderloop if not release explicitly
int w = camera.pixelWidth;
int h = camera.pixelHeight;
cmd.GetTemporaryRT(m_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
cmd.GetTemporaryRT(m_CameraDepthBuffer, w, h, 24, FilterMode.Point, RenderTextureFormat.Depth);
if (!debugParameters.useForwardRenderingOnly)
{
m_gbufferManager.InitGBuffers(w, h, cmd);
}
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
cmd.GetTemporaryRT(m_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
cmd.GetTemporaryRT(m_CameraDepthBuffer, w, h, 24, FilterMode.Point, RenderTextureFormat.Depth);
if (!debugParameters.useForwardRenderingOnly)
{
m_gbufferManager.InitGBuffers(w, h, cmd);
Utilities.SetRenderTarget(renderLoop, m_CameraColorBufferRT, m_CameraDepthBufferRT, ClearFlag.ClearDepth);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
Utilities.SetRenderTarget(renderLoop, m_CameraColorBufferRT, m_CameraDepthBufferRT, ClearFlag.ClearDepth);
}
// TEMP: As we are in development and have not all the setup pass we still clear the color in emissive buffer and gbuffer, but this will be removed later.
// TEMP: As we are in development and have not all the setup pass we still clear the color in emissive buffer and gbuffer, but this will be removed later.
// Clear HDR target
using (new Utilities.ProfilingSample("Clear HDR target", renderLoop))
{
Utilities.SetRenderTarget(renderLoop, m_CameraColorBufferRT, m_CameraDepthBufferRT, ClearFlag.ClearColor, Color.black);
}
// Clear HDR target
using (new Utilities.ProfilingSample("Clear HDR target", renderLoop))
{
Utilities.SetRenderTarget(renderLoop, m_CameraColorBufferRT, m_CameraDepthBufferRT, ClearFlag.ClearColor, Color.black);
}
// Clear GBuffers
using (new Utilities.ProfilingSample("Clear GBuffer", renderLoop))
{
Utilities.SetRenderTarget(renderLoop, m_gbufferManager.GetGBuffers(), m_CameraDepthBufferRT, ClearFlag.ClearColor, Color.black);
}
// Clear GBuffers
using (new Utilities.ProfilingSample("Clear GBuffer", renderLoop))
{
Utilities.SetRenderTarget(renderLoop, m_gbufferManager.GetGBuffers(), m_CameraDepthBufferRT, ClearFlag.ClearColor, Color.black);
// END TEMP
// END TEMP
}
}
void RenderOpaqueRenderList(CullResults cull, Camera camera, RenderLoop renderLoop, string passName, RendererConfiguration rendererConfiguration = 0)

using (new Utilities.ProfilingSample("Depth Prepass", renderLoop))
{
// TODO: Must do opaque then alpha masked for performance!
// TODO: front to back for opaque and by materal for opaque tested when we split in two
// TODO: Must do opaque then alpha masked for performance!
// TODO: front to back for opaque and by materal for opaque tested when we split in two
RenderOpaqueRenderList(cull, camera, renderLoop, "DepthOnly");
}
RenderOpaqueRenderList(cull, camera, renderLoop, "DepthOnly");
}
}
void RenderGBuffer(CullResults cull, Camera camera, RenderLoop renderLoop)

using (new Utilities.ProfilingSample("GBuffer Pass", renderLoop))
{
// setup GBuffer for rendering
// setup GBuffer for rendering
// render opaque objects into GBuffer
RenderOpaqueRenderList(cull, camera, renderLoop, "GBuffer", Utilities.kRendererConfigurationBakedLighting);
}
// render opaque objects into GBuffer
RenderOpaqueRenderList(cull, camera, renderLoop, "GBuffer", Utilities.kRendererConfigurationBakedLighting);
}
}
// This pass is use in case of forward opaque and deferred rendering. We need to render forward objects before tile lighting pass

if (debugParameters.useDepthPrepass)
return;
// TODO: Use the render queue index to only send the forward opaque!
Utilities.SetRenderTarget(renderLoop, m_CameraDepthBufferRT, "Depth Prepass");
RenderOpaqueRenderList(cull, camera, renderLoop, "DepthOnly");
using (new Utilities.ProfilingSample("Depth Prepass", renderLoop))
{
// TODO: Use the render queue index to only send the forward opaque!
Utilities.SetRenderTarget(renderLoop, m_CameraDepthBufferRT);
RenderOpaqueRenderList(cull, camera, renderLoop, "DepthOnly");
}
}
void RenderDebugViewMaterial(CullResults cull, Camera camera, RenderLoop renderLoop)

using (new Utilities.ProfilingSample("Single Pass - Deferred Lighting Pass", renderLoop))
{
// Bind material data
m_LitRenderLoop.Bind();
m_SinglePassLightLoop.RenderDeferredLighting(camera, renderLoop, m_CameraColorBuffer);
// m_TilePassLightLoop.RenderDeferredLighting(camera, renderLoop, m_CameraColorBuffer);
}
// Bind material data
m_LitRenderLoop.Bind();
m_SinglePassLightLoop.RenderDeferredLighting(camera, renderLoop, m_CameraColorBuffer);
// m_TilePassLightLoop.RenderDeferredLighting(camera, renderLoop, m_CameraColorBuffer);
}
}
void RenderSky(Camera camera, RenderLoop renderLoop)

{
using (new Utilities.ProfilingSample("Forward Pass", renderLoop))
{
// Bind material data
m_LitRenderLoop.Bind();
// Bind material data
m_LitRenderLoop.Bind();
if (debugParameters.useForwardRenderingOnly)
{
RenderOpaqueRenderList(cullResults, camera, renderLoop, "Forward");
}
if (debugParameters.useForwardRenderingOnly)
{
RenderOpaqueRenderList(cullResults, camera, renderLoop, "Forward");
}
RenderTransparentRenderList(cullResults, camera, renderLoop, "Forward", Utilities.kRendererConfigurationBakedLighting);
}
RenderTransparentRenderList(cullResults, camera, renderLoop, "Forward", Utilities.kRendererConfigurationBakedLighting);
}
}
void RenderForwardUnlit(CullResults cullResults, Camera camera, RenderLoop renderLoop)

// Bind material data
m_LitRenderLoop.Bind();
// Bind material data
m_LitRenderLoop.Bind();
RenderOpaqueRenderList(cullResults, camera, renderLoop, "ForwardUnlit");
RenderTransparentRenderList(cullResults, camera, renderLoop, "ForwardUnlit");
}
RenderOpaqueRenderList(cullResults, camera, renderLoop, "ForwardUnlit");
RenderTransparentRenderList(cullResults, camera, renderLoop, "ForwardUnlit");
}
}
void RenderVelocity(CullResults cullResults, Camera camera, RenderLoop renderLoop)

// warning CS0162: Unreachable code detected // warning CS0429: Unreachable expression code detected
#pragma warning disable 162, 429
// If opaque velocity have been render during GBuffer no need to render it here
if ((ShaderConfig.VelocityInGbuffer == 0) || debugParameters.useForwardRenderingOnly)
return ;
// warning CS0162: Unreachable code detected // warning CS0429: Unreachable expression code detected
#pragma warning disable 162, 429
// If opaque velocity have been render during GBuffer no need to render it here
if ((ShaderConfig.VelocityInGbuffer == 0) || debugParameters.useForwardRenderingOnly)
return ;
int w = camera.pixelWidth;
int h = camera.pixelHeight;
int w = camera.pixelWidth;
int h = camera.pixelHeight;
cmd.GetTemporaryRT(m_VelocityBuffer, w, h, 0, FilterMode.Point, Builtin.RenderLoop.GetVelocityBufferFormat(), Builtin.RenderLoop.GetVelocityBufferReadWrite());
cmd.SetRenderTarget(m_VelocityBufferRT, m_CameraDepthBufferRT);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
cmd.GetTemporaryRT(m_VelocityBuffer, w, h, 0, FilterMode.Point, Builtin.RenderLoop.GetVelocityBufferFormat(), Builtin.RenderLoop.GetVelocityBufferReadWrite());
cmd.SetRenderTarget(m_VelocityBufferRT, m_CameraDepthBufferRT);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
RenderOpaqueRenderList(cullResults, camera, renderLoop, "MotionVectors");
#pragma warning restore 162, 429
}
RenderOpaqueRenderList(cullResults, camera, renderLoop, "MotionVectors");
#pragma warning restore 162, 429
}
}
void RenderDistortion(CullResults cullResults, Camera camera, RenderLoop renderLoop)

int w = camera.pixelWidth;
int h = camera.pixelHeight;
int w = camera.pixelWidth;
int h = camera.pixelHeight;
cmd.GetTemporaryRT(m_DistortionBuffer, w, h, 0, FilterMode.Point, Builtin.RenderLoop.GetDistortionBufferFormat(), Builtin.RenderLoop.GetDistortionBufferReadWrite());
cmd.SetRenderTarget(m_DistortionBufferRT, m_CameraDepthBufferRT);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
cmd.GetTemporaryRT(m_DistortionBuffer, w, h, 0, FilterMode.Point, Builtin.RenderLoop.GetDistortionBufferFormat(), Builtin.RenderLoop.GetDistortionBufferReadWrite());
cmd.SetRenderTarget(m_DistortionBufferRT, m_CameraDepthBufferRT);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
// Only transparent object can render distortion vectors
RenderTransparentRenderList(cullResults, camera, renderLoop, "DistortionVectors");
}
// Only transparent object can render distortion vectors
RenderTransparentRenderList(cullResults, camera, renderLoop, "DistortionVectors");
}
}

{
// Those could be tweakable for the neutral tonemapper, but in the case of the LookDev we don't need that
const float blackIn = 0.02f;
const float whiteIn = 10.0f;
const float blackOut = 0.0f;
const float whiteOut = 10.0f;
const float whiteLevel = 5.3f;
const float whiteClip = 10.0f;
const float dialUnits = 20.0f;
const float halfDialUnits = dialUnits * 0.5f;
// Those could be tweakable for the neutral tonemapper, but in the case of the LookDev we don't need that
const float blackIn = 0.02f;
const float whiteIn = 10.0f;
const float blackOut = 0.0f;
const float whiteOut = 10.0f;
const float whiteLevel = 5.3f;
const float whiteClip = 10.0f;
const float dialUnits = 20.0f;
const float halfDialUnits = dialUnits * 0.5f;
// converting from artist dial units to easy shader-lerps (0-1)
var tonemapCoeff1 = new Vector4((blackIn * dialUnits) + 1.0f, (blackOut * halfDialUnits) + 1.0f, (whiteIn / dialUnits), (1.0f - (whiteOut / dialUnits)));
var tonemapCoeff2 = new Vector4(0.0f, 0.0f, whiteLevel, whiteClip / halfDialUnits);
// converting from artist dial units to easy shader-lerps (0-1)
var tonemapCoeff1 = new Vector4((blackIn * dialUnits) + 1.0f, (blackOut * halfDialUnits) + 1.0f, (whiteIn / dialUnits), (1.0f - (whiteOut / dialUnits)));
var tonemapCoeff2 = new Vector4(0.0f, 0.0f, whiteLevel, whiteClip / halfDialUnits);
m_FinalPassMaterial.SetVector("_ToneMapCoeffs1", tonemapCoeff1);
m_FinalPassMaterial.SetVector("_ToneMapCoeffs2", tonemapCoeff2);
m_FinalPassMaterial.SetVector("_ToneMapCoeffs1", tonemapCoeff1);
m_FinalPassMaterial.SetVector("_ToneMapCoeffs2", tonemapCoeff2);
m_FinalPassMaterial.SetFloat("_EnableToneMap", debugParameters.enableTonemap ? 1.0f : 0.0f);
m_FinalPassMaterial.SetFloat("_Exposure", debugParameters.exposure);
m_FinalPassMaterial.SetFloat("_EnableToneMap", debugParameters.enableTonemap ? 1.0f : 0.0f);
m_FinalPassMaterial.SetFloat("_Exposure", debugParameters.exposure);
// Resolve our HDR texture to CameraTarget.
cmd.Blit(m_CameraColorBufferRT, BuiltinRenderTextureType.CameraTarget, m_FinalPassMaterial, 0);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
// Resolve our HDR texture to CameraTarget.
cmd.Blit(m_CameraColorBufferRT, BuiltinRenderTextureType.CameraTarget, m_FinalPassMaterial, 0);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
}
// Function to prepare light structure for GPU lighting

public override void Render(Camera[] cameras, RenderLoop renderLoop)
{
if (m_Dirty)
{
Rebuild();
}
if (!m_LitRenderLoop.isInit)
{
m_LitRenderLoop.RenderInit(renderLoop);

ShadowOutput shadows;
using (new Utilities.ProfilingSample("Shadow Pass", renderLoop))
{
m_ShadowPass.Render(renderLoop, cullResults, out shadows);
m_ShadowPass.Render(renderLoop, cullResults, out shadows);
}
renderLoop.SetupCameraProperties(camera); // Need to recall SetupCameraProperties after m_ShadowPass.Render

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


};
[GenerateHLSL]
public enum EnvConstants
{
SpecCubeLodStep = 6
}
[GenerateHLSL]
public struct EnvLightData
{
public Vector3 positionWS;

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


#ifdef PROCESS_PUNCTUAL_LIGHT
uint punctualLightStart;
uint punctualLightCount;
GetCountAndStart(coord, DIRECT_LIGHT, linearDepth, start, punctualLightCount);
GetCountAndStart(coord, DIRECT_LIGHT, linearDepth, punctualLightStart, punctualLightCount);
for (i = 0; i < punctualLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;

// TODO: Area lights are where the sorting is important (Morten approach with while loop)
uint areaLightStart;
uint areaLightCount;
GetCountAndStart(coord, LightCatergory.AreaLight, linearDepth, start, punctualLightCount);
GetCountAndStart(coord, LightCatergory.AreaLight, linearDepth, areaLightStart, areaLightCount);
for (i = 0; i < areaLightCount; ++i)
{
float3 localDiffuseLighting, localSpecularLighting;

#ifdef PROCESS_ENV_LIGHT
uint envLightStart;
uint envLightCount;
GetCountAndStart(coord, REFLECTION_LIGHT, linearDepth, start, envLightCount);
GetCountAndStart(coord, REFLECTION_LIGHT, linearDepth, envLightStart, envLightCount);
float3 iblDiffuseLighting = float3(0.0, 0.0, 0.0);
float3 iblSpecularLighting = float3(0.0, 0.0, 0.0);

float3 localDiffuseLighting, localSpecularLighting;
float2 weight;
context.sampleReflection = SINGLE_PASS_CONTEXT_SAMPLE_REFLECTION_PROBES;
EvaluateBSDF_Env(context, V, positionWS, prelightData, _EnvLightList[FetchIndex(punctualLightStart, i)], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
EvaluateBSDF_Env(context, V, positionWS, prelightData, _EnvLightList[FetchIndex(envLightStart, i)], bsdfData, localDiffuseLighting, localSpecularLighting, weight);
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);
}

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


{
internal class LayeredLitGUI : LitGUI
{
public enum LayerMapping
public enum LayerUVBaseMapping
UV3,
//Triplanar,
Triplanar,
private class Styles
public enum LayerUVDetailMapping
{
UV0,
UV1,
UV3
}
private class StylesLayer
{
public readonly GUIContent[] layerLabels =
{

new GUIContent("Layer 3"),
};
public readonly GUIContent materialLayer = new GUIContent("Material");
public readonly GUIContent syncButton = new GUIContent("Re-Synchronize Layers", "Re-synchronize all layers's properties with the referenced Material");
public readonly GUIContent layers = new GUIContent("Layers");
public readonly GUIContent emission = new GUIContent("Emissive");
public readonly GUIContent layerMapMask = new GUIContent("Layer Mask", "Layer mask (multiplied by vertex color if enabled)");
public readonly GUIContent layerMapVertexColor = new GUIContent("Use Vertex Color", "Layer mask (multiplied by layer mask if enabled)");
public readonly GUIContent layerCount = new GUIContent("Layer Count", "Number of layers.");
public readonly GUIContent layerSize = new GUIContent("Size", "Size of the layer mapping in world units.");
public readonly GUIContent layerMapping = new GUIContent("Mapping", "Mapping mode of the layer.");
public readonly GUIContent materialLayerText = new GUIContent("Material");
public readonly GUIContent syncButtonText = new GUIContent("Re-Synchronize Layers", "Re-synchronize all layers's properties with the referenced Material");
public readonly GUIContent layersText = new GUIContent("Layers");
public readonly GUIContent emissiveText = new GUIContent("Emissive");
public readonly GUIContent layerMapMaskText = new GUIContent("Layer Mask", "Layer mask (multiplied by vertex color if enabled)");
public readonly GUIContent layerMapVertexColorText = new GUIContent("Use Vertex Color", "Layer mask (multiplied by layer mask if enabled)");
public readonly GUIContent layerCountText = new GUIContent("Layer Count", "Number of layers.");
public readonly GUIContent layerTexWorldScaleText = new GUIContent("Tex world scale", "Scale to apply to world position for Planar/Trilinear");
public readonly GUIContent UVBaseText = new GUIContent("Base UV Mapping", "Base UV Mapping mode of the layer.");
public readonly GUIContent UVDetailText = new GUIContent("Detail UV Mapping", "Detail UV Mapping mode of the layer.");
static Styles s_Styles = null;
private static Styles styles { get { if (s_Styles == null) s_Styles = new Styles(); return s_Styles; } }
static StylesLayer s_Styles = null;
private static StylesLayer styles { get { if (s_Styles == null) s_Styles = new StylesLayer(); return s_Styles; } }
// Needed for json serialization to work
[Serializable]

}
private const int kMaxLayerCount = 4;
private const int kSyncButtonWidth = 58;
private const string kLayerMaskMap = "_LayerMaskMap";
private const string kLayerMaskVertexColor = "_LayerMaskVertexColor";
private const string kLayerCount = "_LayerCount";
private const string kLayerMapping = "_LayerMapping";
private const string kLayerSize = "_LayerSize";
const int kMaxLayerCount = 4;
const int kSyncButtonWidth = 58;
private Material[] m_MaterialLayers = new Material[kMaxLayerCount];
Material[] m_MaterialLayers = new Material[kMaxLayerCount];
MaterialProperty layerCountProperty = null;
MaterialProperty layerMaskMapProperty = null;
MaterialProperty layerMaskVertexColorProperty = null;
MaterialProperty[] layerMappingProperty = new MaterialProperty[kMaxLayerCount];
MaterialProperty[] layerSizeProperty = new MaterialProperty[kMaxLayerCount];
MaterialProperty layerMaskMap = null;
const string kLayerMaskMap = "_LayerMaskMap";
MaterialProperty layerMaskVertexColor = null;
const string kLayerMaskVertexColor = "_LayerMaskVertexColor";
MaterialProperty layerCount = null;
const string kLayerCount = "_LayerCount";
MaterialProperty[] layerTexWorldScale = new MaterialProperty[kMaxLayerCount];
const string kLayerTexWorldScale = "_TexWorldScale";
MaterialProperty[] layerUVBase = new MaterialProperty[kMaxLayerCount];
const string kLayerUVBase = "_UVBase";
MaterialProperty[] layerUVMappingMask = new MaterialProperty[kMaxLayerCount];
const string kLayerUVMappingMask = "_UVMappingMask";
MaterialProperty[] layerUVDetail = new MaterialProperty[kMaxLayerCount];
const string kLayerUVDetail = "_UVDetail";
MaterialProperty[] layerUVDetailsMappingMask = new MaterialProperty[kMaxLayerCount];
const string kLayerUVDetailsMappingMask = "_UVDetailsMappingMask";
int layerCount
MaterialProperty layerEmissiveColor = null;
const string kLayerEmissiveColor = "_EmissiveColor";
MaterialProperty layerEmissiveColorMap = null;
const string kLayerEmissiveColorMap = "_EmissiveColorMap";
MaterialProperty layerEmissiveIntensity = null;
const string kLayerEmissiveIntensity = "_EmissiveIntensity";
private void FindLayerProperties(MaterialProperty[] props)
set { layerCountProperty.floatValue = (float)value; }
get { return (int)layerCountProperty.floatValue; }
layerMaskMap = FindProperty(kLayerMaskMap, props);
layerMaskVertexColor = FindProperty(kLayerMaskVertexColor, props);
layerCount = FindProperty(kLayerCount, props);
for (int i = 0; i < numLayer; ++i)
{
layerTexWorldScale[i] = FindProperty(string.Format("{0}{1}", kLayerTexWorldScale, i), props);
layerUVBase[i] = FindProperty(string.Format("{0}{1}", kLayerUVBase, i), props);
layerUVMappingMask[i] = FindProperty(string.Format("{0}{1}", kLayerUVMappingMask, i), props);
layerUVDetail[i] = FindProperty(string.Format("{0}{1}", kLayerUVDetail, i), props);
layerUVDetailsMappingMask[i] = FindProperty(string.Format("{0}{1}", kLayerUVDetailsMappingMask, i), props);
}
layerEmissiveColor = FindProperty(kLayerEmissiveColor, props);
layerEmissiveColorMap = FindProperty(kLayerEmissiveColorMap, props);
layerEmissiveIntensity = FindProperty(kLayerEmissiveIntensity, props);
}
int numLayer
{
set { layerCount.floatValue = (float)value; }
get { return (int)layerCount.floatValue; }
for (int i = 0; i < layerCount; ++i)
for (int i = 0; i < numLayer; ++i)
{
SynchronizeLayerProperties(i);
}

{
bool result = true;
outValueNames = "";
for (int i = 0; i < layerCount; ++i)
for (int i = 0; i < numLayer; ++i)
{
Material layer = m_MaterialLayers[i];
if (layer != null)

outValueNames += shortNames[currentValue] + " ";
for (int j = i + 1; j < layerCount; ++j)
for (int j = i + 1; j < numLayer; ++j)
{
Material otherLayer = m_MaterialLayers[j];
if (otherLayer != null)

{
bool result = true;
outValueNames = "";
for (int i = 0; i < layerCount; ++i)
for (int i = 0; i < numLayer; ++i)
{
Material layer = m_MaterialLayers[i];
if (layer != null)

for (int j = i + 1; j < layerCount; ++j)
for (int j = i + 1; j < numLayer; ++j)
{
Material otherLayer = m_MaterialLayers[j];
if (otherLayer != null)

{
string optionValueNames = "";
// We need to check consistency between all layers.
// Each input options and each input maps might can result in different #defines in the shader so all of them need to be consistent
// Each input options and each input maps can result in different #defines in the shader so all of them need to be consistent
string[] emissiveModeShortNames = { "Color", "Mask" };
string[] detailModeShortNames = { "DNormal", "DAOHeight" };
if (!CheckInputOptionConsistency(kSmoothnessTextureChannelProp, smoothnessSourceShortNames, ref optionValueNames))
if (!CheckInputOptionConsistency(kSmoothnessTextureChannel, smoothnessSourceShortNames, ref optionValueNames))
if (!CheckInputOptionConsistency(kEmissiveColorMode, emissiveModeShortNames, ref optionValueNames))
{
warningInputOptions += "Emissive Mode: " + optionValueNames + "\n";
}
if (!CheckInputOptionConsistency(kNormalMapSpace, normalMapShortNames, ref optionValueNames))
{
warningInputOptions += "Normal Map Space: " + optionValueNames + "\n";

warningInputOptions += "Height Map Mode: " + optionValueNames + "\n";
}
if (!CheckInputOptionConsistency(kDetailMapMode, detailModeShortNames, ref optionValueNames))
{
warningInputOptions += "Detail Map Mode: " + optionValueNames + "\n";
}
if (warningInputOptions != string.Empty)

{
warningInputMaps += "Normal Map: " + optionValueNames + "\n";
}
if (!CheckInputMapConsistency(kDetailMap, ref optionValueNames))
{
warningInputMaps += "Detail Map: " + optionValueNames + "\n";
}
if (!CheckInputMapConsistency(kspecularOcclusionMap, ref optionValueNames))
if (!CheckInputMapConsistency(kSpecularOcclusionMap, ref optionValueNames))
}
if (!CheckInputMapConsistency(kEmissiveColorMap, ref optionValueNames))
{
warningInputMaps += "Emissive Color Map: " + optionValueNames + "\n";
}
if (!CheckInputMapConsistency(kHeightMap, ref optionValueNames))
{

// We synchronize input options with the firsts non null Layer (all layers should have consistent options)
Material firstLayer = null;
int i = 0;
while (i < layerCount && !(firstLayer = m_MaterialLayers[i])) ++i;
while (i < numLayer && !(firstLayer = m_MaterialLayers[i])) ++i;
material.SetFloat(kSmoothnessTextureChannelProp, firstLayer.GetFloat(kSmoothnessTextureChannelProp));
material.SetFloat(kEmissiveColorMode, firstLayer.GetFloat(kEmissiveColorMode));
material.SetFloat(kSmoothnessTextureChannel, firstLayer.GetFloat(kSmoothnessTextureChannel));
// Force emissive to be emissive color
material.SetFloat(kEmissiveColorMode, (float)EmissiveColorMode.UseEmissiveColor);
}
}

EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
m_MaterialLayers[layerIndex] = EditorGUILayout.ObjectField(styles.materialLayer, m_MaterialLayers[layerIndex], typeof(Material), true) as Material;
m_MaterialLayers[layerIndex] = EditorGUILayout.ObjectField(styles.materialLayerText, m_MaterialLayers[layerIndex], typeof(Material), true) as Material;
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(materialImporter, "Change layer material");

EditorGUI.BeginChangeCheck();
m_MaterialEditor.ShaderProperty(layerMappingProperty[layerIndex], styles.layerMapping);
m_MaterialEditor.ShaderProperty(layerUVBase[layerIndex], styles.UVBaseText);
if ((LayerMapping)layerMappingProperty[layerIndex].floatValue == LayerMapping.Planar)
if (((LayerUVBaseMapping)layerUVBase[layerIndex].floatValue == LayerUVBaseMapping.Planar) ||
((LayerUVBaseMapping)layerUVBase[layerIndex].floatValue == LayerUVBaseMapping.Triplanar))
m_MaterialEditor.ShaderProperty(layerSizeProperty[layerIndex], styles.layerSize);
m_MaterialEditor.ShaderProperty(layerTexWorldScale[layerIndex], styles.layerTexWorldScaleText);
else
{
EditorGUI.BeginChangeCheck();
m_MaterialEditor.ShaderProperty(layerUVDetail[layerIndex], styles.UVDetailText);
if (EditorGUI.EndChangeCheck())
{
result = true;
}
}
EditorGUI.indentLevel--;

GUI.changed = false;
EditorGUI.indentLevel++;
GUILayout.Label(styles.layers, EditorStyles.boldLabel);
GUILayout.Label(styles.layersText, EditorStyles.boldLabel);
int newLayerCount = EditorGUILayout.IntSlider(styles.layerCount, (int)layerCountProperty.floatValue, 2, 4);
int newLayerCount = EditorGUILayout.IntSlider(styles.layerCountText, (int)layerCount.floatValue, 2, 4);
layerCountProperty.floatValue = (float)newLayerCount;
layerCount.floatValue = (float)newLayerCount;
m_MaterialEditor.ShaderProperty(layerMaskVertexColorProperty, styles.layerMapVertexColor);
m_MaterialEditor.TexturePropertySingleLine(styles.layerMapMask, layerMaskMapProperty);
m_MaterialEditor.ShaderProperty(layerMaskVertexColor, styles.layerMapVertexColorText);
m_MaterialEditor.TexturePropertySingleLine(styles.layerMapMaskText, layerMaskMap);
for (int i = 0; i < layerCount; i++)
for (int i = 0; i < numLayer; i++)
{
layerChanged |= DoLayerGUI(materialImporter, i);
}

{
GUILayout.FlexibleSpace();
if (GUILayout.Button(styles.syncButton))
if (GUILayout.Button(styles.syncButtonText))
{
SynchronizeAllLayersProperties();
layerChanged = true;

{
// Find first non null layer
int i = 0;
while (i < layerCount && (m_MaterialLayers[i] == null)) ++i;
while (i < numLayer && (m_MaterialLayers[i] == null)) ++i;
if (i < layerCount)
if (i < numLayer)
SetKeyword(material, "_SPECULAROCCLUSIONMAP", material.GetTexture(kspecularOcclusionMap + i));
SetKeyword(material, "_SPECULAROCCLUSIONMAP", material.GetTexture(kSpecularOcclusionMap + i));
SetKeyword(material, "_LAYER_MASK_MAP", material.GetTexture(kLayerMaskMap));
protected override void SetupEmissionGIFlags(Material material)
{
// Setup lightmap emissive flags
bool nonNullEmissive = false;
for(int i = 0 ; i < layerCount ; ++i)
{
string paramName = string.Format("_EmissiveIntensity{0}", i);
if (material.GetFloat(paramName) > 0.0f)
{
nonNullEmissive = true;
break;
}
}
var realtimeEmission = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.RealtimeEmissive) > 0;
bool shouldEmissionBeEnabled = nonNullEmissive || realtimeEmission;
MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags;
if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0)
{
if (shouldEmissionBeEnabled)
flags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;
else
flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack;
material.globalIlluminationFlags = flags;
}
}
if (layerCount == 4)
if (numLayer == 4)
else if (layerCount == 3)
else if (numLayer == 3)
{
SetKeyword(material, "_LAYEREDLIT_4_LAYERS", false);
SetKeyword(material, "_LAYEREDLIT_3_LAYERS", true);

SetKeyword(material, "_LAYEREDLIT_3_LAYERS", false);
}
const string kLayerMappingUV1 = "_LAYER_MAPPING_UV1_";
const string kLayerMappingPlanar = "_LAYER_MAPPING_PLANAR_";
for (int i = 0 ; i <layerCount ; ++i)
for (int i = 0 ; i < numLayer; ++i)
string layerMappingParam = string.Format("{0}{1}", kLayerMapping, i);
LayerMapping layerMapping = (LayerMapping)material.GetFloat(layerMappingParam);
string currentLayerMappingUV1 = string.Format("{0}{1}", kLayerMappingUV1, i);
string currentLayerMappingPlanar = string.Format("{0}{1}", kLayerMappingPlanar, i);
// We setup the masking map based on the enum for each layer.
// using mapping mask allow to reduce the number of generated combination for a very small increase in ALU
string layerUVBaseParam = string.Format("{0}{1}", kLayerUVBase, i);
LayerUVBaseMapping layerUVBaseMapping = (LayerUVBaseMapping)material.GetFloat(layerUVBaseParam);
string layerUVDetailParam = string.Format("{0}{1}", kLayerUVDetail, i);
LayerUVDetailMapping layerUVDetailMapping = (LayerUVDetailMapping)material.GetFloat(layerUVDetailParam);
if(layerMapping == LayerMapping.UV1)
float X, Y, Z, W;
X = (layerUVBaseMapping == LayerUVBaseMapping.UV0) ? 1.0f : 0.0f;
Y = (layerUVBaseMapping == LayerUVBaseMapping.UV1) ? 1.0f : 0.0f;
Z = (layerUVBaseMapping == LayerUVBaseMapping.UV3) ? 1.0f : 0.0f;
W = (layerUVBaseMapping == LayerUVBaseMapping.Planar) ? 1.0f : 0.0f;
layerUVMappingMask[i].colorValue = new Color(X, Y, Z, W);
if (layerUVBaseMapping == LayerUVBaseMapping.Triplanar)
SetKeyword(material, currentLayerMappingUV1, true);
SetKeyword(material, currentLayerMappingPlanar, false);
SetKeyword(material, currentLayerMappingTriplanar, false);
SetKeyword(material, currentLayerMappingTriplanar, true);
else if(layerMapping == LayerMapping.Planar)
// If base is planar mode, detail is planar too
if (W > 0.0f)
SetKeyword(material, currentLayerMappingUV1, false);
SetKeyword(material, currentLayerMappingPlanar, true);
SetKeyword(material, currentLayerMappingTriplanar, false);
X = Y = Z = 0.0f;
}
else
{
X = (layerUVDetailMapping == LayerUVDetailMapping.UV0) ? 1.0f : 0.0f;
Y = (layerUVDetailMapping == LayerUVDetailMapping.UV1) ? 1.0f : 0.0f;
Z = (layerUVDetailMapping == LayerUVDetailMapping.UV3) ? 1.0f : 0.0f;
//else if(layerMapping == LayerMapping.Triplanar)
//{
// SetKeyword(material, currentLayerMappingUV1, false);
// SetKeyword(material, currentLayerMappingPlanar, false);
// SetKeyword(material, currentLayerMappingTriplanar, true);
//}
}
}
private void FindLayerProperties(MaterialProperty[] props)
{
layerMaskMapProperty = FindProperty(kLayerMaskMap, props);
layerMaskVertexColorProperty = FindProperty(kLayerMaskVertexColor, props);
layerCountProperty = FindProperty(kLayerCount, props);
for (int i = 0; i < layerCount; ++i)
{
layerMappingProperty[i] = FindProperty(string.Format("{0}{1}", kLayerMapping, i), props);
layerSizeProperty[i] = FindProperty(string.Format("{0}{1}", kLayerSize, i), props);
layerUVDetailsMappingMask[i].colorValue = new Color(X, Y, Z, 0.0f); // W Reuse planar mode from base
}
}

EditorGUI.BeginChangeCheck();
{
ShaderOptionsGUI();
EditorGUI.indentLevel++;
EditorGUILayout.LabelField(styles.emission);
m_MaterialEditor.LightmapEmissionProperty(1);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
}
if (EditorGUI.EndChangeCheck())

bool layerChanged = DoLayersGUI(materialImporter);
EditorGUILayout.Space();
GUILayout.Label(Styles.emissiveText, EditorStyles.boldLabel);
EditorGUI.indentLevel++;
m_MaterialEditor.TexturePropertySingleLine(Styles.emissiveText, layerEmissiveColorMap, layerEmissiveColor);
m_MaterialEditor.ShaderProperty(layerEmissiveIntensity, Styles.emissiveIntensityText);
m_MaterialEditor.LightmapEmissionProperty(1);
EditorGUI.indentLevel--;
CheckLayerConsistency();

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


// They are use to fill a SurfaceData. With a MaterialGraph this should not exist.
// Reminder. Color here are in linear but the UI (color picker) do the conversion sRGB to linear
_BaseColor0("BaseColor0", Color) = (1,1,1,1)
_BaseColor0("BaseColor0", Color) = (1, 1, 1, 1)
_BaseColor1("BaseColor1", Color) = (1, 1, 1, 1)
_BaseColor2("BaseColor2", Color) = (1, 1, 1, 1)
_BaseColor3("BaseColor3", Color) = (1, 1, 1, 1)

_NormalMap2("NormalMap2", 2D) = "bump" {}
_NormalMap3("NormalMap3", 2D) = "bump" {}
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace("NormalMap space", Float) = 0
_HeightMap0("HeightMap0", 2D) = "black" {}
_HeightMap1("HeightMap1", 2D) = "black" {}
_HeightMap2("HeightMap2", 2D) = "black" {}

_HeightBias2("Height Bias2", Float) = 0
_HeightBias3("Height Bias3", Float) = 0
[Enum(Parallax, 0, Displacement, 1)] _HeightMapMode("Heightmap usage", Float) = 0
_DetailMap0("DetailMap0", 2D) = "black" {}
_DetailMap1("DetailMap1", 2D) = "black" {}
_DetailMap2("DetailMap2", 2D) = "black" {}
_DetailMap3("DetailMap3", 2D) = "black" {}
_EmissiveColor0("EmissiveColor0", Color) = (0, 0, 0)
_EmissiveColor1("EmissiveColor1", Color) = (0, 0, 0)
_EmissiveColor2("EmissiveColor2", Color) = (0, 0, 0)
_EmissiveColor3("EmissiveColor3", Color) = (0, 0, 0)
_DetailMask0("DetailMask0", 2D) = "white" {}
_DetailMask1("DetailMask1", 2D) = "white" {}
_DetailMask2("DetailMask2", 2D) = "white" {}
_DetailMask3("DetailMask3", 2D) = "white" {}
_EmissiveColorMap0("EmissiveColorMap0", 2D) = "white" {}
_EmissiveColorMap1("EmissiveColorMap1", 2D) = "white" {}
_EmissiveColorMap2("EmissiveColorMap2", 2D) = "white" {}
_EmissiveColorMap3("EmissiveColorMap3", 2D) = "white" {}
_DetailAlbedoScale0("_DetailAlbedoScale0", Range(-2.0, 2.0)) = 1
_DetailAlbedoScale1("_DetailAlbedoScale1", Range(-2.0, 2.0)) = 1
_DetailAlbedoScale2("_DetailAlbedoScale2", Range(-2.0, 2.0)) = 1
_DetailAlbedoScale3("_DetailAlbedoScale3", Range(-2.0, 2.0)) = 1
_EmissiveIntensity0("EmissiveIntensity0", Float) = 0
_EmissiveIntensity1("EmissiveIntensity1", Float) = 0
_EmissiveIntensity2("EmissiveIntensity2", Float) = 0
_EmissiveIntensity3("EmissiveIntensity3", Float) = 0
_DetailNormalScale0("_DetailNormalScale0", Range(0.0, 2.0)) = 1
_DetailNormalScale1("_DetailNormalScale1", Range(0.0, 2.0)) = 1
_DetailNormalScale2("_DetailNormalScale2", Range(0.0, 2.0)) = 1
_DetailNormalScale3("_DetailNormalScale3", Range(0.0, 2.0)) = 1
_DetailSmoothnessScale0("_DetailSmoothnessScale0", Range(-2.0, 2.0)) = 1
_DetailSmoothnessScale1("_DetailSmoothnessScale1", Range(-2.0, 2.0)) = 1
_DetailSmoothnessScale2("_DetailSmoothnessScale2", Range(-2.0, 2.0)) = 1
_DetailSmoothnessScale3("_DetailSmoothnessScale3", Range(-2.0, 2.0)) = 1
_DetailHeightScale0("_DetailHeightScale0", Range(-2.0, 2.0)) = 1
_DetailHeightScale1("_DetailHeightScale1", Range(-2.0, 2.0)) = 1
_DetailHeightScale2("_DetailHeightScale2", Range(-2.0, 2.0)) = 1
_DetailHeightScale3("_DetailHeightScale3", Range(-2.0, 2.0)) = 1
_LayerSize0("LayerSize0", Float) = 1.0
_LayerSize1("LayerSize1", Float) = 1.0
_LayerSize2("LayerSize2", Float) = 1.0
_LayerSize3("LayerSize3", Float) = 1.0
_DetailAOScale0("_DetailAOScale0", Range(-2.0, 2.0)) = 1
_DetailAOScale1("_DetailAOScale1", Range(-2.0, 2.0)) = 1
_DetailAOScale2("_DetailAOScale2", Range(-2.0, 2.0)) = 1
_DetailAOScale3("_DetailAOScale3", Range(-2.0, 2.0)) = 1
// Specific to planar mapping
_TexWorldScale0("TexWorldScale0", Float) = 1.0
_TexWorldScale1("TexWorldScale1", Float) = 1.0
_TexWorldScale2("TexWorldScale2", Float) = 1.0
_TexWorldScale3("TexWorldScale3", Float) = 1.0
// Blend mask between layer
_EmissiveColor("EmissiveColor", Color) = (0, 0, 0)
_EmissiveColorMap("EmissiveColorMap", 2D) = "white" {}
_EmissiveIntensity("EmissiveIntensity", Float) = 0
[ToggleOff] _DistortionOnly("Distortion Only", Float) = 0.0
[ToggleOff] _DistortionDepthTest("Distortion Only", Float) = 0.0

[HideInInspector] _DstBlend ("__dst", Float) = 0.0
[HideInInspector] _ZWrite ("__zw", Float) = 1.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0
// Material Id
[HideInInspector] _MaterialId("_MaterialId", FLoat) = 0
[HideInInspector] _LayerCount("__layerCount", Float) = 2.0
[Enum(None, 0, DoubleSided, 1, DoubleSidedLigthingFlip, 2, DoubleSidedLigthingMirror, 3)] _DoubleSidedMode("Double sided mode", Float) = 0
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace("NormalMap space", Float) = 0
[Enum(Parallax, 0, Displacement, 1)] _HeightMapMode("Heightmap usage", Float) = 0
[Enum(DetailMapNormal, 0, DetailMapAOHeight, 1)] _DetailMapMode("DetailMap mode", Float) = 0
[Enum(None, 0, DoubleSided, 1, DoubleSidedLigthingFlip, 2, DoubleSidedLigthingMirror, 3)] _DoubleSidedMode("Double sided mode", Float) = 0
//[Enum(UV0, 0, UV1, 1, Planar, 2, Triplanar, 3)] _LayerMapping0("Layer 0 Mapping", Float) = 0
//[Enum(UV0, 0, UV1, 1, Planar, 2, Triplanar, 3)] _LayerMapping1("Layer 1 Mapping", Float) = 0
//[Enum(UV0, 0, UV1, 1, Planar, 2, Triplanar, 3)] _LayerMapping2("Layer 2 Mapping", Float) = 0
//[Enum(UV0, 0, UV1, 1, Planar, 2, Triplanar, 3)] _LayerMapping3("Layer 3 Mapping", Float) = 0
[HideInInspector] _LayerCount("_LayerCount", Float) = 2.0
[Enum(UV0, 0, UV1, 1, Planar, 2)] _LayerMapping0("Layer 0 Mapping", Float) = 0
[Enum(UV0, 0, UV1, 1, Planar, 2)] _LayerMapping1("Layer 1 Mapping", Float) = 0
[Enum(UV0, 0, UV1, 1, Planar, 2)] _LayerMapping2("Layer 2 Mapping", Float) = 0
[Enum(UV0, 0, UV1, 1, Planar, 2)] _LayerMapping3("Layer 3 Mapping", Float) = 0
_TexWorldScale0("Scale to apply on world coordinate", Float) = 1.0
_TexWorldScale1("Scale to apply on world coordinate", Float) = 1.0
_TexWorldScale2("Scale to apply on world coordinate", Float) = 1.0
_TexWorldScale3("Scale to apply on world coordinate", Float) = 1.0
[Enum(UV0, 0, UV1, 1, UV3, 2, Planar, 3, Triplanar, 4)] _UVBase0("UV Set for base0", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2, Planar, 3, Triplanar, 4)] _UVBase1("UV Set for base1", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2, Planar, 3, Triplanar, 4)] _UVBase2("UV Set for base2", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2, Planar, 3, Triplanar, 4)] _UVBase3("UV Set for base3", Float) = 0
[HideInInspector] _UVMappingMask0("_UVMappingMask0", Color) = (1, 0, 0, 0)
[HideInInspector] _UVMappingMask1("_UVMappingMask1", Color) = (1, 0, 0, 0)
[HideInInspector] _UVMappingMask2("_UVMappingMask2", Color) = (1, 0, 0, 0)
[HideInInspector] _UVMappingMask3("_UVMappingMask3", Color) = (1, 0, 0, 0)
[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail0("UV Set for detail0", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail1("UV Set for detail1", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail2("UV Set for detail2", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail3("UV Set for detail3", Float) = 0
[HideInInspector] _UVDetailsMappingMask0("_UVDetailsMappingMask0", Float) = 0
[HideInInspector] _UVDetailsMappingMask1("_UVDetailsMappingMask1", Float) = 0
[HideInInspector] _UVDetailsMappingMask2("_UVDetailsMappingMask2", Float) = 0
[HideInInspector] _UVDetailsMappingMask3("_UVDetailsMappingMask3", Float) = 0
// Unused but to be able to share litUI.Sahder and layeredUI.Shader
[HideInInspector] _UVBase("UV Set for base", Float) = 0
[HideInInspector] _UVDetail("UV Set for base", Float) = 0
[HideInInspector] _TexWorldScale("Scale to apply on world coordinate", Float) = 1.0
[HideInInspector] _UVMappingMask("_UVMappingMask", Color) = (1, 0, 0, 0)
[HideInInspector] _UVDetailsMappingMask("_UVDetailsMappingMask", Color) = (1, 0, 0, 0)
}
HLSLINCLUDE

#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _ _DOUBLESIDED_LIGHTING_FLIP _DOUBLESIDED_LIGHTING_MIRROR
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature _LAYER_MAPPING_TRIPLANAR_0
#pragma shader_feature _LAYER_MAPPING_TRIPLANAR_1
#pragma shader_feature _LAYER_MAPPING_TRIPLANAR_2
#pragma shader_feature _LAYER_MAPPING_TRIPLANAR_3
#pragma shader_feature _DETAIL_MAP_WITH_NORMAL
#pragma shader_feature _NORMALMAP_TANGENT_SPACE
#pragma shader_feature _HEIGHTMAP_AS_DISPLACEMENT
#pragma shader_feature _REQUIRE_UV3
#pragma shader_feature _EMISSIVE_COLOR
#pragma shader_feature _NORMALMAP_TANGENT_SPACE
#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature _EMISSIVE_COLOR
#pragma shader_feature _HEIGHTMAP_AS_DISPLACEMENT
#pragma shader_feature _LAYER_MASK_MAP
#pragma shader_feature _LAYER_MASK_VERTEX_COLOR
#pragma shader_feature _DETAIL_MAP
#pragma shader_feature _LAYER_VERTEX_COLOR
#pragma shader_feature _ _LAYER_MAPPING_UV1_0 _LAYER_MAPPING_PLANAR_0 _LAYER_MAPPING_TRIPLANAR_0
#pragma shader_feature _ _LAYER_MAPPING_UV1_1 _LAYER_MAPPING_PLANAR_1 _LAYER_MAPPING_TRIPLANAR_1
#pragma shader_feature _ _LAYER_MAPPING_UV1_2 _LAYER_MAPPING_PLANAR_2 _LAYER_MAPPING_TRIPLANAR_2
#pragma shader_feature _ _LAYER_MAPPING_UV1_3 _LAYER_MAPPING_PLANAR_3 _LAYER_MAPPING_TRIPLANAR_3
#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
#pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED
#pragma multi_compile DYNAMICLIGHTMAP_OFF DYNAMICLIGHTMAP_ON
// TODO: We should have this keyword only if VelocityInGBuffer is enable, how to do that ?
//#pragma multi_compile VELOCITYOUTPUT_OFF VELOCITYOUTPUT_ON
//-------------------------------------------------------------------------------------
// Define

# define _LAYER_COUNT 2
#endif
struct LayerCoordinates
{
float2 texcoord[_MAX_LAYER];
bool isTriplanar[_MAX_LAYER];
};
float4 SampleLayer(TEXTURE2D_ARGS(layerTex, layerSampler), LayerCoordinates layerCoord, int layerIndex)
{
if (layerCoord.isTriplanar[layerIndex])
{
// TODO
return SAMPLE_TEXTURE2D(layerTex, layerSampler, layerCoord.texcoord[layerIndex]);
}
else
{
return SAMPLE_TEXTURE2D(layerTex, layerSampler, layerCoord.texcoord[layerIndex]);
}
}
// Set of users variables
#define PROP_DECL(type, name) type name, name##0, name##1, name##2, name##3;
#define PROP_DECL_TEX2D(name)\

TEXTURE2D(name##2); \
TEXTURE2D(name##3);
#define PROP_SAMPLE(name, textureName, layerCoord, swizzle)\
name##0 = SampleLayer(TEXTURE2D_PARAM(textureName##0, sampler##textureName##0), layerCoord, 0).##swizzle; \
name##1 = SampleLayer(TEXTURE2D_PARAM(textureName##1, sampler##textureName##0), layerCoord, 1).##swizzle; \
name##2 = SampleLayer(TEXTURE2D_PARAM(textureName##2, sampler##textureName##0), layerCoord, 2).##swizzle; \
name##3 = SampleLayer(TEXTURE2D_PARAM(textureName##3, sampler##textureName##0), layerCoord, 3).##swizzle;
#define PROP_MUL(name, multiplier, swizzle)\
name##0 *= multiplier##0.##swizzle; \
name##1 *= multiplier##1.##swizzle; \
name##2 *= multiplier##2.##swizzle; \
name##3 *= multiplier##3.##swizzle;
#define PROP_ASSIGN(name, input, swizzle)\
name##0 = input##0.##swizzle; \
name##1 = input##1.##swizzle; \
name##2 = input##2.##swizzle; \
name##3 = input##3.##swizzle;
#define PROP_ASSIGN_VALUE(name, input)\
name##0 = input; \
name##1 = input; \
name##2 = input; \
name##3 = input;
#define PROP_BLEND_COLOR(name, mask) name = BlendLayeredColor(name##0, name##1, name##2, name##3, mask);
#define PROP_BLEND_SCALAR(name, mask) name = BlendLayeredScalar(name##0, name##1, name##2, name##3, mask);
//-------------------------------------------------------------------------------------
// variable declaration

PROP_DECL(float4, _BaseColor);
PROP_DECL_TEX2D(_BaseColorMap);
PROP_DECL_TEX2D(_DetailMask);
PROP_DECL_TEX2D(_DetailMap);
float4 _DetailMap0_ST;
float4 _DetailMap1_ST;
float4 _DetailMap2_ST;
float4 _DetailMap3_ST;
PROP_DECL(float, _UVDetail);
PROP_DECL(float, _DetailAlbedoScale);
PROP_DECL(float, _DetailNormalScale);
PROP_DECL(float, _DetailSmoothnessScale);
PROP_DECL(float, _DetailHeightScale);
PROP_DECL(float, _DetailAOScale);
PROP_DECL(float3, _EmissiveColor);
PROP_DECL(float, _EmissiveIntensity);
PROP_DECL(float, _LayerSize);
float _AlphaCutoff;
TEXTURE2D(_DiffuseLightingMap);
SAMPLER2D(sampler_DiffuseLightingMap);
float3 _EmissiveColor;
TEXTURE2D(_EmissiveColorMap);
SAMPLER2D(sampler_EmissiveColorMap);
float _EmissiveIntensity;
PROP_DECL(float, _TexWorldScale);
PROP_DECL(float4, _UVMappingMask);
PROP_DECL(float4, _UVDetailsMappingMask);
float _AlphaCutoff;
ENDHLSL

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


{
protected static class Styles
{
public enum DetailMapMode
{
DetailWithNormal,
DetailWithAOHeight,
}
public static GUIContent uvSetLabel = new GUIContent("UV Set");
public static string detailText = "Inputs Detail";
public static string lightingText = "Inputs Lighting";

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 detailMapModeText = new GUIContent("Detail Map with Normal", "Detail Map with AO / Height");
public static string InputsText = "Inputs";

public static GUIContent specularOcclusionMapText = new GUIContent("Specular Occlusion Map (RGBA)", "Specular Occlusion Map");
public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map (BC5) - DXT5 for test");
public static GUIContent normalMapSpaceText = new GUIContent("Normal/Tangent Map space", "");
public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map (DXT5) - Need to implement BC5");
public static GUIContent heightMapModeText = new GUIContent("Height Map Mode", "");
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 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

protected MaterialEditor m_MaterialEditor;
private MaterialProperty surfaceType = null;
private MaterialProperty alphaCutoffEnable = null;
private MaterialProperty blendMode = null;
private MaterialProperty alphaCutoff = null;
private MaterialProperty doubleSidedMode = null;
MaterialProperty surfaceType = null;
MaterialProperty alphaCutoffEnable = null;
MaterialProperty blendMode = null;
MaterialProperty alphaCutoff = null;
MaterialProperty doubleSidedMode = null;
private const string kSurfaceType = "_SurfaceType";
private const string kBlendMode = "_BlendMode";
private const string kAlphaCutoff = "_AlphaCutoff";
private const string kAlphaCutoffEnabled = "_AlphaCutoffEnable";
private const string kDoubleSidedMode = "_DoubleSidedMode";
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);

MaskAlpha,
AlbedoAlpha,
}
public enum EmissiveColorMode
public enum UVBaseMapping
UseEmissiveColor,
UseEmissiveMask,
UV0,
Planar,
Triplanar
public enum NormalMapSpace
{
TangentSpace,

Parallax,
Displacement,
}
public enum DetailMapMode
{
DetailWithNormal,

MaterialProperty UVDetail = null;
MaterialProperty smoothnessMapChannel = null;
MaterialProperty emissiveColorMode = null;
MaterialProperty detailMapMode = null;
public enum UVDetailMapping
{
UV0,
UV1,
UV3
}
MaterialProperty baseColor = null;
MaterialProperty baseColorMap = null;
MaterialProperty metallic = null;
MaterialProperty smoothness = null;
MaterialProperty maskMap = null;
MaterialProperty specularOcclusionMap = null;
MaterialProperty normalMap = null;
MaterialProperty normalMapSpace = null;
MaterialProperty heightMap = null;
MaterialProperty heightScale = null;
MaterialProperty heightBias = null;
MaterialProperty tangentMap = null;
MaterialProperty anisotropy = null;
MaterialProperty anisotropyMap = null;
MaterialProperty heightMapMode = null;
MaterialProperty detailMap = null;
MaterialProperty detailMask = null;
MaterialProperty detailAlbedoScale = null;
MaterialProperty detailNormalScale = null;
MaterialProperty detailSmoothnessScale = null;
MaterialProperty detailHeightScale = null;
MaterialProperty detailAOScale = null;
MaterialProperty emissiveColor = null;
MaterialProperty emissiveColorMap = null;
MaterialProperty emissiveIntensity = null;
// MaterialProperty subSurfaceRadius = null;
// MaterialProperty subSurfaceRadiusMap = null;
public enum EmissiveColorMode
{
UseEmissiveColor,
UseEmissiveMask,
}
protected const string kUVDetail = "_UVDetail";
protected const string kSmoothnessTextureChannelProp = "_SmoothnessTextureChannel";
protected const string kEmissiveColorMode = "_EmissiveColorMode";
protected MaterialProperty smoothnessMapChannel = null;
protected const string kSmoothnessTextureChannel = "_SmoothnessTextureChannel";
protected MaterialProperty UVBase = null;
protected const string kUVBase = "_UVBase";
protected MaterialProperty TexWorldScale = null;
protected const string kTexWorldScale = "_TexWorldScale";
protected MaterialProperty UVMappingMask = null;
protected const string kUVMappingMask = "_UVMappingMask";
protected MaterialProperty normalMapSpace = null;
protected MaterialProperty heightMapMode = null;
protected MaterialProperty detailMapMode = null;
protected MaterialProperty UVDetail = null;
protected const string kUVDetail = "_UVDetail";
protected MaterialProperty UVDetailsMappingMask = null;
protected const string kUVDetailsMappingMask = "_UVDetailsMappingMask";
protected MaterialProperty emissiveColorMode = null;
protected const string kEmissiveColorMode = "_EmissiveColorMode";
protected const string kNormalMap = "_NormalMap";
protected MaterialProperty baseColor = null;
protected const string kBaseColor = "_BaseColor";
protected MaterialProperty baseColorMap = null;
protected const string kBaseColorMap = "_BaseColorMap";
protected MaterialProperty metallic = null;
protected const string kMetallic = "_Metallic";
protected MaterialProperty smoothness = null;
protected const string kSmoothness = "_Smoothness";
protected MaterialProperty maskMap = null;
protected const string kspecularOcclusionMap = "_SpecularOcclusionMap";
protected const string kEmissiveColorMap = "_EmissiveColorMap";
protected MaterialProperty specularOcclusionMap = null;
protected const string kSpecularOcclusionMap = "_SpecularOcclusionMap";
protected MaterialProperty normalMap = null;
protected const string kNormalMap = "_NormalMap";
protected MaterialProperty heightMap = null;
protected MaterialProperty heightScale = null;
protected const string kHeightScale = "_HeightScale";
protected MaterialProperty heightBias = null;
protected const string kHeightBias= "_HeightBias";
protected MaterialProperty tangentMap = null;
protected MaterialProperty anisotropy = null;
protected const string kAnisotropy = "_Anisotropy";
protected MaterialProperty anisotropyMap = null;
protected MaterialProperty detailMap = null;
protected MaterialProperty detailMask = null;
protected MaterialProperty detailAlbedoScale = null;
protected MaterialProperty detailNormalScale = null;
protected MaterialProperty detailSmoothnessScale = null;
protected MaterialProperty detailHeightScale = null;
protected MaterialProperty detailAOScale = null;
// MaterialProperty subSurfaceRadius = null;
// MaterialProperty subSurfaceRadiusMap = null;
protected MaterialProperty emissiveColor = null;
protected const string kEmissiveColor = "_EmissiveColor";
protected MaterialProperty emissiveColorMap = null;
protected const string kEmissiveColorMap = "_EmissiveColorMap";
protected MaterialProperty emissiveIntensity = null;
protected const string kEmissiveIntensity = "_EmissiveIntensity";
{
UVDetail = FindProperty(kUVDetail, props);
smoothnessMapChannel = FindProperty(kSmoothnessTextureChannelProp, props);
emissiveColorMode = FindProperty(kEmissiveColorMode, props);
{
smoothnessMapChannel = FindProperty(kSmoothnessTextureChannel, props);
UVBase = FindProperty(kUVBase, props);
TexWorldScale = FindProperty(kTexWorldScale, props);
UVMappingMask = FindProperty(kUVMappingMask, props);
UVDetail = FindProperty(kUVDetail, props);
UVDetailsMappingMask = FindProperty(kUVDetailsMappingMask, props);
emissiveColorMode = FindProperty(kEmissiveColorMode, props);
baseColor = FindProperty("_BaseColor", props);
baseColorMap = FindProperty("_BaseColorMap", props);
metallic = FindProperty("_Metallic", props);
smoothness = FindProperty("_Smoothness", props);
baseColor = FindProperty(kBaseColor, props);
baseColorMap = FindProperty(kBaseColorMap, props);
metallic = FindProperty(kMetallic, props);
smoothness = FindProperty(kSmoothness, props);
specularOcclusionMap = FindProperty(kspecularOcclusionMap, props);
specularOcclusionMap = FindProperty(kSpecularOcclusionMap, props);
heightScale = FindProperty("_HeightScale", props);
heightBias = FindProperty("_HeightBias", props);
tangentMap = FindProperty("_TangentMap", props);
anisotropy = FindProperty("_Anisotropy", props);
anisotropyMap = FindProperty("_AnisotropyMap", props);
emissiveColor = FindProperty("_EmissiveColor", props);
emissiveColorMap = FindProperty(kEmissiveColorMap, props);
emissiveIntensity = FindProperty("_EmissiveIntensity", props);
heightScale = FindProperty(kHeightScale, props);
heightBias = FindProperty(kHeightBias, props);
tangentMap = FindProperty(kTangentMap, props);
anisotropy = FindProperty(kAnisotropy, props);
anisotropyMap = FindProperty(kAnisotropyMap, props);
detailMap = FindProperty(kDetailMap, props);
detailMask = FindProperty(kDetailMask, props);
detailAlbedoScale = FindProperty(kDetailAlbedoScale, props);

detailAOScale = FindProperty(kDetailAOScale, props);
emissiveColor = FindProperty(kEmissiveColor, props);
emissiveColorMap = FindProperty(kEmissiveColorMap, props);
emissiveIntensity = FindProperty(kEmissiveIntensity, props);
// When Planar or Triplanar is enable the UVDetail use the same mode, so we disable the choice on UVDetail
bool enableUVDetail = (UVBaseMapping)UVBase.floatValue == UVBaseMapping.UV0;
m_MaterialEditor.ShaderProperty(emissiveColorMode, Styles.emissiveColorModeText.text);
m_MaterialEditor.ShaderProperty(UVBase, enableUVDetail ? Styles.UVBaseDetailMappingText.text : Styles.UVBaseMappingText.text);
float X, Y, Z, W;
X = ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.UV0) ? 1.0f : 0.0f;
W = ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Planar) ? 1.0f : 0.0f;
UVMappingMask.colorValue = new Color(X, 0.0f, 0.0f, W);
if (((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Planar) || ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.Triplanar))
{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(TexWorldScale, Styles.texWorldScaleText.text);
EditorGUI.indentLevel--;
}
if (enableUVDetail)
{
m_MaterialEditor.ShaderProperty(UVDetail, Styles.UVDetailMappingText.text);
}
// If base is planar mode, detail is planar too
if (W > 0.0f)
{
X = Y = Z = 0.0f;
}
else
{
X = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV0) ? 1.0f : 0.0f;
Y = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV1) ? 1.0f : 0.0f;
Z = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV3) ? 1.0f : 0.0f;
}
UVDetailsMappingMask.colorValue = new Color(X, Y, Z, 0.0f); // W Reuse planar mode from base
m_MaterialEditor.ShaderProperty(detailMapMode, Styles.detailMapModeText.text);
m_MaterialEditor.ShaderProperty(detailMapMode, Styles.detailMapModeText.text);
m_MaterialEditor.ShaderProperty(emissiveColorMode, Styles.emissiveColorModeText.text);
EditorGUI.indentLevel--;
}

bool smoothnessInAlbedoAlpha = (SmoothnessMapChannel)smoothnessMapChannel.floatValue == SmoothnessMapChannel.AlbedoAlpha;
bool useEmissiveMask = (EmissiveColorMode)emissiveColorMode.floatValue == EmissiveColorMode.UseEmissiveMask;
bool smoothnessInAlbedoAlpha = (SmoothnessMapChannel)smoothnessMapChannel.floatValue == SmoothnessMapChannel.AlbedoAlpha;
bool useEmissiveMask = (EmissiveColorMode)emissiveColorMode.floatValue == EmissiveColorMode.UseEmissiveMask;
GUILayout.Label(Styles.InputsText, EditorStyles.boldLabel);
m_MaterialEditor.TexturePropertySingleLine(smoothnessInAlbedoAlpha ? Styles.baseColorSmoothnessText : Styles.baseColorText, baseColorMap, baseColor);

EditorGUILayout.Space();
GUILayout.Label(Styles.detailText, EditorStyles.boldLabel);
m_MaterialEditor.TexturePropertySingleLine(Styles.detailMaskText, detailMask);
m_MaterialEditor.ShaderProperty(UVDetail, Styles.uvSetLabel.text);
m_MaterialEditor.TexturePropertySingleLine(Styles.detailMaskText, detailMask);
if (useDetailMapWithNormal)
{

EditorGUI.indentLevel--;
}
// 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);

{
SetKeyword(material, "_NORMALMAP", material.GetTexture(kNormalMap) || material.GetTexture(kDetailMap)); // With details map, we always use a normal map and Unity provide a default (0, 0, 1) normal map for ir
SetKeyword(material, "_MASKMAP", material.GetTexture(kMaskMap));
SetKeyword(material, "_SPECULAROCCLUSIONMAP", material.GetTexture(kspecularOcclusionMap));
SetKeyword(material, "_SPECULAROCCLUSIONMAP", material.GetTexture(kSpecularOcclusionMap));
SetKeyword(material, "_EMISSIVE_COLOR_MAP", material.GetTexture(kEmissiveColorMap));
SetKeyword(material, "_HEIGHTMAP", material.GetTexture(kHeightMap));
SetKeyword(material, "_TANGENTMAP", material.GetTexture(kTangentMap));

public static bool ShouldEmissionBeEnabled(Material mat)
{
float emissiveIntensity = mat.GetFloat(kEmissiveIntensity);
var realtimeEmission = (mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.RealtimeEmissive) > 0;
return emissiveIntensity > 0.0f || realtimeEmission;
}
MaterialGlobalIlluminationFlags flags = material.globalIlluminationFlags;
if ((flags & (MaterialGlobalIlluminationFlags.BakedEmissive | MaterialGlobalIlluminationFlags.RealtimeEmissive)) != 0)
{

{
// 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)
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE", (NormalMapSpace)material.GetFloat(kNormalMapSpace) == NormalMapSpace.TangentSpace);
SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", ((SmoothnessMapChannel)material.GetFloat(kSmoothnessTextureChannelProp)) == SmoothnessMapChannel.AlbedoAlpha);
SetKeyword(material, "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A", ((SmoothnessMapChannel)material.GetFloat(kSmoothnessTextureChannel)) == SmoothnessMapChannel.AlbedoAlpha);
SetKeyword(material, "_MAPPING_TRIPLANAR", ((UVBaseMapping)material.GetFloat(kUVBase)) == UVBaseMapping.Triplanar);
SetKeyword(material, "_NORMALMAP_TANGENT_SPACE", ((NormalMapSpace)material.GetFloat(kNormalMapSpace)) == NormalMapSpace.TangentSpace);
SetKeyword(material, "_HEIGHTMAP_AS_DISPLACEMENT", ((HeightmapMode)material.GetFloat(kHeightMapMode)) == HeightmapMode.Displacement);
SetKeyword(material, "_DETAIL_MAP_WITH_NORMAL", ((DetailMapMode)material.GetFloat(kDetailMapMode)) == DetailMapMode.DetailWithNormal);
SetKeyword(material, "_REQUIRE_UV3", ((UVDetailMapping)material.GetFloat(kUVDetail)) == UVDetailMapping.UV3 && (UVBaseMapping)material.GetFloat(kUVBase) == UVBaseMapping.UV0);
SetKeyword(material, "_HEIGHTMAP_AS_DISPLACEMENT", (HeightmapMode)material.GetFloat(kHeightMapMode) == HeightmapMode.Displacement);
SetKeyword(material, "_DETAIL_MAP_WITH_NORMAL", (DetailMapMode)material.GetFloat(kDetailMapMode) == DetailMapMode.DetailWithNormal);
public static bool ShouldEmissionBeEnabled(Material mat)
{
float emissiveIntensity = mat.GetFloat("_EmissiveIntensity");
var realtimeEmission = (mat.globalIlluminationFlags & MaterialGlobalIlluminationFlags.RealtimeEmissive) > 0;
return emissiveIntensity > 0.0f || realtimeEmission;
}
// TODO: ? or remove
bool HasValidEmissiveKeyword(Material material)
{
/*

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


_SpecularOcclusionMap("SpecularOcclusion", 2D) = "white" {}
_NormalMap("NormalMap", 2D) = "bump" {}
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace("NormalMap space", Float) = 0
[Enum(Parallax, 0, Displacement, 1)] _HeightMapMode("Heightmap usage", Float) = 0
_TangentMap("TangentMap", 2D) = "bump" {}
_Anisotropy("Anisotropy", Range(0.0, 1.0)) = 0

_DetailNormalScale("_DetailNormalScale", Range(0.0, 2.0)) = 1
_DetailSmoothnessScale("_DetailSmoothnessScale", Range(-2.0, 2.0)) = 1
_DetailHeightScale("_DetailHeightScale", Range(-2.0, 2.0)) = 1
_DetailAOScale("_DetailAOScale", Range(-2.0, 2.0)) = 1
[Enum(UV0, 0, UV1, 1)] _UVDetail("UV Set for detailMap", Float) = 0
_DetailAOScale("_DetailAOScale", Range(-2.0, 2.0)) = 1
_SubSurfaceRadius("SubSurfaceRadius", Range(0.0, 1.0)) = 0
_SubSurfaceRadiusMap("SubSurfaceRadiusMap", 2D) = "white" {}

[HideInInspector] _DstBlend ("__dst", Float) = 0.0
[HideInInspector] _ZWrite ("__zw", Float) = 1.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0
[Enum(None, 0, DoubleSided, 1, DoubleSidedLigthingFlip, 2, DoubleSidedLigthingMirror, 3)] _DoubleSidedMode("Double sided mode", Float) = 0
[Enum(UV0, 0, Planar, 1, TriPlanar, 2)] _UVBase("UV Set for base", Float) = 0
_TexWorldScale("Scale to apply on world coordinate", Float) = 1.0
[HideInInspector] _UVMappingMask("_UVMappingMask", Color) = (1,0,0,0)
[Enum(TangentSpace, 0, ObjectSpace, 1)] _NormalMapSpace("NormalMap space", Float) = 0
[Enum(Parallax, 0, Displacement, 1)] _HeightMapMode("Heightmap usage", Float) = 0
[Enum(DetailMapNormal, 0, DetailMapAOHeight, 1)] _DetailMapMode("DetailMap mode", Float) = 0
[Enum(UV0, 0, UV1, 1, UV3, 2)] _UVDetail("UV Set for detail", Float) = 0
[HideInInspector] _UVDetailsMappingMask("_UVDetailsMappingMask", Color) = (1,0,0,0)
[Enum(None, 0, DoubleSided, 1, DoubleSidedLigthingFlip, 2, DoubleSidedLigthingMirror, 3)] _DoubleSidedMode("Double sided mode", Float) = 0
[Enum(DetailMapNormal, 0, DetailMapAOHeight, 1)] _DetailMapMode("DetailMap mode", Float) = 0
}
HLSLINCLUDE

#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _ _DOUBLESIDED_LIGHTING_FLIP _DOUBLESIDED_LIGHTING_MIRROR
#pragma shader_feature _NORMALMAP
#pragma shader_feature _NORMALMAP_TANGENT_SPACE
#pragma shader_feature _MASKMAP
#pragma shader_feature _SPECULAROCCLUSIONMAP
#pragma shader_feature _MAPPING_TRIPLANAR
#pragma shader_feature _DETAIL_MAP_WITH_NORMAL
#pragma shader_feature _NORMALMAP_TANGENT_SPACE
#pragma shader_feature _HEIGHTMAP_AS_DISPLACEMENT
#pragma shader_feature _REQUIRE_UV3
#pragma shader_feature _NORMALMAP
#pragma shader_feature _MASKMAP
#pragma shader_feature _SPECULAROCCLUSIONMAP
#pragma shader_feature _HEIGHTMAP_AS_DISPLACEMENT
#pragma shader_feature _DETAIL_MAP
#pragma shader_feature _DETAIL_MAP_WITH_NORMAL
#pragma shader_feature _DETAIL_MAP
#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
#pragma multi_compile DIRLIGHTMAP_OFF DIRLIGHTMAP_COMBINED

SAMPLER2D(sampler_DetailMask);
TEXTURE2D(_DetailMap);
SAMPLER2D(sampler_DetailMap);
float4 _DetailMap_ST;
float _UVDetail;
float4 _DetailMap_ST;
float _DetailAlbedoScale;
float _DetailNormalScale;
float _DetailSmoothnessScale;

TEXTURE2D(_AnisotropyMap);
SAMPLER2D(sampler_AnisotropyMap);
TEXTURE2D(_DiffuseLightingMap);
SAMPLER2D(sampler_DiffuseLightingMap);
float3 _EmissiveColor;
TEXTURE2D(_EmissiveColorMap);
SAMPLER2D(sampler_EmissiveColorMap);
float _EmissiveIntensity;
float _SubSurfaceRadius;
TEXTURE2D(_SubSurfaceRadiusMap);
SAMPLER2D(sampler_SubSurfaceRadiusMap);
//float _SubSurfaceRadius;
//TEXTURE2D(_SubSurfaceRadiusMap);
//SAMPLER2D(sampler_SubSurfaceRadiusMap);
// float _Thickness;
//TEXTURE2D(_ThicknessMap);

// float _CoatRoughness;
//TEXTURE2D(_CoatRoughnessMap);
//SAMPLER2D(sampler_CoatRoughnessMap);
TEXTURE2D(_DiffuseLightingMap);
SAMPLER2D(sampler_DiffuseLightingMap);
float3 _EmissiveColor;
TEXTURE2D(_EmissiveColorMap);
SAMPLER2D(sampler_EmissiveColorMap);
float _EmissiveIntensity;
float _TexWorldScale;
float4 _UVMappingMask;
float4 _UVDetailsMappingMask;
ENDHLSL

636
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitData.hlsl


return float2(0.0, 0.0);
#endif
}
float3 LerpWhiteTo(float3 b, float t)
{
float oneMinusT = 1.0 - t;
return float3(oneMinusT, oneMinusT, oneMinusT) + b * t;
}
// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) ((tex.xy) * name##_ST.xy + name##_ST.zw)
#if !defined(LAYERED_LIT_SHADER)
void GetSurfaceAndBuiltinData(FragInput input, out SurfaceData surfaceData, out BuiltinData builtinData)
void GetBuiltinData(FragInput input, SurfaceData surfaceData, float alpha, out BuiltinData builtinData)
#ifdef _HEIGHTMAP
// TODO: in case of shader graph, a node like parallax must be nullify if use to generate code for Meta pass
#ifndef _HEIGHTMAP_AS_DISPLACEMENT
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS); // This should be remove by the compiler as we usually cal it before.
float height = SAMPLE_TEXTURE2D(_HeightMap, sampler_HeightMap, input.texCoord0).r * _HeightScale + _HeightBias;
// Transform view vector in tangent space
float3 viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
float2 offset = ParallaxOffset(viewDirTS, height);
input.texCoord0 += offset;
input.texCoord1 += offset;
#endif
#endif
#ifdef _DETAIL_MAP
float2 texCoordDetail = TRANSFORM_TEX(_UVDetail ? input.texCoord1 : input.texCoord0, _DetailMap);
float detailMask = SAMPLE_TEXTURE2D(_DetailMask, sampler_DetailMask, input.texCoord0).b;
float4 detail = SAMPLE_TEXTURE2D(_DetailMap, sampler_DetailMap, texCoordDetail);
float detailAlbedo = detail.r;
float detailSmoothness = detail.b;
#ifdef _DETAIL_MAP_WITH_NORMAL
float3 detailNormalTS = UnpackNormalAG(detail, _DetailNormalScale);
//float detailAO = 0.0;
#else
// TODO: Use heightmap as a derivative with Morten Mikklesen approach
// Or reconstruct
float U = SAMPLE_TEXTURE2D(_DetailMap, sampler_DetailMap, texCoordDetail + float2(0.005, 0)).a;
float V = SAMPLE_TEXTURE2D(_DetailMap, sampler_DetailMap, texCoordDetail + float2(0, 0.005)).a;
float dHdU = U - detail.a; //create bump map U offset
float dHdV = V - detail.a; //create bump map V offset
//float3 detailNormal = 1 - float3(dHdU, dHdV, 0.05); //create the tangent space normal
float3 detailNormalTS = float3(0.0, 0.0, 1.0);
//float3 detailNormal = UnpackNormalAG(unifiedDetail.r).a;
//float detailAO = detail.b;
#endif
#endif
surfaceData.baseColor = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, input.texCoord0).rgb * _BaseColor.rgb;
#ifdef _DETAIL_MAP
surfaceData.baseColor *= LerpWhiteTo(2.0 * saturate(detailAlbedo * _DetailAlbedoScale), detailMask);
#endif
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
float alpha = _BaseColor.a;
#else
float alpha = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, input.texCoord0).a * _BaseColor.a;
#endif
#ifdef _ALPHATEST_ON
clip(alpha - _AlphaCutoff);
#endif
#ifdef _SPECULAROCCLUSIONMAP
// TODO: Do something. For now just take alpha channel
surfaceData.specularOcclusion = SAMPLE_TEXTURE2D(_SpecularOcclusionMap, sampler_SpecularOcclusionMap, input.texCoord0).a;
#else
// Horizon Occlusion for Normal Mapped Reflections: http://marmosetco.tumblr.com/post/81245981087
//surfaceData.specularOcclusion = saturate(1.0 + horizonFade * dot(r, input.tangentToWorld[2].xyz);
// smooth it
//surfaceData.specularOcclusion *= surfaceData.specularOcclusion;
surfaceData.specularOcclusion = 1.0;
#endif
// TODO: think about using BC5
float3 vertexNormalWS = input.tangentToWorld[2].xyz;
#ifdef _NORMALMAP
#ifdef _NORMALMAP_TANGENT_SPACE
float3 normalTS = UnpackNormalAG(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, input.texCoord0));
#ifdef _DETAIL_MAP
normalTS = lerp(normalTS, blendNormal(normalTS, detailNormalTS), detailMask);
#endif
surfaceData.normalWS = TransformTangentToWorld(normalTS, input.tangentToWorld);
#else // Object space
float3 normalOS = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, input.texCoord0).rgb;
surfaceData.normalWS = TransformObjectToWorldDir(normalOS);
#ifdef _DETAIL_MAP
float3 detailNormalWS = TransformTangentToWorld(detailNormalTS, input.tangentToWorld);
surfaceData.normalWS = lerp(surfaceData.normalWS, blendNormal(surfaceData.normalWS, detailNormalWS), detailMask);
#endif
#endif
#else
surfaceData.normalWS = vertexNormalWS;
#endif
#if defined(_DOUBLESIDED_LIGHTING_FLIP) || defined(_DOUBLESIDED_LIGHTING_MIRROR)
#ifdef _DOUBLESIDED_LIGHTING_FLIP
float3 oppositeNormalWS = -surfaceData.normalWS;
#else
// Mirror the normal with the plane define by vertex normal
float3 oppositeNormalWS = reflect(surfaceData.normalWS, vertexNormalWS);
#endif
// TODO : Test if GetOdddNegativeScale() is necessary here in case of normal map, as GetOdddNegativeScale is take into account in CreateTangentToWorld();
surfaceData.normalWS = input.isFrontFace ?
(GetOdddNegativeScale() >= 0.0 ? surfaceData.normalWS : oppositeNormalWS) :
(-GetOdddNegativeScale() >= 0.0 ? surfaceData.normalWS : oppositeNormalWS);
#endif
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
surfaceData.perceptualSmoothness = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, input.texCoord0).a;
#elif defined(_MASKMAP)
surfaceData.perceptualSmoothness = SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, input.texCoord0).a;
#else
surfaceData.perceptualSmoothness = 1.0;
#endif
surfaceData.perceptualSmoothness *= _Smoothness;
#ifdef _DETAIL_MAP
surfaceData.perceptualSmoothness *= LerpWhiteTo(2.0 * saturate(detailSmoothness * _DetailSmoothnessScale), detailMask);
#endif
surfaceData.materialId = 0;
// MaskMap is Metallic, Ambient Occlusion, (Optional) - emissive Mask, Optional - Smoothness (in alpha)
#ifdef _MASKMAP
surfaceData.metallic = SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, input.texCoord0).r;
surfaceData.ambientOcclusion = SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, input.texCoord0).g;
#else
surfaceData.metallic = 1.0;
surfaceData.ambientOcclusion = 1.0;
#endif
surfaceData.metallic *= _Metallic;
// TODO: think about using BC5
#ifdef _TANGENTMAP
#ifdef _NORMALMAP_TANGENT_SPACE // Normal and tangent use same space
float3 tangentTS = UnpackNormalAG(SAMPLE_TEXTURE2D(_TangentMap, sampler_TangentMap, input.texCoord0));
surfaceData.tangentWS = TransformTangentToWorld(tangentTS, input.tangentToWorld);
#else // Object space (TODO: We need to apply the world rotation here! - Require to pass world transform)
surfaceData.tangentWS = SAMPLE_TEXTURE2D(_TangentMap, sampler_TangentMap, input.texCoord0).rgb;
#endif
#else
surfaceData.tangentWS = input.tangentToWorld[0].xyz;
#endif
// TODO: Is there anything todo regarding flip normal but for the tangent ?
#ifdef _ANISOTROPYMAP
surfaceData.anisotropy = SAMPLE_TEXTURE2D(_AnisotropyMap, sampler_AnisotropyMap, input.texCoord0).g;
#else
surfaceData.anisotropy = 1.0;
#endif
surfaceData.anisotropy *= _Anisotropy;
surfaceData.specular = 0.04;
surfaceData.subSurfaceRadius = 1.0;
surfaceData.thickness = 0.0;
surfaceData.subSurfaceProfile = 0;
surfaceData.coatNormalWS = float3(1.0, 0.0, 0.0);
surfaceData.coatPerceptualSmoothness = 1.0;
surfaceData.specularColor = float3(0.0, 0.0, 0.0);
// Builtin Data
builtinData.opacity = alpha;

// If we chose an emissive color, we have a dedicated texture for it and don't use MaskMap
#ifdef _EMISSIVE_COLOR
#ifdef _EMISSIVE_COLOR_MAP
#ifdef _EMISSIVE_COLOR_MAP
#else
#else
#endif
#elif defined(_MASKMAP) // If we have a MaskMap, use emissive slot as a mask on baseColor
#endif
// If we have a MaskMap, use emissive slot as a mask on baseColor
#elif defined(_MASKMAP) && !defined(LAYERED_LIT_SHADER) // With layered lit we have no emissive mask option
builtinData.emissiveColor = surfaceData.baseColor * (SAMPLE_TEXTURE2D(_MaskMap, sampler_MaskMap, input.texCoord0).b * builtinData.emissiveIntensity).xxx;
#else
builtinData.emissiveColor = float3(0.0, 0.0, 0.0);

builtinData.distortionBlur = 0.0;
}
// Gather all kind of mapping in one struct, allow to improve code readability
struct LayerUV
{
float2 uv;
// triplanar
bool isTriplanar;
float2 uvYZ;
float2 uvZX;
float2 uvXY;
};
struct LayerTexCoord
{
#ifndef LAYERED_LIT_SHADER
LayerUV base;
LayerUV details;
// Regular texcoord
LayerUV base0;
LayerUV base1;
LayerUV base2;
LayerUV base3;
LayerUV details0;
LayerUV details1;
LayerUV details2;
LayerUV details3;
#endif
float3 BlendLayeredColor(float3 rgb0, float3 rgb1, float3 rgb2, float3 rgb3, float weight[4])
// triplanar weight
float3 weights;
};
float4 SampleLayer(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights)
float3 result = float3(0.0, 0.0, 0.0);
if (layerUV.isTriplanar)
{
float4 val = float4(0.0, 0.0, 0.0, 0.0);
result = rgb0 * weight[0] + rgb1 * weight[1];
#if _LAYER_COUNT >= 3
result += (rgb2 * weight[2]);
#endif
#if _LAYER_COUNT >= 4
result += rgb3 * weight[3];
#endif
if (weights.x > 0.0)
val += weights.x * SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ);
if (weights.y > 0.0)
val += weights.y * SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX);
if (weights.z > 0.0)
val += weights.z * SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY);
return val;
}
else
{
return SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uv);
}
}
// TODO: Handle BC5 format, currently this code is for DXT5nm
// THis function below must call UnpackNormalmapRGorAG
float3 SampleNormalLayer(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights)
{
if (layerUV.isTriplanar)
{
float3 val = float3(0.0, 0.0, 0.0);
if (weights.x > 0.0)
val += weights.x * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ));
if (weights.y > 0.0)
val += weights.y * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX));
if (weights.z > 0.0)
val += weights.z * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY));
return result;
return normalize(val);
}
else
{
return UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uv));
}
float3 BlendLayeredNormal(float3 normal0, float3 normal1, float3 normal2, float3 normal3, float weight[4])
// This version is for normalmap with AG encoding only (use with details map)
float3 SampleNormalLayerAG(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights)
float3 result = float3(0.0, 0.0, 0.0);
if (layerUV.isTriplanar)
{
float3 val = float3(0.0, 0.0, 0.0);
// TODO : real normal map blending function
result = normal0 * weight[0] + normal1 * weight[1];
#if _LAYER_COUNT >= 3
result += normal2 * weight[2];
#endif
#if _LAYER_COUNT >= 4
result += normal3 * weight[3];
#endif
if (weights.x > 0.0)
val += weights.x * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvYZ));
if (weights.y > 0.0)
val += weights.y * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvZX));
if (weights.z > 0.0)
val += weights.z * UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uvXY));
return result;
return normalize(val);
}
else
{
return UnpackNormalAG(SAMPLE_TEXTURE2D(layerTex, layerSampler, layerUV.uv));
}
float BlendLayeredScalar(float x0, float x1, float x2, float x3, float weight[4])
// Macro to improve readibility of surface data
#define SAMPLE_LAYER_TEXTURE2D(textureName, samplerName, coord) SampleLayer(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights)
#define SAMPLE_LAYER_NORMALMAP(textureName, samplerName, coord) SampleNormalLayer(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights)
#define SAMPLE_LAYER_NORMALMAP_AG(textureName, samplerName, coord) SampleNormalLayerAG(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights)
// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) ((tex.xy) * name##_ST.xy + name##_ST.zw)
#ifndef LAYERED_LIT_SHADER
#define LAYER_INDEX 0
#define ADD_IDX(Name) Name
#define ADD_ZERO_IDX(Name) Name
#include "LitSurfaceData.hlsl"
void GetSurfaceAndBuiltinData(FragInput input, out SurfaceData surfaceData, out BuiltinData builtinData)
float result = 0.0;
LayerTexCoord layerTexCoord;
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
result = x0 * weight[0] + x1 * weight[1];
#if _LAYER_COUNT >= 3
result += x2 * weight[2];
#ifdef _MAPPING_TRIPLANAR
// one weight for each direction XYZ - Use vertex normal for triplanar
layerTexCoord.weights = ComputeTriplanarWeights(input.tangentToWorld[2].xyz);
#if _LAYER_COUNT >= 4
result += x3 * weight[3];
// Be sure that the compiler is aware that we don't touch UV1 and UV3 for base layer in case of non layer shader
// so it can remove code
_UVMappingMask.yz = float2(0.0, 0.0);
bool isTriplanar = false;
#ifdef _MAPPING_TRIPLANAR
isTriplanar = true;
ComputeLayerTexCoord(input, isTriplanar, layerTexCoord);
ApplyDisplacement(input, layerTexCoord);
return result;
float alpha = GetSurfaceData(input, layerTexCoord, surfaceData);
GetBuiltinData(input, surfaceData, alpha, builtinData);
#else
#define ADD_ZERO_IDX(Name) Name##0
// Generate function for all layer
#define LAYER_INDEX 0
#define ADD_IDX(Name) Name##0
#include "LitSurfaceData.hlsl"
#undef LAYER_INDEX
#undef ADD_IDX
#define LAYER_INDEX 1
#define ADD_IDX(Name) Name##1
#include "LitSurfaceData.hlsl"
#undef LAYER_INDEX
#undef ADD_IDX
#define LAYER_INDEX 2
#define ADD_IDX(Name) Name##2
#include "LitSurfaceData.hlsl"
#undef LAYER_INDEX
#undef ADD_IDX
#define LAYER_INDEX 3
#define ADD_IDX(Name) Name##3
#include "LitSurfaceData.hlsl"
#undef LAYER_INDEX
#undef ADD_IDX
void ComputeMaskWeights(float3 inputMasks, out float outWeights[_MAX_LAYER])
{
float masks[_MAX_LAYER];

outWeights[0] = left;
}
float2 ComputePlanarXZCoord(float3 worldPos, float layerSize)
float3 BlendLayeredColor(float3 rgb0, float3 rgb1, float3 rgb2, float3 rgb3, float weight[4])
return frac(worldPos.xz / layerSize);
}
float3 result = float3(0.0, 0.0, 0.0);
void ComputeLayerCoordinates(out LayerCoordinates outCoord, FragInput input)
{
#if defined(_LAYER_MAPPING_UV1_0)
outCoord.texcoord[0] = input.texCoord1;
outCoord.isTriplanar[0] = false;
#elif defined(_LAYER_MAPPING_PLANAR_0)
outCoord.texcoord[0] = ComputePlanarXZCoord(input.positionWS, _LayerSize0);
outCoord.isTriplanar[0] = false;
#elif defined(_LAYER_MAPPING_TRIPLANAR_0)
outCoord.texcoord[0] = input.texCoord0;
outCoord.isTriplanar[0] = true;
#else
outCoord.texcoord[0] = input.texCoord0;
outCoord.isTriplanar[0] = false;
result = rgb0 * weight[0] + rgb1 * weight[1];
#if _LAYER_COUNT >= 3
result += (rgb2 * weight[2]);
#if defined(_LAYER_MAPPING_UV1_1)
outCoord.texcoord[1] = input.texCoord1;
outCoord.isTriplanar[1] = false;
#elif defined(_LAYER_MAPPING_PLANAR_1)
outCoord.texcoord[1] = ComputePlanarXZCoord(input.positionWS, _LayerSize1);
outCoord.isTriplanar[1] = false;
#elif defined(_LAYER_MAPPING_TRIPLANAR_1)
outCoord.texcoord[1] = input.texCoord0;
outCoord.isTriplanar[1] = true;
#else
outCoord.texcoord[1] = input.texCoord0;
outCoord.isTriplanar[1] = false;
#if _LAYER_COUNT >= 4
result += rgb3 * weight[3];
#if defined(_LAYER_MAPPING_UV1_2)
outCoord.texcoord[2] = input.texCoord1;
outCoord.isTriplanar[2] = false;
#elif defined(_LAYER_MAPPING_PLANAR_2)
outCoord.texcoord[2] = ComputePlanarXZCoord(input.positionWS, _LayerSize2);
outCoord.isTriplanar[2] = false;
#elif defined(_LAYER_MAPPING_TRIPLANAR_2)
outCoord.texcoord[2] = input.texCoord0;
outCoord.isTriplanar[2] = true;
#else
outCoord.texcoord[2] = input.texCoord0;
outCoord.isTriplanar[2] = false;
#endif
#if defined(_LAYER_MAPPING_UV1_3)
outCoord.texcoord[3] = input.texCoord1;
outCoord.isTriplanar[3] = false;
#elif defined(_LAYER_MAPPING_PLANAR_3)
outCoord.texcoord[3] = ComputePlanarXZCoord(input.positionWS, _LayerSize3);
outCoord.isTriplanar[3] = false;
#elif defined(_LAYER_MAPPING_TRIPLANAR_3)
outCoord.texcoord[3] = input.texCoord0;
outCoord.isTriplanar[3] = true;
#else
outCoord.texcoord[3] = input.texCoord0;
outCoord.isTriplanar[3] = false;
#endif
return result;
void GetSurfaceAndBuiltinData(FragInput input, out SurfaceData surfaceData, out BuiltinData builtinData)
float3 BlendLayeredNormal(float3 normal0, float3 normal1, float3 normal2, float3 normal3, float weight[4])
LayerCoordinates layerCoord;
ComputeLayerCoordinates(layerCoord, input);
// Mask Values : Layer 1, 2, 3 are r, g, b
float3 maskValues = float3(0.0, 0.0, 0.0);
float3 result = float3(0.0, 0.0, 0.0);
#if defined(_LAYER_MASK_MAP)
maskValues = SAMPLE_TEXTURE2D(_LayerMaskMap, sampler_LayerMaskMap, input.texCoord0).rgb;
result = normal0 * weight[0] + normal1 * weight[1];
#if _LAYER_COUNT >= 3
result += normal2 * weight[2];
#if defined(_LAYER_MASK_VERTEX_COLOR)
maskValues = input.vertexColor.rgb;
#if _LAYER_COUNT >= 4
result += normal3 * weight[3];
#if defined(_LAYER_MASK_MAP) && defined(_LAYER_MASK_VERTEX_COLOR)
maskValues = input.vertexColor.rgb * SAMPLE_TEXTURE2D(_LayerMaskMap, sampler_LayerMaskMap, input.texCoord0).rgb;
#endif
return normalize(result);
}
float weights[_MAX_LAYER];
ComputeMaskWeights(maskValues, weights);
PROP_DECL(float3, baseColor);
PROP_SAMPLE(baseColor, _BaseColorMap, layerCoord, rgb);
PROP_MUL(baseColor, _BaseColor, rgb);
PROP_BLEND_COLOR(baseColor, weights);
surfaceData.baseColor = baseColor;
float BlendLayeredScalar(float x0, float x1, float x2, float x3, float weight[4])
{
float result = 0.0;
PROP_DECL(float, alpha);
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
PROP_ASSIGN(alpha, _BaseColor, a);
#else
PROP_SAMPLE(alpha, _BaseColorMap, layerCoord, a);
PROP_MUL(alpha, _BaseColor, a);
result = x0 * weight[0] + x1 * weight[1];
#if _LAYER_COUNT >= 3
result += x2 * weight[2];
PROP_BLEND_SCALAR(alpha, weights);
#ifdef _ALPHATEST_ON
clip(alpha - _AlphaCutoff);
#endif
builtinData.opacity = alpha;
PROP_DECL(float, specularOcclusion);
#ifdef _SPECULAROCCLUSIONMAP
// TODO: Do something. For now just take alpha channel
PROP_SAMPLE(specularOcclusion, _SpecularOcclusionMap, layerCoord, a);
#else
// Horizon Occlusion for Normal Mapped Reflections: http://marmosetco.tumblr.com/post/81245981087
//surfaceData.specularOcclusion = saturate(1.0 + horizonFade * dot(r, input.tangentToWorld[2].xyz);
// smooth it
//surfaceData.specularOcclusion *= surfaceData.specularOcclusion;
PROP_ASSIGN_VALUE(specularOcclusion, 1.0);
#if _LAYER_COUNT >= 4
result += x3 * weight[3];
PROP_BLEND_SCALAR(specularOcclusion, weights);
surfaceData.specularOcclusion = specularOcclusion;
// TODO: think about using BC5
float3 vertexNormalWS = input.tangentToWorld[2].xyz;
return result;
}
#ifdef _NORMALMAP
#ifdef _NORMALMAP_TANGENT_SPACE
float3 normalTS0 = UnpackNormalAG(SampleLayer(TEXTURE2D_PARAM(_NormalMap0, sampler_NormalMap0), layerCoord, 0));
float3 normalTS1 = UnpackNormalAG(SampleLayer(TEXTURE2D_PARAM(_NormalMap1, sampler_NormalMap0), layerCoord, 1));
float3 normalTS2 = UnpackNormalAG(SampleLayer(TEXTURE2D_PARAM(_NormalMap2, sampler_NormalMap0), layerCoord, 2));
float3 normalTS3 = UnpackNormalAG(SampleLayer(TEXTURE2D_PARAM(_NormalMap3, sampler_NormalMap0), layerCoord, 3));
#define SURFACEDATA_BLEND_COLOR(surfaceData, name, mask) BlendLayeredColor(surfaceData##0.##name, surfaceData##1.##name, surfaceData##2.##name, surfaceData##3.##name, mask);
#define SURFACEDATA_BLEND_NORMAL(surfaceData, name, mask) BlendLayeredNormal(surfaceData##0.##name, surfaceData##1.##name, surfaceData##2.##name, surfaceData##3.##name, mask);
#define SURFACEDATA_BLEND_SCALAR(surfaceData, name, mask) BlendLayeredScalar(surfaceData##0.##name, surfaceData##1.##name, surfaceData##2.##name, surfaceData##3.##name, mask);
#define PROP_BLEND_SCALAR(name, mask) BlendLayeredScalar(name##0, name##1, name##2, name##3, mask);
float3 normalTS = BlendLayeredNormal(normalTS0, normalTS1, normalTS2, normalTS3, weights);
void GetSurfaceAndBuiltinData(FragInput input, out SurfaceData surfaceData, out BuiltinData builtinData)
{
LayerTexCoord layerTexCoord;
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
surfaceData.normalWS = TransformTangentToWorld(normalTS, input.tangentToWorld);
#else // Object space (TODO: We need to apply the world rotation here!)
surfaceData.normalWS = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, input.texCoord0).rgb;
#endif
#else
surfaceData.normalWS = vertexNormalWS;
#if defined(_LAYER_MAPPING_TRIPLANAR_0) || defined(_LAYER_MAPPING_TRIPLANAR_1) || defined(_LAYER_MAPPING_TRIPLANAR_2) || defined(_LAYER_MAPPING_TRIPLANAR_3)
// one weight for each direction XYZ - Use vertex normal for triplanar
layerTexCoord.weights = ComputeTriplanarWeights(input.tangentToWorld[2].xyz);
#if defined(_DOUBLESIDED_LIGHTING_FLIP) || defined(_DOUBLESIDED_LIGHTING_MIRROR)
#ifdef _DOUBLESIDED_LIGHTING_FLIP
float3 oppositeNormalWS = -surfaceData.normalWS;
#else
// Mirror the normal with the plane define by vertex normal
float3 oppositeNormalWS = reflect(surfaceData.normalWS, vertexNormalWS);
bool isTriplanar = false;
#ifdef _LAYER_MAPPING_TRIPLANAR_0
isTriplanar = true;
// TODO : Test if GetOdddNegativeScale() is necessary here in case of normal map, as GetOdddNegativeScale is take into account in CreateTangentToWorld();
surfaceData.normalWS = IS_FRONT_VFACE(input.cullFace, GetOdddNegativeScale() >= 0.0 ? surfaceData.normalWS : oppositeNormalWS, -GetOdddNegativeScale() >= 0.0 ? surfaceData.normalWS : oppositeNormalWS);
ComputeLayerTexCoord0(input, isTriplanar, layerTexCoord);
isTriplanar = false;
#ifdef _LAYER_MAPPING_TRIPLANAR_1
isTriplanar = true;
PROP_DECL(float, perceptualSmoothness);
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
PROP_SAMPLE(perceptualSmoothness, _BaseColorMap, layerCoord, a);
#elif defined(_MASKMAP)
PROP_SAMPLE(perceptualSmoothness, _MaskMap, layerCoord, a);
#else
PROP_ASSIGN_VALUE(perceptualSmoothness, 1.0);
ComputeLayerTexCoord1(input, isTriplanar, layerTexCoord);
isTriplanar = false;
#ifdef _LAYER_MAPPING_TRIPLANAR_2
isTriplanar = true;
PROP_MUL(perceptualSmoothness, _Smoothness, r);
PROP_BLEND_SCALAR(perceptualSmoothness, weights);
ComputeLayerTexCoord2(input, isTriplanar, layerTexCoord);
isTriplanar = false;
#ifdef _LAYER_MAPPING_TRIPLANAR_3
isTriplanar = true;
#endif
ComputeLayerTexCoord3(input, isTriplanar, layerTexCoord);
ApplyDisplacement0(input, layerTexCoord);
ApplyDisplacement1(input, layerTexCoord);
ApplyDisplacement2(input, layerTexCoord);
ApplyDisplacement3(input, layerTexCoord);
surfaceData.perceptualSmoothness = perceptualSmoothness;
SurfaceData surfaceData0;
SurfaceData surfaceData1;
SurfaceData surfaceData2;
SurfaceData surfaceData3;
float alpha0 = GetSurfaceData0(input, layerTexCoord, surfaceData0);
float alpha1 = GetSurfaceData1(input, layerTexCoord, surfaceData1);
float alpha2 = GetSurfaceData2(input, layerTexCoord, surfaceData2);
float alpha3 = GetSurfaceData3(input, layerTexCoord, surfaceData3);
surfaceData.materialId = 0;
// MaskMap is Metallic, Ambient Occlusion, (Optional) - emissive Mask, Optional - Smoothness (in alpha)
PROP_DECL(float, metallic);
PROP_DECL(float, ambientOcclusion);
#ifdef _MASKMAP
PROP_SAMPLE(metallic, _MaskMap, layerCoord, a);
PROP_SAMPLE(ambientOcclusion, _MaskMap, layerCoord, g);
#else
PROP_ASSIGN_VALUE(metallic, 1.0);
PROP_ASSIGN_VALUE(ambientOcclusion, 1.0);
// Mask Values : Layer 1, 2, 3 are r, g, b
float3 maskValues = SAMPLE_TEXTURE2D(_LayerMaskMap, sampler_LayerMaskMap, input.texCoord0).rgb;
#if defined(_LAYER_MASK_VERTEX_COLOR)
maskValues *= input.vertexColor.rgb;
PROP_MUL(metallic, _Metallic, r);
PROP_BLEND_SCALAR(metallic, weights);
PROP_BLEND_SCALAR(ambientOcclusion, weights);
float weights[_MAX_LAYER];
ComputeMaskWeights(maskValues, weights);
surfaceData.metallic = metallic;
surfaceData.ambientOcclusion = ambientOcclusion;
surfaceData.baseColor = SURFACEDATA_BLEND_COLOR(surfaceData, baseColor, weights);
surfaceData.specularOcclusion = SURFACEDATA_BLEND_SCALAR(surfaceData, specularOcclusion, weights);
// Note: for normal map (in tangent space) it is possible to have better performance
// by blending in tangent space then transform to world and apply flip.
// Sadly this require a specific path (without taking into account that there is detail normal map)
// mean it add an extra cost of maintenance. We chose to not do this optimization in favor
// of simpler code and in the future will rely on shader graph to create optimize code.
surfaceData.normalWS = SURFACEDATA_BLEND_NORMAL(surfaceData, normalWS, weights);
surfaceData.perceptualSmoothness = SURFACEDATA_BLEND_SCALAR(surfaceData, perceptualSmoothness, weights);
surfaceData.ambientOcclusion = SURFACEDATA_BLEND_SCALAR(surfaceData, ambientOcclusion, weights);
surfaceData.metallic = SURFACEDATA_BLEND_SCALAR(surfaceData, metallic, weights);
surfaceData.tangentWS = float3(1.0, 0.0, 0.0);
// Init other unused parameter
surfaceData.materialId = 0;
surfaceData.tangentWS = input.tangentToWorld[0].xyz;
// Builtin Data
// TODO: Sample lightmap/lightprobe/volume proxy
// This should also handle projective lightmap
// Note that data input above can be use to sample into lightmap (like normal)
builtinData.bakeDiffuseLighting = SampleBakedGI(input.positionWS, surfaceData.normalWS, input.texCoord1, input.texCoord2);
// Emissive Intensity is only use here, but is part of BuiltinData to enforce UI parameters as we want the users to fill one color and one intensity
PROP_DECL(float, emissiveIntensity);
PROP_ASSIGN(emissiveIntensity, _EmissiveIntensity, r);
PROP_BLEND_SCALAR(emissiveIntensity, weights);
builtinData.emissiveIntensity = emissiveIntensity; // We still store intensity here so we can reuse it with debug code
// If we chose an emissive color, we have a dedicated texture for it and don't use MaskMap
PROP_DECL(float3, emissiveColor);
#ifdef _EMISSIVE_COLOR
#ifdef _EMISSIVE_COLOR_MAP
PROP_SAMPLE(emissiveColor, _EmissiveColorMap, layerCoord, rgb);
#else
PROP_ASSIGN(emissiveColor, _EmissiveColor, rgb);
#endif
#elif defined(_MASKMAP) // If we have a MaskMap, use emissive slot as a mask on baseColor
PROP_SAMPLE(emissiveColor, _MaskMap, layerCoord, bbb);
PROP_MUL(emissiveColor, baseColor, rgb);
#else
PROP_ASSIGN_VALUE(emissiveColor, float3(0.0, 0.0, 0.0));
#endif
PROP_BLEND_COLOR(emissiveColor, weights);
builtinData.emissiveColor = emissiveColor * builtinData.emissiveIntensity;
builtinData.velocity = CalculateVelocity(input.positionCS, input.previousPositionCS);
builtinData.distortion = float2(0.0, 0.0);
builtinData.distortionBlur = 0.0;
float alpha = PROP_BLEND_SCALAR(alpha, weights);
GetBuiltinData(input, surfaceData, alpha, builtinData);
#endif
#endif // #ifndef LAYERED_LIT_SHADER

24
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSharePass.hlsl


float2 uv1 : TEXCOORD1;
#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL)
float2 uv2 : TEXCOORD2;
#endif
#endif
#ifdef _REQUIRE_UV3
float2 uv3 : TEXCOORD3;
#endif
float4 tangentOS : TANGENT; // Always present as we require it also in case of anisotropic lighting
float4 color : COLOR;

#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL)
float2 texCoord2;
#endif
#ifdef _REQUIRE_UV3
float2 texCoord3;
#endif
float3 tangentToWorld[3];
float4 color;
};

float4 positionCS : SV_Position;
#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL)
#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL) || defined(_REQUIRE_UV3)
float4 interpolators[6] : TEXCOORD0;
#else
float4 interpolators[5] : TEXCOORD0;

output.interpolators[4] = input.color;
#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL) || defined(_REQUIRE_UV3)
output.interpolators[5] = float4(0.0, 0.0, 0.0, 0.0);
output.interpolators[5] = float4(input.texCoord2.xy, 0.0, 0.0);
output.interpolators[5].xy = input.texCoord2.xy;
#endif
#ifdef _REQUIRE_UV3
output.interpolators[5].zw = input.texCoord3.xy;
#endif
#endif
return output;

#if (DYNAMICLIGHTMAP_ON) || (SHADERPASS == SHADERPASS_DEBUG_VIEW_MATERIAL)
output.texCoord2 = input.interpolators[5].xy;
#endif
#ifdef _REQUIRE_UV3
output.texCoord3 = input.interpolators[5].zw;
#endif
#if SHADER_STAGE_FRAGMENT

5
Assets/ScriptableRenderLoop/HDRenderLoop/ShaderVariables.hlsl


return mul(GetObjectToWorldMatrix(), float4(positionOS, 1.0)).xyz;
}
float3 TransformWorldToObject(float3 positionWS)
{
return mul(GetWorldToObjectMatrix(), float4(positionWS, 1.0)).xyz;
}
float3 TransformObjectToView(float3 positionOS)
{
return mul(GetObjectToWorldViewMatrix(), float4(positionOS, 1.0)).xyz;

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


using System.Collections.Generic;
using System;
public Cubemap skyHDRI;
public Texture skyHDRI;
public float rotation = 0.0f;
public float exposure = 0.0f;
public float multiplier = 1.0f;

const int kSkyCubemapSize = 256;
RenderTexture m_SkyboxCubemapRT = null;
RenderTexture m_SkyboxGGXCubemapRT = null;
Material m_GGXConvolveMaterial = null; // Apply GGX convolution to cubemap
MaterialPropertyBlock m_RenderSkyPropertyBlock = null;
GameObject[] m_CubemapFaceCamera = new GameObject[6];

};
}
void RebuildTextures()
{
if(m_SkyboxCubemapRT == null)
{
m_SkyboxCubemapRT = new RenderTexture(kSkyCubemapSize, kSkyCubemapSize, 1, RenderTextureFormat.ARGBHalf);
m_SkyboxCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxCubemapRT.useMipMap = true;
m_SkyboxCubemapRT.autoGenerateMips = true;
m_SkyboxCubemapRT.filterMode = FilterMode.Point;
m_SkyboxCubemapRT.Create();
}
if(m_SkyboxGGXCubemapRT == null)
{
m_SkyboxGGXCubemapRT = new RenderTexture(kSkyCubemapSize, kSkyCubemapSize, 1, RenderTextureFormat.ARGBHalf);
m_SkyboxGGXCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxGGXCubemapRT.useMipMap = true;
m_SkyboxGGXCubemapRT.autoGenerateMips = false;
m_SkyboxGGXCubemapRT.filterMode = FilterMode.Trilinear;
m_SkyboxGGXCubemapRT.Create();
}
}
public void Rebuild()
{
// TODO: We need to have an API to send our sky information to Enlighten. For now use a workaround through skybox/cubemap material...

m_GGXConvolveMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderLoop/GGXConvolve");
m_SkyboxCubemapRT = new RenderTexture(kSkyCubemapSize, kSkyCubemapSize, 1, RenderTextureFormat.ARGBHalf);
m_SkyboxCubemapRT.dimension = TextureDimension.Cube;
m_SkyboxCubemapRT.useMipMap = true;
m_SkyboxCubemapRT.autoGenerateMips = true;
m_SkyboxCubemapRT.Create();
m_RenderSkyPropertyBlock = new MaterialPropertyBlock();
RebuildTextures();
Matrix4x4 cubeProj = Matrix4x4.Perspective(90.0f, 1.0f, 0.1f, 1.0f);

{
Utilities.Destroy(m_StandardSkyboxMaterial);
Utilities.Destroy(m_SkyHDRIMaterial);
Utilities.Destroy(m_GGXConvolveMaterial);
Utilities.Destroy(m_SkyboxGGXCubemapRT);
for(int i = 0 ; i < 6 ; ++i)
{

{
Mesh skyMesh = BuildSkyMesh(camera, forceUVBottom);
m_SkyHDRIMaterial.SetTexture("_Cubemap", skyParameters.skyHDRI);
m_SkyHDRIMaterial.SetVector("_SkyParam", new Vector4(skyParameters.exposure, skyParameters.multiplier, skyParameters.rotation, 0.0f));
m_RenderSkyPropertyBlock.SetTexture("_Cubemap", skyParameters.skyHDRI);
m_RenderSkyPropertyBlock.SetVector("_SkyParam", new Vector4(skyParameters.exposure, skyParameters.multiplier, skyParameters.rotation, 0.0f));
cmd.DrawMesh(skyMesh, Matrix4x4.identity, m_SkyHDRIMaterial);
cmd.DrawMesh(skyMesh, Matrix4x4.identity, m_SkyHDRIMaterial, 0, 0, m_RenderSkyPropertyBlock);
public void RenderSky(Camera camera, SkyParameters skyParameters, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, RenderLoop renderLoop)
private void RenderSkyToCubemap(SkyParameters skyParameters, RenderTexture target, RenderLoop renderLoop)
using (new Utilities.ProfilingSample("Sky Pass", renderLoop))
for (int i = 0; i < 6; ++i)
{
Utilities.SetRenderTarget(renderLoop, target, 0, (CubemapFace)i);
Camera faceCamera = m_CubemapFaceCamera[i].GetComponent<Camera>();
RenderSky(faceCamera, skyParameters, true, renderLoop);
}
}
//using (new EditorGUI.DisabledScope(m_LookDevEnvLibrary.hdriList.Count <= 1))
if (IsSkyValid(skyParameters))
private void RenderCubemapGGXConvolution(Texture input, RenderTexture target, RenderLoop renderLoop)
{
using (new Utilities.ProfilingSample("Sky Pass: GGX Convolution", renderLoop))
using (new Utilities.ProfilingSample("Sky Pass: Render Cubemap", renderLoop))
int mipCount = 1 + (int)Mathf.Log(input.width, 2.0f);
if (mipCount < ((int)EnvConstants.SpecCubeLodStep + 1))
// Render sky into a cubemap - doesn't happen every frame, can be control
for (int i = 0; i < 6; ++i)
Debug.LogWarning("RenderCubemapGGXConvolution: Cubemap size is too small for GGX convolution, needs at least " + ((int)EnvConstants.SpecCubeLodStep + 1) + " mip levels");
return;
}
// Copy the first mip.
// All parameters are neutral because exposure/multiplier have already been applied in the first copy.
SkyParameters skyParams = new SkyParameters();
skyParams.exposure = 0.0f;
skyParams.multiplier = 1.0f;
skyParams.rotation = 0.0f;
skyParams.skyHDRI = input;
RenderSkyToCubemap(skyParams, target, renderLoop);
// Do the convolution on remaining mipmaps
float invOmegaP = (6.0f * input.width * input.width) / (4.0f * Mathf.PI); // Solid angle associated to a pixel of the cubemap;
m_GGXConvolveMaterial.SetTexture("_MainTex", input);
m_GGXConvolveMaterial.SetFloat("_MipMapCount", mipCount);
m_GGXConvolveMaterial.SetFloat("_InvOmegaP", invOmegaP);
for (int mip = 1; mip < ((int)EnvConstants.SpecCubeLodStep + 1); ++mip)
{
MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();
propertyBlock.SetFloat("_Level", mip);
for (int face = 0; face < 6; ++face)
Utilities.SetRenderTarget(renderLoop, m_SkyboxCubemapRT, 0, (CubemapFace)i);
Camera faceCamera = m_CubemapFaceCamera[i].GetComponent<Camera>();
RenderSky(faceCamera, skyParameters, true, renderLoop);
Utilities.SetRenderTarget(renderLoop, target, mip, (CubemapFace)face);
Camera faceCamera = m_CubemapFaceCamera[face].GetComponent<Camera>();
Mesh skyMesh = BuildSkyMesh(faceCamera, true);
var cmd = new CommandBuffer { name = "" };
cmd.DrawMesh(skyMesh, Matrix4x4.identity, m_GGXConvolveMaterial, 0, 0, propertyBlock);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
m_StandardSkyboxMaterial.SetTexture("_Tex", m_SkyboxCubemapRT);
RenderSettings.skybox = m_StandardSkyboxMaterial; // Setup this material as the default to be use in RenderSettings
RenderSettings.ambientIntensity = 1.0f; // fix this to 1, this parameter should not exist!
RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Skybox; // Force skybox for our HDRI
RenderSettings.reflectionIntensity = 1.0f;
//DynamicGI.UpdateEnvironment();
}
}
// TODO: do a render to texture here
public void RenderSky(Camera camera, SkyParameters skyParameters, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, RenderLoop renderLoop)
{
using (new Utilities.ProfilingSample("Sky Pass", renderLoop))
{
//using (new EditorGUI.DisabledScope(m_LookDevEnvLibrary.hdriList.Count <= 1))
if (IsSkyValid(skyParameters))
{
// When loading RenderDoc, RenderTextures will go null
RebuildTextures();
// Downsample the cubemap and provide it to Enlighten
using (new Utilities.ProfilingSample("Sky Pass: Render Cubemap", renderLoop))
{
// Render sky into a cubemap - doesn't happen every frame, can be controlled
RenderSkyToCubemap(skyParameters, m_SkyboxCubemapRT, renderLoop);
// Convolve downsampled cubemap
RenderCubemapGGXConvolution(m_SkyboxCubemapRT, m_SkyboxGGXCubemapRT, renderLoop);
// TODO: currently workaround is to set the cubemap in a Skybox/cubemap material
//m_SkyboxMaterial.SetTexture(cubemap);
// Render the sky itself
Utilities.SetRenderTarget(renderLoop, colorBuffer, depthBuffer);
RenderSky(camera, skyParameters, false, renderLoop);
// TODO: Properly send the cubemap to Enlighten. Currently workaround is to set the cubemap in a Skybox/cubemap material
m_StandardSkyboxMaterial.SetTexture("_Tex", m_SkyboxCubemapRT);
RenderSettings.skybox = m_StandardSkyboxMaterial; // Setup this material as the default to be use in RenderSettings
RenderSettings.ambientIntensity = 1.0f; // fix this to 1, this parameter should not exist!
RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Skybox; // Force skybox for our HDRI
RenderSettings.reflectionIntensity = 1.0f;
RenderSettings.customReflection = null;
//DynamicGI.UpdateEnvironment();
}
// Render the sky itself
Utilities.SetRenderTarget(renderLoop, colorBuffer, depthBuffer);
RenderSky(camera, skyParameters, false, renderLoop);
}
}
}
}

4
Assets/ScriptableRenderLoop/RenderPasses/ShadowRenderPass.cs


namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[System.Serializable]
public struct ShadowSettings
public class ShadowSettings
{
public bool enabled;
public int shadowAtlasWidth;

{
get
{
ShadowSettings settings;
ShadowSettings settings = new ShadowSettings();
settings.enabled = true;
settings.shadowAtlasHeight = settings.shadowAtlasWidth = 4096;
settings.directionalLightCascadeCount = 1;

2
Assets/ScriptableRenderLoop/ShaderLibrary/AreaLighting.hlsl


// Clamp to avoid artifacts. This particular constant gives the best results.
cosTheta = Clamp(cosTheta, -0.9999, 0.9999);
float theta = FastACos(cosTheta);
float res = cross(v1, v2).z * theta / sin(theta);
float res = cross(v1, v2).z * theta * rsqrt(1.0f - cosTheta * cosTheta); // optimization from * 1 / sin(theta)
return res;
}

23
Assets/ScriptableRenderLoop/ShaderLibrary/CommonMaterial.hlsl


// ref https://gist.github.com/selfshadow/8048308
// Reoriented Normal Mapping
// Blending when n1 and n2 are already 'unpacked' and normalised
float3 blendNormalRNM(float3 n1, float3 n2)
float3 BlendNormalRNM(float3 n1, float3 n2)
{
float3 t = n1.xyz + float3(0.0, 0.0, 1.0);
float3 u = n2.xyz * float3(-1.0, -1.0, 1.0);

float3 blendNormal(float3 n1, float3 n2)
float3 BlendNormal(float3 n1, float3 n2)
// Ref: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch01.html
float3 ComputeTriplanarWeights(float3 normal)
{
// Determine the blend weights for the 3 planar projections.
// N_orig is the vertex-interpolated normal vector.
float3 blendWeights = abs(normal);
// Tighten up the blending zone
blendWeights = (blendWeights - 0.2) * 7.0;
// Force weights to sum to 1.0 (very important!)
blendWeights = max(blendWeights, float3(0.0, 0.0, 0.0));
blendWeights /= dot(blendWeights, 1.0);
return blendWeights;
}
float3 LerpWhiteTo(float3 b, float t)
{
float oneMinusT = 1.0 - t;
return float3(oneMinusT, oneMinusT, oneMinusT) + b * t;
}
#endif // UNITY_COMMON_MATERIAL_INCLUDED

5
Assets/ScriptableRenderLoop/ShaderLibrary/ImageBasedLighting.hlsl


return perceptualRoughness * UNITY_SPECCUBE_LOD_STEPS;
}
float mipmapLevelToPerceptualRoughness(float mipmapLevel)
{
return mipmapLevel / UNITY_SPECCUBE_LOD_STEPS;
}
// Ref: See "Moving Frostbite to PBR" Listing 22
// This formulation is for GGX only (with smith joint visibility or regular)
float3 GetSpecularDominantDir(float3 N, float3 R, float roughness)

2
ProjectSettings/ProjectVersion.txt


m_EditorVersion: 5.6.0a4
m_EditorVersion: 5.6.0a5

35
.collabignore


# ===========================
# Default Collab Ignore Rules
# ===========================
# OS Generated
# ============
.DS_Store
._*
.Spotlight-V100
.Trashes
Icon?
ehthumbs.db
[Tt]humbs.db
[Dd]esktop.ini
# Visual Studio / MonoDevelop generated
# =====================================
[Ee]xported[Oo]bj/
*.userprefs
*.csproj
*.pidb
*.suo
*.sln
*.user
*.unityproj
*.booproj
# Unity generated
# ===============
/[Tt]emp/
[Oo]bj/
[Bb]uild
/[Ll]ibrary/
sysinfo.txt
*.stackdump

232
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSurfaceData.hlsl


void ADD_IDX(ComputeLayerTexCoord)(FragInput input, bool isTriplanar, inout LayerTexCoord layerTexCoord)
{
// TODO: Do we want to manage local or world triplanar/planar
//float3 position = localTriplanar ? TransformWorldToObject(input.positionWS) : input.positionWS;
float3 position = input.positionWS;
position *= ADD_IDX(_TexWorldScale);
// Handle uv0, uv1 and plnar XZ coordinate based on _CoordWeight weight (exclusif 0..1)
ADD_IDX(layerTexCoord.base).uv = ADD_IDX(_UVMappingMask).x * input.texCoord0 +
ADD_IDX(_UVMappingMask).y * input.texCoord1 +
ADD_IDX(_UVMappingMask).z * input.texCoord3 +
ADD_IDX(_UVMappingMask).w * position.xz;
float2 uvDetails = ADD_IDX(_UVDetailsMappingMask).x * input.texCoord0 +
ADD_IDX(_UVDetailsMappingMask).y * input.texCoord1 +
ADD_IDX(_UVDetailsMappingMask).z * input.texCoord3 +
// Note that if base is planar, detail map is planar
ADD_IDX(_UVMappingMask).w * position.xz;
ADD_IDX(layerTexCoord.details).uv = TRANSFORM_TEX(uvDetails, ADD_IDX(_DetailMap));
// triplanar
ADD_IDX(layerTexCoord.base).isTriplanar = isTriplanar;
ADD_IDX(layerTexCoord.base).uvYZ = position.yz;
ADD_IDX(layerTexCoord.base).uvZX = position.zx;
ADD_IDX(layerTexCoord.base).uvXY = position.xy;
ADD_IDX(layerTexCoord.details).isTriplanar = isTriplanar;
ADD_IDX(layerTexCoord.details).uvYZ = TRANSFORM_TEX(position.yz, ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvZX = TRANSFORM_TEX(position.zx, ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvXY = TRANSFORM_TEX(position.xy, ADD_IDX(_DetailMap));
}
void ADD_IDX(ApplyDisplacement)(inout FragInput input, inout LayerTexCoord layerTexCoord)
{
#ifdef _HEIGHTMAP
#ifndef _HEIGHTMAP_AS_DISPLACEMENT
// Transform view vector in tangent space
// Hope the compiler can optimize this in case of multiple layer
float3 V = GetWorldSpaceNormalizeViewDir(input.positionWS);
float3 viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
float height = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r * ADD_IDX(_HeightScale) + ADD_IDX(_HeightBias);
float2 offset = ParallaxOffset(viewDirTS, height);
ADD_IDX(layerTexCoord.base).uv += offset;
ADD_IDX(layerTexCoord.base).uvYZ += offset;
ADD_IDX(layerTexCoord.base).uvZX += offset;
ADD_IDX(layerTexCoord.base).uvXY += offset;
ADD_IDX(layerTexCoord.details).uv += offset;
ADD_IDX(layerTexCoord.details).uvYZ += offset;
ADD_IDX(layerTexCoord.details).uvZX += offset;
ADD_IDX(layerTexCoord.details).uvXY += offset;
// Only modify tex coord for first layer, this will be use by for builtin data (like lightmap)
if (LAYER_INDEX == 0)
{
input.texCoord0 += offset;
input.texCoord1 += offset;
input.texCoord2 += offset;
input.texCoord3 += offset;
}
#endif
#endif
}
// Return opacity
float ADD_IDX(GetSurfaceData)(FragInput input, LayerTexCoord layerTexCoord, out SurfaceData surfaceData)
{
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
float alpha = ADD_IDX(_BaseColor).a;
#else
float alpha = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_BaseColorMap), ADD_ZERO_IDX(sampler_BaseColorMap), ADD_IDX(layerTexCoord.base)).a * ADD_IDX(_BaseColor).a;
#endif
// Perform alha test very early to save performance (a killed pixel will not sample textures)
#ifdef _ALPHATEST_ON
clip(alpha - _AlphaCutoff);
#endif
#ifdef _DETAIL_MAP
float detailMask = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_DetailMask), ADD_ZERO_IDX(sampler_DetailMask), ADD_IDX(layerTexCoord.base)).b;
float2 detailAlbedoAndSmoothness = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_DetailMap), ADD_ZERO_IDX(sampler_DetailMap), ADD_IDX(layerTexCoord.details)).rb;
float detailAlbedo = detailAlbedoAndSmoothness.r;
float detailSmoothness = detailAlbedoAndSmoothness.g;
#ifdef _DETAIL_MAP_WITH_NORMAL
// Resample the detail map but this time for the normal map. This call should be optimize by the compiler
// We split both call due to trilinear mapping
float3 detailNormalTS = SAMPLE_LAYER_NORMALMAP_AG(ADD_IDX(_DetailMap), ADD_ZERO_IDX(sampler_DetailMap), ADD_IDX(layerTexCoord.details));
//float detailAO = 0.0;
#else
// TODO: Use heightmap as a derivative with Morten Mikklesen approach, how this work with our abstraction and triplanar ?
float3 detailNormalTS = float3(0.0, 0.0, 1.0);
//float detailAO = detail.b;
#endif
#endif
surfaceData.baseColor = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_BaseColorMap), ADD_ZERO_IDX(sampler_BaseColorMap), ADD_IDX(layerTexCoord.base)).rgb * ADD_IDX(_BaseColor).rgb;
#ifdef _DETAIL_MAP
surfaceData.baseColor *= LerpWhiteTo(2.0 * saturate(detailAlbedo * ADD_IDX(_DetailAlbedoScale)), detailMask);
#endif
#ifdef _SPECULAROCCLUSIONMAP
// TODO: Do something. For now just take alpha channel
surfaceData.specularOcclusion = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_SpecularOcclusionMap), ADD_ZERO_IDX(sampler_SpecularOcclusionMap), ADD_IDX(layerTexCoord.base)).a;
#else
// Horizon Occlusion for Normal Mapped Reflections: http://marmosetco.tumblr.com/post/81245981087
//surfaceData.specularOcclusion = saturate(1.0 + horizonFade * dot(r, input.tangentToWorld[2].xyz);
// smooth it
//surfaceData.specularOcclusion *= surfaceData.specularOcclusion;
surfaceData.specularOcclusion = 1.0;
#endif
// TODO: think about using BC5
float3 vertexNormalWS = normalize(input.tangentToWorld[2].xyz);
#ifdef _NORMALMAP
#ifdef _NORMALMAP_TANGENT_SPACE
float3 normalTS = SAMPLE_LAYER_NORMALMAP(ADD_IDX(_NormalMap), ADD_ZERO_IDX(sampler_NormalMap), ADD_IDX(layerTexCoord.base));
#ifdef _DETAIL_MAP
normalTS = lerp(normalTS, BlendNormal(normalTS, detailNormalTS), detailMask);
#endif
surfaceData.normalWS = TransformTangentToWorld(normalTS, input.tangentToWorld);
#else // Object space
// TODO: We are suppose to do * 2 - 1 here. how to deal with triplanar...
float3 normalOS = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_NormalMap), ADD_ZERO_IDX(sampler_NormalMap), ADD_IDX(layerTexCoord.base)).rgb;
surfaceData.normalWS = TransformObjectToWorldDir(normalOS);
#ifdef _DETAIL_MAP
float3 detailNormalWS = TransformTangentToWorld(detailNormalTS, input.tangentToWorld);
surfaceData.normalWS = lerp(surfaceData.normalWS, BlendNormal(surfaceData.normalWS, detailNormalWS), detailMask);
#endif
#endif
#else
surfaceData.normalWS = vertexNormalWS;
#endif
#if defined(_DOUBLESIDED_LIGHTING_FLIP) || defined(_DOUBLESIDED_LIGHTING_MIRROR)
#ifdef _DOUBLESIDED_LIGHTING_FLIP
float3 oppositeNormalWS = -surfaceData.normalWS;
#else
// Mirror the normal with the plane define by vertex normal
float3 oppositeNormalWS = reflect(surfaceData.normalWS, vertexNormalWS);
#endif
// TODO : Test if GetOdddNegativeScale() is necessary here in case of normal map, as GetOdddNegativeScale is take into account in CreateTangentToWorld();
surfaceData.normalWS = input.isFrontFace ?
(GetOdddNegativeScale() >= 0.0 ? surfaceData.normalWS : oppositeNormalWS) :
(-GetOdddNegativeScale() >= 0.0 ? surfaceData.normalWS : oppositeNormalWS);
#endif
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
surfaceData.perceptualSmoothness = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_BaseColorMap), ADD_ZERO_IDX(sampler_BaseColorMap), ADD_IDX(layerTexCoord.base)).a;
#elif defined(_MASKMAP)
surfaceData.perceptualSmoothness = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_MaskMap), ADD_ZERO_IDX(sampler_MaskMap), ADD_IDX(layerTexCoord.base)).a;
#else
surfaceData.perceptualSmoothness = 1.0;
#endif
surfaceData.perceptualSmoothness *= _Smoothness;
#ifdef _DETAIL_MAP
surfaceData.perceptualSmoothness *= LerpWhiteTo(2.0 * saturate(detailSmoothness * ADD_IDX(_DetailSmoothnessScale)), detailMask);
#endif
// MaskMap is Metallic, Ambient Occlusion, (Optional) - emissive Mask, Optional - Smoothness (in alpha)
#ifdef _MASKMAP
surfaceData.metallic = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_MaskMap), ADD_ZERO_IDX(sampler_MaskMap), ADD_IDX(layerTexCoord.base)).r;
surfaceData.ambientOcclusion = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_MaskMap), ADD_ZERO_IDX(sampler_MaskMap), ADD_IDX(layerTexCoord.base)).g;
#else
surfaceData.metallic = 1.0;
surfaceData.ambientOcclusion = 1.0;
#endif
surfaceData.metallic *= _Metallic;
// This part of the code is not used in case of layered shader but we keep the same macro system for simplicity
#if !defined(LAYERED_LIT_SHADER)
surfaceData.materialId = 0; // TODO
// TODO: think about using BC5
#ifdef _TANGENTMAP
#ifdef _NORMALMAP_TANGENT_SPACE // Normal and tangent use same space
float3 tangentTS = SAMPLE_LAYER_NORMALMAP(ADD_IDX(_TangentMap), ADD_ZERO_IDX(sampler_TangentMap), ADD_IDX(layerTexCoord.base)));
surfaceData.tangentWS = TransformTangentToWorld(tangentTS, input.tangentToWorld);
#else // Object space (TODO: We need to apply the world rotation here! - Require to pass world transform)
surfaceData.tangentWS = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_TangentMap), ADD_ZERO_IDX(sampler_TangentMap), ADD_IDX(layerTexCoord.base)).rgb;
#endif
#else
surfaceData.tangentWS = normalize(input.tangentToWorld[0].xyz);
#endif
// TODO: Is there anything todo regarding flip normal but for the tangent ?
#ifdef _ANISOTROPYMAP
surfaceData.anisotropy = SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_AnisotropyMap), ADD_ZERO_IDX(sampler_AnisotropyMap), ADD_IDX(layerTexCoord.base)).g;
#else
surfaceData.anisotropy = 1.0;
#endif
surfaceData.anisotropy *= _Anisotropy;
surfaceData.specular = 0.04;
surfaceData.subSurfaceRadius = 1.0;
surfaceData.thickness = 0.0;
surfaceData.subSurfaceProfile = 0;
surfaceData.coatNormalWS = float3(1.0, 0.0, 0.0);
surfaceData.coatPerceptualSmoothness = 1.0;
surfaceData.specularColor = float3(0.0, 0.0, 0.0);
#else // #if !defined(LAYERED_LIT_SHADER)
// Mandatory to setup value to keep compiler quiet
// Layered shader only support materialId 0
surfaceData.materialId = 0;
surfaceData.tangentWS = input.tangentToWorld[0].xyz;
surfaceData.anisotropy = 0;
surfaceData.specular = 0.04;
surfaceData.subSurfaceRadius = 1.0;
surfaceData.thickness = 0.0;
surfaceData.subSurfaceProfile = 0;
surfaceData.coatNormalWS = float3(1.0, 0.0, 0.0);
surfaceData.coatPerceptualSmoothness = 1.0;
surfaceData.specularColor = float3(0.0, 0.0, 0.0);
#endif // #if !defined(LAYERED_LIT_SHADER)
return alpha;
}

9
Assets/ScriptableRenderLoop/HDRenderLoop/Material/Lit/LitSurfaceData.hlsl.meta


fileFormatVersion: 2
guid: b24a503f5b489bb4896bc43d861f7f49
timeCreated: 1479984801
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

68
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/GGXConvolve.shader


Shader "Hidden/HDRenderLoop/GGXConvolve"
{
SubShader
{
Pass
{
ZWrite Off
ZTest LEqual
Blend One Zero
HLSLPROGRAM
#pragma target 5.0
#pragma only_renderers d3d11 // TEMP: unitl we go futher in dev
#pragma vertex Vert
#pragma fragment Frag
#include "Common.hlsl"
#include "ImageBasedLighting.hlsl"
struct Attributes
{
float3 positionCS : POSITION;
float3 eyeVector : NORMAL;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float3 eyeVector : TEXCOORD0;
};
Varyings Vert(Attributes input)
{
Varyings output;
output.positionCS = float4(input.positionCS.xy, UNITY_RAW_FAR_CLIP_VALUE, 1.0);
output.eyeVector = input.eyeVector;
return output;
}
TEXTURECUBE(_MainTex);
SAMPLERCUBE(sampler_MainTex);
float _Level;
float _MipMapCount;
float _InvOmegaP;
half4 Frag(Varyings input) : SV_Target
{
float3 N = input.eyeVector;
float3 V = N;
float perceptualRoughness = mipmapLevelToPerceptualRoughness(_Level);
// We approximate the pre-integration with V == N
float4 val = IntegrateLD( TEXTURECUBE_PARAM(_MainTex, sampler_MainTex),
V,
N,
PerceptualRoughnessToRoughness(perceptualRoughness),
_MipMapCount,
_InvOmegaP,
2048,
false);
return val;
}
ENDHLSL
}
}
}

9
Assets/ScriptableRenderLoop/HDRenderLoop/Sky/Resources/GGXConvolve.shader.meta


fileFormatVersion: 2
guid: 123ed592ad5c2494b8aed301fd609e7b
timeCreated: 1479994507
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

141
Assets/TestScenes/HDTest/Material/HDRenderLoopMaterials/Chrome.mat


%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Chrome
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _ALPHACUTOFFENABLE_OFF _DETAIL_MAP_WITH_NORMAL _DISTORTIONDEPTHTEST_OFF
_DISTORTIONONLY_OFF _EMISSION _NORMALMAP_TANGENT_SPACE
m_LightmapFlags: 1
m_CustomRenderQueue: -1
stringTagMap: {}
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _AnisotropyMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BaseColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissiveColorMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _HeightMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MaskMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _NormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SpecularOcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _SubSurfaceRadiusMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _TangentMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _AlphaCutoff: 0.5
- _AlphaCutoffEnable: 0
- _Anisotropy: 0
- _BlendMode: 0
- _BumpScale: 1
- _CullMode: 2
- _Cutoff: 0.5
- _DetailAOScale: 1
- _DetailAlbedoScale: 1
- _DetailHeightScale: 1
- _DetailMapMode: 0
- _DetailNormalMapScale: 1
- _DetailNormalScale: 1
- _DetailSmoothnessScale: 1
- _DistortionDepthTest: 0
- _DistortionOnly: 0
- _DoubleSidedMode: 0
- _DstBlend: 0
- _EmissiveColorMode: 1
- _EmissiveIntensity: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _HeightBias: 0
- _HeightMapMode: 0
- _HeightScale: 1
- _MaterialId: 0
- _Metallic: 1
- _Mode: 0
- _NormalMapSpace: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _Smoothness: 1
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SubSurfaceRadius: 0
- _SurfaceType: 0
- _UVDetail: 0
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _BaseColor: {r: 1, g: 1, b: 1, a: 1}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissiveColor: {r: 0, g: 0, b: 0, a: 1}

8
Assets/TestScenes/HDTest/Material/HDRenderLoopMaterials/Chrome.mat.meta


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