浏览代码

HDRenderPipeline: Push draft not compling

/Branch_Batching2
sebastienlagarde 8 年前
当前提交
b7ce99a8
共有 9 个文件被更改,包括 410 次插入263 次删除
  1. 7
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  2. 366
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitData.hlsl
  3. 151
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl
  4. 11
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitTessellation.hlsl
  5. 3
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/SampleLayer.hlsl
  6. 7
      Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderVariables.hlsl
  7. 17
      Assets/TestScenes/HDTest/GraphicTest/LayeredTessellation/Layer-2-woord-rock.mat
  8. 102
      Assets/ScriptableRenderLoop/ShaderLibrary/PerPixelDisplacement.hlsl
  9. 9
      Assets/ScriptableRenderLoop/ShaderLibrary/PerPixelDisplacement.hlsl.meta

7
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader


_TexWorldScale2("Tiling", Float) = 1.0
_TexWorldScale3("Tiling", Float) = 1.0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase0("UV Set for base0", Float) = 0
[Enum(UV0, 0, Planar, 4, Triplanar, 5)] _UVBase0("UV Set for base0", Float) = 0 // no UV1/2/3 for main layer (matching Lit.shader and for PPDisplacement restriction)
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase1("UV Set for base1", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase2("UV Set for base2", Float) = 0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, Planar, 4, Triplanar, 5)] _UVBase3("UV Set for base3", Float) = 0

#pragma shader_feature _MASKMAP
#pragma shader_feature _SPECULAROCCLUSIONMAP
#pragma shader_feature _EMISSIVE_COLOR_MAP
#pragma shader_feature _HEIGHTMAP
#pragma shader_feature _HEIGHTMAP0
#pragma shader_feature _HEIGHTMAP1
#pragma shader_feature _HEIGHTMAP2
#pragma shader_feature _HEIGHTMAP3
#pragma shader_feature _DETAIL_MAP
#pragma shader_feature _ _LAYER_MASK_VERTEX_COLOR_MUL _LAYER_MASK_VERTEX_COLOR_ADD
#pragma shader_feature _MAIN_LAYER_INFLUENCE_MODE

366
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitData.hlsl


layerTexCoord.weights = ComputeTriplanarWeights(normalWS);
#endif
// Be sure that the compiler is aware that we don't touch UV1 to UV3 for base layer in case of non layer shader
// so it can remove code
_UVMappingMask.yzw = float3(0.0, 0.0, 0.0);
// Be sure that the compiler is aware that we don't touch UV1 to UV3 for main layer so it can optimize code
_UVMappingMask.yzw = float3(0.0, 0.0, 0.0);
ComputeLayerTexCoord( texCoord0, texCoord1, texCoord2, texCoord3,
positionWS, normalWS, isTriplanar, layerTexCoord);
}

#undef LAYER_INDEX
#undef ADD_IDX
void ComputeMaskWeights(float4 inputMasks, out float outWeights[_MAX_LAYER])
{
float masks[_MAX_LAYER];
#if defined(_DENSITY_MODE)
masks[0] = inputMasks.a;
#else
masks[0] = 1.0;
#endif
masks[1] = inputMasks.r;
masks[2] = inputMasks.g;
masks[3] = inputMasks.b;
// calculate weight of each layers
// Algorithm is like this:
// Top layer have priority on others layers
// If a top layer doesn't use the full weight, the remaining can be use by the following layer.
float weightsSum = 0.0;
[unroll]
for (int i = _LAYER_COUNT - 1; i >= 0; --i)
{
outWeights[i] = min(masks[i], (1.0 - weightsSum));
weightsSum = saturate(weightsSum + masks[i]);
}
}
float3 BlendLayeredVector3(float3 x0, float3 x1, float3 x2, float3 x3, float weight[4])
{
float3 result = float3(0.0, 0.0, 0.0);

#ifdef _LAYER_MAPPING_TRIPLANAR_0
isTriplanar = true;
#endif
// Be sure that the compiler is aware that we don't touch UV1 to UV3 for main layer so it can optimize code
_UVMappingMask0.yzw = float3(0.0, 0.0, 0.0);
ComputeLayerTexCoord0( texCoord0, texCoord1, texCoord2, texCoord3,
positionWS, normalWS, isTriplanar, layerTexCoord, _LayerTiling0);

positionWS, normalWS, isTriplanar, layerTexCoord, _LayerTiling3);
}
void ApplyPerPixelDisplacement(FragInputs input, float3 V, inout LayerTexCoord layerTexCoord)
// declare the sampler for the heigthmap
#if defined(_HEIGHTMAP0)
#define sampler_HeightMap0 sampler_ShareHeightMap
#elif defined(_HEIGHTMAP1)
#define sampler_HeightMap1 sampler_ShareHeightMap
#elif defined(_HEIGHTMAP2)
#define sampler_HeightMap2 sampler_ShareHeightMap
#elif defined(_HEIGHTMAP3)
#define sampler_HeightMap3 sampler_ShareHeightMap
#endif
// This function is just syntaxic sugar to nullify height not used based on option and layer
void SetEnabledHeightByLayer(inout float height0, inout float height1, inout float height2, inout float height3)
#if defined(_HEIGHTMAP) && defined(_PER_PIXEL_DISPLACEMENT)
float3 viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
int numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, viewDirTS.z);
#ifndef _HEIGHTMAP0
height0 = 0.0;
#endif
#ifndef _HEIGHTMAP1
height1 = 0.0;
#endif
#ifndef _HEIGHTMAP2
height2 = 0.0;
#endif
#ifndef _HEIGHTMAP3
height3 = 0.0;
#endif
// To be correct, we need to perform PPP on each unique UVSet
// And if we are triplanar we are suppose to do it 3 time (one for each direction)
// It is catastrophic for performance so PPP is only allowed on the UVSet use for the Main layer.
// However it still take into account all heightmap to produce the height use for the displacement
ParallaxOcclusionMappingLayer0(layerTexCoord, numSteps, viewDirTS);
#if _LAYER_COUNT < 4
height3 = 0.0;
#endif
#if _LAYER_COUNT < 3
height2 = 0.0;
float3 ComputeMainNormalInfluence(FragInputs input, float3 normalTS0, float3 normalTS1, float3 normalTS2, float3 normalTS3, LayerTexCoord layerTexCoord, float weights[_MAX_LAYER])
// Return the maximun amplitude use by all enabled heightmap
// use for tessellation culling and per pixel displacement
float GetMaxDisplacement()
// Get our regular normal from regular layering
float3 normalTS = BlendLayeredVector3(normalTS0, normalTS1, normalTS2, normalTS3, weights);
float maxDisplacement = 0.0;
#if defined(_HEIGHTMAP0)
maxDisplacement = max(_HeightAmplitude0, maxDisplacement);
#endif
#if defined(_HEIGHTMAP1)
maxDisplacement = max( _HeightAmplitude1
#if defined(_MAIN_LAYER_INFLUENCE_MODE)
+ _HeightAmplitude0 * _InheritBaseHeight1
#endif
, maxDisplacement);
#endif
#if _LAYER_COUNT >= 3
#if defined(_HEIGHTMAP2)
maxDisplacement = max( _HeightAmplitude2
#if defined(_MAIN_LAYER_INFLUENCE_MODE)
+ _HeightAmplitude0 * _InheritBaseHeight2
#endif
, maxDisplacement);
#endif
#endif
// THen get Main Layer Normal influence factor. Main layer is 0 because it can't be influence. In this case the final lerp return normalTS.
float influenceFactor = BlendLayeredScalar(0.0, _InheritBaseNormal1, _InheritBaseNormal2, _InheritBaseNormal3, weights);
// We will add smoothly the contribution of the normal map by using lower mips with help of bias sampling. InfluenceFactor must be [0..numMips] // Caution it cause banding...
// Note: that we don't take details map into account here.
float maxMipBias = log2(max(_NormalMap0_TexelSize.z, _NormalMap0_TexelSize.w)); // don't do + 1 as it is for bias, not lod
float3 mainNormalTS = GetNormalTS0(input, layerTexCoord, float3(0.0, 0.0, 1.0), 0.0, true, maxMipBias * (1.0 - influenceFactor));
#if _LAYER_COUNT >= 4
#if defined(_HEIGHTMAP3)
maxDisplacement = max( _HeightAmplitude3
#if defined(_MAIN_LAYER_INFLUENCE_MODE)
+ _HeightAmplitude0 * _InheritBaseHeight3
#endif
, maxDisplacement);
#endif
#endif
}
// Add on our regular normal a bit of Main Layer normal base on influence factor. Note that this affect only the "visible" normal.
return lerp(normalTS, BlendNormalRNM(normalTS, mainNormalTS), influenceFactor);
struct PerPixelHeightDisplacementParam
{
float4 weights;
float mainHeightInfluence;
};
// Calculate displacement for per vertex displacement mapping
float ComputePerPixelHeightDisplacement(float2 uv, float lod, PerPixelHeightDisplacementParam param)
{
float height0 = SAMPLE_TEXTURE2D_LOD(_HeightMap0, sampler_ShareHeightMap, uv, lod).r) * _HeightAmplitude0;
float height1 = SAMPLE_TEXTURE2D_LOD(_HeightMap1, sampler_ShareHeightMap, uv, lod).r) * _HeightAmplitude1;
float height2 = SAMPLE_TEXTURE2D_LOD(_HeightMap2, sampler_ShareHeightMap, uv, lod).r) * _HeightAmplitude2;
float height3 = SAMPLE_TEXTURE2D_LOD(_HeightMap3, sampler_ShareHeightMap, uv, lod).r) * _HeightAmplitude3;
SetEnabledHeightByLayer(height0, height1, height2, height3);
return BlendLayeredScalar(height0, height1, height2, height3, param.weights) + param.mainHeightInfluence;
float3 ComputeMainBaseColorInfluence(float3 baseColor0, float3 baseColor1, float3 baseColor2, float3 baseColor3, float compoMask, LayerTexCoord layerTexCoord, float weights[_MAX_LAYER])
#include "PerPixelDisplacement.hlsl"
// PPD is affecting only one mapping at the same time, mean we need to execute it for each mapping (UV0, UV1, 3 times for triplanar etc..)
// We chose to not support all this case that are extremely hard to manage (for example mixing different mapping, mean it also require different tangent space that is not supported in Unity)
// For these reasons we put the following rules
// Rules:
// - Mapping is the same for all layers that use an Heightmap (i.e all are UV, planar or triplanar)
// - Mapping UV is UV0 only because we need to convert view vector in texture space and this is only available for UV0
// - Heightmap can be enabled per layer
// From these rules it mean that PPD is enable only if the user 1) ask for it, 2) if there is one heightmap enabled on active layer, 3) if mapping is the same for all layer respecting 2), 4) if mapping is UV0, planar or triplanar mapping
// Most contraint are handled by the inspector (i.e the UI) like the mapping constraint and is assumed in the shader.
void ApplyPerPixelDisplacement(FragInputs input, float3 V, inout LayerTexCoord layerTexCoord)
float3 baseColor = BlendLayeredVector3(baseColor0, baseColor1, baseColor2, baseColor3, weights);
bool isPPDEnable = false;
// We can take any of the layer UV as PPDlayerUV as they must match except for the tiling
// TODO: Handle different tiling
LayerUV PPDlayerUV;
float influenceFactor = BlendLayeredScalar(0.0, _InheritBaseColor1, _InheritBaseColor2, _InheritBaseColor3, weights);
float influenceThreshold = BlendLayeredScalar(1.0, _InheritBaseColorThreshold1, _InheritBaseColorThreshold2, _InheritBaseColorThreshold3, weights);
#if defined(_PER_PIXEL_DISPLACEMENT)
influenceFactor = influenceFactor * (1.0 - saturate(compoMask / influenceThreshold));
#if defined(_HEIGHTMAP0)
isPPDEnable = true;
PPDlayerUV.uv = layerTexCoord.base0;
#endif
// We want to calculate the mean color of the texture. For this we will sample a low mipmap
float textureBias = 15.0; // Use maximum bias
float3 baseMeanColor0 = SAMPLE_LAYER_TEXTURE2D_BIAS(_BaseColorMap0, sampler_BaseColorMap0, layerTexCoord.base0, textureBias).rgb *_BaseColor0.rgb;
float3 baseMeanColor1 = SAMPLE_LAYER_TEXTURE2D_BIAS(_BaseColorMap1, sampler_BaseColorMap0, layerTexCoord.base1, textureBias).rgb *_BaseColor1.rgb;
float3 baseMeanColor2 = SAMPLE_LAYER_TEXTURE2D_BIAS(_BaseColorMap2, sampler_BaseColorMap0, layerTexCoord.base2, textureBias).rgb *_BaseColor2.rgb;
float3 baseMeanColor3 = SAMPLE_LAYER_TEXTURE2D_BIAS(_BaseColorMap3, sampler_BaseColorMap0, layerTexCoord.base3, textureBias).rgb *_BaseColor3.rgb;
#if defined(_HEIGHTMAP1)
isPPDEnable = true;
PPDlayerUV.uv = layerTexCoord.base1;
#endif
float3 meanColor = BlendLayeredVector3(baseMeanColor0, baseMeanColor1, baseMeanColor2, baseMeanColor3, weights);
#if _LAYER_COUNT >= 3
#if defined(_HEIGHTMAP2)
isPPDEnable = true;
PPDlayerUV.uv = layerTexCoord.base2;
#endif
#endif
// If we inherit from base layer, we will add a bit of it
// We add variance of current visible level and the base color 0 or mean (to retrieve initial color) depends on influence
// (baseColor - meanColor) + lerp(meanColor, baseColor0, inheritBaseColor) simplify to
return saturate(influenceFactor * (baseColor0 - meanColor) + baseColor);
#if _LAYER_COUNT >= 4
#if defined(_HEIGHTMAP3)
isPPDEnable = true;
PPDlayerUV.uv = layerTexCoord.base3;
#endif
#endif
#endif
if (isPPDEnable)
{
// We need to calculate the texture space direction. It depends on the mapping.
float3 viewDirTS;
if (PPDlayerUV.isPlanar)
{
// Planar is xz coordinate
viewDirTS = normalize(V.xz);
}
else
{
viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
}
float maximunHeight = GetMaxDisplacement();
int numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, viewDirTS.z);
// Compute lod as we will sample inside a loop (so can't use regular sampling)
// It appear that CALCULATE_TEXTURE2D_LOD only return interger lod. We want to use float lod to have smoother transition and fading
// float lod = CALCULATE_TEXTURE2D_LOD(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), uv);
float lod = ComputeTextureLOD(uv, GET_TEXELSIZE_NAME(ADD_IDX(_HeightMap)));
PerPixelHeightDisplacementParam ppdParam();
// For PPP
// To be correct, we need to perform PPP on each unique UVSet
// And if we are triplanar we are suppose to do it 3 time (one for each direction)
// It is catastrophic for performance so PPP is only allowed on the UVSet use for the Main layer.
// However it still take into account all heightmap to produce the height use for the displacement
ParallaxOcclusionMappingLayer(float2 uv, float lod, numSteps, float3 viewDirTS, float maximunHeight, PerPixelHeightDisplacementParam ppdParam);
#if defined(_HEIGHTMAP0)
layerTexCoord.base0.uv += offset;
if (layerTexCoord.triplanar)
{
layerTexCoord.base0.uvYZ;
layerTexCoord.base0.uvZX;
layerTexCoord.base0.uvXY;
}
#endif
#if defined(_HEIGHTMAP1)
layerTexCoord.base1.uv += offset;
#endif
#if _LAYER_COUNT >= 3
#if defined(_HEIGHTMAP2)
layerTexCoord.base2.uv += offset;
#endif
#endif
#if _LAYER_COUNT >= 4
#if defined(_HEIGHTMAP3)
layerTexCoord.base3.uv += offset;
#endif
#endif
}
}
void ComputeMaskWeights(float4 inputMasks, out float outWeights[_MAX_LAYER])
{
float masks[_MAX_LAYER];
#if defined(_DENSITY_MODE)
masks[0] = inputMasks.a;
#else
masks[0] = 1.0;
#endif
masks[1] = inputMasks.r;
masks[2] = inputMasks.g;
masks[3] = inputMasks.b;
// calculate weight of each layers
// Algorithm is like this:
// Top layer have priority on others layers
// If a top layer doesn't use the full weight, the remaining can be use by the following layer.
float weightsSum = 0.0;
[unroll]
for (int i = _LAYER_COUNT - 1; i >= 0; --i)
{
outWeights[i] = min(masks[i], (1.0 - weightsSum));
weightsSum = saturate(weightsSum + masks[i]);
}
}
// Caution: Blend mask are Layer 1 R - Layer 2 G - Layer 3 B - Main Layer A

float4 blendMasks = useLodSampling ? SAMPLE_LAYER_TEXTURE2D_LOD(_LayerMaskMap, sampler_LayerMaskMap, layerTexCoord.base0, lod) : SAMPLE_LAYER_TEXTURE2D(_LayerMaskMap, sampler_LayerMaskMap, layerTexCoord.base0);
#if defined(_LAYER_MASK_VERTEX_COLOR_MUL)
blendMasks *= vertexColor;
blendMasks *= vertexColor;
blendMasks = saturate(blendMasks + vertexColor * 2.0 - 1.0);
blendMasks = saturate(blendMasks + vertexColor * 2.0 - 1.0);
/*
// Calculate displacement for per vertex displacement mapping
float ComputePerPixelHeightDisplacement(LayerTexCoord layerTexCoord, float4 vertexColor, float lod, float4 weights)
{
float height0 = SampleHeightmapLodOffset0(layerTexCoord, lod, _HeightCenter0, _HeightAmplitude0, _HeightCenterOffset0, _HeightFactor0);
float height1 = SampleHeightmapLodOffset1(layerTexCoord, lod, _HeightCenter1, _HeightAmplitude1, _HeightCenterOffset1, _HeightFactor1);
float height2 = SampleHeightmapLodOffset2(layerTexCoord, lod, _HeightCenter2, _HeightAmplitude2, _HeightCenterOffset2, _HeightFactor2);
float height3 = SampleHeightmapLodOffset3(layerTexCoord, lod, _HeightCenter3, _HeightAmplitude3, _HeightCenterOffset3, _HeightFactor3);
float heightResult = BlendLayeredScalar(height0, height1, height2, height3, weights);
#if defined(_MAIN_LAYER_INFLUENCE_MODE)
// Think that inheritbasedheight will be 0 if height0 is fully visible in weights. So there is no double contribution of height0
float inheritBaseHeight = BlendLayeredScalar(0.0, _InheritBaseHeight1, _InheritBaseHeight2, _InheritBaseHeight3, weights);
return heightResult + height0 * inheritBaseHeight;
#endif
}
*/
// Calculate displacement for per vertex displacement mapping
float ComputePerVertexDisplacement(LayerTexCoord layerTexCoord, float4 vertexColor, float lod)
{

ComputeMaskWeights(blendMasks, weights);
float height0 = SampleHeightmapLod0(layerTexCoord, lod, _HeightCenter0, _HeightAmplitude0, _HeightCenterOffset0, _HeightFactor0);
float height1 = SampleHeightmapLod1(layerTexCoord, lod, _HeightCenter1, _HeightAmplitude1, _HeightCenterOffset1, _HeightFactor1);
float height2 = SampleHeightmapLod2(layerTexCoord, lod, _HeightCenter2, _HeightAmplitude2, _HeightCenterOffset2, _HeightFactor2);
float height3 = SampleHeightmapLod3(layerTexCoord, lod, _HeightCenter3, _HeightAmplitude3, _HeightCenterOffset3, _HeightFactor3);
float height0 = SAMPLE_LAYER_TEXTURE2D_LOD(_HeightMap0, sampler_ShareHeightMap, layerTexCoord.base0, lod).r - _HeightCenter0) * _HeightAmplitude0;
float height1 = SAMPLE_LAYER_TEXTURE2D_LOD(_HeightMap1, sampler_ShareHeightMap, layerTexCoord.base1, lod).r - _HeightCenter1) * _HeightAmplitude1;
float height2 = SAMPLE_LAYER_TEXTURE2D_LOD(_HeightMap2, sampler_ShareHeightMap, layerTexCoord.base2, lod).r - _HeightCenter2) * _HeightAmplitude2;
float height3 = SAMPLE_LAYER_TEXTURE2D_LOD(_HeightMap3, sampler_ShareHeightMap, layerTexCoord.base3, lod).r - _HeightCenter3) * _HeightAmplitude3;
SetEnabledHeightByLayer(height0, height1, height2, height3);
float heightResult = BlendLayeredScalar(height0, height1, height2, height3, weights);
#if defined(_MAIN_LAYER_INFLUENCE_MODE)

}
// Calculate weights to apply to each layer
// Caution: This function must not be use for per vertex of per pixel displacement, there is a dedicated function for them.
// this function handle triplanar
// Caution: This function must not be use for per vertex/pixel displacement, there is a dedicated function for them.
// This function handle triplanar
void ComputeLayerWeights(FragInputs input, LayerTexCoord layerTexCoord, float4 inputAlphaMask, out float outWeights[_MAX_LAYER])
{
float4 blendMasks = GetBlendMask(layerTexCoord, input.color);

#endif
#if defined(_HEIGHT_BASED_BLEND)
float height0 = SampleHeightmap0(layerTexCoord, _HeightCenterOffset0, _HeightFactor0);
float height1 = SampleHeightmap1(layerTexCoord, _HeightCenterOffset1, _HeightFactor1);
float height2 = SampleHeightmap2(layerTexCoord, _HeightCenterOffset2, _HeightFactor2);
float height3 = SampleHeightmap3(layerTexCoord, _HeightCenterOffset3, _HeightFactor3);
float height0 = SAMPLE_LAYER_TEXTURE2D(_HeightMap0, sampler_ShareHeightMap, layerTexCoord.base0).r - _HeightCenter0) * _HeightAmplitude0;
float height1 = SAMPLE_LAYER_TEXTURE2D(_HeightMap1, sampler_ShareHeightMap, layerTexCoord.base1).r - _HeightCenter1) * _HeightAmplitude1;
float height2 = SAMPLE_LAYER_TEXTURE2D(_HeightMap2, sampler_ShareHeightMap, layerTexCoord.base2).r - _HeightCenter2) * _HeightAmplitude2;
float height3 = SAMPLE_LAYER_TEXTURE2D(_HeightMap3, sampler_ShareHeightMap, layerTexCoord.base3).r - _HeightCenter3) * _HeightAmplitude3;
SetEnabledHeightByLayer(height0, height1, height2, height3);
// HACK, use height0 to avoid compiler error for unused sampler
// To remove once we have POM
heights.y += (heights.x * 0.0001);
// don't apply on main layer
blendMasks.rgb = ApplyHeightBasedBlend(blendMasks.rgb, heights.yzw, float3(_BlendUsingHeight1, _BlendUsingHeight2, _BlendUsingHeight3));

}
float3 ComputeMainNormalInfluence(FragInputs input, float3 normalTS0, float3 normalTS1, float3 normalTS2, float3 normalTS3, LayerTexCoord layerTexCoord, float weights[_MAX_LAYER])
{
// Get our regular normal from regular layering
float3 normalTS = BlendLayeredVector3(normalTS0, normalTS1, normalTS2, normalTS3, weights);
// THen get Main Layer Normal influence factor. Main layer is 0 because it can't be influence. In this case the final lerp return normalTS.
float influenceFactor = BlendLayeredScalar(0.0, _InheritBaseNormal1, _InheritBaseNormal2, _InheritBaseNormal3, weights);
// We will add smoothly the contribution of the normal map by using lower mips with help of bias sampling. InfluenceFactor must be [0..numMips] // Caution it cause banding...
// Note: that we don't take details map into account here.
float maxMipBias = log2(max(_NormalMap0_TexelSize.z, _NormalMap0_TexelSize.w)); // don't do + 1 as it is for bias, not lod
float3 mainNormalTS = GetNormalTS0(input, layerTexCoord, float3(0.0, 0.0, 1.0), 0.0, true, maxMipBias * (1.0 - influenceFactor));
// Add on our regular normal a bit of Main Layer normal base on influence factor. Note that this affect only the "visible" normal.
return lerp(normalTS, BlendNormalRNM(normalTS, mainNormalTS), influenceFactor);
}
float3 ComputeMainBaseColorInfluence(float3 baseColor0, float3 baseColor1, float3 baseColor2, float3 baseColor3, float compoMask, LayerTexCoord layerTexCoord, float weights[_MAX_LAYER])
{
float3 baseColor = BlendLayeredVector3(baseColor0, baseColor1, baseColor2, baseColor3, weights);
float influenceFactor = BlendLayeredScalar(0.0, _InheritBaseColor1, _InheritBaseColor2, _InheritBaseColor3, weights);
float influenceThreshold = BlendLayeredScalar(1.0, _InheritBaseColorThreshold1, _InheritBaseColorThreshold2, _InheritBaseColorThreshold3, weights);
influenceFactor = influenceFactor * (1.0 - saturate(compoMask / influenceThreshold));
// We want to calculate the mean color of the texture. For this we will sample a low mipmap
float textureBias = 15.0; // Use maximum bias
float3 baseMeanColor0 = SAMPLE_LAYER_TEXTURE2D_BIAS(_BaseColorMap0, sampler_BaseColorMap0, layerTexCoord.base0, textureBias).rgb *_BaseColor0.rgb;
float3 baseMeanColor1 = SAMPLE_LAYER_TEXTURE2D_BIAS(_BaseColorMap1, sampler_BaseColorMap0, layerTexCoord.base1, textureBias).rgb *_BaseColor1.rgb;
float3 baseMeanColor2 = SAMPLE_LAYER_TEXTURE2D_BIAS(_BaseColorMap2, sampler_BaseColorMap0, layerTexCoord.base2, textureBias).rgb *_BaseColor2.rgb;
float3 baseMeanColor3 = SAMPLE_LAYER_TEXTURE2D_BIAS(_BaseColorMap3, sampler_BaseColorMap0, layerTexCoord.base3, textureBias).rgb *_BaseColor3.rgb;
float3 meanColor = BlendLayeredVector3(baseMeanColor0, baseMeanColor1, baseMeanColor2, baseMeanColor3, weights);
// If we inherit from base layer, we will add a bit of it
// We add variance of current visible level and the base color 0 or mean (to retrieve initial color) depends on influence
// (baseColor - meanColor) + lerp(meanColor, baseColor0, inheritBaseColor) simplify to
return saturate(influenceFactor * (baseColor0 - meanColor) + baseColor);
}
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)

151
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl


void ADD_IDX(ComputeLayerTexCoord)( float2 texCoord0, float2 texCoord1, float2 texCoord2, float2 texCoord3,
float3 positionWS, float3 normalWS, bool isTriplanar, inout LayerTexCoord layerTexCoord, float additionalTiling = 1.0)
float3 positionWS, float3 vertexNormalWS, bool isTriplanar, inout LayerTexCoord layerTexCoord, float additionalTiling = 1.0)
{
// Handle uv0, uv1, uv2, uv3 based on _UVMappingMask weight (exclusif 0..1)
float2 uvBase = ADD_IDX(_UVMappingMask).x * texCoord0 +

{
uvBase = -position.xz;
uvDetails = -position.xz;
ADD_IDX(layerTexCoord.base).isPlanar = true;
ADD_IDX(layerTexCoord.details).isPlanar = true;
}
else
{
ADD_IDX(layerTexCoord.base).isPlanar = false;
ADD_IDX(layerTexCoord.details).isPlanar = false;
}
ADD_IDX(layerTexCoord.base).uv = TRANSFORM_TEX(uvBase, ADD_IDX(_BaseColorMap));

ADD_IDX(layerTexCoord.base).isTriplanar = isTriplanar;
float3 direction = sign(normalWS);
float3 direction = sign(vertexNormalWS);
// In triplanar, if we are facing away from the world axis, a different axis will be flipped for each direction.
// This is particularly problematic for tangent space normal maps which need to be in the right direction.

ADD_IDX(layerTexCoord.details).uvYZ = TRANSFORM_TEX(uvYZ, ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvZX = TRANSFORM_TEX(uvZX, ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvXY = TRANSFORM_TEX(uvXY, ADD_IDX(_DetailMap));
}
// TODO: Ideally we should concat these value in the inspector - But still in development and use change frequently
float ADD_IDX(SampleHeightmap)(LayerTexCoord layerTexCoord, float centerOffset, float heightMultiplier, float layerCenterOffset = 0.0, float layerHeightMultiplier = 1.0)
{
#ifdef _HEIGHTMAP
return (SAMPLE_LAYER_TEXTURE2D(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base)).r - centerOffset - layerCenterOffset) * heightMultiplier * layerHeightMultiplier;
#else
return 0.0;
#endif
}
float ADD_IDX(SampleHeightmapLod)(LayerTexCoord layerTexCoord, float lod, float centerOffset, float heightMultiplier, float layerCenterOffset = 0.0, float layerHeightMultiplier = 1.0)
{
#ifdef _HEIGHTMAP
return (SAMPLE_LAYER_TEXTURE2D_LOD(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base), lod).r - centerOffset - layerCenterOffset) * heightMultiplier * layerHeightMultiplier;
#else
return 0.0;
#endif
}
// Use with Per pixel Displacement - No triplanar allowed here as this should be perform 3 times for each UVSet
float ADD_IDX(SampleHeightmapLodOffset)(LayerTexCoord layerTexCoord, float lod, float2 texOffset, float centerOffset, float heightMultiplier, float layerCenterOffset = 0.0, float layerHeightMultiplier = 1.0)
{
#ifdef _HEIGHTMAP
return (SAMPLE_TEXTURE2D_LOD(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), ADD_IDX(layerTexCoord.base).uv + texOffset, lod).r - centerOffset - layerCenterOffset) * heightMultiplier * layerHeightMultiplier;
#else
return 0.0;
#endif
}
// Note: The sampling of heightmap inside POM don't use sampling abstraction (with triplanar) as
// POM must be apply separately for each uv set (so 3 time for triplanar)
void ADD_IDX(ParallaxOcclusionMappingLayer)(inout LayerTexCoord layerTexCoord, int numSteps, float3 viewDirTS)
{
// Convention: 1.0 is top, 0.0 is bottom - POM is always inward, no extrusion
float stepSize = 1.0 / (float)numSteps;
// View vector is from the point to the camera, but we want to raymarch from camera to point, so reverse the sign
// The length of viewDirTS vector determines the furthest amount of displacement:
// float parallaxLimit = -length(viewDirTS.xy) / viewDirTS.z;
// float2 parallaxDir = normalize(Out.viewDirTS.xy);
// float2 parallaxMaxOffsetTS = parallaxDir * parallaxLimit;
// Above code simplify to
float2 parallaxMaxOffsetTS = (viewDirTS.xy / -viewDirTS.z) * ADD_IDX(_HeightAmplitude);
float2 texOffsetPerStep = stepSize * parallaxMaxOffsetTS;
float2 uv = ADD_IDX(layerTexCoord.base).uv;
// Compute lod as we will sample inside a loop (so can't use regular sampling)
// It appear that CALCULATE_TEXTURE2D_LOD only return interger lod. We want to use float lod to have smoother transition and fading
// float lod = CALCULATE_TEXTURE2D_LOD(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), uv);
float lod = ComputeTextureLOD(uv, GET_TEXELSIZE_NAME(ADD_IDX(_HeightMap)));
// Do a first step before the loop to init all value correctly
float2 texOffsetCurrent = 0;
float prevHeight = SAMPLE_TEXTURE2D_LOD(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), uv + texOffsetCurrent, lod).r;
texOffsetCurrent += texOffsetPerStep;
float currHeight = SAMPLE_TEXTURE2D_LOD(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), uv + texOffsetCurrent, lod).r;
float rayHeight = 1.0 - stepSize; // Start at top less one sample
// Linear search
for (int stepIndex = 0; stepIndex < numSteps; ++stepIndex)
{
// Have we found a height below our ray height ? then we have an intersection
if (currHeight > rayHeight)
break; // end the loop
prevHeight = currHeight;
rayHeight -= stepSize;
texOffsetCurrent += texOffsetPerStep;
// Sample height map which in this case is stored in the alpha channel of the normal map:
currHeight = SAMPLE_TEXTURE2D_LOD(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), uv + texOffsetCurrent, lod).r;
}
// Found below and above points, now perform line interesection (ray) with piecewise linear heightfield approximation
// Refine the search by adding few extra intersection
#define POM_REFINE 1
#if POM_REFINE
float pt0 = rayHeight + stepSize;
float pt1 = rayHeight;
float delta0 = pt0 - prevHeight;
float delta1 = pt1 - currHeight;
float2 offset = float2(0.0, 0.0);
float threshold = 1.0;
for (int i = 0; i < 5; ++i)
{
float t = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);
offset = (1 - t) * texOffsetPerStep * numSteps;
currHeight = SAMPLE_TEXTURE2D_LOD(ADD_IDX(_HeightMap), ADD_ZERO_IDX(sampler_HeightMap), uv + offset, lod).r;
threshold = t - currHeight;
if (abs(threshold) <= 0.01)
break;
if (threshold < 0.0)
{
delta1 = threshold;
pt1 = t;
}
else
{
delta0 = threshold;
pt0 = t;
}
}
#else
//float pt0 = rayHeight + stepSize;
//float pt1 = rayHeight;
//float delta0 = pt0 - prevHeight;
//float delta1 = pt1 - currHeight;
//float t = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);
//float2 offset = (1 - t) * texOffsetPerStep * numSteps;
// A bit more optimize
float delta0 = currHeight - rayHeight;
float delta1 = (rayHeight + stepSize) - prevHeight;
float ratio = delta0 / (delta0 + delta1);
float2 offset = texOffsetCurrent - ratio * texOffsetPerStep;
#endif
// TODO: expose LOD fading
//float lodThreshold = 0.0;
//offset *= (1.0 - saturate(lod - lodThreshold));
// Apply offset only on base. Details could use another mapping and will not be consistant...
// Don't know if this will still ok.
// TODO: check with artists
ADD_IDX(layerTexCoord.base).uv += offset;
}
float3 ADD_IDX(GetNormalTS)(FragInputs input, LayerTexCoord layerTexCoord, float3 detailNormalTS, float detailMask, bool useBias, float bias)

11
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitTessellation.hlsl


float4 GetTessellationFactors(float3 p0, float3 p1, float3 p2, float3 n0, float3 n1, float3 n2)
{
float maxDisplacement = ADD_ZERO_IDX(_HeightAmplitude);
#ifdef _LAYER_COUNT
maxDisplacement = max(maxDisplacement, _HeightAmplitude1);
#if _LAYER_COUNT >= 3
maxDisplacement = max(maxDisplacement, _HeightAmplitude2);
#endif
#if _LAYER_COUNT >= 4
maxDisplacement = max(maxDisplacement, _HeightAmplitude3);
#endif
#endif
float maxDisplacement = GetMaxDisplacement();
bool frustumCulled = WorldViewFrustumCull(p0, p1, p2, maxDisplacement, (float4[4])unity_CameraWorldClipPlanes);

3
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/SampleLayer.hlsl


// Gather all kind of mapping in one struct, allow to improve code readability
struct LayerUV
{
float2 uv;
float2 uv;
bool isPlanar; // mutually exclusive with isTriplanar
// triplanar
bool isTriplanar;
float2 uvYZ;

7
Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderVariables.hlsl


// As I haven't change the variables name yet, I simply don't define anything, and I put the transform function at the end of the file outside the guard header.
// This need to be fixed.
float4x4 glstate_matrix_inv_projection;
#define UNITY_MATRIX_M unity_ObjectToWorld
// These are updated per eye in VR

float4x4 GetWorldToHClipMatrix()
{
return UNITY_MATRIX_VP;
}
// Transform from clip space to homogenous world space
float4x4 GetClipToHWorldMatrix()
{
return glstate_matrix_inv_projection;
}
float GetOddNegativeScale()

17
Assets/TestScenes/HDTest/GraphicTest/LayeredTessellation/Layer-2-woord-rock.mat


m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_Name: Layer-2-woord-rock
m_Shader: {fileID: 4800000, guid: eab0538d9d5746246806a9611c04ac4d, type: 3}
m_Shader: {fileID: 4800000, guid: 81d02e8644315b742b154842a3a2f98c, type: 3}
_TESSELLATION_DISPLACEMENT _USEHEIGHTBASEDBLENDV2_OFF _USEHEIGHTBASEDBLEND_OFF
_TESSELLATION_DISPLACEMENT _USEDENSITYMODE_OFF _USEHEIGHTBASEDBLENDV2_OFF _USEHEIGHTBASEDBLEND_OFF
_USEMAINLAYERINFLUENCE_OFF
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_CustomRenderQueue: -1

- _HeightCenter1: 0.5
- _HeightCenter2: 0
- _HeightCenter3: 0
- _HeightCenterOffset0: 0
- _HeightFactor0: 1
- _HeightFactor1: 1
- _HeightFactor2: 1
- _HeightFactor3: 1

- _HorizonFade: 1
- _InheritBaseColor1: 0
- _InheritBaseColor2: 0
- _InheritBaseColor3: 0

- _InheritBaseNormal3: 0
- _LayerCount: 2
- _LayerMaskVertexColor: 0
- _LayerTiling0: 1
- _LayerTiling1: 1
- _LayerTiling2: 1
- _LayerTiling3: 1
- _MinimumOpacity0: 1
- _MinimumOpacity1: 1
- _MinimumOpacity2: 1
- _MinimumOpacity3: 1

- _NormalScale2: 1
- _NormalScale3: 1
- _OcclusionStrength: 1
- _OpacityAsDensity0: 0
- _OpacityAsDensity1: 0
- _OpacityAsDensity2: 0
- _OpacityAsDensity3: 0

- _UVMappingPlanar2: 0
- _UVMappingPlanar3: 0
- _UVSec: 0
- _UseDensityMode: 0
- _UseMainLayerInfluence: 0
- _VertexColorMode: 0
- _ZTestMode: 8
- _ZWrite: 1
m_Colors:

102
Assets/ScriptableRenderLoop/ShaderLibrary/PerPixelDisplacement.hlsl


// This is implementation of parallax occlusion mapping (POM)
// This function require that the caller define a callback for the height sampling. "ppdParam" are transfer to the callback function (can be use to normalize coordinate, apply blend weights of layering...)
// it return the offset to apply to the uvset provide in input
// viewDirTS is view vector in texture space define by the uv
float2 ParallaxOcclusionMappingLayer(float2 uv, float lod, int numSteps, float3 viewDirTS, float maximunHeight, PerPixelHeightDisplacementParam ppdParam)
{
// Convention: 1.0 is top, 0.0 is bottom - POM is always inward, no extrusion
float stepSize = 1.0 / (float)numSteps;
// View vector is from the point to the camera, but we want to raymarch from camera to point, so reverse the sign
// The length of viewDirTS vector determines the furthest amount of displacement:
// float parallaxLimit = -length(viewDirTS.xy) / viewDirTS.z;
// float2 parallaxDir = normalize(Out.viewDirTS.xy);
// float2 parallaxMaxOffsetTS = parallaxDir * parallaxLimit;
// Above code simplify to
float2 parallaxMaxOffsetTS = (viewDirTS.xy / -viewDirTS.z) * maximunHeight;
float2 texOffsetPerStep = stepSize * parallaxMaxOffsetTS;
// Do a first step before the loop to init all value correctly
float2 texOffsetCurrent = 0;
float prevHeight = ComputePerPixelHeightDisplacement(uv + texOffsetCurrent, lod, ppdParam);
texOffsetCurrent += texOffsetPerStep;
float currHeight = ComputePerPixelHeightDisplacement(uv + texOffsetCurrent, lod, ppdParam);
float rayHeight = 1.0 - stepSize; // Start at top less one sample
// Linear search
for (int stepIndex = 0; stepIndex < numSteps; ++stepIndex)
{
// Have we found a height below our ray height ? then we have an intersection
if (currHeight > rayHeight)
break; // end the loop
prevHeight = currHeight;
rayHeight -= stepSize;
texOffsetCurrent += texOffsetPerStep;
// Sample height map which in this case is stored in the alpha channel of the normal map:
currHeight = ComputePerPixelHeightDisplacement(uv + texOffsetCurrent, lod, ppdParam);
}
// Found below and above points, now perform line interesection (ray) with piecewise linear heightfield approximation
// Refine the search by adding few extra intersection
#define POM_REFINE 1
#if POM_REFINE
float pt0 = rayHeight + stepSize;
float pt1 = rayHeight;
float delta0 = pt0 - prevHeight;
float delta1 = pt1 - currHeight;
float2 offset = float2(0.0, 0.0);
float threshold = 1.0;
for (int i = 0; i < 5; ++i)
{
float t = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);
offset = (1 - t) * texOffsetPerStep * numSteps;
currHeight = ComputePerPixelHeightDisplacement(uv + texOffsetCurrent, lod, ppdParam);
threshold = t - currHeight;
if (abs(threshold) <= 0.01)
break;
if (threshold < 0.0)
{
delta1 = threshold;
pt1 = t;
}
else
{
delta0 = threshold;
pt0 = t;
}
}
#else
//float pt0 = rayHeight + stepSize;
//float pt1 = rayHeight;
//float delta0 = pt0 - prevHeight;
//float delta1 = pt1 - currHeight;
//float t = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);
//float2 offset = (1 - t) * texOffsetPerStep * numSteps;
// A bit more optimize
float delta0 = currHeight - rayHeight;
float delta1 = (rayHeight + stepSize) - prevHeight;
float ratio = delta0 / (delta0 + delta1);
float2 offset = texOffsetCurrent - ratio * texOffsetPerStep;
#endif
// TODO: expose LOD fading
//float lodThreshold = 0.0;
//offset *= (1.0 - saturate(lod - lodThreshold));
return offset;
}

9
Assets/ScriptableRenderLoop/ShaderLibrary/PerPixelDisplacement.hlsl.meta


fileFormatVersion: 2
guid: 0a40799d368cbbd4982d2f423cdd8595
timeCreated: 1486045136
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存