浏览代码

Merge pull request #333 from EvgeniiG/master

Add a stencil copy, fix the deferred CS and enable it by default
/RenderPassXR_Sandbox
GitHub 7 年前
当前提交
508adf85
共有 9 个文件被更改,包括 183 次插入50 次删除
  1. 88
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  2. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipelineAsset.asset
  3. 30
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  4. 38
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/shadeopaque.compute
  5. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  6. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader
  7. 3
      Assets/ScriptableRenderPipeline/ShaderLibrary/AreaLighting.hlsl
  8. 58
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CopyStencilBuffer.shader
  9. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CopyStencilBuffer.shader.meta

88
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


readonly GBufferManager m_gbufferManager = new GBufferManager();
Material m_CopyStencilBuffer;
// Various set of material use in render loop
Material m_FilterAndCombineSubsurfaceScattering;
// Old SSS Model >>>

readonly RenderTargetIdentifier m_DistortionBufferRT;
private RenderTexture m_CameraDepthStencilBuffer = null;
private RenderTexture m_CameraDepthStencilBufferCopy = null;
private RenderTexture m_CameraDepthBufferCopy = null;
private RenderTexture m_CameraStencilBufferCopy = null; // Currently, it's manually copied using a pixel shader, and optimized to only contain the SSS bit
private RenderTargetIdentifier m_CameraDepthStencilBufferCopyRT;
private RenderTargetIdentifier m_CameraDepthBufferCopyRT;
private RenderTargetIdentifier m_CameraStencilBufferCopyRT;
// Post-processing context and screen-space effects (recycled on every frame to avoid GC alloc)
readonly PostProcessRenderContext m_PostProcessContext;

// Currently we use only 2 bits to identify the kind of lighting that is expected from the render pipeline
// Usage is define in LightDefinitions.cs
[Flags]
public enum StencilBits
public enum StencilBitMask
Lighting = 3, // 0
All = 255 // 0xFF
Clear = 0, // 0x0
Lighting = 3, // 0x3 - 2 bit
All = 255 // 0xFF - 8 bit
}
// Detect when windows size is changing

CreateSssMaterials(sssSettings.useDisneySSS);
// <<< Old SSS Model
m_CopyStencilBuffer = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CopyStencilBuffer");
m_CameraMotionVectorsMaterial = Utilities.CreateEngineMaterial("Hidden/HDRenderPipeline/CameraMotionVectors");
InitializeDebugMaterials();

};
#endif
void CreateDepthBuffer(Camera camera)
void CreateDepthStencilBuffer(Camera camera)
{
if (m_CameraDepthStencilBuffer != null)
{

if (NeedDepthBufferCopy())
{
if (m_CameraDepthStencilBufferCopy != null)
if (m_CameraDepthBufferCopy != null)
m_CameraDepthStencilBufferCopy.Release();
m_CameraDepthBufferCopy.Release();
m_CameraDepthStencilBufferCopy = new RenderTexture(camera.pixelWidth, camera.pixelHeight, 24, RenderTextureFormat.Depth);
m_CameraDepthStencilBufferCopy.filterMode = FilterMode.Point;
m_CameraDepthStencilBufferCopy.Create();
m_CameraDepthStencilBufferCopyRT = new RenderTargetIdentifier(m_CameraDepthStencilBufferCopy);
m_CameraDepthBufferCopy = new RenderTexture(camera.pixelWidth, camera.pixelHeight, 24, RenderTextureFormat.Depth);
m_CameraDepthBufferCopy.filterMode = FilterMode.Point;
m_CameraDepthBufferCopy.Create();
m_CameraDepthBufferCopyRT = new RenderTargetIdentifier(m_CameraDepthBufferCopy);
}
if (NeedStencilBufferCopy())
{
if (m_CameraStencilBufferCopy != null)
{
m_CameraStencilBufferCopy.Release();
}
m_CameraStencilBufferCopy = new RenderTexture(camera.pixelWidth, camera.pixelHeight, 0, RenderTextureFormat.R8);
m_CameraStencilBufferCopy.filterMode = FilterMode.Point;
m_CameraStencilBufferCopy.Create();
m_CameraStencilBufferCopyRT = new RenderTargetIdentifier(m_CameraStencilBufferCopy);
}
}

if (resolutionChanged || m_CameraDepthStencilBuffer == null)
{
CreateDepthBuffer(camera);
CreateDepthStencilBuffer(camera);
}
if (resolutionChanged || m_LightLoop.NeedResize())

return SystemInfo.graphicsDeviceType != GraphicsDeviceType.PlayStation4;
}
Texture GetDepthTexture()
bool NeedStencilBufferCopy()
{
// Currently, Unity does not offer a way to bind the stencil buffer as a texture in a compute shader.
// Therefore, it's manually copied using a pixel shader, and optimized to only contain the SSS bit.
return m_DebugDisplaySettings.renderingDebugSettings.enableSSSAndTransmission;
}
RenderTargetIdentifier GetDepthTexture()
if (NeedDepthBufferCopy())
return m_CameraDepthStencilBufferCopy;
else
return m_CameraDepthStencilBuffer;
return NeedDepthBufferCopy() ? m_CameraDepthBufferCopy : m_CameraDepthStencilBuffer;
}
RenderTargetIdentifier GetStencilTexture()
{
return NeedStencilBufferCopy() ? m_CameraStencilBufferCopyRT : m_CameraDepthStencilBufferRT;
}
private void CopyDepthBufferIfNeeded(CommandBuffer cmd)

{
using (new Utilities.ProfilingSample("Copy depth-stencil buffer", cmd))
{
cmd.CopyTexture(m_CameraDepthStencilBufferRT, m_CameraDepthStencilBufferCopyRT);
cmd.CopyTexture(m_CameraDepthStencilBufferRT, m_CameraDepthBufferCopyRT);
}
private void PrepareAndBindStencilTexture(CommandBuffer cmd)
{
if (NeedStencilBufferCopy())
{
using (new Utilities.ProfilingSample("Copy StencilBuffer", cmd))
{
Utilities.DrawFullScreen(cmd, m_CopyStencilBuffer, m_CameraStencilBufferCopyRT, m_CameraDepthStencilBufferRT);
}
}
cmd.SetGlobalTexture("_StencilTexture", GetStencilTexture());
}
public void UpdateCommonSettings()

{
CopyDepthBufferIfNeeded(cmd);
}
// Required for the SSS pass.
PrepareAndBindStencilTexture(cmd);
if (m_DebugDisplaySettings.IsDebugMaterialDisplayEnabled())
{

return;
}
RenderTargetIdentifier[] colorRTs = { m_CameraColorBufferRT, m_CameraSubsurfaceBufferRT };
RenderTargetIdentifier[] colorRTs = { m_CameraColorBufferRT, m_CameraSubsurfaceBufferRT };
RenderTargetIdentifier depthTexture = GetDepthTexture();
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_DebugDisplaySettings, colorRTs, m_CameraDepthStencilBufferRT, new RenderTargetIdentifier(GetDepthTexture()), true);
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_DebugDisplaySettings, colorRTs, m_CameraDepthStencilBufferRT, depthTexture, true);
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_DebugDisplaySettings, colorRTs, m_CameraDepthStencilBufferRT, new RenderTargetIdentifier(GetDepthTexture()), false);
m_LightLoop.RenderDeferredLighting(hdCamera, cmd, m_DebugDisplaySettings, colorRTs, m_CameraDepthStencilBufferRT, depthTexture, false);
}
// Combines specular lighting and diffuse lighting with subsurface scattering.

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipelineAsset.asset


tileSettings:
enableTileAndCluster: 1
enableSplitLightEvaluation: 1
enableComputeLightEvaluation: 0
enableComputeLightEvaluation: 1
enableComputeLightVariants: 0
enableComputeMaterialVariants: 0
enableClustered: 1

30
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


public void RenderDeferredLighting( HDCamera hdCamera, CommandBuffer cmd,
DebugDisplaySettings debugDisplaySettings,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer, RenderTargetIdentifier depthStencilTexture,
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer, RenderTargetIdentifier depthTexture,
if (m_TileSettings.enableComputeLightEvaluation && outputSplitLighting)
{
// The CS is always in the MRT mode. Do not execute the same shader twice.
return;
}
// TODO: To reduce GC pressure don't do concat string here
using (new Utilities.ProfilingSample((m_TileSettings.enableTileAndCluster ? "TilePass - Deferred Lighting Pass" : "SinglePass - Deferred Lighting Pass") + (outputSplitLighting ? " MRT" : ""), cmd))

// Pass global parameters to compute shader
// TODO: get rid of this by making global parameters visible to compute shaders
PushGlobalParams(camera, cmd, shadeOpaqueShader, kernel);
hdCamera.SetupComputeShader(shadeOpaqueShader, cmd);
// TODO: Update value like in ApplyDebugDisplaySettings() call. Sadly it is high likely that this will not be keep in sync. we really need to get rid of this by making global parameters visible to compute shaders
cmd.SetComputeIntParam(shadeOpaqueShader, "_DebugViewMaterial", Shader.GetGlobalInt("_DebugViewMaterial"));

cmd.SetComputeBufferParam(shadeOpaqueShader, kernel, "g_vLightListGlobal", bUseClusteredForDeferred ? s_PerVoxelLightLists : s_LightList);
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_MainDepthTexture", depthStencilTexture);
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_MainDepthTexture", depthTexture);
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_GBufferTexture0", Shader.PropertyToID("_GBufferTexture0"));
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_GBufferTexture1", Shader.PropertyToID("_GBufferTexture1"));
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_GBufferTexture2", Shader.PropertyToID("_GBufferTexture2"));

cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_LtcDisneyDiffuseMatrix", Shader.GetGlobalTexture("_LtcDisneyDiffuseMatrix"));
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_LtcMultiGGXFresnelDisneyDiffuse", Shader.GetGlobalTexture("_LtcMultiGGXFresnelDisneyDiffuse"));
hdCamera.SetupComputeShader(shadeOpaqueShader, cmd);
cmd.SetComputeMatrixParam(shadeOpaqueShader, "g_mInvScrProjection", Shader.GetGlobalMatrix("g_mInvScrProjection"));
cmd.SetComputeIntParam(shadeOpaqueShader, "_UseTileLightList", Shader.GetGlobalInt("_UseTileLightList"));

cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_IESArray", IESArrayTexture ? IESArrayTexture : m_DefaultTexture2DArray);
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "_SkyTexture", skyTexture ? skyTexture : m_DefaultTexture2DArray);
// Since we need the stencil test, the compute path does not currently support SSS.
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "combinedLightingUAV", colorBuffers[0]);
// Set SSS parameters.
cmd.SetComputeIntParam( shadeOpaqueShader, "_EnableSSSAndTransmission", Shader.GetGlobalInt( "_EnableSSSAndTransmission"));
cmd.SetComputeIntParam( shadeOpaqueShader, "_TexturingModeFlags", Shader.GetGlobalInt( "_TexturingModeFlags"));
cmd.SetComputeIntParam( shadeOpaqueShader, "_TransmissionFlags", Shader.GetGlobalInt( "_TransmissionFlags"));
cmd.SetComputeFloatParams(shadeOpaqueShader, "_ThicknessRemaps", Shader.GetGlobalFloatArray("_ThicknessRemaps"));
// We are currently supporting two different SSS mode: Jimenez (with 2-Gaussian profile) and Disney
// We have added the ability to switch between each other for subsurface scattering, but for transmittance this is more tricky as we need to add
// shader variant for forward, gbuffer and deferred shader. We want to avoid this.
// So for transmittance we use Disney profile formulation (that we know is more correct) in both case, and in the case of Jimenez we hack the parameters with 2-Gaussian parameters (Ideally we should fit but haven't find good fit) so it approximately match.
// Note: Jimenez SSS is in cm unit whereas Disney is in mm unit making an inconsistency here to compare model side by side
cmd.SetComputeVectorArrayParam(shadeOpaqueShader, "_ShapeParams", Shader.GetGlobalVectorArray("_ShapeParams"));
cmd.SetComputeVectorArrayParam(shadeOpaqueShader, "_TransmissionTints", Shader.GetGlobalVectorArray("_TransmissionTints"));
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "specularLightingUAV", colorBuffers[0]);
cmd.SetComputeTextureParam(shadeOpaqueShader, kernel, "diffuseLightingUAV", colorBuffers[1]);
// always do deferred lighting in blocks of 16x16 (not same as tiled light size)

38
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/shadeopaque.compute


#pragma kernel ShadeOpaque_Indirect_Clustered_Variant14 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant14 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=14
#pragma kernel ShadeOpaque_Indirect_Clustered_Variant15 SHADE_OPAQUE_ENTRY=ShadeOpaque_Indirect_Clustered_Variant15 USE_CLUSTERED_LIGHTLIST USE_INDIRECT VARIANT=15
//#pragma #pragma enable_d3d11_debug_symbols
// 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

DECLARE_GBUFFER_TEXTURE(_GBufferTexture);
#ifdef OUTPUT_SPLIT_LIGHTING
RWTexture2D<float4> specularLightingUAV;
RWTexture2D<float3> diffuseLightingUAV;
#else
RWTexture2D<float4> combinedLightingUAV;
#endif
RWTexture2D<float3> diffuseLightingUAV;
RWTexture2D<float4> specularLightingUAV;
CBUFFER_START(UnityShadeOpaque)
uint g_TileListOffset;

#endif
float depth = LOAD_TEXTURE2D(_MainDepthTexture, posInput.unPositionSS).x;
// TODO: add an early-out using HiZ/HiS or our light tile data.
if (depth == 0) { return; }
UpdatePositionInput(depth, _InvViewProjMatrix, _ViewProjMatrix, posInput);
float3 V = GetWorldSpaceNormalizeViewDir(posInput.positionWS);

float3 specularLighting;
LightLoop(V, posInput, preLightData, bsdfData, bakeDiffuseLighting, featureFlags, diffuseLighting, specularLighting);
#ifdef OUTPUT_SPLIT_LIGHTING
specularLightingUAV[pixelCoord] = float4(specularLighting, 1.0);
diffuseLightingUAV[pixelCoord] = diffuseLighting;
#else
combinedLightingUAV[pixelCoord] = float4(diffuseLighting + specularLighting, 1.0);
#endif
if (_EnableSSSAndTransmission != 0 && bsdfData.materialId == MATERIALID_LIT_SSS)
{
// We SSSSS is enabled with use split lighting.
// SSSSS algorithm need to know which pixels contribute to SSS and which doesn't. We could use the stencil for that but it mean that it will increase the cost of SSSSS
// A simpler solution is to add a slight contribution here that isn't visible (here we chose fp16 min (which is also fp11 and fp10 min).
// The SSSSS algorithm will check if diffuse lighting is black and discard the pixel if it is the case
diffuseLighting.r = max(diffuseLighting.r, HFLT_MIN);
specularLightingUAV[pixelCoord] = float4(specularLighting, 1.0);
diffuseLightingUAV[pixelCoord] = diffuseLighting;
}
else
{
specularLightingUAV[pixelCoord] = float4(diffuseLighting + specularLighting, 1.0);
}
}

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


#if defined(SHADERPASS) && (SHADERPASS == SHADERPASS_LIGHT_TRANSPORT) // In case of GI pass don't modify the diffuseColor
if (0)
#else
if (_EnableSSSAndTransmission > 0) // If we globally disable SSS effect, don't modify diffuseColor
if (_EnableSSSAndTransmission != 0) // If we globally disable SSS effect, don't modify diffuseColor
#endif
{
// We modify the albedo here as this code is used by all lighting (including light maps and GI).

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CombineSubsurfaceScattering.shader


{
Stencil
{
Ref 1 // StencilBits.SSS
Ref 1 // StencilLightingUsage.SplitLighting
Comp Equal
Pass Keep
}

3
Assets/ScriptableRenderPipeline/ShaderLibrary/AreaLighting.hlsl


float a = cosOmega * acos(x) - z; // y*ArcCos[-y*Sqrt[(1/x-1)/(1-y^2)]]-Sqrt[(1-y^2)*(x/(1-x))-y^2]*(1/x-1)
float b = atan(y); // ArcTan[Sqrt[(1-y^2)*(x/(1-x))-y^2]]
// Replacing max() with saturate() results in a 12 cycle SGPR forwarding stall on PS4.
return max(INV_PI * (a * sinSqSigma + b), 0); // (a/Pi)*x+(b/Pi)
return saturate(INV_PI * (a * sinSqSigma + b));
}
#endif
#endif

58
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CopyStencilBuffer.shader


Shader "Hidden/HDRenderPipeline/CopyStencilBuffer"
{
SubShader
{
Pass
{
Stencil
{
Ref 1 // StencilLightingUsage.SplitLighting
Comp Equal
Pass Keep
}
Cull Off
ZTest Always
ZWrite Off
Blend Off
HLSLPROGRAM
#pragma target 4.5
#pragma only_renderers d3d11 ps4 metal // TEMP: until we go further in dev
// #pragma enable_d3d11_debug_symbols
#pragma vertex Vert
#pragma fragment Frag
#include "../../../../ShaderLibrary/Common.hlsl"
#include "../../../ShaderConfig.cs.hlsl"
#include "../../../ShaderVariables.hlsl"
#include "../../../Lighting/LightDefinition.cs.hlsl"
struct Attributes
{
uint vertexID : SV_VertexID;
};
struct Varyings
{
float4 positionCS : SV_Position;
};
Varyings Vert(Attributes input)
{
Varyings output;
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
return output;
}
// Should use HiS and therefore be faster than a GPU memcpy().
float4 Frag(Varyings input) : SV_Target // use SV_StencilRef in D3D 11.3+
{
return float4(STENCILLIGHTINGUSAGE_SPLIT_LIGHTING, 0, 0, 0);
}
ENDHLSL
}
}
Fallback Off
}

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/CopyStencilBuffer.shader.meta


fileFormatVersion: 2
guid: 7fd941b2d9d2a39429de64bde023932c
timeCreated: 1499946987
licenseType: Pro
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存