浏览代码

HDRenderPipeline: Add support for depth postpass and backface/frontface rendering

/main
Sebastien Lagarde 7 年前
当前提交
61e38068
共有 3 个文件被更改,包括 120 次插入41 次删除
  1. 59
      ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  2. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDStringConstants.cs
  3. 96
      ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/BaseUnlitUI.cs

59
ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


// The pass "SRPDefaultUnlit" is a fall back to legacy unlit rendering and is required to support unity 2d + unity UI that render in the scene.
ShaderPassName[] m_ForwardAndForwardOnlyPassNames = { new ShaderPassName(), new ShaderPassName(), HDShaderPassNames.s_SRPDefaultUnlitName};
ShaderPassName[] m_AllTransparentPassNames = { HDShaderPassNames.s_TransparentDepthPrepassName,
HDShaderPassNames.s_TransparentBackfaceName,
HDShaderPassNames.s_ForwardOnlyName,
HDShaderPassNames.s_ForwardName,
HDShaderPassNames.s_TransparentDepthPostpassName,
HDShaderPassNames.s_SRPDefaultUnlitName };
ShaderPassName[] m_AllTransparentDebugDisplayPassNames = { HDShaderPassNames.s_TransparentDepthPrepassName,
HDShaderPassNames.s_TransparentBackfaceDebugDisplayName,
HDShaderPassNames.s_ForwardOnlyDebugDisplayName,
HDShaderPassNames.s_ForwardDebugDisplayName,
HDShaderPassNames.s_TransparentDepthPostpassName,
HDShaderPassNames.s_SRPDefaultUnlitName };
ShaderPassName[] m_ForwardOnlyPassNames = { new ShaderPassName(), HDShaderPassNames.s_SRPDefaultUnlitName};
ShaderPassName[] m_DepthOnlyAndDepthForwardOnlyPassNames = { HDShaderPassNames.s_DepthForwardOnlyName, HDShaderPassNames.s_DepthOnlyName };
ShaderPassName[] m_DepthForwardOnlyPassNames = { HDShaderPassNames.s_DepthForwardOnlyName };

RenderSky(hdCamera, cmd);
// Do a depth pre-pass for transparent objects that want it that will fill the depth buffer to reduce the overdraw (typical usage is hair rendering)
RenderTransparentDepthPrepass(m_CullResults, camera, renderContext, cmd);
// Render pre refraction objects
RenderForward(m_CullResults, camera, renderContext, cmd, ForwardPass.PreRefraction);
RenderForwardError(m_CullResults, camera, renderContext, cmd, ForwardPass.PreRefraction);

}
}
RenderDebug(hdCamera, cmd);
RenderDebug(hdCamera, cmd);
#if UNITY_EDITOR
// bind depth surface for editor grid/gizmo/selection rendering

m_LightLoop.RenderForward(camera, cmd, pass == ForwardPass.Opaque);
if (m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled())
if (pass == ForwardPass.Opaque)
m_ForwardAndForwardOnlyPassNames[0] = m_ForwardOnlyPassNames[0] = HDShaderPassNames.s_ForwardOnlyDebugDisplayName;
m_ForwardAndForwardOnlyPassNames[1] = HDShaderPassNames.s_ForwardDebugDisplayName;
}
else
{
m_ForwardAndForwardOnlyPassNames[0] = m_ForwardOnlyPassNames[0] = HDShaderPassNames.s_ForwardOnlyName;
m_ForwardAndForwardOnlyPassNames[1] = HDShaderPassNames.s_ForwardName;
}
if (m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled())
{
m_ForwardAndForwardOnlyPassNames[0] = m_ForwardOnlyPassNames[0] = HDShaderPassNames.s_ForwardOnlyDebugDisplayName;
m_ForwardAndForwardOnlyPassNames[1] = HDShaderPassNames.s_ForwardDebugDisplayName;
}
else
{
m_ForwardAndForwardOnlyPassNames[0] = m_ForwardOnlyPassNames[0] = HDShaderPassNames.s_ForwardOnlyName;
m_ForwardAndForwardOnlyPassNames[1] = HDShaderPassNames.s_ForwardName;
}
if (pass == ForwardPass.Opaque)
{
var passNames = m_Asset.renderingSettings.ShouldUseForwardRenderingOnly() ? m_ForwardAndForwardOnlyPassNames : m_ForwardOnlyPassNames;
// Forward opaque material always have a prepass (whether or not we use deferred, whether or not there is option like alpha test only) so we pass the right depth state here.
RenderOpaqueRenderList(cullResults, camera, renderContext, cmd, passNames, m_currentRendererConfigurationBakedLighting, null, m_DepthStateOpaqueWithPrepass);

RenderTransparentRenderList(cullResults, camera, renderContext, cmd, m_ForwardAndForwardOnlyPassNames, m_currentRendererConfigurationBakedLighting, preRefractionQueue: pass == ForwardPass.PreRefraction);
var passNames = m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled() ? m_AllTransparentDebugDisplayPassNames : m_AllTransparentPassNames;
RenderTransparentRenderList(cullResults, camera, renderContext, cmd, passNames, m_currentRendererConfigurationBakedLighting, preRefractionQueue: pass == ForwardPass.PreRefraction);
}
}
void RenderTransparentDepthPrepass(CullResults cullResults, Camera camera, ScriptableRenderContext renderContext, CommandBuffer cmd)
{
using (new ProfilingSample(cmd,"Forward Transparent Depth Prepass", GetSampler(CustomSamplerId.ForwardTransparentDepthPrepass)))
{
CoreUtils.SetRenderTarget(cmd, m_CameraDepthStencilBufferRT);
RenderTransparentRenderList(cullResults, camera, renderContext, cmd, HDShaderPassNames.s_TransparentDepthPrepassName, preRefractionQueue: true);
RenderTransparentRenderList(cullResults, camera, renderContext, cmd, HDShaderPassNames.s_TransparentDepthPrepassName);
}
}

{
if (CoreUtils.IsPostProcessingActive(layer))
{
cmd.SetGlobalTexture(HDShaderIDs._CameraDepthTexture, GetDepthTexture());
// Note: Here we don't use GetDepthTexture() to get the depth texture but m_CameraDepthStencilBuffer as the Forward transparent pass can
// write extra data to deal with DOF/MB
cmd.SetGlobalTexture(HDShaderIDs._CameraDepthTexture, m_CameraDepthStencilBuffer);
cmd.SetGlobalTexture(HDShaderIDs._CameraMotionVectorsTexture, m_VelocityBufferRT);
var context = m_PostProcessContext;

6
ScriptableRenderPipeline/HDRenderPipeline/HDStringConstants.cs


public static readonly string s_MotionVectorsStr = "MotionVectors";
public static readonly string s_DistortionVectorsStr = "DistortionVectors";
public static readonly string s_TransparentDepthPrepassStr = "TransparentDepthPrepass";
public static readonly string s_TransparentBackfaceStr = "TransparentBackface";
public static readonly string s_TransparentBackfaceDebugDisplayStr = "TransparentBackfaceDebugDisplay";
public static readonly string s_TransparentDepthPostpassStr = "TransparentDepthPostpass";
public static readonly string s_MetaStr = "Meta";
public static readonly string s_ShadowCasterStr = "ShadowCaster";

public static readonly ShaderPassName s_MotionVectorsName = new ShaderPassName(s_MotionVectorsStr);
public static readonly ShaderPassName s_DistortionVectorsName = new ShaderPassName(s_DistortionVectorsStr);
public static readonly ShaderPassName s_TransparentDepthPrepassName = new ShaderPassName(s_TransparentDepthPrepassStr);
public static readonly ShaderPassName s_TransparentBackfaceName = new ShaderPassName(s_TransparentBackfaceStr);
public static readonly ShaderPassName s_TransparentBackfaceDebugDisplayName = new ShaderPassName(s_TransparentBackfaceDebugDisplayStr);
public static readonly ShaderPassName s_TransparentDepthPostpassName = new ShaderPassName(s_TransparentDepthPostpassStr);
// Legacy name
public static readonly ShaderPassName s_AlwaysName = new ShaderPassName("Always");

96
ScriptableRenderPipeline/HDRenderPipeline/Material/Unlit/Editor/BaseUnlitUI.cs


public static GUIContent alphaCutoffText = new GUIContent("Alpha Cutoff", "Threshold for alpha cutoff");
public static GUIContent alphaCutoffShadowText = new GUIContent("Alpha Cutoff Shadow", "Threshold for alpha cutoff in case of shadow pass");
public static GUIContent alphaCutoffPrepassText = new GUIContent("Alpha Cutoff Prepass", "Threshold for alpha cutoff in case of depth prepass");
public static GUIContent transparentDepthPrepassEnableText = new GUIContent("Enable transparent depth prepass", "It allow to ");
public static GUIContent alphaCutoffPostpassText = new GUIContent("Alpha Cutoff Postpass", "Threshold for alpha cutoff in case of depth postpass");
public static GUIContent transparentDepthPrepassEnableText = new GUIContent("Enable transparent depth prepass", "It allow to to fill depth buffer to improve sorting");
public static GUIContent transparentDepthPostpassEnableText = new GUIContent("Enable transparent depth postpass", "It allow to fill depth buffer for postprocess effect like DOF");
public static GUIContent transparentBackfaceEnableText = new GUIContent("Enable back then front rendering", "It allow to better sort transparent mesh by first rendering back faces then front faces in two separate drawcall");
public static GUIContent enableTransparentFogText = new GUIContent("Enable fog", "Enable fog on transparent material");
public static GUIContent enableBlendModePreserveSpecularLightingText = new GUIContent("Blend preserve specular lighting", "Blend mode will only affect diffuse lighting, allowing correct specular lighting (reflection) on transparent object");

protected const string kAlphaCutoffShadow = "_AlphaCutoffShadow";
protected MaterialProperty alphaCutoffPrepass = null;
protected const string kAlphaCutoffPrepass = "_AlphaCutoffPrepass";
protected MaterialProperty alphaCutoffPostpass = null;
protected const string kAlphaCutoffPostpass = "_AlphaCutoffPostpass";
protected MaterialProperty transparentDepthPostpassEnable = null;
protected const string kTransparentDepthPostpassEnable = "_TransparentDepthPostpassEnable";
protected MaterialProperty transparentBackfaceEnable = null;
protected const string kTransparentBackfaceEnable = "_TransparentBackfaceEnable";
protected MaterialProperty doubleSidedEnable = null;
protected const string kDoubleSidedEnable = "_DoubleSidedEnable";
protected MaterialProperty blendMode = null;

alphaCutoffShadow = FindProperty(kAlphaCutoffShadow, props, false);
alphaCutoffPrepass = FindProperty(kAlphaCutoffPrepass, props, false);
alphaCutoffPostpass = FindProperty(kAlphaCutoffPostpass, props, false);
transparentDepthPostpassEnable = FindProperty(kTransparentDepthPostpassEnable, props, false);
transparentBackfaceEnable = FindProperty(kTransparentBackfaceEnable, props, false);
doubleSidedEnable = FindProperty(kDoubleSidedEnable, props, false);
blendMode = FindProperty(kBlendMode, props, false);

EditorGUI.indentLevel--;
}
}
if (transparentDepthPostpassEnable != null)
{
m_MaterialEditor.ShaderProperty(transparentDepthPostpassEnable, StylesBaseUnlit.transparentDepthPostpassEnableText);
if (transparentDepthPostpassEnable.floatValue == 1.0f)
{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(alphaCutoffPostpass, StylesBaseUnlit.alphaCutoffPostpassText);
EditorGUI.indentLevel--;
}
}
if (transparentBackfaceEnable != null && ((SurfaceType)surfaceType.floatValue == SurfaceType.Transparent))
m_MaterialEditor.ShaderProperty(transparentBackfaceEnable, StylesBaseUnlit.transparentBackfaceEnableText);
m_MaterialEditor.ShaderProperty(doubleSidedEnable, StylesBaseUnlit.doubleSidedEnableText);
{
// Grey the option is backface rendering is enabled
bool disabledScope = transparentBackfaceEnable != null && transparentBackfaceEnable.floatValue > 0.0f && ((SurfaceType)surfaceType.floatValue == SurfaceType.Transparent);
using (new EditorGUI.DisabledScope(disabledScope))
{
m_MaterialEditor.ShaderProperty(doubleSidedEnable, StylesBaseUnlit.doubleSidedEnableText);
}
}
EditorGUI.indentLevel--;
}

}
}
bool doubleSidedEnable = material.HasProperty(kDoubleSidedEnable) && material.GetFloat(kDoubleSidedEnable) > 0.0f;
if (doubleSidedEnable)
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Off);
}
else
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Back);
}
SetKeyword(material, "_DOUBLESIDED_ON", doubleSidedEnable);
bool fogEnabled = material.HasProperty(kEnableFogOnTransparent) && material.GetFloat(kEnableFogOnTransparent) > 0.0f && surfaceType == SurfaceType.Transparent;
SetKeyword(material, "_ENABLE_FOG_ON_TRANSPARENT", fogEnabled);

break;
}
}
// Can't enable double sided and backface rendering at the same time, give priority to backface rendering
bool isBackFaceEnable = material.HasProperty(kTransparentBackfaceEnable) && material.GetFloat(kTransparentBackfaceEnable) > 0.0f && surfaceType == SurfaceType.Transparent;
bool doubleSidedEnable = material.HasProperty(kDoubleSidedEnable) && material.GetFloat(kDoubleSidedEnable) > 0.0f && !isBackFaceEnable;
if (doubleSidedEnable)
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Off);
}
// For both regular and backface, forward pass use backface culling
else
{
material.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Back);
}
SetKeyword(material, "_DOUBLESIDED_ON", doubleSidedEnable);
// A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect
// or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color.

material.SetShaderPassEnabled(HDShaderPassNames.s_TransparentDepthPrepassStr, false);
}
}
if (material.HasProperty(kTransparentDepthPostpassEnable))
{
bool depthWriteEnable = (material.GetFloat(kTransparentDepthPostpassEnable) > 0.0f) && ((SurfaceType)material.GetFloat(kSurfaceType) == SurfaceType.Transparent);
if (depthWriteEnable)
{
material.SetShaderPassEnabled(HDShaderPassNames.s_TransparentDepthPostpassStr, true);
}
else
{
material.SetShaderPassEnabled(HDShaderPassNames.s_TransparentDepthPostpassStr, false);
}
}
if (material.HasProperty(kTransparentBackfaceEnable))
{
bool backFaceEnable = (material.GetFloat(kTransparentBackfaceEnable) > 0.0f) && ((SurfaceType)material.GetFloat(kSurfaceType) == SurfaceType.Transparent);
if (backFaceEnable)
{
material.SetShaderPassEnabled(HDShaderPassNames.s_TransparentBackfaceStr, true);
material.SetShaderPassEnabled(HDShaderPassNames.s_TransparentBackfaceDebugDisplayStr, true);
}
else
{
material.SetShaderPassEnabled(HDShaderPassNames.s_TransparentBackfaceStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_TransparentBackfaceDebugDisplayStr, false);
}
}
}
// Dedicated to emissive - for emissive Enlighten/PVR

正在加载...
取消
保存