浏览代码

New more "regular" version of height based blend.

/RenderPassXR_Sandbox
Julien Ignace 7 年前
当前提交
057a142d
共有 7 个文件被更改,包括 129 次插入78 次删除
  1. 37
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/InfluenceLayeredLit/Editor/InfluenceLayeredLitUI.cs
  2. 21
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/InfluenceLayeredLit/InfluenceLayeredLit.shader
  3. 21
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/InfluenceLayeredLit/InfluenceLayeredLitTessellation.shader
  4. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader
  5. 118
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  6. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl
  7. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader

37
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/InfluenceLayeredLit/Editor/InfluenceLayeredLitUI.cs


public readonly GUIContent useDensityModeModeText = new GUIContent("Use Density Mode", "Enable density mode");
public readonly GUIContent useMainLayerInfluenceModeText = new GUIContent("Main Layer Influence", "Switch between regular layers mode and base/layers mode");
public readonly GUIContent blendUsingHeight = new GUIContent("Blend Using Height", "Blend Layers using height.");
public readonly GUIContent heightOffset = new GUIContent("Height Offset", "Offset applied to the height before layering.");
public readonly GUIContent heightTransition = new GUIContent("Height Transition", "Size in world units of the smooth transition between layers.");
public StylesLayer()
{
layerLabelColors[0].normal.textColor = Color.white;

MaterialProperty[] opacityAsDensity = new MaterialProperty[kMaxLayerCount];
const string kOpacityAsDensity = "_OpacityAsDensity";
// HeightmapMode control
MaterialProperty[] blendUsingHeight = new MaterialProperty[kMaxLayerCount - 1]; // Only in case of influence mode
const string kBlendUsingHeight = "_BlendUsingHeight";
// Influence
MaterialProperty[] inheritBaseNormal = new MaterialProperty[kMaxLayerCount - 1];
const string kInheritBaseNormal = "_InheritBaseNormal";

const string kInheritBaseColor = "_InheritBaseColor";
// Height blend
MaterialProperty[] heightOffset = new MaterialProperty[kMaxLayerCount];
const string kHeightOffset = "_HeightOffset";
MaterialProperty heightTransition = null;
const string kHeightTransition = "_HeightTransition";
// UI
MaterialProperty[] showLayer = new MaterialProperty[kMaxLayerCount];
const string kShowLayer = "_ShowLayer";

useMainLayerInfluence = FindProperty(kkUseMainLayerInfluence, props);
useHeightBasedBlend = FindProperty(kUseHeightBasedBlend, props);
heightTransition = FindProperty(kHeightTransition, props);
useDensityMode = FindProperty(kUseDensityMode, props);

opacityAsDensity[i] = FindProperty(string.Format("{0}{1}", kOpacityAsDensity, i), props);
heightOffset[i] = FindProperty(string.Format("{0}{1}", kHeightOffset, i), props);
blendUsingHeight[i - 1] = FindProperty(string.Format("{0}{1}", kBlendUsingHeight, i), props);
// Influence
inheritBaseNormal[i - 1] = FindProperty(string.Format("{0}{1}", kInheritBaseNormal, i), props);
inheritBaseHeight[i - 1] = FindProperty(string.Format("{0}{1}", kInheritBaseHeight, i), props);

Material material = m_MaterialEditor.target as Material;
bool mainLayerInfluenceEnable = useMainLayerInfluence.floatValue > 0.0f;
bool heightBasedBlend = useHeightBasedBlend.floatValue > 0.0f;
EditorGUILayout.LabelField(styles.layeringOptionText, EditorStyles.boldLabel);
{

m_MaterialEditor.ShaderProperty(opacityAsDensity[layerIndex], styles.opacityAsDensityText);
}
bool heightBasedBlendEnable = useHeightBasedBlend.floatValue > 0.0f;
if (heightBasedBlendEnable)
{
m_MaterialEditor.ShaderProperty(blendUsingHeight[paramIndex], styles.blendUsingHeight);
}
if (mainLayerInfluenceEnable)
{
m_MaterialEditor.ShaderProperty(inheritBaseColor[paramIndex], styles.inheritBaseColorText);

m_MaterialEditor.ShaderProperty(inheritBaseHeight[paramIndex], styles.inheritBaseHeightText);
}
}
if(heightBasedBlend)
{
m_MaterialEditor.ShaderProperty(heightOffset[layerIndex], styles.heightOffset);
}
EditorGUI.indentLevel--;

if (EditorGUI.EndChangeCheck())
{
useHeightBasedBlend.floatValue = enabled ? 1.0f : 0.0f;
}
if (enabled)
{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(heightTransition, styles.heightTransition);
EditorGUI.indentLevel--;
}
m_MaterialEditor.ShaderProperty(objectScaleAffectTile, mainLayerModeInfluenceEnable ? styles.objectScaleAffectTileText2 : styles.objectScaleAffectTileText);

21
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/InfluenceLayeredLit/InfluenceLayeredLit.shader


_HeightAmplitude2("Height Scale2", Float) = 1
_HeightAmplitude3("Height Scale3", Float) = 1
_HeightCenter0("Height Bias0", Float) = 0
_HeightCenter1("Height Bias1", Float) = 0
_HeightCenter2("Height Bias2", Float) = 0
_HeightCenter3("Height Bias3", Float) = 0
_HeightCenter0("Height Bias0", Range(0.0, 1.0)) = 0.5
_HeightCenter1("Height Bias1", Range(0.0, 1.0)) = 0.5
_HeightCenter2("Height Bias2", Range(0.0, 1.0)) = 0.5
_HeightCenter3("Height Bias3", Range(0.0, 1.0)) = 0.5
_DetailMap0("DetailMap0", 2D) = "black" {}
_DetailMap1("DetailMap1", 2D) = "black" {}

// Layer blending options
_LayerMaskMap("LayerMaskMap", 2D) = "white" {}
[ToggleOff] _UseHeightBasedBlend("UseHeightBasedBlend", Float) = 0.0
// Layer blending options V2
_HeightOffset0("Height Offset0", Float) = 0
_HeightOffset1("Height Offset1", Float) = 0
_HeightOffset2("Height Offset2", Float) = 0
_HeightOffset3("Height Offset3", Float) = 0
_HeightTransition("Height Transition", Range(0, 1.0)) = 0.0
_BlendUsingHeight1("_BlendUsingHeight1", Float) = 0.0
_BlendUsingHeight2("_BlendUsingHeight2", Float) = 0.0
_BlendUsingHeight3("_BlendUsingHeight3", Float) = 0.0
_InheritBaseNormal1("_InheritBaseNormal1", Range(0, 1.0)) = 0.0
_InheritBaseNormal2("_InheritBaseNormal2", Range(0, 1.0)) = 0.0

21
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/InfluenceLayeredLit/InfluenceLayeredLitTessellation.shader


_HeightAmplitude2("Height Scale2", Float) = 1
_HeightAmplitude3("Height Scale3", Float) = 1
_HeightCenter0("Height Bias0", Float) = 0
_HeightCenter1("Height Bias1", Float) = 0
_HeightCenter2("Height Bias2", Float) = 0
_HeightCenter3("Height Bias3", Float) = 0
_HeightCenter0("Height Bias0", Range(0.0, 1.0)) = 0.5
_HeightCenter1("Height Bias1", Range(0.0, 1.0)) = 0.5
_HeightCenter2("Height Bias2", Range(0.0, 1.0)) = 0.5
_HeightCenter3("Height Bias3", Range(0.0, 1.0)) = 0.5
_DetailMap0("DetailMap0", 2D) = "black" {}
_DetailMap1("DetailMap1", 2D) = "black" {}

// Layer blending options
_LayerMaskMap("LayerMaskMap", 2D) = "white" {}
[ToggleOff] _UseHeightBasedBlend("UseHeightBasedBlend", Float) = 0.0
// Layer blending options V2
_HeightOffset0("Height Offset0", Float) = 0
_HeightOffset1("Height Offset1", Float) = 0
_HeightOffset2("Height Offset2", Float) = 0
_HeightOffset3("Height Offset3", Float) = 0
_HeightTransition("Height Transition", Range(0, 1.0)) = 0.0
_BlendUsingHeight1("_BlendUsingHeight1", Float) = 0.0
_BlendUsingHeight2("_BlendUsingHeight2", Float) = 0.0
_BlendUsingHeight3("_BlendUsingHeight3", Float) = 0.0
_InheritBaseNormal1("_InheritBaseNormal1", Range(0, 1.0)) = 0.0
_InheritBaseNormal2("_InheritBaseNormal2", Range(0, 1.0)) = 0.0

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


_HeightMap("HeightMap", 2D) = "black" {}
_HeightAmplitude("Height Amplitude", Float) = 0.01 // In world units
_HeightCenter("Height Center", Float) = 0.5 // In texture space
_HeightCenter("Height Center", Range(0.0, 1.0)) = 0.5 // In texture space
_DetailMap("DetailMap", 2D) = "black" {}
_DetailMask("DetailMask", 2D) = "white" {}

118
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl


#include "ShaderLibrary/SampleUVMapping.hlsl"
#include "../MaterialUtilities.hlsl"
#ifdef LAYERED_LIT_USE_SIMPLE_BLEND
static const float defaultHeightValue = 1.0f;
#else
static const float defaultHeightValue = 0.0f;
#endif
void GetBuiltinData(FragInputs input, SurfaceData surfaceData, float alpha, float depthOffset, out BuiltinData builtinData)
{

void SetEnabledHeightByLayer(inout float height0, inout float height1, inout float height2, inout float height3)
{
#ifndef _HEIGHTMAP0
height0 = defaultHeightValue;
height0 = 0.0;
height1 = defaultHeightValue;
height1 = 0.0;
height2 = defaultHeightValue;
height2 = 0.0;
height3 = defaultHeightValue;
height3 = 0.0;
height3 = defaultHeightValue;
height3 = 0.0;
height2 = defaultHeightValue;
height2 = 0.0;
#endif
}

#if defined(_DENSITY_MODE)
#else
masks[0] = 1.0;
#endif
masks[1] = inputMasks.r;
#if _LAYER_COUNT > 2
masks[2] = inputMasks.g;

return 0.0;
}
float4 GetMaxHeight(float4 heights)
{
float maxHeight = max(heights.r, heights.g);
#ifdef _LAYEREDLIT_4_LAYERS
maxHeight = max(Max3(heights.r, heights.g, heights.b), heights.a);
#endif
#ifdef _LAYEREDLIT_3_LAYERS
maxHeight = Max3(heights.r, heights.g, heights.b);
#endif
return maxHeight;
}
// Returns layering blend mask after application of height based blend.
float4 ApplyHeightBlend(float4 heights, float4 blendMask)
{
// Add offsets for all the layers.
heights = heights + float4(_HeightOffset0, _HeightOffset1, _HeightOffset2, _HeightOffset3);
// We need to mask out inactive layers so that their height does not impact the result.
float4 maskedHeights = heights * blendMask.argb;
float maxHeight = GetMaxHeight(maskedHeights);
// Make sure that transition is not zero otherwise the next computation will be wrong.
// The epsilon here also has to be bigger than the epsilon in the next computation.
float transition = max(_HeightTransition, 1e-5);
// The goal here is to have all but the heighest layer at negative heights, then we add the transition so that if the next heighest layer is near transition it will have a positive value.
// Then we clamp this to zero and normalize everything so that heighest layer has a value of 1.
maskedHeights = maskedHeights - maxHeight.xxxx;
// We need to add an epsilon here for active layers (hence the blendMask again) so that at least a layer shows up if everything's too low.
maskedHeights = (max(0, maskedHeights + transition) + 1e-6) * blendMask.argb;
// Normalize
maxHeight = GetMaxHeight(maskedHeights);
maskedHeights = maskedHeights / maxHeight.xxxx;
return maskedHeights.yzwx;
}
float4 blendMasks = GetBlendMask(layerTexCoord, vertexColor, true, lod);
float4 inputBlendMasks = GetBlendMask(layerTexCoord, vertexColor, true, lod);
ComputeMaskWeights(blendMasks, weights);
#if defined(_HEIGHTMAP0) || defined(_HEIGHTMAP1) || defined(_HEIGHTMAP2) || defined(_HEIGHTMAP3)
float height0 = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap0, SAMPLER_HEIGHTMAP_IDX, layerTexCoord.base0, lod).r - _HeightCenter0) * _HeightAmplitude0;

ApplyTessellationTileScale(height0, height1, height2, height3); // Only apply with per vertex displacement
SetEnabledHeightByLayer(height0, height1, height2, height3);
float4 resultBlendMasks = inputBlendMasks;
#if defined(_HEIGHT_BASED_BLEND)
resultBlendMasks = ApplyHeightBlend(float4(height0, height1, height2, height3), inputBlendMasks);
#endif
ComputeMaskWeights(resultBlendMasks, weights);
return heightResult + height0 * inheritBaseHeight;
return heightResult + height0 * inheritBaseHeight * inputBlendMasks.a; // We multiply by the input mask for the first layer because if the mask here is black it means that the layer is not actually underneath any visible layer so we don't want to inherit its height.
#else
float heightResult = 0.0;

float3 ApplyHeightBasedBlend(float3 inputMask, float3 inputHeight, float3 blendUsingHeight)
{
return saturate(lerp(inputMask * inputHeight * blendUsingHeight * 100, 1, inputMask * inputMask)); // 100 arbitrary scale to limit blendUsingHeight values.
}
void ComputeLayerWeights(FragInputs input, LayerTexCoord layerTexCoord, float4 inputAlphaMask, out float outWeights[_MAX_LAYER])
void ComputeLayerWeights(FragInputs input, LayerTexCoord layerTexCoord, float4 inputAlphaMask, float4 blendMasks, out float outWeights[_MAX_LAYER])
float4 blendMasks = GetBlendMask(layerTexCoord, input.color);
#if defined(_DENSITY_MODE)
// Note: blendMasks.argb because a is main layer
float4 opacityAsDensity = saturate((inputAlphaMask - (float4(1.0, 1.0, 1.0, 1.0) - blendMasks.argb)) * 20.0);
float4 useOpacityAsDensityParam = float4(_OpacityAsDensity0, _OpacityAsDensity1, _OpacityAsDensity2, _OpacityAsDensity3);
blendMasks.argb = lerp(blendMasks.argb, opacityAsDensity, useOpacityAsDensityParam);
#endif
for (int i = 0; i < _MAX_LAYER; ++i)
{
outWeights[i] = 0.0f;
}
#if defined(_HEIGHT_BASED_BLEND)

// We don't use height 0 for the height blend based mode
heights.y += (heights.x * 0.0001);
#endif
#else
float4 heights = float4(0.0, 0.0, 0.0, 0.0);
blendMasks = ApplyHeightBlend(heights, blendMasks);
#endif
// If no heightmap is set on any layer, we don't need to try and blend them based on height...
// don't apply on main layer
blendMasks.rgb = ApplyHeightBasedBlend(blendMasks.rgb, heights.yzw, float3(_BlendUsingHeight1, _BlendUsingHeight2, _BlendUsingHeight3));
#if defined(_DENSITY_MODE)
// Note: blendMasks.argb because a is main layer
float4 opacityAsDensity = saturate((inputAlphaMask - (float4(1.0, 1.0, 1.0, 1.0) - blendMasks.argb)) * 20.0);
float4 useOpacityAsDensityParam = float4(_OpacityAsDensity0, _OpacityAsDensity1, _OpacityAsDensity2, _OpacityAsDensity3);
blendMasks.argb = lerp(blendMasks.argb, opacityAsDensity, useOpacityAsDensityParam);
float3 ComputeMainNormalInfluence(FragInputs input, float3 normalTS0, float3 normalTS1, float3 normalTS2, float3 normalTS3, LayerTexCoord layerTexCoord, float weights[_MAX_LAYER])
float3 ComputeMainNormalInfluence(FragInputs input, float3 normalTS0, float3 normalTS1, float3 normalTS2, float3 normalTS3, LayerTexCoord layerTexCoord, float inputMainLayerMask, float weights[_MAX_LAYER])
{
// Get our regular normal from regular layering
float3 normalTS = BlendLayeredVector3(normalTS0, normalTS1, normalTS2, normalTS3, weights);

// Add on our regular normal a bit of Main Layer normal base on influence factor. Note that this affect only the "visible" normal.
#ifdef SURFACE_GRADIENT
return normalTS + influenceFactor * mainNormalTS;
return normalTS + influenceFactor * mainNormalTS * inputMainLayerMask;
return lerp(normalTS, BlendNormalRNM(normalTS, mainNormalTS), influenceFactor);
return lerp(normalTS, BlendNormalRNM(normalTS, mainNormalTS), influenceFactor * inputMainLayerMask);
#endif
}

float alpha3 = GetSurfaceData3(input, layerTexCoord, surfaceData3, normalTS3);
// Note: If per pixel displacement is enabled it mean we will fetch again the various heightmaps at the intersection location. Not sure the compiler can optimize.
float4 blendMasks = GetBlendMask(layerTexCoord, input.color);
ComputeLayerWeights(input, layerTexCoord, float4(alpha0, alpha1, alpha2, alpha3), weights);
ComputeLayerWeights(input, layerTexCoord, float4(alpha0, alpha1, alpha2, alpha3), blendMasks, weights);
// For layered shader, alpha of base color is used as either an opacity mask, a composition mask for inheritance parameters or a density mask.
float alpha = PROP_BLEND_SCALAR(alpha, weights);

#if defined(_MAIN_LAYER_INFLUENCE_MODE)
surfaceData.baseColor = ComputeMainBaseColorInfluence(surfaceData0.baseColor, surfaceData1.baseColor, surfaceData2.baseColor, surfaceData3.baseColor, layerTexCoord, weights);
float3 normalTS = ComputeMainNormalInfluence(input, normalTS0, normalTS1, normalTS2, normalTS3, layerTexCoord, weights);
float3 normalTS = ComputeMainNormalInfluence(input, normalTS0, normalTS1, normalTS2, normalTS3, layerTexCoord, blendMasks.a, weights);
#else
surfaceData.baseColor = SURFACEDATA_BLEND_VECTOR3(surfaceData, baseColor, weights);
float3 normalTS = BlendLayeredVector3(normalTS0, normalTS1, normalTS2, normalTS3, weights);

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl


PROP_DECL(float, _HeightAmplitude);
PROP_DECL(float, _HeightCenter);
float _BlendUsingHeight1;
float _BlendUsingHeight2;
float _BlendUsingHeight3;
PROP_DECL(float, _OpacityAsDensity);
float _InheritBaseNormal1;
float _InheritBaseNormal2;

float _InheritBaseColor2;
float _InheritBaseColor3;
float _LayerTilingBlendMask;
PROP_DECL(float, _HeightOffset);
float _HeightTransition;
float _TexWorldScaleBlendMask;
PROP_DECL(float, _TexWorldScale);

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader


_HeightMap("HeightMap", 2D) = "black" {}
_HeightAmplitude("Height Amplitude", Float) = 0.01 // In world units
_HeightCenter("Height Center", Float) = 0.5 // In texture space
_HeightCenter("Height Center", Range(0.0, 1.0)) = 0.5 // In texture space
_DetailMap("DetailMap", 2D) = "black" {}
_DetailMask("DetailMask", 2D) = "white" {}

正在加载...
取消
保存