浏览代码

Merge branch 'SSSSS'

/main
Evgenii Golubev 8 年前
当前提交
0ca79425
共有 31 个文件被更改,包括 930 次插入178 次删除
  1. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Debug/Resources/DebugViewMaterialGBuffer.shader
  2. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Debug/Resources/DebugViewTiles.shader
  3. 7
      Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.asset
  4. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.asset.meta
  5. 200
      Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.cs
  6. 5
      Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/LightLoop.cs
  7. 57
      Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/Resources/Deferred.shader
  8. 18
      Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass/Resources/shadeopaque.compute
  9. 170
      Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  10. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  11. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
  12. 8
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs
  13. 27
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Editor/LitUI.cs
  14. 14
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.shader
  15. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl
  16. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitProperties.hlsl
  17. 11
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitTessellation.shader
  18. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Resources/PreIntegratedFGD.shader
  19. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Unlit/Unlit.shader
  20. 78
      Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/CommonSettings.cs
  21. 34
      Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/Editor/CommonSettingsEditor.cs
  22. 12
      Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl
  23. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/HDRISky/Resources/SkyHDRI.shader
  24. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/Resources/SkyProcedural.shader
  25. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/Resources/GGXConvolve.shader
  26. 92
      Assets/ScriptableRenderLoop/HDRenderPipeline/Utilities.cs
  27. 2
      ProjectSettings/GraphicsSettings.asset
  28. 133
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  29. 9
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader.meta
  30. 195
      Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/SubsurfaceScatteringParameters.cs
  31. 12
      Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/SubsurfaceScatteringParameters.cs.meta

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Debug/Resources/DebugViewMaterialGBuffer.shader


HLSLPROGRAM
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
#pragma vertex Vert
#pragma fragment Frag

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Debug/Resources/DebugViewTiles.shader


HLSLPROGRAM
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
#pragma vertex Vert
#pragma fragment Frag

7
Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.asset


m_ShadowCascadeSplit0: 0.05
m_ShadowCascadeSplit1: 0.2
m_ShadowCascadeSplit2: 0.3
m_SssProfileStdDev1: {r: 0.3, g: 0.3, b: 0.3, a: 0}
m_SssProfileStdDev2: {r: 1, g: 1, b: 1, a: 0}
m_SssProfileLerpWeight: 0.5
m_SssBilateralScale: 0.1
m_SkyParameters: {fileID: 0}
m_LightLoopProducer: {fileID: 11400000, guid: bf8cd9ae03ff7d54c89603e67be0bfc5,
type: 2}

maxShadowDistance: 1000
directionalLightCascadeCount: 4
directionalLightCascades: {x: 0.05, y: 0.2, z: 0.3}
m_SssParameters:
profiles: []
bilateralScale: 0.1
m_TextureSettings:
spotCookieSize: 128
pointCookieSize: 512

2
Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.asset.meta


fileFormatVersion: 2
guid: e185fecca3c73cd47a09f1092663ef32
timeCreated: 1485857876
timeCreated: 1485874614
licenseType: Pro
NativeFormatImporter:
mainObjectFileID: 11400000

200
Assets/ScriptableRenderLoop/HDRenderPipeline/HDRenderPipeline.cs


return SkyParametersSingleton.overrideSettings;
return m_SkyParameters;
}
}
}

public ShadowSettings shadowSettings
{
get { return m_ShadowSettings; }
}
[SerializeField]
SubsurfaceScatteringParameters m_SssParameters = SubsurfaceScatteringParameters.Default;
public SubsurfaceScatteringParameters sssParameters
{
get { return m_SssParameters; }
}
[SerializeField]

public void UpdateCommonSettings()
{
var commonSettings = commonSettingsToUse;
// TODO: how can we avoid dynamic memory allocation each frame?
m_SssParameters.profiles = new SubsurfaceScatteringProfile[SubsurfaceScatteringParameters.numProfiles];
m_SssParameters.profiles[0] = new SubsurfaceScatteringProfile();
m_SssParameters.profiles[0].stdDev1 = commonSettings.sssProfileStdDev1;
m_SssParameters.profiles[0].stdDev2 = commonSettings.sssProfileStdDev2;
m_SssParameters.profiles[0].lerpWeight = commonSettings.sssProfileLerpWeight;
m_SssParameters.bilateralScale = commonSettings.sssBilateralScale;
}
}

// Various set of material use in render loop
readonly Material m_DebugViewMaterialGBuffer;
readonly Material m_CombineSubsurfaceScattering;
readonly int m_CameraDepthBuffer;
readonly int m_CameraSubsurfaceBuffer;
readonly int m_CameraFilteringBuffer;
readonly int m_CameraDepthStencilBuffer;
readonly int m_CameraStencilBuffer;
// 'm_CameraColorBuffer' does not contain diffuse lighting of SSS materials until the SSS pass.
// It is stored within 'm_CameraSubsurfaceBufferRT'.
readonly RenderTargetIdentifier m_CameraDepthBufferRT;
readonly RenderTargetIdentifier m_CameraSubsurfaceBufferRT;
readonly RenderTargetIdentifier m_CameraFilteringBufferRT;
readonly RenderTargetIdentifier m_CameraDepthStencilBufferRT;
// 'm_CameraStencilBufferRT' is a temporary copy of the stencil buffer and should be removed
// once we are able to read from the depth buffer and perform the stencil test simultaneously.
readonly RenderTargetIdentifier m_CameraStencilBufferRT;
readonly RenderTargetIdentifier m_VelocityBufferRT;
readonly RenderTargetIdentifier m_DistortionBufferRT;

{
m_Owner = owner;
m_CameraColorBuffer = Shader.PropertyToID("_CameraColorTexture");
m_CameraDepthBuffer = Shader.PropertyToID("_CameraDepthTexture");
m_CameraColorBuffer = Shader.PropertyToID("_CameraColorTexture");
m_CameraSubsurfaceBuffer = Shader.PropertyToID("_CameraSubsurfaceTexture");
m_CameraFilteringBuffer = Shader.PropertyToID("_CameraFilteringBuffer");
m_CameraDepthStencilBuffer = Shader.PropertyToID("_CameraDepthTexture");
m_CameraStencilBuffer = Shader.PropertyToID("_CameraStencilTexture");
m_CameraColorBufferRT = new RenderTargetIdentifier(m_CameraColorBuffer);
m_CameraDepthBufferRT = new RenderTargetIdentifier(m_CameraDepthBuffer);
m_CameraColorBufferRT = new RenderTargetIdentifier(m_CameraColorBuffer);
m_CameraSubsurfaceBufferRT = new RenderTargetIdentifier(m_CameraSubsurfaceBuffer);
m_CameraFilteringBufferRT = new RenderTargetIdentifier(m_CameraFilteringBuffer);
m_CameraDepthStencilBufferRT = new RenderTargetIdentifier(m_CameraDepthStencilBuffer);
m_CameraStencilBufferRT = new RenderTargetIdentifier(m_CameraStencilBuffer);
m_CombineSubsurfaceScattering = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CombineSubsurfaceScattering");
m_gbufferManager.gbufferCount = m_LitRenderLoop.GetMaterialGBufferCount();
RenderTextureFormat[] RTFormat;
RenderTextureReadWrite[] RTReadWrite;

RenderForwardOnlyOpaqueDepthPrepass(cullResults, camera, renderContext);
RenderGBuffer(cullResults, camera, renderContext);
// 'm_CameraStencilBufferRT' is a temporary copy of the stencil buffer and should be removed
// once we are able to read from the depth buffer and perform the stencil test simultaneously.
using (new Utilities.ProfilingSample("Copy depth-stencil buffer", renderContext))
{
var cmd = new CommandBuffer();
cmd.CopyTexture(m_CameraDepthStencilBufferRT, m_CameraStencilBufferRT);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
if (debugParameters.debugViewMaterial != 0)
{
RenderDebugViewMaterial(cullResults, hdCamera, renderContext);

ShadowOutput shadows;
using (new Utilities.ProfilingSample("Shadow Pass", renderContext))
{
{
}
}
{
{
{
{
m_LightLoop.BuildGPULightLists(camera, renderContext, m_CameraDepthBufferRT); // TODO: Use async compute here to run light culling during shadow
}
m_LightLoop.BuildGPULightLists(camera, renderContext, m_CameraDepthStencilBufferRT); // TODO: Use async compute here to run light culling during shadow
}
PushGlobalParams(hdCamera, renderContext);

RenderDeferredLighting(hdCamera, renderContext);
// We compute subsurface scattering here. Therefore, no objects rendered afterwards will exhibit SSS.
// Currently, there is no efficient way to switch between SRT and MRT for the forward pass;
// therefore, forward-rendered objects do not output split lighting required for the SSS pass.
CombineSubsurfaceScattering(hdCamera, renderContext, m_Owner.sssParameters);
// For opaque forward we have split rendering in two categories
// Material that are always forward and material that can be deferred or forward depends on render pipeline options (like switch to rendering forward only mode)
// Material that are always forward are unlit and complex (Like Hair) and don't require sorting, so it is ok to split them.

FinalPass(camera, renderContext);
cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, m_CameraDepthBufferRT);
cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, m_CameraDepthStencilBufferRT);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}

{
// 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
Utilities.SetRenderTarget(renderContext, m_CameraDepthBufferRT);
Utilities.SetRenderTarget(renderContext, m_CameraDepthStencilBufferRT);
RenderOpaqueRenderList(cull, camera, renderContext, "DepthOnly");
}
}

using (new Utilities.ProfilingSample("GBuffer Pass", renderContext))
{
// setup GBuffer for rendering
Utilities.SetRenderTarget(renderContext, m_gbufferManager.GetGBuffers(), m_CameraDepthBufferRT);
Utilities.SetRenderTarget(renderContext, m_gbufferManager.GetGBuffers(), m_CameraDepthStencilBufferRT);
// render opaque objects into GBuffer
RenderOpaqueRenderList(cull, camera, renderContext, "GBuffer", Utilities.kRendererConfigurationBakedLighting);
}

using (new Utilities.ProfilingSample("Forward opaque depth", renderContext))
{
Utilities.SetRenderTarget(renderContext, m_CameraDepthBufferRT);
Utilities.SetRenderTarget(renderContext, m_CameraDepthStencilBufferRT);
RenderOpaqueRenderList(cull, camera, renderContext, "ForwardOnlyOpaqueDepthOnly");
}
}

using (new Utilities.ProfilingSample("DebugView Material Mode Pass", renderContext))
// Render Opaque forward
{
Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthBufferRT, Utilities.kClearAll, Color.black);
Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, Utilities.kClearAll, Color.black);
Shader.SetGlobalInt("_DebugViewMaterial", (int)debugParameters.debugViewMaterial);

void RenderDeferredLighting(HDCamera hdCamera, ScriptableRenderContext renderContext)
{
if (debugParameters.ShouldUseForwardRenderingOnly())
if (debugParameters.ShouldUseForwardRenderingOnly() || m_LightLoop == null)
if (m_LightLoop != null)
m_LightLoop.RenderDeferredLighting(hdCamera, renderContext, m_CameraColorBuffer);
RenderTargetIdentifier[] colorRTs = { m_CameraColorBufferRT, m_CameraSubsurfaceBufferRT };
// Output split lighting for materials tagged with the SSS stencil bit.
m_LightLoop.RenderDeferredLighting(hdCamera, renderContext, colorRTs, m_CameraStencilBufferRT, true);
// Output combined lighting for all the other materials.
m_LightLoop.RenderDeferredLighting(hdCamera, renderContext, colorRTs, m_CameraStencilBufferRT, false);
}
// Combines specular lighting and diffuse lighting with subsurface scattering.
void CombineSubsurfaceScattering(HDCamera hdCamera, ScriptableRenderContext context, SubsurfaceScatteringParameters sssParameters)
{
// Currently, forward-rendered objects do not output split lighting required for the SSS pass.
if (debugParameters.ShouldUseForwardRenderingOnly()) return;
// Assume that the height of the projection window is 2 meters.
float distanceToProjectionWindow = 1.0f / Mathf.Tan(0.5f * Mathf.Deg2Rad * hdCamera.camera.fieldOfView);
m_CombineSubsurfaceScattering.SetFloat("_DistToProjWindow", distanceToProjectionWindow);
m_CombineSubsurfaceScattering.SetFloat("_BilateralScale", 0.05f * sssParameters.bilateralScale);
// TODO: use user-defined values for '_ProfileID' and '_FilterRadius.'
m_CombineSubsurfaceScattering.SetVectorArray("_FilterKernel", sssParameters.profiles[0].filterKernel);
m_CombineSubsurfaceScattering.SetFloat("_FilterRadius", 3.0f);
MaterialPropertyBlock properties = new MaterialPropertyBlock();
var cmd = new CommandBuffer() { name = "Combine Subsurface Scattering" };
cmd.SetGlobalTexture("_CameraDepthTexture", m_CameraDepthStencilBufferRT);
// Perform the vertical SSS filtering pass.
properties.SetFloat("_DstBlend", (float)BlendMode.Zero); // TODO: this doesn't work for some reason...
properties.SetFloat("_FilterHorizontal", 0);
cmd.SetGlobalTexture("_IrradianceSource", m_CameraSubsurfaceBufferRT);
Utilities.DrawFullscreen(cmd, m_CombineSubsurfaceScattering, hdCamera,
m_CameraFilteringBufferRT, m_CameraStencilBufferRT, properties);
// Perform the horizontal SSS filtering pass, and combine diffuse and specular lighting.
properties.SetFloat("_DstBlend", (float)BlendMode.One); // TODO: this doesn't work for some reason...
properties.SetFloat("_FilterHorizontal", 1);
cmd.SetGlobalTexture("_IrradianceSource", m_CameraFilteringBufferRT);
Utilities.DrawFullscreen(cmd, m_CombineSubsurfaceScattering, hdCamera,
m_CameraColorBufferRT, m_CameraStencilBufferRT, properties);
context.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
void UpdateSkyEnvironment(HDCamera hdCamera, ScriptableRenderContext renderContext)

void RenderSky(HDCamera hdCamera, ScriptableRenderContext renderContext)
{
m_SkyManager.RenderSky(hdCamera, m_LightLoop == null ? null : m_LightLoop.GetCurrentSunLight(), m_CameraColorBufferRT, m_CameraDepthBufferRT, renderContext);
m_SkyManager.RenderSky(hdCamera, m_LightLoop == null ? null : m_LightLoop.GetCurrentSunLight(), m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, renderContext);
void RenderForward(CullResults cullResults, Camera camera, ScriptableRenderContext renderContext, bool renderOpaque)
{
// TODO: Currently we can't render opaque object forward when deferred is enabled

using (new Utilities.ProfilingSample("Forward Pass", renderContext))
{
Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthBufferRT);
Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
if (m_LightLoop != null)
m_LightLoop.RenderForward(camera, renderContext, renderOpaque);

{
using (new Utilities.ProfilingSample("Forward Only Pass", renderContext))
{
Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthBufferRT);
Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT);
if (m_LightLoop != null)
m_LightLoop.RenderForward(camera, renderContext, true);

var cmd = new CommandBuffer { name = "" };
cmd.GetTemporaryRT(m_VelocityBuffer, w, h, 0, FilterMode.Point, Builtin.RenderLoop.GetVelocityBufferFormat(), Builtin.RenderLoop.GetVelocityBufferReadWrite());
cmd.SetRenderTarget(m_VelocityBufferRT, m_CameraDepthBufferRT);
cmd.SetRenderTarget(m_VelocityBufferRT, m_CameraDepthStencilBufferRT);
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();

var cmd = new CommandBuffer { name = "" };
cmd.GetTemporaryRT(m_DistortionBuffer, w, h, 0, FilterMode.Point, Builtin.RenderLoop.GetDistortionBufferFormat(), Builtin.RenderLoop.GetDistortionBufferReadWrite());
cmd.SetRenderTarget(m_DistortionBufferRT, m_CameraDepthBufferRT);
cmd.SetRenderTarget(m_DistortionBufferRT, m_CameraDepthStencilBufferRT);
cmd.ClearRenderTarget(false, true, Color.black); // TODO: can we avoid this clear for performance ?
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();

int w = camera.pixelWidth;
int h = camera.pixelHeight;
cmd.GetTemporaryRT(m_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
cmd.GetTemporaryRT(m_CameraDepthBuffer, w, h, 24, FilterMode.Point, RenderTextureFormat.Depth);
cmd.GetTemporaryRT(m_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
cmd.GetTemporaryRT(m_CameraSubsurfaceBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
cmd.GetTemporaryRT(m_CameraFilteringBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.RGB111110Float, RenderTextureReadWrite.Linear, 1, true); // Enable UAV
cmd.GetTemporaryRT(m_CameraDepthStencilBuffer, w, h, 24, FilterMode.Point, RenderTextureFormat.Depth);
cmd.GetTemporaryRT(m_CameraStencilBuffer, w, h, 24, FilterMode.Point, RenderTextureFormat.Depth);
{
{
}
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
renderContext.ExecuteCommandBuffer(cmd);
cmd.Dispose();
Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.ClearDepth);
}
// Clear the diffuse SSS lighting target
using (new Utilities.ProfilingSample("Clear SSS diffuse target", renderContext))
{
Utilities.SetRenderTarget(renderContext, m_CameraSubsurfaceBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.ClearColor, Color.black);
}
Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthBufferRT, ClearFlag.ClearDepth);
}
// Clear the SSS filtering target
using (new Utilities.ProfilingSample("Clear SSS filtering target", renderContext))
{
Utilities.SetRenderTarget(renderContext, m_CameraFilteringBuffer, m_CameraDepthStencilBufferRT, ClearFlag.ClearColor, Color.black);
}
// Clear HDR target
// Clear the HDR target
{
Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthBufferRT, ClearFlag.ClearColor, Color.black);
}
{
Utilities.SetRenderTarget(renderContext, m_CameraColorBufferRT, m_CameraDepthStencilBufferRT, ClearFlag.ClearColor, Color.black);
}
{
using (new Utilities.ProfilingSample("Clear GBuffer", renderContext))
Utilities.SetRenderTarget(renderContext, m_gbufferManager.GetGBuffers(), m_CameraDepthBufferRT, ClearFlag.ClearColor, Color.black);
}
using (new Utilities.ProfilingSample("Clear GBuffer", renderContext))
{
Utilities.SetRenderTarget(renderContext, m_gbufferManager.GetGBuffers(), m_CameraDepthStencilBufferRT, ClearFlag.ClearColor, Color.black);
}
// END TEMP
}
}

5
Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/LightLoop.cs


using UnityEngine;
using UnityEngine.Rendering;
namespace UnityEngine.Experimental.Rendering.HDPipeline

public virtual void PushGlobalParams(Camera camera, ScriptableRenderContext loop) {}
public virtual void RenderDeferredLighting(HDCamera hdCamera, ScriptableRenderContext renderContext, RenderTargetIdentifier cameraColorBufferRT) {}
public virtual void RenderDeferredLighting(HDCamera hdCamera, ScriptableRenderContext renderContext,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier stencilBuffer,
bool outputSplitLighting) {}
public virtual void RenderForward(Camera camera, ScriptableRenderContext renderContext, bool renderOpaque) {}

57
Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/Resources/Deferred.shader


// We need to be able to control the blend mode for deferred shader in case we do multiple pass
_SrcBlend("", Float) = 1
_DstBlend("", Float) = 1
_StencilRef("_StencilRef", Int) = 0
Stencil
{
Ref [_StencilRef]
Comp Equal
Pass Keep
}
Blend Off
Blend[_SrcBlend][_DstBlend]
ZTest Always
Blend [_SrcBlend][_DstBlend]
#pragma only_renderers d3d11 ps4 metal // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
#pragma vertex Vert
#pragma fragment Frag

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

// Note: We have fix as guidelines that we have only one deferred material (with control of GBuffer enabled). Mean a users that add a new
// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
// deferred material must replace the old one here. If in the future we want to support multiple layout (cause a lot of consistency problem),
float3 positionOS : POSITION;
uint vertexId : SV_VertexID;
};
struct Varyings

struct Outputs
{
#ifdef OUTPUT_SPLIT_LIGHTING
float4 specularLighting : SV_Target0;
float3 diffuseLighting : SV_Target1;
#else
float4 combinedLighting : SV_Target0;
#endif
};
// TODO: implement SV_vertexID full screen quad
// Lights are draw as one fullscreen quad
float3 positionWS = TransformObjectToWorld(input.positionOS);
output.positionCS = TransformWorldToHClip(positionWS);
// Generate a triangle in homogeneous clip space, s.t.
// v0 = (-1, -1, 1), v1 = (3, -1, 1), v2 = (-1, 3, 1).
float2 uv = float2((input.vertexId << 1) & 2, input.vertexId & 2);
output.positionCS = float4(uv * 2.0 - 1.0, 1.0, 1.0);
float4 Frag(Varyings input) : SV_Target
Outputs Frag(Varyings input)
{
// input.positionCS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw);

float3 specularLighting;
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, diffuseLighting, specularLighting);
return float4(diffuseLighting + specularLighting, 1.0);
Outputs outputs;
#ifdef OUTPUT_SPLIT_LIGHTING
outputs.specularLighting = float4(specularLighting, 1.0);
outputs.diffuseLighting = diffuseLighting;
#else
outputs.combinedLighting = float4(diffuseLighting + specularLighting, 1.0);
#endif
return outputs;
}
ENDHLSL

18
Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass/Resources/shadeopaque.compute


#pragma kernel ShadeOpaque_Fptl SHADE_OPAQUE_ENTRY=ShadeOpaque_Fptl USE_FPTL_LIGHTLIST=1
#pragma kernel ShadeOpaque_Clustered SHADE_OPAQUE_ENTRY=ShadeOpaque_Clustered USE_CLUSTERED_LIGHTLIST=1
// Split lighting is required for the SSS pass.
// Not currently possible since we need to access the stencil buffer from the compute shader.
// #pragma multi_compile _ OUTPUT_SPLIT_LIGHTING
#define LIGHTLOOP_TILE_PASS 1
#define LIGHTLOOP_TILE_DIRECT 1

//-------------------------------------------------------------------------------------
// Include

TEXTURE2D(_CameraDepthTexture);
SAMPLER2D(sampler_CameraDepthTexture);
RWTexture2D<float4> uavOutput;
#ifdef OUTPUT_SPLIT_LIGHTING
RWTexture2D<float4> specularLightingUAV;
RWTexture2D<float3> diffuseLightingUAV;
#else
RWTexture2D<float4> combinedLightingUAV;
#endif
[numthreads(TILE_SIZE, TILE_SIZE, 1)]
void SHADE_OPAQUE_ENTRY(uint2 dispatchThreadId : SV_DispatchThreadID, uint2 groupId : SV_GroupID)

float3 specularLighting;
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, diffuseLighting, specularLighting);
uavOutput[pixelCoord] = float4(diffuseLighting + specularLighting, 1.0);
#ifdef OUTPUT_SPLIT_LIGHTING
specularLightingUAV[pixelCoord] = float4(specularLighting, 1.0);
diffuseLightingUAV[pixelCoord] = diffuseLighting;
#else
combinedLightingUAV[pixelCoord] = float4(diffuseLighting + specularLighting, 1.0);
#endif
}

170
Assets/ScriptableRenderLoop/HDRenderPipeline/Lighting/TilePass/TilePass.cs


}
}
Material m_DeferredDirectMaterialSRT = null;
Material m_DeferredDirectMaterialMRT = null;
Material m_DeferredIndirectMaterialSRT = null;
Material m_DeferredIndirectMaterialMRT = null;
Material m_DeferredAllMaterialSRT = null;
Material m_DeferredAllMaterialMRT = null;
Material m_DeferredDirectMaterial = null;
Material m_DeferredIndirectMaterial = null;
Material m_DeferredAllMaterial = null;
Material m_DebugViewTilesMaterial = null;
Material m_DebugViewTilesMaterial = null;
Material m_SingleDeferredMaterial = null;
Material m_SingleDeferredMaterialSRT = null;
Material m_SingleDeferredMaterialMRT = null;
int GetNumTileX(Camera camera)
{

s_LightList = null;
m_DeferredDirectMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
m_DeferredDirectMaterial.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredDirectMaterial.EnableKeyword("LIGHTLOOP_TILE_DIRECT");
m_DeferredDirectMaterial.DisableKeyword("LIGHTLOOP_TILE_INDIRECT");
m_DeferredDirectMaterial.DisableKeyword("LIGHTLOOP_TILE_ALL");
string[] tileKeywords = {"LIGHTLOOP_TILE_DIRECT", "LIGHTLOOP_TILE_INDIRECT", "LIGHTLOOP_TILE_ALL"};
m_DeferredDirectMaterialSRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
Utilities.SelectKeyword(m_DeferredDirectMaterialSRT, tileKeywords, 0);
m_DeferredDirectMaterialSRT.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredDirectMaterialSRT.DisableKeyword("OUTPUT_SPLIT_LIGHTING");
m_DeferredDirectMaterialSRT.SetInt("_StencilRef", (int)StencilBits.None);
m_DeferredDirectMaterialSRT.SetInt("_SrcBlend", (int)BlendMode.One);
m_DeferredDirectMaterialSRT.SetInt("_DstBlend", (int)BlendMode.Zero);
m_DeferredDirectMaterialMRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
Utilities.SelectKeyword(m_DeferredDirectMaterialMRT, tileKeywords, 0);
m_DeferredDirectMaterialMRT.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredDirectMaterialMRT.EnableKeyword("OUTPUT_SPLIT_LIGHTING");
m_DeferredDirectMaterialMRT.SetInt("_StencilRef", (int)StencilBits.SSS);
m_DeferredDirectMaterialMRT.SetInt("_SrcBlend", (int)BlendMode.One);
m_DeferredDirectMaterialMRT.SetInt("_DstBlend", (int)BlendMode.Zero);
m_DeferredIndirectMaterialSRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
Utilities.SelectKeyword(m_DeferredIndirectMaterialSRT, tileKeywords, 1);
m_DeferredIndirectMaterialSRT.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredIndirectMaterialSRT.DisableKeyword("OUTPUT_SPLIT_LIGHTING");
m_DeferredIndirectMaterialSRT.SetInt("_StencilRef", (int)StencilBits.None);
m_DeferredIndirectMaterialSRT.SetInt("_SrcBlend", (int)BlendMode.One);
m_DeferredIndirectMaterialSRT.SetInt("_DstBlend", (int)BlendMode.One); // Additive
m_DeferredIndirectMaterialMRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
Utilities.SelectKeyword(m_DeferredIndirectMaterialMRT, tileKeywords, 1);
m_DeferredIndirectMaterialMRT.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredIndirectMaterialMRT.EnableKeyword("OUTPUT_SPLIT_LIGHTING");
m_DeferredIndirectMaterialMRT.SetInt("_StencilRef", (int)StencilBits.SSS);
m_DeferredIndirectMaterialMRT.SetInt("_SrcBlend", (int)BlendMode.One);
m_DeferredIndirectMaterialMRT.SetInt("_DstBlend", (int)BlendMode.One); // Additive
m_DeferredIndirectMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
m_DeferredIndirectMaterial.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredIndirectMaterial.DisableKeyword("LIGHTLOOP_TILE_DIRECT");
m_DeferredIndirectMaterial.EnableKeyword("LIGHTLOOP_TILE_INDIRECT");
m_DeferredIndirectMaterial.DisableKeyword("LIGHTLOOP_TILE_ALL");
m_DeferredAllMaterialSRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
Utilities.SelectKeyword(m_DeferredAllMaterialSRT, tileKeywords, 2);
m_DeferredAllMaterialSRT.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredAllMaterialSRT.DisableKeyword("OUTPUT_SPLIT_LIGHTING");
m_DeferredAllMaterialSRT.SetInt("_StencilRef", (int)StencilBits.None);
m_DeferredAllMaterialSRT.SetInt("_SrcBlend", (int)BlendMode.One);
m_DeferredAllMaterialSRT.SetInt("_DstBlend", (int)BlendMode.Zero);
m_DeferredAllMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
m_DeferredAllMaterial.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredAllMaterial.DisableKeyword("LIGHTLOOP_TILE_DIRECT");
m_DeferredAllMaterial.DisableKeyword("LIGHTLOOP_TILE_INDIRECT");
m_DeferredAllMaterial.EnableKeyword("LIGHTLOOP_TILE_ALL");
m_DeferredAllMaterialMRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
Utilities.SelectKeyword(m_DeferredAllMaterialMRT, tileKeywords, 2);
m_DeferredAllMaterialMRT.EnableKeyword("LIGHTLOOP_TILE_PASS");
m_DeferredAllMaterialMRT.EnableKeyword("OUTPUT_SPLIT_LIGHTING");
m_DeferredAllMaterialMRT.SetInt("_StencilRef", (int)StencilBits.SSS);
m_DeferredAllMaterialMRT.SetInt("_SrcBlend", (int)BlendMode.One);
m_DeferredAllMaterialMRT.SetInt("_DstBlend", (int)BlendMode.Zero);
m_SingleDeferredMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
m_SingleDeferredMaterial.EnableKeyword("LIGHTLOOP_SINGLE_PASS");
m_SingleDeferredMaterialSRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
m_SingleDeferredMaterialSRT.EnableKeyword("LIGHTLOOP_SINGLE_PASS");
m_SingleDeferredMaterialSRT.DisableKeyword("OUTPUT_SPLIT_LIGHTING");
m_SingleDeferredMaterialSRT.SetInt("_StencilRef", (int)StencilBits.None);
m_SingleDeferredMaterialSRT.SetInt("_SrcBlend", (int)BlendMode.One);
m_SingleDeferredMaterialSRT.SetInt("_DstBlend", (int)BlendMode.Zero);
m_SingleDeferredMaterialMRT = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/Deferred");
m_SingleDeferredMaterialMRT.EnableKeyword("LIGHTLOOP_SINGLE_PASS");
m_SingleDeferredMaterialMRT.EnableKeyword("OUTPUT_SPLIT_LIGHTING");
m_SingleDeferredMaterialMRT.SetInt("_StencilRef", (int)StencilBits.SSS);
m_SingleDeferredMaterialMRT.SetInt("_SrcBlend", (int)BlendMode.One);
m_SingleDeferredMaterialMRT.SetInt("_DstBlend", (int)BlendMode.Zero);
m_DefaultTexture2DArray = new Texture2DArray(1, 1, 1, TextureFormat.ARGB32, false);
m_DefaultTexture2DArray.SetPixels32(new Color32[1] { new Color32(128, 128, 128, 128) }, 0);

// enableClustered
Utilities.SafeRelease(s_GlobalLightListAtomic);
Utilities.Destroy(m_DeferredDirectMaterial);
Utilities.Destroy(m_DeferredIndirectMaterial);
Utilities.Destroy(m_DeferredAllMaterial);
Utilities.Destroy(m_DeferredDirectMaterialSRT);
Utilities.Destroy(m_DeferredDirectMaterialMRT);
Utilities.Destroy(m_DeferredIndirectMaterialSRT);
Utilities.Destroy(m_DeferredIndirectMaterialMRT);
Utilities.Destroy(m_DeferredAllMaterialSRT);
Utilities.Destroy(m_DeferredAllMaterialMRT);
Utilities.Destroy(m_SingleDeferredMaterial);
Utilities.Destroy(m_SingleDeferredMaterialSRT);
Utilities.Destroy(m_SingleDeferredMaterialMRT);
Utilities.Destroy(s_DefaultAdditionalLightDataGameObject);
s_DefaultAdditionalLightDataGameObject = null;

}
#endif
public override void RenderDeferredLighting(HDCamera hdCamera, ScriptableRenderContext renderContext, RenderTargetIdentifier cameraColorBufferRT)
public override void RenderDeferredLighting(HDCamera hdCamera, ScriptableRenderContext renderContext,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier stencilBuffer,
bool outputSplitLighting)
{
var bUseClusteredForDeferred = !usingFptl;

if (m_PassSettings.disableTileAndCluster)
{
// This is a debug brute force renderer to debug tile/cluster which render all the lights
Utilities.SetupMaterialHDCamera(hdCamera, m_SingleDeferredMaterial);
m_SingleDeferredMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m_SingleDeferredMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
cmd.Blit(null, cameraColorBufferRT, m_SingleDeferredMaterial, 0);
if (outputSplitLighting)
{
Utilities.DrawFullscreen(cmd, m_SingleDeferredMaterialMRT, hdCamera, colorBuffers, stencilBuffer);
}
else
{
Utilities.DrawFullscreen(cmd, m_SingleDeferredMaterialSRT, hdCamera, colorBuffers[0], stencilBuffer);
}
}
else
{

cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_IESArray", IESArrayTexture ? IESArrayTexture : m_DefaultTexture2DArray);
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_SkyTexture", skyTexture ? skyTexture : m_DefaultTexture2DArray);
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "uavOutput", cameraColorBufferRT);
// Since we need the stencil test, the compute path does not currently support SSS.
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "combinedLightingUAV", colorBuffers[0]);
cmd.DispatchCompute(shadeOpaqueShader, kernel, numTilesX, numTilesY, 1);
}
else

{
Utilities.SetupMaterialHDCamera(hdCamera, m_DeferredDirectMaterial);
m_DeferredDirectMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m_DeferredDirectMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
m_DeferredDirectMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DeferredDirectMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
if (outputSplitLighting)
{
Utilities.SelectKeyword(m_DeferredDirectMaterialMRT, "USE_CLUSTERED_LIGHTLIST", "USE_FPTL_LIGHTLIST", bUseClusteredForDeferred);
Utilities.DrawFullscreen(cmd, m_DeferredDirectMaterialMRT, hdCamera, colorBuffers, stencilBuffer);
Utilities.SetupMaterialHDCamera(hdCamera, m_DeferredIndirectMaterial);
m_DeferredIndirectMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m_DeferredIndirectMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); // Additive
m_DeferredIndirectMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DeferredIndirectMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
Utilities.SelectKeyword(m_DeferredIndirectMaterialMRT, "USE_CLUSTERED_LIGHTLIST", "USE_FPTL_LIGHTLIST", bUseClusteredForDeferred);
Utilities.DrawFullscreen(cmd, m_DeferredIndirectMaterialMRT, hdCamera, colorBuffers, stencilBuffer);
}
else
{
Utilities.SelectKeyword(m_DeferredDirectMaterialSRT, "USE_CLUSTERED_LIGHTLIST", "USE_FPTL_LIGHTLIST", bUseClusteredForDeferred);
Utilities.DrawFullscreen(cmd, m_DeferredDirectMaterialSRT, hdCamera, colorBuffers[0], stencilBuffer);
cmd.Blit(null, cameraColorBufferRT, m_DeferredDirectMaterial, 0);
cmd.Blit(null, cameraColorBufferRT, m_DeferredIndirectMaterial, 0);
Utilities.SelectKeyword(m_DeferredIndirectMaterialSRT, "USE_CLUSTERED_LIGHTLIST", "USE_FPTL_LIGHTLIST", bUseClusteredForDeferred);
Utilities.DrawFullscreen(cmd, m_DeferredIndirectMaterialSRT, hdCamera, colorBuffers[0], stencilBuffer);
}
Utilities.SetupMaterialHDCamera(hdCamera, m_DeferredAllMaterial);
m_DeferredAllMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
m_DeferredAllMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
m_DeferredAllMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DeferredAllMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
cmd.Blit(null, cameraColorBufferRT, m_DeferredAllMaterial, 0);
if (outputSplitLighting)
{
Utilities.SelectKeyword(m_DeferredAllMaterialMRT, "USE_CLUSTERED_LIGHTLIST", "USE_FPTL_LIGHTLIST", bUseClusteredForDeferred);
Utilities.DrawFullscreen(cmd, m_DeferredAllMaterialMRT, hdCamera, colorBuffers, stencilBuffer);
}
else
{
Utilities.SelectKeyword(m_DeferredAllMaterialSRT, "USE_CLUSTERED_LIGHTLIST", "USE_FPTL_LIGHTLIST", bUseClusteredForDeferred);
Utilities.DrawFullscreen(cmd, m_DeferredAllMaterialSRT, hdCamera, colorBuffers[0], stencilBuffer);
}
}
}

m_DebugViewTilesMaterial.EnableKeyword(bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
m_DebugViewTilesMaterial.DisableKeyword(!bUseClusteredForDeferred ? "USE_CLUSTERED_LIGHTLIST" : "USE_FPTL_LIGHTLIST");
cmd.Blit(null, cameraColorBufferRT, m_DebugViewTilesMaterial, 0);
cmd.Blit(null, colorBuffers[0], m_DebugViewTilesMaterial, 0);
}
}

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


HLSLINCLUDE
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DISTORTION_ON

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader


HLSLINCLUDE
#pragma target 5.0
#pragma only_renderers d3d11 ps4 // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4 // TEMP: until we go further in dev
#pragma shader_feature _ALPHATEST_ON
#pragma shader_feature _DISTORTION_ON

8
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs


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 materialClassText = new GUIContent("Material Class", "Subsurface Scattering: enable for translucent materials such as skin, vegetation, fruit, marble, wax and milk.");
public static GUIContent emissiveColorModeText = new GUIContent("Emissive Color Usage", "Use emissive color or emissive mask");
public static string InputsText = "Inputs";

Phong,
Displacement,
DisplacementPhong,
}
public enum MaterialClass
{
Standard,
SSS,
Hair
}
void SurfaceTypePopup()

27
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Editor/LitUI.cs


using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{

protected const string kUVDetail = "_UVDetail";
protected MaterialProperty UVDetailsMappingMask = null;
protected const string kUVDetailsMappingMask = "_UVDetailsMappingMask";
protected MaterialProperty materialClass = null;
protected const string kMaterialClass = "_MaterialClass";
protected MaterialProperty emissiveColorMode = null;
protected const string kEmissiveColorMode = "_EmissiveColorMode";

ppdMinSamples = FindProperty(kPpdMinSamples, props);
ppdMaxSamples = FindProperty(kPpdMaxSamples, props);
detailMapMode = FindProperty(kDetailMapMode, props);
materialClass = FindProperty(kMaterialClass, props);
emissiveColorMode = FindProperty(kEmissiveColorMode, props);
}

EditorGUI.indentLevel++;
GUILayout.Label(Styles.InputsOptionsText, EditorStyles.boldLabel);
m_MaterialEditor.ShaderProperty(smoothnessMapChannel, Styles.smoothnessMapChannelText.text);
m_MaterialEditor.ShaderProperty(UVBase, enableUVDetail ? Styles.UVBaseDetailMappingText.text : Styles.UVBaseMappingText.text);
m_MaterialEditor.ShaderProperty(smoothnessMapChannel, Styles.smoothnessMapChannelText);
m_MaterialEditor.ShaderProperty(UVBase, enableUVDetail ? Styles.UVBaseDetailMappingText : Styles.UVBaseMappingText);
float X, Y, Z, W;
X = ((UVBaseMapping)UVBase.floatValue == UVBaseMapping.UV0) ? 1.0f : 0.0f;

{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(TexWorldScale, Styles.texWorldScaleText.text);
m_MaterialEditor.ShaderProperty(TexWorldScale, Styles.texWorldScaleText);
m_MaterialEditor.ShaderProperty(UVDetail, Styles.UVDetailMappingText.text);
m_MaterialEditor.ShaderProperty(UVDetail, Styles.UVDetailMappingText);
}
X = ((UVDetailMapping)UVDetail.floatValue == UVDetailMapping.UV0) ? 1.0f : 0.0f;

UVDetailsMappingMask.colorValue = new Color(X, Y, Z, W);
//m_MaterialEditor.ShaderProperty(detailMapMode, Styles.detailMapModeText.text);
m_MaterialEditor.ShaderProperty(normalMapSpace, Styles.normalMapSpaceText.text);
m_MaterialEditor.ShaderProperty(emissiveColorMode, Styles.emissiveColorModeText.text);
m_MaterialEditor.ShaderProperty(enablePerPixelDisplacement, Styles.enablePerPixelDisplacementText.text);
m_MaterialEditor.ShaderProperty(ppdMinSamples, Styles.ppdMinSamplesText.text);
m_MaterialEditor.ShaderProperty(ppdMaxSamples, Styles.ppdMaxSamplesText.text);
//m_MaterialEditor.ShaderProperty(detailMapMode, Styles.detailMapModeText);
m_MaterialEditor.ShaderProperty(normalMapSpace, Styles.normalMapSpaceText);
m_MaterialEditor.ShaderProperty(emissiveColorMode, Styles.emissiveColorModeText);
m_MaterialEditor.ShaderProperty(enablePerPixelDisplacement, Styles.enablePerPixelDisplacementText);
m_MaterialEditor.ShaderProperty(ppdMinSamples, Styles.ppdMinSamplesText);
m_MaterialEditor.ShaderProperty(ppdMaxSamples, Styles.ppdMaxSamplesText);
m_MaterialEditor.ShaderProperty(materialClass, Styles.materialClassText);
EditorGUI.indentLevel--;
}

material.DisableKeyword("_REQUIRE_UV2");
material.DisableKeyword("_REQUIRE_UV3");
}
material.SetInt("_StencilRef", (int)material.GetFloat(kMaterialClass)); // See 'StencilBits'.
}
}
} // namespace UnityEditor

14
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Lit.shader


_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
_DetailAOScale("_DetailAOScale", Range(-2.0, 2.0)) = 1
[Enum(Standard, 0, Subsurface Scattering, 1, Hair, 2)] _MaterialClass("Material Class", Int) = 0
_SubSurfaceRadius("SubSurfaceRadius", Range(0.0, 1.0)) = 0
_SubSurfaceRadiusMap("SubSurfaceRadiusMap", 2D) = "white" {}
//_Thickness("Thickness", Range(0.0, 1.0)) = 0

[ToggleOff] _AlphaCutoffEnable("Alpha Cutoff Enable", Float) = 0.0
_AlphaCutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
// Stencil state
[HideInInspector] _StencilRef("_StencilRef", Int) = 0
// Blending state
[HideInInspector] _SurfaceType("__surfacetype", Float) = 0.0

Tags { "LightMode" = "GBuffer" } // This will be only for opaque object based on the RenderQueue index
Cull [_CullMode]
Stencil
{
Ref [_StencilRef]
Comp Always
Pass Replace
}
HLSLPROGRAM

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl


// 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
surfaceData.materialId = _MaterialClass;
// TODO: think about using BC5
#ifdef _TANGENTMAP

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitProperties.hlsl


TEXTURE2D(_AnisotropyMap);
SAMPLER2D(sampler_AnisotropyMap);
float _MaterialClass;
//float _SubSurfaceRadius;
//TEXTURE2D(_SubSurfaceRadiusMap);
//SAMPLER2D(sampler_SubSurfaceRadiusMap);

11
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitTessellation.shader


_DetailHeightScale("_DetailHeightScale", Range(-2.0, 2.0)) = 1
_DetailAOScale("_DetailAOScale", Range(-2.0, 2.0)) = 1
[Enum(Standard, 0, Subsurface Scattering, 1, Hair, 2)] _MaterialClass("Material Class", Int) = 0
_SubSurfaceRadius("SubSurfaceRadius", Range(0.0, 1.0)) = 0
_SubSurfaceRadiusMap("SubSurfaceRadiusMap", 2D) = "white" {}
//_Thickness("Thickness", Range(0.0, 1.0)) = 0

_AlphaCutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
_HorizonFade("Horizon fade", Range(0.0, 5.0)) = 1.0
// Stencil state
[HideInInspector] _StencilRef("_StencilRef", Int) = 0
// Blending state
[HideInInspector] _SurfaceType("__surfacetype", Float) = 0.0

Tags { "LightMode" = "GBuffer" } // This will be only for opaque object based on the RenderQueue index
Cull [_CullMode]
Stencil
{
Ref [_StencilRef]
Comp Always
Pass Replace
}
HLSLPROGRAM

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Resources/PreIntegratedFGD.shader


#pragma vertex Vert
#pragma fragment Frag
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
#include "Common.hlsl"
#include "ImageBasedLighting.hlsl"

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


HLSLINCLUDE
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
//-------------------------------------------------------------------------------------
// Variant

78
Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/CommonSettings.cs


{
[Serializable]
public struct Settings
{
[SerializeField]
float m_ShadowMaxDistance;
[SerializeField]
int m_ShadowCascadeCount;
[SerializeField]
float m_ShadowCascadeSplit0;
{
// Shadows
[SerializeField] float m_ShadowMaxDistance;
[SerializeField] int m_ShadowCascadeCount;
[SerializeField] float m_ShadowCascadeSplit0;
[SerializeField] float m_ShadowCascadeSplit1;
[SerializeField] float m_ShadowCascadeSplit2;
[SerializeField]
float m_ShadowCascadeSplit1;
[SerializeField]
float m_ShadowCascadeSplit2;
public float shadowMaxDistance { set { m_ShadowMaxDistance = value; OnValidate(); } get { return m_ShadowMaxDistance; } }
public int shadowCascadeCount { set { m_ShadowCascadeCount = value; OnValidate(); } get { return m_ShadowCascadeCount; } }
public float shadowMaxDistance { set { m_ShadowMaxDistance = value; OnValidate(); } get { return m_ShadowMaxDistance; } }
public int shadowCascadeCount { set { m_ShadowCascadeCount = value; OnValidate(); } get { return m_ShadowCascadeCount; } }
public void OnValidate()
// Subsurface scattering
[ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
[SerializeField] Color m_SssProfileStdDev1;
[ColorUsage(false, true, 0.05f, 2.0f, 1.0f, 1.0f)]
[SerializeField] Color m_SssProfileStdDev2;
[SerializeField] float m_SssProfileLerpWeight;
[SerializeField] float m_SssBilateralScale;
public Color sssProfileStdDev1 { set { m_SssProfileStdDev1 = value; OnValidate(); } get { return m_SssProfileStdDev1; } }
public Color sssProfileStdDev2 { set { m_SssProfileStdDev2 = value; OnValidate(); } get { return m_SssProfileStdDev2; } }
public float sssProfileLerpWeight { set { m_SssProfileLerpWeight = value; OnValidate(); } get { return m_SssProfileLerpWeight; } }
public float sssBilateralScale { set { m_SssBilateralScale = value; OnValidate(); } get { return m_SssBilateralScale; } }
void OnValidate()
m_ShadowMaxDistance = Mathf.Max(0.0f, m_ShadowMaxDistance);
m_ShadowCascadeCount = Math.Min(4, Math.Max(1, m_ShadowCascadeCount));
m_ShadowCascadeSplit0 = Mathf.Min(1.0f, Mathf.Max(0.0f, m_ShadowCascadeSplit0));
m_ShadowCascadeSplit1 = Mathf.Min(1.0f, Mathf.Max(0.0f, m_ShadowCascadeSplit1));
m_ShadowCascadeSplit2 = Mathf.Min(1.0f, Mathf.Max(0.0f, m_ShadowCascadeSplit2));
m_ShadowMaxDistance = Mathf.Max(0.0f, m_ShadowMaxDistance);
m_ShadowCascadeCount = Math.Min(4, Math.Max(1, m_ShadowCascadeCount));
m_ShadowCascadeSplit0 = Mathf.Clamp01(m_ShadowCascadeSplit0);
m_ShadowCascadeSplit1 = Mathf.Clamp01(m_ShadowCascadeSplit1);
m_ShadowCascadeSplit2 = Mathf.Clamp01(m_ShadowCascadeSplit2);
m_SssProfileStdDev1.r = Mathf.Max(0.05f, m_SssProfileStdDev1.r);
m_SssProfileStdDev1.g = Mathf.Max(0.05f, m_SssProfileStdDev1.g);
m_SssProfileStdDev1.b = Mathf.Max(0.05f, m_SssProfileStdDev1.b);
m_SssProfileStdDev1.a = 0.0f;
m_SssProfileStdDev2.r = Mathf.Max(0.05f, m_SssProfileStdDev2.r);
m_SssProfileStdDev2.g = Mathf.Max(0.05f, m_SssProfileStdDev2.g);
m_SssProfileStdDev2.b = Mathf.Max(0.05f, m_SssProfileStdDev2.b);
m_SssProfileStdDev2.a = 0.0f;
m_SssProfileLerpWeight = Mathf.Clamp01(m_SssProfileLerpWeight);
m_SssBilateralScale = Mathf.Clamp01(m_SssBilateralScale);
m_ShadowMaxDistance = ShadowSettings.Default.maxShadowDistance,
m_ShadowCascadeCount = ShadowSettings.Default.directionalLightCascadeCount,
m_ShadowCascadeSplit0 = ShadowSettings.Default.directionalLightCascades.x,
m_ShadowCascadeSplit1 = ShadowSettings.Default.directionalLightCascades.y,
m_ShadowCascadeSplit2 = ShadowSettings.Default.directionalLightCascades.z,
m_ShadowCascadeCount = ShadowSettings.Default.directionalLightCascadeCount,
m_ShadowCascadeSplit0 = ShadowSettings.Default.directionalLightCascades.x,
m_ShadowMaxDistance = ShadowSettings.Default.maxShadowDistance,
m_ShadowCascadeSplit1 = ShadowSettings.Default.directionalLightCascades.y,
m_ShadowCascadeSplit2 = ShadowSettings.Default.directionalLightCascades.z
m_SssProfileStdDev1 = SubsurfaceScatteringProfile.Default.stdDev1,
m_SssProfileStdDev2 = SubsurfaceScatteringProfile.Default.stdDev2,
m_SssProfileLerpWeight = SubsurfaceScatteringProfile.Default.lerpWeight,
m_SssBilateralScale = SubsurfaceScatteringParameters.Default.bilateralScale
[SerializeField]
private Settings m_Settings = Settings.s_Defaultsettings;

34
Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/Editor/CommonSettingsEditor.cs


public readonly GUIContent shadowsCascades = new GUIContent("Cascade values");
public readonly GUIContent[] shadowSplits = new GUIContent[] { new GUIContent("Split 0"), new GUIContent("Split 1"), new GUIContent("Split 2") };
public readonly GUIContent sssCategory = new GUIContent("Subsurface scattering");
public readonly GUIContent sssProfileStdDev1 = new GUIContent("SSS profile standard deviation #1", "Determines the shape of the 1st Gaussian filter. Increases the strength and the radius of the blur of the corresponding color channel.");
public readonly GUIContent sssProfileStdDev2 = new GUIContent("SSS profile standard deviation #2", "Determines the shape of the 2nd Gaussian filter. Increases the strength and the radius of the blur of the corresponding color channel.");
public readonly GUIContent sssProfileLerpWeight = new GUIContent("SSS profile filter interpolation", "Controls linear interpolation between the two Gaussian filters.");
public readonly GUIContent sssBilateralScale = new GUIContent("SSS bilateral filtering scale", "Larger values make the filter more tolerant to depth differences.");
}
private static Styles s_Styles = null;

private SerializedProperty m_ShadowCascadeCount;
private SerializedProperty[] m_ShadowCascadeSplits = new SerializedProperty[3];
// Subsurface scattering
private SerializedProperty m_SssProfileStdDev1;
private SerializedProperty m_SssProfileStdDev2;
private SerializedProperty m_SssProfileLerpWeight;
private SerializedProperty m_SssBilateralScale;
void OnEnable()
{
m_SkyRenderer = serializedObject.FindProperty("m_SkyRendererTypeName");

m_SkyRendererFullTypeNames.Add("");
m_SkyRendererTypeValues.Add(m_SkyRendererTypeValues.Count);
m_SkyRendererTypes.Add(null);
m_SssProfileStdDev1 = serializedObject.FindProperty("m_SssProfileStdDev1");
m_SssProfileStdDev2 = serializedObject.FindProperty("m_SssProfileStdDev2");
m_SssProfileLerpWeight = serializedObject.FindProperty("m_SssProfileLerpWeight");
m_SssBilateralScale = serializedObject.FindProperty("m_SssBilateralScale");
}
void OnSkyInspectorGUI()

EditorGUI.indentLevel--;
}
/* public override void OnInspectorGUI()
void OnSubsurfaceInspectorGUI()
{
EditorGUILayout.LabelField(styles.sssCategory);
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_SssProfileStdDev1, styles.sssProfileStdDev1);
EditorGUILayout.PropertyField(m_SssProfileStdDev2, styles.sssProfileStdDev2);
EditorGUILayout.PropertyField(m_SssProfileLerpWeight, styles.sssProfileLerpWeight);
EditorGUILayout.PropertyField(m_SssBilateralScale, styles.sssBilateralScale);
EditorGUI.indentLevel--;
}
/*
public override void OnInspectorGUI()
OnSubsurfaceInspectorGUI();
}*/
}
*/
}
}

12
Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/ShaderPassForward.hlsl


#endif // TESSELLATION_ON
void Frag( PackedVaryingsToPS packedInput,
out float4 outColor : SV_Target
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif
)
void Frag(PackedVaryingsToPS packedInput,
out float4 outColor : SV_Target0
#ifdef _DEPTHOFFSET_ON
, out float outputDepth : SV_Depth
#endif
)
{
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/HDRISky/Resources/SkyHDRI.shader


#pragma fragment Frag
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
#include "Color.hlsl"
#include "Common.hlsl"

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/ProceduralSky/Resources/SkyProcedural.shader


HLSLPROGRAM
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
#pragma vertex Vert
#pragma fragment Frag

2
Assets/ScriptableRenderLoop/HDRenderPipeline/Sky/Resources/GGXConvolve.shader


HLSLPROGRAM
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: unitl we go futher in dev
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
#pragma multi_compile _ USE_MIS

92
Assets/ScriptableRenderLoop/HDRenderPipeline/Utilities.cs


[Flags]
public enum ClearFlag
{
ClearNone = 0,
ClearNone = 0,
}
[Flags]
public enum StencilBits
{
None = 0,
SSS = 1, // BaseLitGUI.MaterialClass.SSS
Hair = 2, // BaseLitGUI.MaterialClass.Hair
All = 255 // 0xff
}
public class Utilities

m.DisableKeyword(keyword);
}
public static void SelectKeyword(Material material, string keyword1, string keyword2, bool enableFirst)
{
material.EnableKeyword (enableFirst ? keyword1 : keyword2);
material.DisableKeyword(enableFirst ? keyword2 : keyword1);
}
public static void SelectKeyword(Material material, string[] keywords, int enabledKeywordIndex)
{
material.EnableKeyword(keywords[enabledKeywordIndex]);
for (int i = 0; i < keywords.Length; i++)
{
if (i != enabledKeywordIndex)
{
material.DisableKeyword(keywords[i]);
}
}
}
public static HDRenderPipeline GetHDRenderPipeline()
{
HDRenderPipeline renderContext = GraphicsSettings.renderPipelineAsset as HDRenderPipeline;

}
return renderContext;
}
static Mesh m_ScreenSpaceTriangle = null;
static Mesh GetScreenSpaceTriangle()
{
// If the assembly has been reloaded, the pointer will become NULL.
if (!m_ScreenSpaceTriangle)
{
m_ScreenSpaceTriangle = new Mesh
{
// Note: neither the vertex nor the index data is actually used if the vertex shader computes vertices
// using 'SV_VertexID'. However, there is currently no way to bind NULL vertex or index buffers.
vertices = new[] { new Vector3(-1, -1, 1), new Vector3(3, -1, 1), new Vector3(-1, 3, 1) },
triangles = new[] { 0, 1, 2 }
};
}
return m_ScreenSpaceTriangle;
}
// Draws a full screen triangle as a faster alternative to drawing a full-screen quad.
public static void DrawFullscreen(CommandBuffer commandBuffer, Material material, HDCamera camera,
RenderTargetIdentifier colorBuffer,
MaterialPropertyBlock properties = null, int shaderPassID = 0)
{
SetupMaterialHDCamera(camera, material);
commandBuffer.SetRenderTarget(colorBuffer);
commandBuffer.DrawMesh(GetScreenSpaceTriangle(), Matrix4x4.identity, material, 0, shaderPassID, properties);
}
// Draws a full screen triangle as a faster alternative to drawing a full-screen quad.
public static void DrawFullscreen(CommandBuffer commandBuffer, Material material, HDCamera camera,
RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthStencilBuffer,
MaterialPropertyBlock properties = null, int shaderPassID = 0)
{
SetupMaterialHDCamera(camera, material);
commandBuffer.SetRenderTarget(colorBuffer, depthStencilBuffer);
commandBuffer.DrawMesh(GetScreenSpaceTriangle(), Matrix4x4.identity, material, 0, shaderPassID, properties);
}
// Draws a full screen triangle as a faster alternative to drawing a full-screen quad.
public static void DrawFullscreen(CommandBuffer commandBuffer, Material material, HDCamera camera,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer,
MaterialPropertyBlock properties = null, int shaderPassID = 0)
{
SetupMaterialHDCamera(camera, material);
commandBuffer.SetRenderTarget(colorBuffers, depthStencilBuffer);
commandBuffer.DrawMesh(GetScreenSpaceTriangle(), Matrix4x4.identity, material, 0, shaderPassID, properties);
}
// Draws a full screen triangle as a faster alternative to drawing a full-screen quad.
// Important: the first RenderTarget must be created with 0 depth bits!
public static void DrawFullscreen(CommandBuffer commandBuffer, Material material, HDCamera camera,
RenderTargetIdentifier[] colorBuffers,
MaterialPropertyBlock properties = null, int shaderPassID = 0)
{
// It is currently not possible to have MRT without also setting a depth target.
// To work around this deficiency of the CommandBuffer.SetRenderTarget() API,
// we pass the first color target as the depth target. If it has 0 depth bits,
// no depth target ends up being bound.
DrawFullscreen(commandBuffer, material, camera, colorBuffers, colorBuffers[0], properties, shaderPassID);
}
}
}

2
ProjectSettings/GraphicsSettings.asset


m_PreloadedShaders: []
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
type: 0}
m_CustomRenderPipeline: {fileID: 11400000, guid: e185fecca3c73cd47a09f1092663ef32,
m_CustomRenderPipeline: {fileID: 11400000, guid: b9f70be9ae966df448c8d09888d77fd0,
type: 2}
m_TransparencySortMode: 0
m_TransparencySortAxis: {x: 0, y: 0, z: 1}

133
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader


Shader "Hidden/HDRenderPipeline/CombineSubsurfaceScattering"
{
Properties
{
_FilterRadius("", Float) = 20
_BilateralScale("", Float) = 0.1
[HideInInspector] _DstBlend("", Float) = 1 // Can be set to 1 for blending with specular
}
SubShader
{
Pass
{
Stencil
{
Ref 1 // StencilBits.SSS
Comp Equal
Pass Keep
}
ZTest Always
ZWrite Off
Blend One [_DstBlend], Zero [_DstBlend]
HLSLPROGRAM
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
#pragma vertex Vert
#pragma fragment Frag
//-------------------------------------------------------------------------------------
// Include
//-------------------------------------------------------------------------------------
#include "Common.hlsl"
#include "Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderVariables.hlsl"
//-------------------------------------------------------------------------------------
// Inputs & outputs
//-------------------------------------------------------------------------------------
#define N_SAMPLES 7
float _BilateralScale; // Uses world-space units
float _DistToProjWindow; // The height of the projection window is 2 meters
float _FilterHorizontal; // Vertical = 0, horizontal = 1
float4 _FilterKernel[7]; // RGB = weights, A = radial distance
float _FilterRadius; // Uses world-space units
TEXTURE2D(_CameraDepthTexture);
TEXTURE2D(_IrradianceSource);
SAMPLER2D(sampler_IrradianceSource);
#define bilinearSampler sampler_IrradianceSource
//-------------------------------------------------------------------------------------
// Implementation
//-------------------------------------------------------------------------------------
struct Attributes
{
uint vertexId : SV_VertexID;
};
struct Varyings
{
float4 positionCS : SV_Position;
};
Varyings Vert(Attributes input)
{
Varyings output;
// Generate a triangle in homogeneous clip space, s.t.
// v0 = (-1, -1, 1), v1 = (3, -1, 1), v2 = (-1, 3, 1).
float2 uv = float2((input.vertexId << 1) & 2, input.vertexId & 2);
output.positionCS = float4(uv * 2 - 1, 1, 1);
return output;
}
float4 Frag(Varyings input) : SV_Target
{
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw);
float rawDepth = LOAD_TEXTURE2D(_CameraDepthTexture, posInput.unPositionSS).r;
float cDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
float radiusScale = _FilterRadius * _DistToProjWindow / cDepth;
// Compute the filtering direction.
float2 unitDirection = _FilterHorizontal ? float2(1, 0) : float2(0, 1);
float2 scaledDirection = radiusScale * unitDirection;
// Premultiply with the inverse of the screen size.
scaledDirection *= _ScreenSize.zw;
// Take the first (central) sample.
float3 sWeight = _FilterKernel[0].rgb;
float2 sPosition = posInput.unPositionSS;
float3 sIrradiance = LOAD_TEXTURE2D(_IrradianceSource, sPosition).rgb;
float3 cIrradiance = sIrradiance;
// Accumulate filtered irradiance (already weighted by (albedo / Pi)).
float3 filteredIrradiance = sIrradiance * sWeight;
[unroll]
for (int i = 1; i < N_SAMPLES; i++)
{
sWeight = _FilterKernel[i].rgb; // TODO: normalize weights
sPosition = posInput.positionSS + scaledDirection * _FilterKernel[i].a;
sIrradiance = SAMPLE_TEXTURE2D_LOD(_IrradianceSource, bilinearSampler, sPosition, 0).rgb;
rawDepth = SAMPLE_TEXTURE2D_LOD(_CameraDepthTexture, bilinearSampler, sPosition, 0).r;
// Apply bilateral filtering.
float sDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
float dDepth = abs(sDepth - cDepth);
float dScale = _BilateralScale * _FilterRadius * _DistToProjWindow;
float t = saturate(dDepth / dScale);
// TODO: use real-world distances for weighting.
filteredIrradiance += lerp(sIrradiance, cIrradiance, t) * sWeight;
}
return float4(filteredIrradiance, 1.0);
}
ENDHLSL
}
}
Fallback Off
}

9
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader.meta


fileFormatVersion: 2
guid: 867b36db983aa0548889a66f8d685ff6
timeCreated: 1485184880
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

195
Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/SubsurfaceScatteringParameters.cs


using System;
namespace UnityEngine.Experimental.Rendering
{
[Serializable]
public class SubsurfaceScatteringProfile
{
public const int numSamples = 7;
Color m_StdDev1;
Color m_StdDev2;
float m_LerpWeight;
Vector4[] m_FilterKernel;
bool m_KernelNeedsUpdate;
// --- Methods ---
public Color stdDev1
{
get { return m_StdDev1; }
set { if (m_StdDev1 != value) { m_StdDev1 = value; m_KernelNeedsUpdate = true; } }
}
public Color stdDev2
{
get { return m_StdDev2; }
set { if (m_StdDev2 != value) { m_StdDev2 = value; m_KernelNeedsUpdate = true; } }
}
public float lerpWeight
{
get { return m_LerpWeight; }
set { if (m_LerpWeight != value) { m_LerpWeight = value; m_KernelNeedsUpdate = true; } }
}
public Vector4[] filterKernel
{
get { if (m_KernelNeedsUpdate) ComputeKernel(); return m_FilterKernel; }
}
public static SubsurfaceScatteringProfile Default
{
get
{
SubsurfaceScatteringProfile profile = new SubsurfaceScatteringProfile();
profile.m_StdDev1 = new Color(0.3f, 0.3f, 0.3f, 0.0f);
profile.m_StdDev2 = new Color(1.0f, 1.0f, 1.0f, 0.0f);
profile.m_LerpWeight = 0.5f;
profile.ComputeKernel();
return profile;
}
}
static float Gaussian(float x, float stdDev)
{
float variance = stdDev * stdDev;
return Mathf.Exp(-x * x / (2 * variance)) / Mathf.Sqrt(2 * Mathf.PI * variance);
}
static float GaussianCombination(float x, float stdDev1, float stdDev2, float lerpWeight)
{
return Mathf.Lerp(Gaussian(x, stdDev1), Gaussian(x, stdDev2), lerpWeight);
}
static float RationalApproximation(float t)
{
// Abramowitz and Stegun formula 26.2.23.
// The absolute value of the error should be less than 4.5 e-4.
float[] c = {2.515517f, 0.802853f, 0.010328f};
float[] d = {1.432788f, 0.189269f, 0.001308f};
return t - ((c[2] * t + c[1]) * t + c[0]) / (((d[2] * t + d[1]) * t + d[0]) * t + 1.0f);
}
// Ref: https://www.johndcook.com/blog/csharp_phi_inverse/
static float NormalCdfInverse(float p, float stdDev)
{
float x;
if (p < 0.5)
{
// F^-1(p) = - G^-1(p)
x = -RationalApproximation(Mathf.Sqrt(-2.0f * Mathf.Log(p)));
}
else
{
// F^-1(p) = G^-1(1-p)
x = RationalApproximation(Mathf.Sqrt(-2.0f * Mathf.Log(1.0f - p)));
}
return x * stdDev;
}
static float GaussianCombinationCdfInverse(float p, float stdDev1, float stdDev2, float lerpWeight)
{
return Mathf.Lerp(NormalCdfInverse(p, stdDev1), NormalCdfInverse(p, stdDev2), lerpWeight);
}
// Ref: http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
static float VanDerCorputBase2(uint i)
{
i = (i << 16) | (i >> 16);
i = ((i & 0x00ff00ff) << 8) | ((i & 0xff00ff00) >> 8);
i = ((i & 0x0f0f0f0f) << 4) | ((i & 0xf0f0f0f0) >> 4);
i = ((i & 0x33333333) << 2) | ((i & 0xcccccccc) >> 2);
i = ((i & 0x55555555) << 1) | ((i & 0xaaaaaaaa) >> 1);
return i * (1.0f / 4294967296);
}
void ComputeKernel()
{
if (m_FilterKernel == null)
{
m_FilterKernel = new Vector4[numSamples];
}
// Our goal is to blur the image using a filter which is represented
// as a product of a linear combination of two normalized 1D Gaussians
// as suggested by Jimenez et al. in "Separable Subsurface Scattering".
// A normalized (i.e. energy-preserving) 1D Gaussian with the mean of 0
// is defined as follows: G1(x, v) = exp(-x� / (2 * v)) / sqrt(2 * Pi * v),
// where 'v' is variance and 'x' is the radial distance from the origin.
// Using the weight 'w', our 1D and the resulting 2D filters are given as:
// A1(v1, v2, w, x) = G1(x, v1) * (1 - w) + G1(r, v2) * w,
// A2(v1, v2, w, x, y) = A1(v1, v2, w, x) * A1(v1, v2, w, y).
// The resulting filter function is a non-Gaussian PDF.
// It is separable by design, but generally not radially symmmetric.
// Find the widest Gaussian across 3 color channels.
float maxStdDev1 = Mathf.Max(m_StdDev1.r, m_StdDev1.g, m_StdDev1.b);
float maxStdDev2 = Mathf.Max(m_StdDev2.r, m_StdDev2.g, m_StdDev2.b);
Vector3 weightSum = new Vector3(0, 0, 0);
// Importance sample the linear combination of two Gaussians.
for (uint i = 0; i < numSamples; i++)
{
float u = VanDerCorputBase2(i + 1);
float pos = GaussianCombinationCdfInverse(u, maxStdDev1, maxStdDev2, m_LerpWeight);
float pdf = GaussianCombination(pos, maxStdDev1, maxStdDev2, m_LerpWeight);
Vector3 val;
val.x = GaussianCombination(pos, m_StdDev1.r, m_StdDev2.r, m_LerpWeight);
val.y = GaussianCombination(pos, m_StdDev1.g, m_StdDev2.g, m_LerpWeight);
val.z = GaussianCombination(pos, m_StdDev1.b, m_StdDev2.b, m_LerpWeight);
m_FilterKernel[i].x = val.x / (pdf * numSamples);
m_FilterKernel[i].y = val.y / (pdf * numSamples);
m_FilterKernel[i].z = val.z / (pdf * numSamples);
m_FilterKernel[i].w = pos;
weightSum.x += m_FilterKernel[i].x;
weightSum.y += m_FilterKernel[i].y;
weightSum.z += m_FilterKernel[i].z;
}
// Renormalize the weights to conserve energy.
for (uint i = 0; i < numSamples; i++)
{
m_FilterKernel[i].x *= 1.0f / weightSum.x;
m_FilterKernel[i].y *= 1.0f / weightSum.y;
m_FilterKernel[i].z *= 1.0f / weightSum.z;
}
m_KernelNeedsUpdate = false;
}
}
[System.Serializable]
public class SubsurfaceScatteringParameters
{
public const int numProfiles = 1;
public SubsurfaceScatteringProfile[] profiles;
public float bilateralScale;
// --- Methods ---
public static SubsurfaceScatteringParameters Default
{
get
{
SubsurfaceScatteringParameters parameters = new SubsurfaceScatteringParameters();
parameters.profiles = new SubsurfaceScatteringProfile[numProfiles];
for (int i = 0; i < numProfiles; i++)
{
parameters.profiles[i] = SubsurfaceScatteringProfile.Default;
}
parameters.bilateralScale = 0.1f;
return parameters;
}
}
}
}

12
Assets/ScriptableRenderLoop/HDRenderPipeline/SceneSettings/SubsurfaceScatteringParameters.cs.meta


fileFormatVersion: 2
guid: e9493dbe9d624704d9a80a75d52835b3
timeCreated: 1485361779
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存