浏览代码

Merge pull request #946 from Unity-Technologies/Improve-forward-opaque-pass

Remove the constrain to have a depth prepass for a forward material
/main
GitHub 6 年前
当前提交
bbd2c5ef
共有 11 个文件被更改,包括 102 次插入79 次删除
  1. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDEditorUtils.cs
  2. 17
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDRenderPipelineMenuItems.cs
  3. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/BaseLitUI.cs
  4. 38
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Unlit/BaseUnlitUI.cs
  5. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  6. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLit.shader
  7. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitTessellation.shader
  8. 13
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.shader
  9. 15
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitTessellation.shader
  10. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Material.hlsl
  11. 41
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Unlit/Unlit.shader

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDEditorUtils.cs


{ "HDRenderPipeline/LayeredLitTessellation", LayeredLitGUI.SetupMaterialKeywordsAndPass },
{ "HDRenderPipeline/Lit", LitGUI.SetupMaterialKeywordsAndPass },
{ "HDRenderPipeline/LitTessellation", LitGUI.SetupMaterialKeywordsAndPass },
{ "HDRenderPipeline/Unlit", UnlitGUI.SetupMaterialKeywordsAndPass }
{ "HDRenderPipeline/Unlit", UnlitGUI.SetupMaterialKeywordsAndPass },
{ "HDRenderPipeline/Decal", DecalUI.SetupMaterialKeywordsAndPass }
};
// Note: This function returns null if used with a package setup.

17
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/HDRenderPipelineMenuItems.cs


var sceneName = Path.GetFileNameWithoutExtension(scenePath);
var description = string.Format("{0} {1}/{2} - ", sceneName, i + 1, scenes.Length);
ResetAllLoadedMaterialKeywords(description, scale, scale * i);
if (ResetAllLoadedMaterialKeywords(description, scale, scale * i))
{
EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene());
}
}
ResetAllMaterialAssetsKeywords(scale, scale * (scenes.Length - 1));

}
}
static void ResetAllLoadedMaterialKeywords(string descriptionPrefix, float progressScale, float progressOffset)
static bool ResetAllLoadedMaterialKeywords(string descriptionPrefix, float progressScale, float progressOffset)
bool anyMaterialDirty = false; // Will be true if any material is dirty.
for (int i = 0, length = materials.Length; i < length; i++)
{

(i / (float)(length - 1)) * progressScale + progressOffset);
CheckOutFile(VSCEnabled, materials[i]);
HDEditorUtils.ResetMaterialKeywords(materials[i]);
if (HDEditorUtils.ResetMaterialKeywords(materials[i]))
{
anyMaterialDirty = true;
}
return anyMaterialDirty;
}
class UnityContextualLogHandler : ILogHandler

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Lit/BaseLitUI.cs


public static GUIContent lockWithObjectScaleText = new GUIContent("Lock with object scale", "Displacement mapping will take the absolute value of the scale of the object into account.");
public static GUIContent lockWithTilingRateText = new GUIContent("Lock with height map tiling rate", "Displacement mapping will take the absolute value of the tiling rate of the height map into account.");
public static GUIContent enableMotionVectorForVertexAnimationText = new GUIContent("Enable MotionVector For Vertex Animation", "This will enable an object motion vector pass for this material. Useful if wind animation is enabled or if displacement map is animated");
// Material ID
public static GUIContent materialIDText = new GUIContent("Material type", "Select a material feature to enable on top of regular material");
public static GUIContent transmissionEnableText = new GUIContent("Enable Transmission", "Enable Transmission for getting back lighting");

protected MaterialProperty displacementLockTilingScale = null;
protected const string kDisplacementLockTilingScale = "_DisplacementLockTilingScale";
protected MaterialProperty enableMotionVectorForVertexAnimation = null;
protected const string kEnableMotionVectorForVertexAnimation = "_EnableMotionVectorForVertexAnimation";
// Per pixel displacement params
protected MaterialProperty ppdMinSamples = null;
protected const string kPpdMinSamples = "_PPDMinSamples";

displacementLockObjectScale = FindProperty(kDisplacementLockObjectScale, props);
displacementLockTilingScale = FindProperty(kDisplacementLockTilingScale, props);
enableMotionVectorForVertexAnimation = FindProperty(kEnableMotionVectorForVertexAnimation, props);
// Per pixel displacement
ppdMinSamples = FindProperty(kPpdMinSamples, props);
ppdMaxSamples = FindProperty(kPpdMaxSamples, props);

m_MaterialEditor.ShaderProperty(supportDBuffer, StylesBaseLit.supportDBufferText);
m_MaterialEditor.ShaderProperty(enableMotionVectorForVertexAnimation, StylesBaseLit.enableMotionVectorForVertexAnimationText);
m_MaterialEditor.ShaderProperty(enableMotionVectorForVertexAnimation, StylesBaseUnlit.enableMotionVectorForVertexAnimationText);
EditorGUI.BeginChangeCheck();
m_MaterialEditor.ShaderProperty(displacementMode, StylesBaseLit.displacementModeText);

static public void SetupBaseLitMaterialPass(Material material)
{
SetupBaseUnlitMaterialPass(material);
material.SetShaderPassEnabled(HDShaderPassNames.s_MotionVectorsStr, material.GetFloat(kEnableMotionVectorForVertexAnimation) > 0.0f);
}
}
} // namespace UnityEditor

38
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Unlit/BaseUnlitUI.cs


public static GUIContent transparentPrepassText = new GUIContent("Pre Refraction Pass", "Render objects before the refraction pass");
public static GUIContent enableMotionVectorForVertexAnimationText = new GUIContent("Enable MotionVector For Vertex Animation", "This will enable an object motion vector pass for this material. Useful if wind animation is enabled or if displacement map is animated");
public static string advancedText = "Advanced Options";
}

protected MaterialProperty enableBlendModePreserveSpecularLighting = null;
protected const string kEnableBlendModePreserveSpecularLighting = "_EnableBlendModePreserveSpecularLighting";
protected MaterialProperty enableMotionVectorForVertexAnimation = null;
protected const string kEnableMotionVectorForVertexAnimation = "_EnableMotionVectorForVertexAnimation";
protected const string kZTestDepthEqualForOpaque = "_ZTestDepthEqualForOpaque";
protected const string kZTestModeDistortion = "_ZTestModeDistortion";
// See comment in LitProperties.hlsl
const string kEmissionColor = "_EmissionColor";

enableFogOnTransparent = FindProperty(kEnableFogOnTransparent, props, false);
enableBlendModePreserveSpecularLighting = FindProperty(kEnableBlendModePreserveSpecularLighting, props, false);
enableMotionVectorForVertexAnimation = FindProperty(kEnableMotionVectorForVertexAnimation, props, false);
}
void SurfaceTypePopup()

CoreUtils.SetKeyword(material, "_BLENDMODE_ADD", false);
CoreUtils.SetKeyword(material, "_BLENDMODE_PRE_MULTIPLY", false);
// If the material use the kZTestDepthEqualForOpaque it mean it require depth equal test for opaque but transparent are not affected
if (material.HasProperty(kZTestDepthEqualForOpaque))
{
if (surfaceType == SurfaceType.Opaque)
material.SetInt(kZTestDepthEqualForOpaque, (int)UnityEngine.Rendering.CompareFunction.Equal);
else
material.SetInt(kZTestDepthEqualForOpaque, (int)UnityEngine.Rendering.CompareFunction.LessEqual);
}
if (surfaceType == SurfaceType.Opaque)
{
material.SetOverrideTag("RenderType", alphaTestEnable ? "TransparentCutout" : "");

if (material.HasProperty(kDistortionEnable))
{
bool distortionDepthTest = material.GetFloat(kDistortionDepthTest) > 0.0f;
if (distortionDepthTest)
if (material.HasProperty(kZTestModeDistortion))
material.SetInt("_ZTestMode", (int)UnityEngine.Rendering.CompareFunction.LessEqual);
}
else
{
material.SetInt("_ZTestMode", (int)UnityEngine.Rendering.CompareFunction.Always);
if (distortionDepthTest)
{
material.SetInt(kZTestModeDistortion, (int)UnityEngine.Rendering.CompareFunction.LessEqual);
}
else
{
material.SetInt(kZTestModeDistortion, (int)UnityEngine.Rendering.CompareFunction.Always);
}
}
var distortionBlendMode = material.GetInt(kDistortionBlendMode);

}
}
if (material.HasProperty(kEnableMotionVectorForVertexAnimation))
{
material.SetShaderPassEnabled(HDShaderPassNames.s_MotionVectorsStr, material.GetFloat(kEnableMotionVectorForVertexAnimation) > 0.0f);
}
}
// Dedicated to emissive - for emissive Enlighten/PVR

3
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


m_ForwardAndForwardOnlyPassNames[1] = HDShaderPassNames.s_ForwardName;
var passNames = m_FrameSettings.enableForwardRenderingOnly ? 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);
RenderOpaqueRenderList(cullResults, camera, renderContext, cmd, passNames, m_currentRendererConfigurationBakedLighting);
}
else
{

14
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLit.shader


[HideInInspector] _DstBlend ("__dst", Float) = 0.0
[HideInInspector] _ZWrite ("__zw", Float) = 1.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0
[HideInInspector] _ZTestMode("_ZTestMode", Int) = 8
[HideInInspector] _ZTestDepthEqualForOpaque("_ZTestDepthEqualForOpaque", Int) = 4 // Less equal
[ToggleUI] _EnableFogOnTransparent("Enable Fog", Float) = 1.0
[ToggleUI] _EnableBlendModePreserveSpecularLighting("Enable Blend Mode Preserve Specular Lighting", Float) = 1.0

Pass Replace
}
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_CullMode]
Blend [_SrcBlend][_DstBlend]
// In case of forward we want to have depth equal for opaque mesh
ZTest [_ZTestDepthEqualForOpaque]
ZWrite [_ZWrite]
Cull [_CullMode]
HLSLPROGRAM

#pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
#define SHADERPASS SHADERPASS_FORWARD
// In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)
#ifndef _SURFACE_TYPE_TRANSPARENT
#define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST
#endif
#include "../../ShaderVariables.hlsl"
#ifdef DEBUG_DISPLAY
#include "../../Debug/DebugDisplay.hlsl"

14
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitTessellation.shader


[HideInInspector] _DstBlend ("__dst", Float) = 0.0
[HideInInspector] _ZWrite ("__zw", Float) = 1.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0
[HideInInspector] _ZTestMode("_ZTestMode", Int) = 8
[HideInInspector] _ZTestDepthEqualForOpaque("_ZTestDepthEqualForOpaque", Int) = 4 // Less equal
[ToggleUI] _EnableFogOnTransparent("Enable Fog", Float) = 1.0
[ToggleUI] _EnableBlendModePreserveSpecularLighting("Enable Blend Mode Preserve Specular Lighting", Float) = 1.0

Pass Replace
}
Blend[_SrcBlend][_DstBlend]
ZWrite[_ZWrite]
Cull[_CullMode]
Blend [_SrcBlend][_DstBlend]
// In case of forward we want to have depth equal for opaque mesh
ZTest [_ZTestDepthEqualForOpaque]
ZWrite [_ZWrite]
Cull [_CullMode]
HLSLPROGRAM

#pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
#define SHADERPASS SHADERPASS_FORWARD
// In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)
#ifndef _SURFACE_TYPE_TRANSPARENT
#define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST
#endif
#include "../../ShaderVariables.hlsl"
#ifdef DEBUG_DISPLAY
#include "../../Debug/DebugDisplay.hlsl"

13
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.shader


[HideInInspector] _ZWrite("__zw", Float) = 1.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0
[HideInInspector] _CullModeForward("__cullmodeForward", Float) = 2.0 // This mode is dedicated to Forward to correctly handle backface then front face rendering thin transparent
[HideInInspector] _ZTestMode("_ZTestMode", Int) = 8
[HideInInspector] _ZTestDepthEqualForOpaque("_ZTestDepthEqualForOpaque", Int) = 4 // Less equal
[HideInInspector] _ZTestModeDistortion("_ZTestModeDistortion", Int) = 8
[ToggleUI] _EnableFogOnTransparent("Enable Fog", Float) = 1.0
[ToggleUI] _EnableBlendModePreserveSpecularLighting("Enable Blend Mode Preserve Specular Lighting", Float) = 1.0

#pragma multi_compile _ SHADOWS_SHADOWMASK
#define SHADERPASS SHADERPASS_GBUFFER
#define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST
#define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST // This define allow to not perform the alpha test (alpha test is done during depth prepass)
#include "../../ShaderVariables.hlsl"
#ifdef DEBUG_DISPLAY
#include "../../Debug/DebugDisplay.hlsl"

Blend [_DistortionSrcBlend] [_DistortionDstBlend], [_DistortionBlurSrcBlend] [_DistortionBlurDstBlend]
BlendOp Add, [_DistortionBlurBlendOp]
ZTest [_ZTestMode]
ZTest [_ZTestModeDistortion]
ZWrite off
Cull [_CullMode]

}
Blend [_SrcBlend] [_DstBlend]
// In case of forward we want to have depth equal for opaque mesh
ZTest [_ZTestDepthEqualForOpaque]
ZWrite [_ZWrite]
Cull [_CullModeForward]

#pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
#define SHADERPASS SHADERPASS_FORWARD
// In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)
#ifndef _SURFACE_TYPE_TRANSPARENT
#define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST
#endif
#include "../../ShaderVariables.hlsl"
#ifdef DEBUG_DISPLAY
#include "../../Debug/DebugDisplay.hlsl"

15
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitTessellation.shader


[HideInInspector] _ZWrite("__zw", Float) = 1.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0
[HideInInspector] _CullModeForward("__cullmodeForward", Float) = 2.0 // This mode is dedicated to Forward to correctly handle backface then front face rendering thin transparent
[HideInInspector] _ZTestMode("_ZTestMode", Int) = 8
[HideInInspector] _ZTestDepthEqualForOpaque("_ZTestDepthEqualForOpaque", Int) = 4 // Less equal
[HideInInspector] _ZTestModeDistortion("_ZTestModeDistortion", Int) = 8
[ToggleUI] _EnableFogOnTransparent("Enable Fog", Float) = 1.0
[ToggleUI] _EnableBlendModePreserveSpecularLighting("Enable Blend Mode Preserve Specular Lighting", Float) = 1.0

#pragma multi_compile _ SHADOWS_SHADOWMASK
#define SHADERPASS SHADERPASS_GBUFFER
#define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST
#define SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST // This define allow to not perform the alpha test (alpha test is done during depth prepass)
#include "../../ShaderVariables.hlsl"
#ifdef DEBUG_DISPLAY
#include "../../Debug/DebugDisplay.hlsl"

Blend [_DistortionSrcBlend] [_DistortionDstBlend], [_DistortionBlurSrcBlend] [_DistortionBlurDstBlend]
BlendOp Add, [_DistortionBlurBlendOp]
ZTest [_ZTestMode]
ZTest [_ZTestModeDistortion]
ZWrite off
Cull [_CullMode]

}
Blend [_SrcBlend] [_DstBlend]
// In case of forward we want to have depth equal for opaque mesh
ZTest [_ZTestDepthEqualForOpaque]
Cull[_CullModeForward]
Cull [_CullModeForward]
HLSLPROGRAM

#pragma multi_compile USE_FPTL_LIGHTLIST USE_CLUSTERED_LIGHTLIST
#define SHADERPASS SHADERPASS_FORWARD
// In case of opaque we don't want to perform the alpha test, it is done in depth prepass and we use depth equal for ztest (setup from UI)
#ifndef _SURFACE_TYPE_TRANSPARENT
#define SHADERPASS_FORWARD_BYPASS_ALPHA_TEST
#endif
#include "../../ShaderVariables.hlsl"
#ifdef DEBUG_DISPLAY
#include "../../Debug/DebugDisplay.hlsl"

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Material.hlsl


// Alpha test replacement
//-----------------------------------------------------------------------------
// This function must be use instead of clip instruction. It allow to manage in which case the clip is perform
// This function must be use instead of clip instruction. It allow to manage in which case the clip is perform for optimization purpose
// If we have a prepass, we need to remove the clip from the GBuffer pass (otherwise HiZ does not work on PS4) - SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST
// For Forward (Lit or Unlit)
// Opaque geometry always has a depth pre-pass so we never want to do the clip here. For transparent we perform the clip as usual.
// If we have a prepass, we may want to remove the clip from the GBuffer pass (otherwise HiZ does not work on PS4) - SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST
// For Forward Opaque:
// If we have a prepass, we may want to remove the clip from the forward pass (otherwise HiZ does not work on PS4) - SHADERPASS_FORWARD_BYPASS_ALPHA_TEST
// For Forward Transparent
#if !(SHADERPASS == SHADERPASS_FORWARD && !defined(_SURFACE_TYPE_TRANSPARENT)) && !(SHADERPASS == SHADERPASS_FORWARD_UNLIT && !defined(_SURFACE_TYPE_TRANSPARENT)) && !defined(SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST) && !(SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)
// Note: If SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST or SHADERPASS_FORWARD_BYPASS_ALPHA_TEST are used, it mean that we must use ZTest depth equal for the pass (Need to use _ZTestDepthEqualForOpaque property).
#if !defined(SHADERPASS_FORWARD_BYPASS_ALPHA_TEST) && !defined(SHADERPASS_GBUFFER_BYPASS_ALPHA_TEST) && !(SHADERPASS == SHADERPASS_LIGHT_TRANSPORT)
clip(alpha - alphaCutoff);
#endif
}

41
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Unlit/Unlit.shader


[HideInInspector] _DstBlend("__dst", Float) = 0.0
[HideInInspector] _ZWrite("__zw", Float) = 1.0
[HideInInspector] _CullMode("__cullmode", Float) = 2.0
[HideInInspector] _ZTestMode("_ZTestMode", Int) = 8
[HideInInspector] _ZTestModeDistortion("_ZTestModeDistortion", Int) = 8
[ToggleUI] _EnableFogOnTransparent("Enable Fog", Float) = 0.0
[ToggleUI] _DoubleSidedEnable("Double sided enable", Float) = 0.0

SubShader
{
// Caution: The outline selection in the editor use the vertex shader/hull/domain shader of the first pass declare. So it should not bethe meta pass.
// Caution: The outline selection in the editor use the vertex shader/hull/domain shader of the first pass declare. So it should not be the meta pass.
// Unlit shader always render in forward
Name ""
Name "Depth prepass"
Tags{ "LightMode" = "DepthForwardOnly" }
Cull[_CullMode]

// Unlit shader always render in forward
Pass
{
Name "ForwardUnlit"
Name "Forward Unlit"
Tags { "LightMode" = "ForwardOnly" }
Blend [_SrcBlend] [_DstBlend]

Pass
{
Name "Motion Vectors"
Tags{ "LightMode" = "MotionVectors" } // Caution, this need to be call like this to setup the correct parameters by C++ (legacy Unity)
// If velocity pass (motion vectors) is enabled we tag the stencil so it don't perform CameraMotionVelocity
Stencil
{
WriteMask [_StencilWriteMaskMV]
Ref [_StencilRefMV]
Comp Always
Pass Replace
}
Cull[_CullMode]
ZWrite On
HLSLPROGRAM
#define SHADERPASS SHADERPASS_VELOCITY
#include "../../ShaderVariables.hlsl"
#include "../../Material/Material.hlsl"
#include "ShaderPass/UnlitSharePass.hlsl"
#include "UnlitData.hlsl"
#include "../../ShaderPass/ShaderPassVelocity.hlsl"
ENDHLSL
}
Pass
{
ZTest [_ZTestMode]
ZTest [_ZTestModeDistortion]
ZWrite off
Cull [_CullMode]

正在加载...
取消
保存