浏览代码

Added per channel blend selection mode for decals to render pipe asset

/main
Paul Melamed 6 年前
当前提交
c6fc1808
共有 9 个文件被更改,包括 152 次插入64 次删除
  1. 97
      com.unity.render-pipelines.high-definition/HDRP/Editor/Material/Decal/DecalUI.cs
  2. 1
      com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/GlobalDecalSettingsUI.cs
  3. 2
      com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/SerializedGlobalDecalSettings.cs
  4. 39
      com.unity.render-pipelines.high-definition/HDRP/Material/Decal/Decal.hlsl
  5. 26
      com.unity.render-pipelines.high-definition/HDRP/Material/Decal/Decal.shader
  6. 22
      com.unity.render-pipelines.high-definition/HDRP/Material/Decal/DecalSystem.cs
  7. 1
      com.unity.render-pipelines.high-definition/HDRP/Material/Decal/GlobalDecalSettings.cs
  8. 26
      com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDRenderPipeline.cs
  9. 2
      com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDStringConstants.cs

97
com.unity.render-pipelines.high-definition/HDRP/Editor/Material/Decal/DecalUI.cs


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

CoreUtils.SetKeyword(material, "_MASKMAP", material.GetTexture(kMaskMap));
CoreUtils.SetKeyword(material, "_NORMAL_BLEND_MASK_B", material.GetFloat(kNormalBlendSrc) == 1.0f);
CoreUtils.SetKeyword(material, "_MAOS_BLEND_MASK_B", material.GetFloat(kMaskBlendSrc) == 1.0f);
if (material.GetFloat(kMaskBlendMode) == 0.0f)
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsStrNoMask, true); // no mask always on
BlendMode blendMode = (BlendMode)material.GetFloat(kMaskBlendMode);
switch(blendMode)
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsStr, true);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOStr, false);
}
else if (material.GetFloat(kMaskBlendMode) == 1.0f)
{
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMSStr, true);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOStr, false);
}
else if (material.GetFloat(kMaskBlendMode) == 2.0f)
{
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMStr, true);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOStr, false);
}
else if (material.GetFloat(kMaskBlendMode) == 3.0f)
{
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsSStr, true);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOStr, false);
}
else if (material.GetFloat(kMaskBlendMode) == 4.0f)
{
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOStr, true);
case BlendMode.Metal_AO_Smoothness:
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsStr, true);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOStr, false);
break;
case BlendMode.Metal_Smoothness:
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMSStr, true);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOStr, false);
break;
case BlendMode.Metal:
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMStr, true);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOStr, false);
break;
case BlendMode.Smoothness:
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsSStr, true);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOStr, false);
break;
case BlendMode.AO:
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsMStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsSStr, false);
material.SetShaderPassEnabled(HDShaderPassNames.s_MeshDecalsAOStr, true);
break;
protected void SetupMaterialKeywordsAndPassInternal(Material material)
protected void SetupMaterialKeywordsAndPassInternal(Material material, bool perChannelMask)
{
SetupMaterialKeywordsAndPass(material);
}

float maskBlendSrcValue = maskBlendSrc.floatValue;
float maskBlendModeValue = maskBlendMode.floatValue;
HDRenderPipelineAsset hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
bool perChannelMask = hdrp.renderPipelineSettings.decalSettings.perChannelMask;
// Detect any changes to the material
EditorGUI.BeginChangeCheck();

m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, normalMap);
normalBlendSrcValue = EditorGUILayout.Popup( "Normal blend source", (int)normalBlendSrcValue, blendSourceNames);
m_MaterialEditor.TexturePropertySingleLine(Styles.maskMapText, maskMap);
maskBlendSrcValue = EditorGUILayout.Popup( "Mask blend source", (int)maskBlendSrcValue, blendSourceNames);
maskBlendModeValue = EditorGUILayout.Popup( "Mask blend mode", (int)maskBlendModeValue, blendModeNames);
maskBlendSrcValue = EditorGUILayout.Popup( "Mask blend source", (int)maskBlendSrcValue, blendSourceNames);
EditorGUILayout.LabelField("Individual mask map channel blending mode can be enabled/disabled in pipeline asset.");
EditorGUILayout.LabelField("Warning!!! Enabling this feature incurs a performance cost.");
if(perChannelMask)
{
maskBlendModeValue = EditorGUILayout.Popup( "Mask blend mode", (int)maskBlendModeValue, blendModeNames);
}
m_MaterialEditor.ShaderProperty(decalBlend, Styles.decalBlendText);
EditorGUI.indentLevel--;
}

maskBlendMode.floatValue = maskBlendModeValue;
foreach (var obj in m_MaterialEditor.targets)
SetupMaterialKeywordsAndPassInternal((Material)obj);
SetupMaterialKeywordsAndPassInternal((Material)obj, perChannelMask);
}
}

1
com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/GlobalDecalSettingsUI.cs


EditorGUILayout.PropertyField(d.drawDistance, _.GetContent("Draw Distance"));
EditorGUILayout.PropertyField(d.atlasWidth, _.GetContent("Atlas Width"));
EditorGUILayout.PropertyField(d.atlasHeight, _.GetContent("Atlas Height"));
EditorGUILayout.PropertyField(d.perChannelMask, _.GetContent("Per Channel Mask"));
--EditorGUI.indentLevel;
}
}

2
com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/SerializedGlobalDecalSettings.cs


public SerializedProperty drawDistance;
public SerializedProperty atlasWidth;
public SerializedProperty atlasHeight;
public SerializedProperty perChannelMask;
public SerializedGlobalDecalSettings(SerializedProperty root)
{

atlasWidth = root.Find((GlobalDecalSettings s) => s.atlasWidth);
atlasHeight = root.Find((GlobalDecalSettings s) => s.atlasHeight);
perChannelMask = root.Find((GlobalDecalSettings s) => s.perChannelMask);
}
}
}

39
com.unity.render-pipelines.high-definition/HDRP/Material/Decal/Decal.hlsl


DBufferType2 MERGE_NAME(NAME, 2) = LOAD_TEXTURE2D(MERGE_NAME(TEX, 2), unCoord2); \
DBufferType3 MERGE_NAME(NAME, 3) = LOAD_TEXTURE2D(MERGE_NAME(TEX, 3), unCoord2);
#define ENCODE_INTO_DBUFFER(DECAL_SURFACE_DATA, NAME) EncodeIntoDBuffer(DECAL_SURFACE_DATA, MERGE_NAME(NAME,0), MERGE_NAME(NAME,1), MERGE_NAME(NAME,2), MERGE_NAME(NAME,3))
#define DECODE_FROM_DBUFFER(NAME, DECAL_SURFACE_DATA) DecodeFromDBuffer(MERGE_NAME(NAME,0), MERGE_NAME(NAME,1), MERGE_NAME(NAME,2), MERGE_NAME(NAME,3), DECAL_SURFACE_DATA)
#ifdef _PER_CHANNEL_MASK
#define ENCODE_INTO_DBUFFER(DECAL_SURFACE_DATA, NAME) EncodeIntoDBuffer(DECAL_SURFACE_DATA, MERGE_NAME(NAME,0), MERGE_NAME(NAME,1), MERGE_NAME(NAME,2), MERGE_NAME(NAME,3))
#define DECODE_FROM_DBUFFER(NAME, DECAL_SURFACE_DATA) DecodeFromDBuffer(MERGE_NAME(NAME,0), MERGE_NAME(NAME,1), MERGE_NAME(NAME,2), MERGE_NAME(NAME,3), DECAL_SURFACE_DATA)
#else
#define ENCODE_INTO_DBUFFER(DECAL_SURFACE_DATA, NAME) EncodeIntoDBuffer(DECAL_SURFACE_DATA, MERGE_NAME(NAME,0), MERGE_NAME(NAME,1), MERGE_NAME(NAME,2))
#define DECODE_FROM_DBUFFER(NAME, DECAL_SURFACE_DATA) DecodeFromDBuffer(MERGE_NAME(NAME,0), MERGE_NAME(NAME,1), MERGE_NAME(NAME,2), DECAL_SURFACE_DATA)
#endif
#endif
#endif // #ifdef DBUFFERMATERIAL_COUNT

SAMPLER(_trilinear_clamp_sampler_DecalAtlas2D);
// Must be in sync with RT declared in HDRenderPipeline.cs ::Rebuild
void EncodeIntoDBuffer( DecalSurfaceData surfaceData,
out DBufferType0 outDBuffer0,
out DBufferType1 outDBuffer1,
out DBufferType2 outDBuffer2,
out DBufferType3 outDBuffer3
void EncodeIntoDBuffer( DecalSurfaceData surfaceData
, out DBufferType0 outDBuffer0
, out DBufferType1 outDBuffer1
, out DBufferType2 outDBuffer2
#ifdef _PER_CHANNEL_MASK
, out DBufferType3 outDBuffer3
#endif
#ifdef _PER_CHANNEL_MASK
#endif
DBufferType0 inDBuffer0,
DBufferType1 inDBuffer1,
DBufferType2 inDBuffer2,
DBufferType3 inDBuffer3,
out DecalSurfaceData surfaceData
DBufferType0 inDBuffer0
, DBufferType1 inDBuffer1
, DBufferType2 inDBuffer2
#ifdef _PER_CHANNEL_MASK
, DBufferType3 inDBuffer3
#endif
, out DecalSurfaceData surfaceData
)
{
ZERO_INITIALIZE(DecalSurfaceData, surfaceData);

surfaceData.mask = inDBuffer2;
#ifdef _PER_CHANNEL_MASK
#else
surfaceData.MAOSBlend = float2(surfaceData.mask.w, surfaceData.mask.w);
#endif
}

26
com.unity.render-pipelines.high-definition/HDRP/Material/Decal/Decal.shader


#pragma shader_feature _MAOS_BLEND_MASK_B
#pragma multi_compile_instancing
#pragma multi_compile _ _PER_CHANNEL_MASK
//-------------------------------------------------------------------------------------
// Define
//-------------------------------------------------------------------------------------

HLSLPROGRAM
#define SHADERPASS SHADERPASS_DBUFFER_PROJECTOR
#include "../../ShaderVariables.hlsl"
#include "Decal.hlsl"
#include "ShaderPass/DecalSharePass.hlsl"
#include "DecalData.hlsl"
#include "../../ShaderPass/ShaderPassDBuffer.hlsl"
ENDHLSL
}
Pass
{
Name "DBufferMesh" // Name is not used
Tags{"LightMode" = "DBufferMesh"} // No mask
Cull Back
ZWrite Off
ZTest LEqual
// using alpha compositing https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch23.html
Blend 0 SrcAlpha OneMinusSrcAlpha, Zero OneMinusSrcAlpha
Blend 1 SrcAlpha OneMinusSrcAlpha, Zero OneMinusSrcAlpha
Blend 2 SrcAlpha OneMinusSrcAlpha, Zero OneMinusSrcAlpha
HLSLPROGRAM
#define SHADERPASS SHADERPASS_DBUFFER_MESH
#include "../../ShaderVariables.hlsl"
#include "Decal.hlsl"
#include "ShaderPass/DecalSharePass.hlsl"

22
com.unity.render-pipelines.high-definition/HDRP/Material/Decal/DecalSystem.cs


}
}
public bool perChannelMask
{
get
{
HDRenderPipelineAsset hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
if (hdrp != null)
{
return hdrp.renderPipelineSettings.decalSettings.perChannelMask;
}
return false;
}
}
public Camera CurrentCamera
{
get

Vector3 cameraPos = instance.CurrentCamera.transform.position;
Matrix4x4 worldToView = LightLoop.WorldToCamera(instance.CurrentCamera);
bool perChannelMask = instance.perChannelMask;
for (int resultIndex = 0; resultIndex < m_NumResults; resultIndex++)
{
int decalIndex = m_ResultIndices[resultIndex];

m_DecalDatas[m_DecalDatasCount].normalToWorld = normalToWorldBatch[instanceCount];
m_DecalDatas[m_DecalDatasCount].baseColor = m_BaseColor;
m_DecalDatas[m_DecalDatasCount].blendParams = m_BlendParams;
if(!perChannelMask)
{
m_DecalDatas[m_DecalDatasCount].blendParams.z = 0.0f;
}
// we have not allocated the textures in atlas yet, so only store references to them
m_DiffuseTextureScaleBias[m_DecalDatasCount] = m_Diffuse;
m_NormalTextureScaleBias[m_DecalDatasCount] = m_Normal;

return;
int batchIndex = 0;
int totalToDraw = m_NumResults;
int shaderPass = (int)m_Material.GetFloat("_MaskBlendMode");
int shaderPass = instance.perChannelMask ? (int)m_Material.GetFloat("_MaskBlendMode") : 0;
for (; batchIndex < m_NumResults / kDrawIndexedBatchSize; batchIndex++)
{
m_PropertyBlock.SetMatrixArray(HDShaderIDs._NormalToWorldID, m_NormalToWorld[batchIndex]);

1
com.unity.render-pipelines.high-definition/HDRP/Material/Decal/GlobalDecalSettings.cs


public int drawDistance = 1000;
public int atlasWidth = 4096;
public int atlasHeight = 4096;
public bool perChannelMask = false;
}
}

26
com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDRenderPipeline.cs


rendererConfiguration = 0,
sorting = { flags = SortFlags.CommonOpaque }
};
drawSettings.SetShaderPassName(0, HDShaderPassNames.s_MeshDecalsName);
drawSettings.SetShaderPassName(1, HDShaderPassNames.s_MeshDecalsMSName);
drawSettings.SetShaderPassName(2, HDShaderPassNames.s_MeshDecalsMName);
drawSettings.SetShaderPassName(3, HDShaderPassNames.s_MeshDecalsSName);
drawSettings.SetShaderPassName(4, HDShaderPassNames.s_MeshDecalsAOName);
if(m_Asset.GetRenderPipelineSettings().decalSettings.perChannelMask)
{
drawSettings.SetShaderPassName(0, HDShaderPassNames.s_MeshDecalsName);
drawSettings.SetShaderPassName(1, HDShaderPassNames.s_MeshDecalsMSName);
drawSettings.SetShaderPassName(2, HDShaderPassNames.s_MeshDecalsMName);
drawSettings.SetShaderPassName(3, HDShaderPassNames.s_MeshDecalsSName);
drawSettings.SetShaderPassName(4, HDShaderPassNames.s_MeshDecalsAOName);
}
else
{
drawSettings.SetShaderPassName(0, HDShaderPassNames.s_MeshDecalsNoMaskName);
}
renderContext.DrawRenderers(cullResults.visibleRenderers, ref drawSettings, filterRenderersSettings);
CoreUtils.SetKeyword(cmd, "_PER_CHANNEL_MASK", m_Asset.GetRenderPipelineSettings().decalSettings.perChannelMask);
renderContext.DrawRenderers(cullResults.visibleRenderers, ref drawSettings, filterRenderersSettings);
DecalSystem.instance.RenderIntoDBuffer(cmd);
m_DbufferManager.UnSetHTile(cmd);
m_DbufferManager.SetHTileTexture(cmd); // mask per 8x8 tile used for optimization when looking up dbuffer values

2
com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDStringConstants.cs


public static readonly string s_TransparentDepthPostpassStr = "TransparentDepthPostpass";
public static readonly string s_MetaStr = "Meta";
public static readonly string s_ShadowCasterStr = "ShadowCaster";
public static readonly string s_MeshDecalsStrNoMask = "DBufferMesh";
public static readonly string s_MeshDecalsStr = "DBufferMesh_MAOS";
public static readonly string s_MeshDecalsMSStr = "DBufferMesh_MS";
public static readonly string s_MeshDecalsMStr = "DBufferMesh_M";

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_TransparentDepthPostpassName = new ShaderPassName(s_TransparentDepthPostpassStr);
public static readonly ShaderPassName s_MeshDecalsNoMaskName = new ShaderPassName(s_MeshDecalsStrNoMask);
public static readonly ShaderPassName s_MeshDecalsName = new ShaderPassName(s_MeshDecalsStr);
public static readonly ShaderPassName s_MeshDecalsMSName = new ShaderPassName(s_MeshDecalsMSStr);
public static readonly ShaderPassName s_MeshDecalsMName = new ShaderPassName(s_MeshDecalsMStr);

正在加载...
取消
保存