浏览代码

Added terrain height based blending.

/main
Yao Xiaoling 6 年前
当前提交
5b75827c
共有 6 个文件被更改,包括 319 次插入320 次删除
  1. 41
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/TerrainLit/TerrainLitUI.cs
  2. 62
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/TerrainLit/TerrainLit.shader
  3. 230
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/TerrainLit/TerrainLitData.hlsl
  4. 153
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/TerrainLit/TerrainLit_Basemap_Gen.shader
  5. 144
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/TerrainLit/TerrainLitSplatCommon.hlsl
  6. 9
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/TerrainLit/TerrainLitSplatCommon.hlsl.meta

41
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/TerrainLit/TerrainLitUI.cs


{
public readonly GUIContent layersText = new GUIContent("Inputs");
public readonly GUIContent layerMapMaskText = new GUIContent("Layer Mask", "Layer mask");
public readonly GUIContent useHeightBasedBlendText = new GUIContent("Use Height Based Blend", "Layer will be blended with the underlying layer based on the height.");
public readonly GUIContent heightTransition = new GUIContent("Height Transition", "Size in world units of the smooth transition between layers.");
}

m_PropertySuffixes[3] = "3";
}
// Layer options
MaterialProperty useHeightBasedBlend = null;
const string kUseHeightBasedBlend = "_UseHeightBasedBlend";
// Density/opacity mode
MaterialProperty[] opacityAsDensity = new MaterialProperty[kMaxLayerCount];
const string kOpacityAsDensity = "_OpacityAsDensity";

const string kHeightTransition = "_HeightTransition";
bool m_UseHeightBasedBlend;
useHeightBasedBlend = FindProperty(kUseHeightBasedBlend, props);
heightTransition = FindProperty(kHeightTransition, props);
heightTransition = FindProperty(kHeightTransition, props, false);
for (int i = 0; i < kMaxLayerCount; ++i)
{
// Density/opacity mode

EditorGUI.indentLevel++;
GUILayout.Label(styles.layersText, EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
EditorGUI.showMixedValue = useHeightBasedBlend.hasMixedValue;
m_UseHeightBasedBlend = EditorGUILayout.Toggle(styles.useHeightBasedBlendText, useHeightBasedBlend.floatValue > 0.0f);
if (EditorGUI.EndChangeCheck())
{
useHeightBasedBlend.floatValue = m_UseHeightBasedBlend ? 1.0f : 0.0f;
}
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(heightTransition, styles.heightTransition);
EditorGUI.indentLevel--;
if (m_UseHeightBasedBlend)
{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(heightTransition, styles.heightTransition);
EditorGUI.indentLevel--;
}
EditorGUI.indentLevel--;
}

// TODO: planar/triplannar supprt
//SetupLayersMappingKeywords(material);
for (int i = 0; i < kMaxLayerCount; ++i)
{
CoreUtils.SetKeyword(material, "_NORMALMAP" + i, material.GetTexture(kNormalMap + i) || material.GetTexture(kDetailMap + i));
CoreUtils.SetKeyword(material, "_MASKMAP" + i, material.GetTexture(kMaskMap + i));
CoreUtils.SetKeyword(material, "_HEIGHTMAP" + i, material.GetTexture(kHeightMap + i));
CoreUtils.SetKeyword(material, "_THICKNESSMAP" + i, material.GetTexture(kThicknessMap + i));
}
bool useHeightBasedBlend = material.GetFloat(kUseHeightBasedBlend) != 0.0f;
CoreUtils.SetKeyword(material, "_HEIGHT_BASED_BLEND", useHeightBasedBlend);
}
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)

62
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/TerrainLit/TerrainLit.shader


{
Properties
{
[HideInInspector] _Control0("Control 0 (RGBA)", 2D) = "red" {}
[HideInInspector] _Control1("Control 1 (RGBA)", 2D) = "black" {}
[HideInInspector] _Control0("Control 0 (RGBA)", 2D) = "" {}
[HideInInspector] _Control1("Control 1 (RGBA)", 2D) = "" {}
[HideInInspector] _Splat0("Layer 0", 2D) = "white" {}
[HideInInspector] _Splat1("Layer 1", 2D) = "white" {}

[HideInInspector] _Normal7("Normal 7", 2D) = "bump" {}
// Since we don't use a mask texture for getting the mask, we'll need the metallic property to be serialized as in sRGB space.
[HideInInspector] [Gamma] _Metallic0("Metallic 0", Range(0.0, 1.0)) = 0
[HideInInspector] [Gamma] _Metallic1("Metallic 1", Range(0.0, 1.0)) = 0
[HideInInspector] [Gamma] _Metallic2("Metallic 2", Range(0.0, 1.0)) = 0
[HideInInspector] [Gamma] _Metallic3("Metallic 3", Range(0.0, 1.0)) = 0
[HideInInspector] [Gamma] _Metallic4("Metallic 4", Range(0.0, 1.0)) = 0
[HideInInspector] [Gamma] _Metallic5("Metallic 5", Range(0.0, 1.0)) = 0
[HideInInspector] [Gamma] _Metallic6("Metallic 6", Range(0.0, 1.0)) = 0
[HideInInspector] [Gamma] _Metallic7("Metallic 7", Range(0.0, 1.0)) = 0
[HideInInspector] _Smoothness0("Smoothness0", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness1("Smoothness1", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness2("Smoothness2", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness3("Smoothness3", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness4("Smoothness4", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness5("Smoothness5", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness6("Smoothness6", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness7("Smoothness7", Range(0.0, 1.0)) = 1.0
[HideInInspector] [Gamma] _Metallic0("Metallic 0", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic1("Metallic 1", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic2("Metallic 2", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic3("Metallic 3", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic4("Metallic 4", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic5("Metallic 5", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic6("Metallic 6", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic7("Metallic 7", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness0("Smoothness 0", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness1("Smoothness 1", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness2("Smoothness 2", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness3("Smoothness 3", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness4("Smoothness 4", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness5("Smoothness 5", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness6("Smoothness 6", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness7("Smoothness 7", Range(0.0, 1.0)) = 0.0
// TODO: route values from terrain layers. enable _DENSITY_MODE if any of these enabled.
[HideInInspector] [ToggleUI] _OpacityAsDensity0("_OpacityAsDensity0", Float) = 0.0

[HideInInspector] [ToggleUI] _OpacityAsDensity6("_OpacityAsDensity6", Float) = 0.0
[HideInInspector] [ToggleUI] _OpacityAsDensity7("_OpacityAsDensity7", Float) = 0.0
// TODO: Allow heightmap?
[HideInInspector] [ToggleUI] _UseHeightBasedBlend("UseHeightBasedBlend", Float) = 0.0
[HideInInspector] _HeightTransition("Height Transition", Range(0, 1.0)) = 0.0
[HideInInspector] _HeightMap0("HeightMap0", 2D) = "black" {}
[HideInInspector] _HeightMap1("HeightMap1", 2D) = "black" {}
[HideInInspector] _HeightMap2("HeightMap2", 2D) = "black" {}
[HideInInspector] _HeightMap3("HeightMap3", 2D) = "black" {}
[HideInInspector] _HeightMap4("HeightMap4", 2D) = "black" {}
[HideInInspector] _HeightMap5("HeightMap5", 2D) = "black" {}
[HideInInspector] _HeightMap6("HeightMap6", 2D) = "black" {}
[HideInInspector] _HeightMap7("HeightMap7", 2D) = "black" {}
// Caution: Default value of _HeightAmplitude must be (_HeightMax - _HeightMin) * 0.01
// Those two properties are computed from the ones exposed in the UI and depends on the displaement mode so they are separate because we don't want to lose information upon displacement mode change.
_HeightTransition("Height Transition", Range(0, 1.0)) = 0.0
[HideInInspector] _Height0("Height 0", 2D) = "black" {}
[HideInInspector] _Height1("Height 1", 2D) = "black" {}
[HideInInspector] _Height2("Height 2", 2D) = "black" {}
[HideInInspector] _Height3("Height 3", 2D) = "black" {}
[HideInInspector] _Height4("Height 4", 2D) = "black" {}
[HideInInspector] _Height5("Height 5", 2D) = "black" {}
[HideInInspector] _Height6("Height 6", 2D) = "black" {}
[HideInInspector] _Height7("Height 7", 2D) = "black" {}
[HideInInspector] _HeightAmplitude0("Height Scale0", Float) = 0.02
[HideInInspector] _HeightAmplitude1("Height Scale1", Float) = 0.02
[HideInInspector] _HeightAmplitude2("Height Scale2", Float) = 0.02

[HideInInspector] _HeightCenter7("Height Bias7", Range(0.0, 1.0)) = 0.5
// TODO: support tri-planar?
// TODO: support more maps?
/*
[HideInInspector] _TexWorldScale0("Tiling", Float) = 1.0
[HideInInspector] _TexWorldScale1("Tiling", Float) = 1.0
[HideInInspector] _TexWorldScale2("Tiling", Float) = 1.0

_MaskMap1("MaskMap1", 2D) = "white" {}
_MaskMap2("MaskMap2", 2D) = "white" {}
_MaskMap3("MaskMap3", 2D) = "white" {}
*/
// All the following properties exist only in layered lit material
// Following are builtin properties

230
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/TerrainLit/TerrainLitData.hlsl


#include "../Lit/LitBuiltinData.hlsl"
#include "../Decal/DecalUtilities.hlsl"
#if defined(_TERRAIN_8_SPLATS)
#define _LAYER_COUNT 8
#elif defined(_TERRAIN_7_SPLATS)
#define _LAYER_COUNT 7
#elif defined(_TERRAIN_6_SPLATS)
#define _LAYER_COUNT 6
#elif defined(_TERRAIN_5_SPLATS)
#define _LAYER_COUNT 5
#elif defined(_TERRAIN_4_SPLATS)
#define _LAYER_COUNT 4
#elif defined(_TERRAIN_3_SPLATS)
#define _LAYER_COUNT 3
#elif defined(_TERRAIN_2_SPLATS)
#define _LAYER_COUNT 2
#else
#define _LAYER_COUNT 1
#endif
TEXTURE2D(_Splat0);
TEXTURE2D(_Normal0);
float4 _Splat0_ST;
float _Metallic0;
float _Smoothness0;
TEXTURE2D(_Splat1);
TEXTURE2D(_Normal1);
float4 _Splat1_ST;
float _Metallic1;
float _Smoothness1;
TEXTURE2D(_Splat2);
TEXTURE2D(_Normal2);
float4 _Splat2_ST;
float _Metallic2;
float _Smoothness2;
TEXTURE2D(_Splat3);
TEXTURE2D(_Normal3);
float4 _Splat3_ST;
float _Metallic3;
float _Smoothness3;
TEXTURE2D(_Splat4);
TEXTURE2D(_Normal4);
float4 _Splat4_ST;
float _Metallic4;
float _Smoothness4;
TEXTURE2D(_Splat5);
TEXTURE2D(_Normal5);
float4 _Splat5_ST;
float _Metallic5;
float _Smoothness5;
TEXTURE2D(_Splat6);
TEXTURE2D(_Normal6);
float4 _Splat6_ST;
float _Metallic6;
float _Smoothness6;
TEXTURE2D(_Splat7);
TEXTURE2D(_Normal7);
float4 _Splat7_ST;
float _Metallic7;
float _Smoothness7;
TEXTURE2D(_Control0);
TEXTURE2D(_Control1);
SAMPLER(sampler_Splat0);
SAMPLER(sampler_Control0);
float GetMaxHeight(float4 heights0
#if _LAYER_COUNT > 4
, float4 heights1
#endif
)
{
float maxHeight = heights0.r;
#if _LAYER_COUNT > 1
maxHeight = max(maxHeight, heights0.g);
#endif
#if _LAYER_COUNT > 2
maxHeight = max(maxHeight, heights0.b);
#endif
#if _LAYER_COUNT > 3
maxHeight = max(maxHeight, heights0.a);
#endif
#if _LAYER_COUNT > 4
maxHeight = max(maxHeight, heights1.r);
#endif
#if _LAYER_COUNT > 5
maxHeight = max(maxHeight, heights1.g);
#endif
#if _LAYER_COUNT > 6
maxHeight = max(maxHeight, heights1.b);
#endif
#if _LAYER_COUNT > 7
maxHeight = max(maxHeight, heights1.a);
#endif
return maxHeight;
}
float _HeightTransition;
// Returns layering blend mask after application of height based blend.
void ApplyHeightBlend(float4 heights0, float4 heights1, inout float4 blendMasks0, inout float4 blendMasks1)
{
// We need to mask out inactive layers so that their height does not impact the result.
float4 maskedHeights0 = heights0 * blendMasks0;
#if _LAYER_COUNT > 4
float4 maskedHeights1 = heights1 * blendMasks1;
#endif
float maxHeight = GetMaxHeight(maskedHeights0
#if _LAYER_COUNT > 4
, maskedHeights1
#endif
);
// 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 highest layer at negative heights, then we add the transition so that if the next highest layer is near transition it will have a positive value.
// Then we clamp this to zero and normalize everything so that highest layer has a value of 1.
maskedHeights0 = maskedHeights0 - 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.
maskedHeights0 = (max(0, maskedHeights0 + transition) + 1e-6) * blendMasks0;
#if _LAYER_COUNT > 4
maskedHeights1 = maskedHeights1 - maxHeight.xxxx;
maskedHeights1 = (max(0, maskedHeights1 + transition) + 1e-6) * blendMasks1;
#endif
// Normalize
maxHeight = GetMaxHeight(maskedHeights0
#if _LAYER_COUNT > 4
, maskedHeights1
#endif
);
blendMasks0 = maskedHeights0 / maxHeight.xxxx;
#if _LAYER_COUNT > 4
blendMasks1 = maskedHeights1 / maxHeight.xxxx;
#endif
}
#include "TerrainLitSplatCommon.hlsl"
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{

#ifdef _TERRAIN_HEIGHT_MAP
float4 heights0 = float4(0, 0, 0, 0);
float4 heights1 = float4(0, 0, 0, 0);
heights0.r = (SAMPLE_TEXTURE2D(_HeightMap0, sampler_Splat0, uvSplats[0]).r - _HeightCenter0) * _HeightAmplitude0;
heights0.r = (SAMPLE_TEXTURE2D(_Height0, sampler_Splat0, uvSplats[0]).r * blendMasks0.r - _HeightCenter0) * _HeightAmplitude0;
heights0.g = (SAMPLE_TEXTURE2D(_HeightMap1, sampler_Splat0, uvSplats[1]).r - _HeightCenter1) * _HeightAmplitude1;
heights0.g = (SAMPLE_TEXTURE2D(_Height1, sampler_Splat0, uvSplats[1]).r * blendMasks0.g - _HeightCenter1) * _HeightAmplitude1;
heights0.b = (SAMPLE_TEXTURE2D(_HeightMap2, sampler_Splat0, uvSplats[2]).r - _HeightCenter2) * _HeightAmplitude2;
heights0.b = (SAMPLE_TEXTURE2D(_Height2, sampler_Splat0, uvSplats[2]).r * blendMasks0.b - _HeightCenter2) * _HeightAmplitude2;
heights0.a = (SAMPLE_TEXTURE2D(_HeightMap3, sampler_Splat0, uvSplats[3]).r - _HeightCenter3) * _HeightAmplitude3;
heights0.a = (SAMPLE_TEXTURE2D(_Height3, sampler_Splat0, uvSplats[3]).r * blendMasks0.a - _HeightCenter3) * _HeightAmplitude3;
heights1.r = (SAMPLE_TEXTURE2D(_HeightMap3, sampler_Splat0, uvSplats[4]).r - _HeightCenter4) * _HeightAmplitude4;
heights1.r = (SAMPLE_TEXTURE2D(_Height4, sampler_Splat0, uvSplats[4]).r * blendMasks1.r - _HeightCenter4) * _HeightAmplitude4;
heights1.g = (SAMPLE_TEXTURE2D(_HeightMap3, sampler_Splat0, uvSplats[5]).r - _HeightCenter5) * _HeightAmplitude5;
heights1.g = (SAMPLE_TEXTURE2D(_Height5, sampler_Splat0, uvSplats[5]).r * blendMasks1.g - _HeightCenter5) * _HeightAmplitude5;
heights1.b = (SAMPLE_TEXTURE2D(_HeightMap3, sampler_Splat0, uvSplats[6]).r - _HeightCenter6) * _HeightAmplitude6;
heights1.b = (SAMPLE_TEXTURE2D(_Height6, sampler_Splat0, uvSplats[6]).r * blendMasks1.b - _HeightCenter6) * _HeightAmplitude6;
heights1.a = (SAMPLE_TEXTURE2D(_HeightMap3, sampler_Splat0, uvSplats[7]).r - _HeightCenter7) * _HeightAmplitude7;
heights1.a = (SAMPLE_TEXTURE2D(_Height7, sampler_Splat0, uvSplats[7]).r * blendMasks1.a - _HeightCenter7) * _HeightAmplitude7;
#endif
// Modify blendMask to take into account the height of the layer. Higher height should be more visible.

float weights[_MAX_LAYER];
ZERO_INITIALIZE_ARRAY(float, weights, _MAX_LAYER);
#if defined(_DENSITY_MODE)
#if _LAYER_COUNT > 7
weights[7] = min(blendMasks1.a, (1.0f - weightsSum));
weightsSum = saturate(weightsSum + weights[7]);
#if _LAYER_COUNT > 7
weights[7] = min(blendMasks1.a, (1.0f - weightsSum));
weightsSum = saturate(weightsSum + weights[7]);
#endif
#if _LAYER_COUNT > 6
weights[6] = min(blendMasks1.b, (1.0f - weightsSum));
weightsSum = saturate(weightsSum + weights[6]);
#endif
#if _LAYER_COUNT > 5
weights[5] = min(blendMasks1.g, (1.0f - weightsSum));
weightsSum = saturate(weightsSum + weights[5]);
#endif
#if _LAYER_COUNT > 4
weights[4] = min(blendMasks1.r, (1.0f - weightsSum));
weightsSum = saturate(weightsSum + weights[4]);
#endif
#if _LAYER_COUNT > 3
weights[3] = min(blendMasks0.a, (1.0f - weightsSum));
weightsSum = saturate(weightsSum + weights[3]);
#endif
#if _LAYER_COUNT > 2
weights[2] = min(blendMasks0.b, (1.0f - weightsSum));
weightsSum = saturate(weightsSum + weights[2]);
#endif
#if _LAYER_COUNT > 1
weights[1] = min(blendMasks0.g, (1.0f - weightsSum));
weightsSum = saturate(weightsSum + weights[1]);
#endif
weights[0] = min(blendMasks0.r, (1.0f - weightsSum));
#else
weights[0] = blendMasks0.r;
weights[1] = blendMasks0.g;
weights[2] = blendMasks0.b;
weights[3] = blendMasks0.a;
weights[4] = blendMasks1.r;
weights[5] = blendMasks1.g;
weights[6] = blendMasks1.b;
weights[7] = blendMasks1.a;
#if _LAYER_COUNT > 6
weights[6] = min(blendMasks1.b, (1.0f - weightsSum));
weightsSum = saturate(weightsSum + weights[6]);
#endif
#if _LAYER_COUNT > 5
weights[5] = min(blendMasks1.g, (1.0f - weightsSum));
weightsSum = saturate(weightsSum + weights[5]);
#endif
#if _LAYER_COUNT > 4
weights[4] = min(blendMasks1.r, (1.0f - weightsSum));
weightsSum = saturate(weightsSum + weights[4]);
#endif
#if _LAYER_COUNT > 3
weights[3] = min(blendMasks0.a, (1.0f - weightsSum));
weightsSum = saturate(weightsSum + weights[3]);
#endif
#if _LAYER_COUNT > 2
weights[2] = min(blendMasks0.b, (1.0f - weightsSum));
weightsSum = saturate(weightsSum + weights[2]);
#endif
#if _LAYER_COUNT > 1
weights[1] = min(blendMasks0.g, (1.0f - weightsSum));
weightsSum = saturate(weightsSum + weights[1]);
#endif
weights[0] = min(blendMasks0.r, (1.0f - weightsSum));
// TODO: conditional samplings
surfaceData.baseColor = SAMPLE_TEXTURE2D(_Splat0, sampler_Splat0, uvSplats[0]).rgb * weights[0];

153
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/TerrainLit/TerrainLit_Basemap_Gen.shader


{
Properties
{
[HideInInspector] _Control0 ("AlphaMap", 2D) = "" {}
[HideInInspector] _Control1 ("AlphaMap", 2D) = "" {}
[HideInInspector] _Control0("AlphaMap", 2D) = "" {}
[HideInInspector] _Control1("AlphaMap", 2D) = "" {}
[HideInInspector] _Splat0("Layer 0", 2D) = "white" {}
[HideInInspector] _Splat1("Layer 1", 2D) = "white" {}
[HideInInspector] _Splat2("Layer 2", 2D) = "white" {}
[HideInInspector] _Splat3("Layer 3", 2D) = "white" {}
[HideInInspector] _Splat4("Layer 4", 2D) = "white" {}
[HideInInspector] _Splat5("Layer 5", 2D) = "white" {}
[HideInInspector] _Splat6("Layer 6", 2D) = "white" {}
[HideInInspector] _Splat7("Layer 7", 2D) = "white" {}
[HideInInspector] _Height0("Height 0", 2D) = "black" {}
[HideInInspector] _Height1("Height 1", 2D) = "black" {}
[HideInInspector] _Height2("Height 2", 2D) = "black" {}
[HideInInspector] _Height3("Height 3", 2D) = "black" {}
[HideInInspector] _Height4("Height 4", 2D) = "black" {}
[HideInInspector] _Height5("Height 5", 2D) = "black" {}
[HideInInspector] _Height6("Height 6", 2D) = "black" {}
[HideInInspector] _Height7("Height 7", 2D) = "black" {}
[HideInInspector] _Splat0 ("Layer 0 (R)", 2D) = "white" {}
[HideInInspector] _Splat1 ("Layer 1 (G)", 2D) = "white" {}
[HideInInspector] _Splat2 ("Layer 2 (B)", 2D) = "white" {}
[HideInInspector] _Splat3 ("Layer 3 (A)", 2D) = "white" {}
[HideInInspector] _Splat4 ("Layer 0 (R)", 2D) = "white" {}
[HideInInspector] _Splat5 ("Layer 1 (G)", 2D) = "white" {}
[HideInInspector] _Splat6 ("Layer 2 (B)", 2D) = "white" {}
[HideInInspector] _Splat7 ("Layer 3 (A)", 2D) = "white" {}
[HideInInspector] _HeightAmplitude0("Height Scale0", Float) = 0.02
[HideInInspector] _HeightAmplitude1("Height Scale1", Float) = 0.02
[HideInInspector] _HeightAmplitude2("Height Scale2", Float) = 0.02
[HideInInspector] _HeightAmplitude3("Height Scale3", Float) = 0.02
[HideInInspector] _HeightAmplitude4("Height Scale4", Float) = 0.02
[HideInInspector] _HeightAmplitude5("Height Scale5", Float) = 0.02
[HideInInspector] _HeightAmplitude6("Height Scale6", Float) = 0.02
[HideInInspector] _HeightAmplitude7("Height Scale7", Float) = 0.02
[HideInInspector] _HeightCenter0("Height Bias0", Range(0.0, 1.0)) = 0.5
[HideInInspector] _HeightCenter1("Height Bias1", Range(0.0, 1.0)) = 0.5
[HideInInspector] _HeightCenter2("Height Bias2", Range(0.0, 1.0)) = 0.5
[HideInInspector] _HeightCenter3("Height Bias3", Range(0.0, 1.0)) = 0.5
[HideInInspector] _HeightCenter4("Height Bias4", Range(0.0, 1.0)) = 0.5
[HideInInspector] _HeightCenter5("Height Bias5", Range(0.0, 1.0)) = 0.5
[HideInInspector] _HeightCenter6("Height Bias6", Range(0.0, 1.0)) = 0.5
[HideInInspector] _HeightCenter7("Height Bias7", Range(0.0, 1.0)) = 0.5
[HideInInspector] _Smoothness0 ("Smoothness0", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness1 ("Smoothness1", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness2 ("Smoothness2", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness3 ("Smoothness3", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness4 ("Smoothness0", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness5 ("Smoothness1", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness6 ("Smoothness2", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness7 ("Smoothness3", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness0("Smoothness 0", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness1("Smoothness 1", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness2("Smoothness 2", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness3("Smoothness 3", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness4("Smoothness 4", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness5("Smoothness 5", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness6("Smoothness 6", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness7("Smoothness 7", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Metallic0 ("Metallic0", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Metallic1 ("Metallic1", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Metallic2 ("Metallic2", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Metallic3 ("Metallic3", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Metallic4 ("Metallic0", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Metallic5 ("Metallic1", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Metallic6 ("Metallic2", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Metallic7 ("Metallic3", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic0("Metallic 0", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic1("Metallic 1", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic2("Metallic 2", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic3("Metallic 3", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic4("Metallic 4", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic5("Metallic 5", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic6("Metallic 6", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic7("Metallic 7", Range(0.0, 1.0)) = 0.0
}
SubShader
{

#define USE_LEGACY_UNITY_MATRIX_VARIABLES
#include "CoreRP/ShaderLibrary/Common.hlsl"
#include "../../ShaderVariables.hlsl"
#define _TERRAIN_8_SPLATS
#include "TerrainLitSplatCommon.hlsl"
TEXTURE2D(_Control0);
TEXTURE2D(_Control1);
SAMPLER(sampler_Control0);
#pragma shader_feature _TERRAIN_HEIGHT_MAP
// Needed because unity tries to match the name of the used textures to samplers. Heights can be used without splats.
SAMPLER(sampler_Height0);
void FetchWeights(float2 uv, out float4 weights0, out float4 weights1)
{
weights0 = SAMPLE_TEXTURE2D(_Control0, sampler_Control0, uv);
weights1 = SAMPLE_TEXTURE2D(_Control1, sampler_Control0, uv);
#ifdef _TERRAIN_HEIGHT_MAP
float4 weightedHeights0;
float4 weightedHeights1;
weightedHeights0.r = (SAMPLE_TEXTURE2D(_Height0, sampler_Height0, TRANSFORM_TEX(uv, _Splat0)).r * weights0.r - _HeightCenter0) * _HeightAmplitude0;
weightedHeights0.g = (SAMPLE_TEXTURE2D(_Height1, sampler_Height0, TRANSFORM_TEX(uv, _Splat1)).r * weights0.g - _HeightCenter1) * _HeightAmplitude1;
weightedHeights0.b = (SAMPLE_TEXTURE2D(_Height2, sampler_Height0, TRANSFORM_TEX(uv, _Splat2)).r * weights0.b - _HeightCenter2) * _HeightAmplitude2;
weightedHeights0.a = (SAMPLE_TEXTURE2D(_Height3, sampler_Height0, TRANSFORM_TEX(uv, _Splat3)).r * weights0.a - _HeightCenter3) * _HeightAmplitude3;
weightedHeights1.r = (SAMPLE_TEXTURE2D(_Height4, sampler_Height0, TRANSFORM_TEX(uv, _Splat4)).r * weights1.r - _HeightCenter4) * _HeightAmplitude4;
weightedHeights1.g = (SAMPLE_TEXTURE2D(_Height5, sampler_Height0, TRANSFORM_TEX(uv, _Splat5)).r * weights1.g - _HeightCenter5) * _HeightAmplitude5;
weightedHeights1.b = (SAMPLE_TEXTURE2D(_Height6, sampler_Height0, TRANSFORM_TEX(uv, _Splat6)).r * weights1.b - _HeightCenter6) * _HeightAmplitude6;
weightedHeights1.a = (SAMPLE_TEXTURE2D(_Height7, sampler_Height0, TRANSFORM_TEX(uv, _Splat7)).r * weights1.a - _HeightCenter7) * _HeightAmplitude7;
// Modify blendMask to take into account the height of the layer. Higher height should be more visible.
ApplyHeightBlend(weightedHeights0, weightedHeights1, weights0, weights1);
#endif
}
struct appdata_t {
float3 vertex : POSITION;

HLSLPROGRAM
TEXTURE2D(_Splat0);
TEXTURE2D(_Splat1);
TEXTURE2D(_Splat2);
TEXTURE2D(_Splat3);
TEXTURE2D(_Splat4);
TEXTURE2D(_Splat5);
TEXTURE2D(_Splat6);
TEXTURE2D(_Splat7);
SAMPLER(sampler_Splat0);
float _Smoothness0;
float _Smoothness1;
float _Smoothness2;
float _Smoothness3;
float _Smoothness4;
float _Smoothness5;
float _Smoothness6;
float _Smoothness7;
float4 _Splat0_ST;
float4 _Splat1_ST;
float4 _Splat2_ST;
float4 _Splat3_ST;
float4 _Splat4_ST;
float4 _Splat5_ST;
float4 _Splat6_ST;
float4 _Splat7_ST;
#pragma vertex vert
#pragma fragment frag

float4 frag(v2f i) : SV_Target
{
float4 weights0 = SAMPLE_TEXTURE2D(_Control0, sampler_Control0, i.texcoord);
float4 weights1 = SAMPLE_TEXTURE2D(_Control1, sampler_Control0, i.texcoord);
float4 weights0, weights1;
FetchWeights(i.texcoord, weights0, weights1);
float4 splat0 = SAMPLE_TEXTURE2D(_Splat0, sampler_Splat0, TRANSFORM_TEX(i.texcoord, _Splat0));
float4 splat1 = SAMPLE_TEXTURE2D(_Splat1, sampler_Splat0, TRANSFORM_TEX(i.texcoord, _Splat1));

HLSLPROGRAM
float _Metallic0;
float _Metallic1;
float _Metallic2;
float _Metallic3;
float _Metallic4;
float _Metallic5;
float _Metallic6;
float _Metallic7;
#pragma vertex vert
#pragma fragment frag

float4 frag(v2f i) : SV_Target
{
float4 weights0 = SAMPLE_TEXTURE2D(_Control0, sampler_Control0, i.texcoord);
float4 weights1 = SAMPLE_TEXTURE2D(_Control1, sampler_Control0, i.texcoord);
float4 weights0, weights1;
FetchWeights(i.texcoord, weights0, weights1);
float4 metallic = { _Metallic0 * weights0.x, 0, 0, 0 };
metallic.r += _Metallic1 * weights0.y;

144
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/TerrainLit/TerrainLitSplatCommon.hlsl


#if defined(_TERRAIN_8_SPLATS)
#define _LAYER_COUNT 8
#elif defined(_TERRAIN_7_SPLATS)
#define _LAYER_COUNT 7
#elif defined(_TERRAIN_6_SPLATS)
#define _LAYER_COUNT 6
#elif defined(_TERRAIN_5_SPLATS)
#define _LAYER_COUNT 5
#elif defined(_TERRAIN_4_SPLATS)
#define _LAYER_COUNT 4
#elif defined(_TERRAIN_3_SPLATS)
#define _LAYER_COUNT 3
#elif defined(_TERRAIN_2_SPLATS)
#define _LAYER_COUNT 2
#else
#define _LAYER_COUNT 1
#endif
#define DECLARE_TERRAIN_LAYER(n) \
TEXTURE2D(_Splat##n); \
TEXTURE2D(_Normal##n); \
TEXTURE2D(_Height##n); \
float4 _Splat##n##_ST; \
float _Metallic##n; \
float _Smoothness##n; \
float _HeightCenter##n; \
float _HeightAmplitude##n
DECLARE_TERRAIN_LAYER(0);
DECLARE_TERRAIN_LAYER(1);
DECLARE_TERRAIN_LAYER(2);
DECLARE_TERRAIN_LAYER(3);
DECLARE_TERRAIN_LAYER(4);
DECLARE_TERRAIN_LAYER(5);
DECLARE_TERRAIN_LAYER(6);
DECLARE_TERRAIN_LAYER(7);
#undef DECLARE_TERRAIN_LAYER
TEXTURE2D(_Control0);
TEXTURE2D(_Control1);
SAMPLER(sampler_Splat0);
SAMPLER(sampler_Control0);
float GetMaxHeight(float4 heights0
#if _LAYER_COUNT > 4
, float4 heights1
#endif
)
{
float maxHeight = heights0.r;
#if _LAYER_COUNT > 1
maxHeight = max(maxHeight, heights0.g);
#endif
#if _LAYER_COUNT > 2
maxHeight = max(maxHeight, heights0.b);
#endif
#if _LAYER_COUNT > 3
maxHeight = max(maxHeight, heights0.a);
#endif
#if _LAYER_COUNT > 4
maxHeight = max(maxHeight, heights1.r);
#endif
#if _LAYER_COUNT > 5
maxHeight = max(maxHeight, heights1.g);
#endif
#if _LAYER_COUNT > 6
maxHeight = max(maxHeight, heights1.b);
#endif
#if _LAYER_COUNT > 7
maxHeight = max(maxHeight, heights1.a);
#endif
return maxHeight;
}
float GetSumHeight(float4 heights0
#if _LAYER_COUNT > 4
, float4 heights1
#endif
)
{
float sumHeight = heights0.r;
#if _LAYER_COUNT > 1
sumHeight += heights0.g;
#endif
#if _LAYER_COUNT > 2
sumHeight += heights0.b;
#endif
#if _LAYER_COUNT > 3
sumHeight += heights0.a;
#endif
#if _LAYER_COUNT > 4
sumHeight += heights1.r;
#endif
#if _LAYER_COUNT > 5
sumHeight += heights1.g;
#endif
#if _LAYER_COUNT > 6
sumHeight += heights1.b;
#endif
#if _LAYER_COUNT > 7
sumHeight += heights1.a;
#endif
return sumHeight;
}
float _HeightTransition;
// Returns layering blend mask after application of height based blend.
void ApplyHeightBlend(float4 weightedHeights0, float4 weightedHeights1, inout float4 blendMasks0, inout float4 blendMasks1)
{
float maxHeight = GetMaxHeight(weightedHeights0
#if _LAYER_COUNT > 4
, weightedHeights1
#endif
);
// 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 highest layer at negative heights, then we add the transition so that if the next highest layer is near transition it will have a positive value.
// Then we clamp this to zero and normalize everything so that highest layer has a value of 1.
weightedHeights0 = weightedHeights0 - 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.
weightedHeights0 = (max(0, weightedHeights0 + transition) + 1e-6) * blendMasks0;
#if _LAYER_COUNT > 4
weightedHeights1 = weightedHeights1 - maxHeight.xxxx;
weightedHeights1 = (max(0, weightedHeights1 + transition) + 1e-6) * blendMasks1;
#endif
// Normalize
float totalHeight = GetSumHeight(weightedHeights0
#if _LAYER_COUNT > 4
, weightedHeights1
#endif
);
blendMasks0 = weightedHeights0 / totalHeight.xxxx;
#if _LAYER_COUNT > 4
blendMasks1 = weightedHeights1 / totalHeight.xxxx;
#endif
}

9
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/TerrainLit/TerrainLitSplatCommon.hlsl.meta


fileFormatVersion: 2
guid: ebaf5373f132117419d2576ec6b276b6
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存