浏览代码

HDRenderPipeline: Push another no working draft

/Branch_Batching2
Sebastien Lagarde 8 年前
当前提交
0e8d4904
共有 7 个文件被更改,包括 294 次插入165 次删除
  1. 361
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitData.hlsl
  2. 2
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl
  3. 9
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitTessellation.hlsl
  4. 24
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/SampleLayer.hlsl
  5. 22
      Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/TessellationShare.hlsl
  6. 15
      Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl
  7. 26
      Assets/ScriptableRenderLoop/ShaderLibrary/PerPixelDisplacement.hlsl

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


#endif
// triplanar weight
float3 weights;
float3 triplanarWeights;
};
#ifndef LAYERED_LIT_SHADER

#ifdef _MAPPING_TRIPLANAR
// one weight for each direction XYZ - Use vertex normal for triplanar
layerTexCoord.weights = ComputeTriplanarWeights(normalWS);
layerTexCoord.triplanarWeights = ComputeTriplanarWeights(normalWS);
#endif
bool isTriplanar = false;

#if defined(_LAYER_MAPPING_TRIPLANAR_0) || defined(_LAYER_MAPPING_TRIPLANAR_1) || defined(_LAYER_MAPPING_TRIPLANAR_2) || defined(_LAYER_MAPPING_TRIPLANAR_3)
// one weight for each direction XYZ - Use vertex normal for triplanar
layerTexCoord.weights = ComputeTriplanarWeights(normalWS);
layerTexCoord.triplanarWeights = ComputeTriplanarWeights(normalWS);
#endif
bool isTriplanar = false;

positionWS, normalWS, isTriplanar, layerTexCoord, _LayerTiling3);
}
// declare the sampler for the heigthmap
// Declare the sampler for the heigthmap - Take the sampler of the first valid Heightmap
#if defined(_HEIGHTMAP0)
#define sampler_HeightMap0 sampler_ShareHeightMap
#elif defined(_HEIGHTMAP1)

#define sampler_HeightMap3 sampler_ShareHeightMap
#endif
// This function is just syntaxic sugar to nullify height not used based on option and layer
// This function is just syntaxic sugar to nullify height not used based on heightmap avaibility and layer
void SetEnabledHeightByLayer(inout float height0, inout float height1, inout float height2, inout float height3)
{
#ifndef _HEIGHTMAP0

#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;
#if _LAYER_COUNT > 2
masks[2] = inputMasks.g;
#else
masks[2] = 0.0;
#endif
#if _LAYER_COUNT > 3
masks[3] = inputMasks.b;
#else
masks[3] = 0.0;
#endif
// 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 GetBlendMask(LayerTexCoord layerTexCoord, float4 vertexColor, bool useLodSampling = false, float lod = 0)
{
// Caution:
// Blend mask are Main Layer A - Layer 1 R - Layer 2 G - Layer 3 B
// Value for main layer is not use for blending itself but for alternate weighting like density.
// Settings this specific Main layer blend mask in alpha allow to be transparent in case we don't use it and 1 is provide by default.
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;
#elif defined(_LAYER_MASK_VERTEX_COLOR_ADD)
blendMasks = saturate(blendMasks + vertexColor * 2.0 - 1.0);
#endif
return blendMasks;
}
// Return the maximun amplitude use by all enabled heightmap
// use for tessellation culling and per pixel displacement
float GetMaxDisplacement()

#endif
}
// Return the minimun uv size for all layers including triplanar
float2 GetMinUvSize(LayerTexCoord layerTexCoord)
{
float2 minUvSize = float2(FLT_MAX, FLT_MAX);
#if defined(_HEIGHTMAP0)
if (layerTexCoord.base0.isTriplanar)
{
minUvSize = min(layerTexCoord.base0.uvYZ * _HeightMap0_TexelSize.zw);
minUvSize = min(layerTexCoord.base0.uvZX * _HeightMap0_TexelSize.zw);
minUvSize = min(layerTexCoord.base0.uvXY * _HeightMap0_TexelSize.zw);
}
else
{
minUvSize = min(layerTexCoord.base0.uv * _HeightMap0_TexelSize.zw);
}
#endif
#if defined(_HEIGHTMAP1)
if (layerTexCoord.base1.isTriplanar)
{
minUvSize = min(layerTexCoord.base1.uvYZ * _HeightMap1_TexelSize.zw);
minUvSize = min(layerTexCoord.base1.uvZX * _HeightMap1_TexelSize.zw);
minUvSize = min(layerTexCoord.base1.uvXY * _HeightMap1_TexelSize.zw);
}
else
{
minUvSize = min(layerTexCoord.base1.uv * _HeightMap1_TexelSize.zw);
}
#endif
#if _LAYER_COUNT >= 3
#if defined(_HEIGHTMAP2)
if (layerTexCoord.base2.isTriplanar)
{
minUvSize = min(layerTexCoord.base2.uvYZ * _HeightMap2_TexelSize.zw);
minUvSize = min(layerTexCoord.base2.uvZX * _HeightMap2_TexelSize.zw);
minUvSize = min(layerTexCoord.base2.uvXY * _HeightMap2_TexelSize.zw);
}
else
{
minUvSize = min(layerTexCoord.base2.uv * _HeightMap2_TexelSize.zw);
}
#endif
#endif
#if _LAYER_COUNT >= 4
#if defined(_HEIGHTMAP3)
if (layerTexCoord.base3.isTriplanar)
{
minUvSize = min(layerTexCoord.base3.uvYZ * _HeightMap3_TexelSize.zw);
minUvSize = min(layerTexCoord.base3.uvZX * _HeightMap3_TexelSize.zw);
minUvSize = min(layerTexCoord.base3.uvXY * _HeightMap3_TexelSize.zw);
}
else
{
minUvSize = min(layerTexCoord.base3.uv * _HeightMap3_TexelSize.zw);
}
#endif
#endif
return minUvSize;
}
float4 weights;
float weights[_MAX_LAYER];
float2 uv[_MAX_LAYER];
float ComputePerPixelHeightDisplacement(float2 uv, float lod, PerPixelHeightDisplacementParam param)
float ComputePerPixelHeightDisplacement(float2 texOffsetCurrent, 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;
// Note: No multiply by amplitude here, this is bake into the weights and apply in BlendLayeredScalar
// The amplitude is normalize to be able to work with POM algorithm
// Tiling is automatically handled correctly here as we use 4 differents uv even if they come from the same UVSet (they include the tiling)
float height0 = SAMPLE_TEXTURE2D_LOD(_HeightMap0, sampler_ShareHeightMap, param.uv[0] + texOffsetCurrent, lod).r)
float height1 = SAMPLE_TEXTURE2D_LOD(_HeightMap1, sampler_ShareHeightMap, param.uv[1] + texOffsetCurrent, lod).r);
float height2 = SAMPLE_TEXTURE2D_LOD(_HeightMap2, sampler_ShareHeightMap, param.uv[2] + texOffsetCurrent, lod).r);
float height3 = SAMPLE_TEXTURE2D_LOD(_HeightMap3, sampler_ShareHeightMap, param.uv[3] + texOffsetCurrent, lod).r);
SetEnabledHeightByLayer(height0, height1, height2, height3); // Not needed as already put in weights but paranoid mode
return BlendLayeredScalar(height0, height1, height2, height3, param.weights) + height0 * param.mainHeightInfluence;
}
#include "PerPixelDisplacement.hlsl"

// - 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
// - Blend Mask use same mapping as main layer (UVO, Planar, Triplanar)
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;
bool ppdEnable = false;
#if defined(_HEIGHTMAP0)
isPPDEnable = true;
PPDlayerUV.uv = layerTexCoord.base0;
#if defined(_HEIGHTMAP0) || defined(_HEIGHTMAP1) || (_LAYER_COUNT >= 3 && defined(_HEIGHTMAP2)) || (_LAYER_COUNT >= 4 && defined(_HEIGHTMAP3))
ppdEnable = true;
#if defined(_HEIGHTMAP1)
isPPDEnable = true;
PPDlayerUV.uv = layerTexCoord.base1;
#if _LAYER_COUNT >= 3
#if defined(_HEIGHTMAP2)
isPPDEnable = true;
PPDlayerUV.uv = layerTexCoord.base2;
#endif
#endif
#if _LAYER_COUNT >= 4
#if defined(_HEIGHTMAP3)
isPPDEnable = true;
PPDlayerUV.uv = layerTexCoord.base3;
#endif
#endif
#endif
if (isPPDEnable)
if (ppdEnable)
// 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();
// Even if we use same mapping we can have different tiling. For per pixel displacement we will perform the ray marching with already tiled uv
float maxHeight = GetMaxDisplacement();
// Compute lod as we will sample inside a loop(so can't use regular sampling)
// Note: It appear that CALCULATE_TEXTURE2D_LOD only return interger lod. We want to use float lod to have smoother transition and fading, so do our own calculation.
// Approximation of lod to used. Be conservative here, we will take the highest mip of all layers.
// Remember, we assume that we used the same mapping for all layer, so only size matter.
float2 minUvSize = GetMinUvSize(layerTexCoord);
float lod = ComputeTextureLOD(minUvSize);
int numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, viewDirTS.z);
// Calculate blend weights
float4 blendMasks = GetBlendMask(layerTexCoord, input.color);
// 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();
float weights[_MAX_LAYER];
ComputeMaskWeights(blendMasks, weights);
// For PPP
// Be sure we are not considering weight here were there is no heightmap
SetEnabledHeightByLayer(weights[0], weights[1], weights[2], weights[3]);
// 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);
PerPixelHeightDisplacementParam ppdParam;
#if defined(_MAIN_LAYER_INFLUENCE_MODE)
// For per pixel displacement we need to have normalized height scale to calculate the interesection (required by the algorithm we use)
// mean that we will normalize by the highest amplitude.
// We store this normalization factor with the weights as it will be multiply by the readed height.
ppdParam.weights[0] = weights[0] * (_HeightAmplitude0) / maxHeight;
ppdParam.weights[1] = weights[1] * (_HeightAmplitude1 + _HeightAmplitude0 * _InheritBaseHeight1) / maxHeight;
ppdParam.weights[2] = weights[2] * (_HeightAmplitude2 + _HeightAmplitude0 * _InheritBaseHeight2) / maxHeight;
ppdParam.weights[3] = weights[3] * (_HeightAmplitude3 + _HeightAmplitude0 * _InheritBaseHeight3) / maxHeight;
#if defined(_HEIGHTMAP0)
layerTexCoord.base0.uv += offset;
if (layerTexCoord.triplanar)
// Think that inheritbasedheight will be 0 if height0 is fully visible in weights. So there is no double contribution of height0
float mainHeightInfluence = BlendLayeredScalar(0.0, _InheritBaseHeight1, _InheritBaseHeight2, _InheritBaseHeight3, weights);
ppdParam.mainHeightInfluence = mainHeightInfluence;
#else
[unroll]
for (int i = 0; i < _MAX_LAYER; ++i)
layerTexCoord.base0.uvYZ;
layerTexCoord.base0.uvZX;
layerTexCoord.base0.uvXY;
ppdParam.weights[i] = weights[i];
ppdParam.mainHeightInfluence = 0.0;
layerTexCoord.base3
#if defined(_HEIGHTMAP1)
layerTexCoord.base1.uv += offset;
#endif
// We need to calculate the texture space direction. It depends on the mapping.
if (ppdlayerUV.triplanar)
{
// TODO: implement. Require 3 call to POM + dedicated viewDirTS based on triplanar convention
// apply the 3 offset on all layers
/*
#if _LAYER_COUNT >= 3
#if defined(_HEIGHTMAP2)
layerTexCoord.base2.uv += offset;
#endif
#endif
ppdParam.uv[0] = layerTexCoord.base0.uvYZ;
ppdParam.uv[1] = layerTexCoord.base1.uvYZ;
ppdParam.uv[2] = layerTexCoord.base2.uvYZ;
ppdParam.uv[3] = layerTexCoord.base3.uvYZ;
#if _LAYER_COUNT >= 4
#if defined(_HEIGHTMAP3)
layerTexCoord.base3.uv += offset;
#endif
#endif
float3 viewDirTS = ;
int numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, abs(viewDirTS.z));
ParallaxOcclusionMapping(float2 uv, lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam);
}
}
// Apply to all uvYZ
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;
// Repeat for uvZX
// 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;
// Repeat for uvXY
[unroll]
for (int i = _LAYER_COUNT - 1; i >= 0; --i)
{
outWeights[i] = min(masks[i], (1.0 - weightsSum));
weightsSum = saturate(weightsSum + masks[i]);
}
}
// Apply to all layer that used triplanar
*/
}
else if (ppdlayerUV.planar) // Caution: this if is dynamic as planar is not a variant, should we do one ?
{
ppdParam.uv[0] = layerTexCoord.base0.uv;
ppdParam.uv[1] = layerTexCoord.base1.uv;
ppdParam.uv[2] = layerTexCoord.base2.uv;
ppdParam.uv[3] = layerTexCoord.base3.uv;
// Caution: Blend mask are Layer 1 R - Layer 2 G - Layer 3 B - Main Layer A
float4 GetBlendMask(LayerTexCoord layerTexCoord, float4 vertexColor, bool useLodSampling = false, float lod = 0)
{
// Caution:
// Blend mask are Main Layer A - Layer 1 R - Layer 2 G - Layer 3 B
// Value for Mani layer is not use for blending itself but for alternate weighting like density.
// Settings this specific Main layer blend mask in alpha allow to be transparent in case we don't use it and 1 is provide by default.
float4 blendMasks = useLodSampling ? SAMPLE_LAYER_TEXTURE2D_LOD(_LayerMaskMap, sampler_LayerMaskMap, layerTexCoord.base0, lod) : SAMPLE_LAYER_TEXTURE2D(_LayerMaskMap, sampler_LayerMaskMap, layerTexCoord.base0);
// For planar the view vector is the world view vector (unless we want to support object triplanar ? and in this case used TransformWorldToObject)
// TODO: do we support object triplanar ? See ComputeLayerTexCoord
float3 viewDirTS = V;
int numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, viewDirTS.z);
float2 offset = ParallaxOcclusionMapping(float2 uv, lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam);
// Apply offset to all UVSet0
// _UVMappingPlanar0 will be 1.0 is UVSet0 is used;
layerTexCoord.base0.uv += _UVMappingPlanar0 * offset;
layerTexCoord.details0.uv += _UVMappingPlanar0 * offset;
layerTexCoord.base1.uv += _UVMappingPlanar1 * offset;
layerTexCoord.details1.uv += _UVMappingPlanar1 * offset;
layerTexCoord.base2.uv += _UVMappingPlanar2 * offset;
layerTexCoord.details2.uv += _UVMappingPlanar2 * offset;
layerTexCoord.base3.uv += _UVMappingPlanar3 * offset;
layerTexCoord.details3.uv += _UVMappingPlanar3 * offset;
}
else // UVSet0
{
ppdParam.uv[0] = layerTexCoord.base0.uv;
ppdParam.uv[1] = layerTexCoord.base1.uv;
ppdParam.uv[2] = layerTexCoord.base2.uv;
ppdParam.uv[3] = layerTexCoord.base3.uv;
#if defined(_LAYER_MASK_VERTEX_COLOR_MUL)
blendMasks *= vertexColor;
#elif defined(_LAYER_MASK_VERTEX_COLOR_ADD)
blendMasks = saturate(blendMasks + vertexColor * 2.0 - 1.0);
#endif
float3 viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
int numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, viewDirTS.z);
float2 offset = ParallaxOcclusionMapping(float2 uv, lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam);
return blendMasks;
// Apply offset to all UVSet0
// _UVMappingMask0.x will be 1.0 is UVSet0 is used;
layerTexCoord.base0.uv += _UVMappingMask0.x * offset;
layerTexCoord.details0.uv += _UVDetailsMappingMask0.x * offset;
layerTexCoord.base1.uv += _UVMappingMask1.x * offset;
layerTexCoord.details1.uv += _UVDetailsMappingMask1.x * offset;
layerTexCoord.base2.uv += _UVMappingMask2.x * offset;
layerTexCoord.details2.uv += _UVDetailsMappingMask2.x * offset;
layerTexCoord.base3.uv += _UVMappingMask3.x * offset;
layerTexCoord.details3.uv += _UVDetailsMappingMask3.x * offset;
}
}
}
// Calculate displacement for per vertex displacement mapping

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


// Note that if base is planar/triplanar, detail map is too
// planar
// TODO: Do we want to manage local or world triplanar/planar
// TODO: Do we want to manage local or world triplanar/planar ? In this case update ApplyPerPixelDisplacement() too
//float3 position = localTriplanar ? TransformWorldToObject(positionWS) : positionWS;
float3 position = positionWS;
position *= ADD_IDX(_TexWorldScale);

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


return CalcTriEdgeTessFactors(tessFactor);
}
float3 GetDisplacement(VaryingsMeshToDS input)
// tessellationFactors
// x - 1->2 edge
// y - 2->0 edge
// z - 0->1 edge
// w - inside tessellation factor
float3 GetTessellationDisplacement(VaryingsMeshToDS input, float4 tessellationFactors, float3 baryCoords, VaryingsMeshToDS input0, VaryingsMeshToDS input1, VaryingsMeshToDS input2)
{
// This call will work for both LayeredLit and Lit shader
LayerTexCoord layerTexCoord;

input.normalWS,
layerTexCoord);
// TODO: Move to camera relative and change distance to length
// http://www.sebastiansylvan.com/post/the-problem-with-tessellation-in-directx-11/
float lod = 0.0;
float4 vertexColor = float4(0.0, 0.0, 0.0, 0.0);
#ifdef VARYINGS_DS_NEED_COLOR

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


#undef SAMPLE_TEXTURE_FUNC
// Macro to improve readibility of surface data
#define SAMPLE_LAYER_TEXTURE2D(textureName, samplerName, coord) SampleLayer(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, 0.0) // Last 0.0 is unused
#define SAMPLE_LAYER_TEXTURE2D_LOD(textureName, samplerName, coord, lod) SampleLayerLod(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, lod)
#define SAMPLE_LAYER_TEXTURE2D_BIAS(textureName, samplerName, coord, bias) SampleLayerBias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, bias)
#define SAMPLE_LAYER_TEXTURE2D(textureName, samplerName, coord) SampleLayer(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.triplanarWeights, 0.0) // Last 0.0 is unused
#define SAMPLE_LAYER_TEXTURE2D_LOD(textureName, samplerName, coord, lod) SampleLayerLod(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.triplanarWeights, lod)
#define SAMPLE_LAYER_TEXTURE2D_BIAS(textureName, samplerName, coord, bias) SampleLayerBias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.triplanarWeights, bias)
#define SAMPLE_LAYER_NORMALMAP(textureName, samplerName, coord, scale) SampleLayerNormal(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, 0.0)
#define SAMPLE_LAYER_NORMALMAP_LOD(textureName, samplerName, coord, scale, lod) SampleLayerNormalLod(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, lod)
#define SAMPLE_LAYER_NORMALMAP_BIAS(textureName, samplerName, coord, scale, bias) SampleLayerNormalBias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, bias)
#define SAMPLE_LAYER_NORMALMAP(textureName, samplerName, coord, scale) SampleLayerNormal(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.triplanarWeights, scale, 0.0)
#define SAMPLE_LAYER_NORMALMAP_LOD(textureName, samplerName, coord, scale, lod) SampleLayerNormalLod(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.triplanarWeights, scale, lod)
#define SAMPLE_LAYER_NORMALMAP_BIAS(textureName, samplerName, coord, scale, bias) SampleLayerNormalBias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.triplanarWeights, scale, bias)
#define SAMPLE_LAYER_NORMALMAP_AG(textureName, samplerName, coord, scale) SampleLayerNormalAG(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, 0.0)
#define SAMPLE_LAYER_NORMALMAP_AG_LOD(textureName, samplerName, coord, scale, lod) SampleLayerNormalAGLod(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, lod)
#define SAMPLE_LAYER_NORMALMAP_AG_BIAS(textureName, samplerName, coord, scale, bias) SampleLayerNormalAGBias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, bias)
#define SAMPLE_LAYER_NORMALMAP_AG(textureName, samplerName, coord, scale) SampleLayerNormalAG(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.triplanarWeights, scale, 0.0)
#define SAMPLE_LAYER_NORMALMAP_AG_LOD(textureName, samplerName, coord, scale, lod) SampleLayerNormalAGLod(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.triplanarWeights, scale, lod)
#define SAMPLE_LAYER_NORMALMAP_AG_BIAS(textureName, samplerName, coord, scale, bias) SampleLayerNormalAGBias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.triplanarWeights, scale, bias)
#define SAMPLE_LAYER_NORMALMAP_RGB(textureName, samplerName, coord, scale) SampleLayerNormalRGB(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, 0.0)
#define SAMPLE_LAYER_NORMALMAP_RGB_LOD(textureName, samplerName, coord, scale, lod) SampleLayerNormalRGBLod(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, lod)
#define SAMPLE_LAYER_NORMALMAP_RGB_BIAS(textureName, samplerName, coord, scale, bias) SampleLayerNormalRGBBias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale, bias)
#define SAMPLE_LAYER_NORMALMAP_RGB(textureName, samplerName, coord, scale) SampleLayerNormalRGB(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.triplanarWeights, scale, 0.0)
#define SAMPLE_LAYER_NORMALMAP_RGB_LOD(textureName, samplerName, coord, scale, lod) SampleLayerNormalRGBLod(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.triplanarWeights, scale, lod)
#define SAMPLE_LAYER_NORMALMAP_RGB_BIAS(textureName, samplerName, coord, scale, bias) SampleLayerNormalRGBBias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.triplanarWeights, scale, bias)

22
Assets/ScriptableRenderLoop/HDRenderPipeline/ShaderPass/TessellationShare.hlsl


// AMD recommand this value for GCN http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/05/GCNPerformanceTweets.pdf
#define MAX_TESSELLATION_FACTORS 15
struct TessellationFactors
{
float edge[3] : SV_TessFactor;

float3 n1 = varying1.vmesh.normalWS;
float3 n2 = varying2.vmesh.normalWS;
// ref: http://reedbeta.com/blog/tess-quick-ref/
// x - 1->2 edge
// y - 2->0 edge
// z - 0->1 edge
// w - inside tessellation factor
output.edge[0] = tf.x;
output.edge[1] = tf.y;
output.edge[2] = tf.z;
output.inside = tf.w;
output.edge[0] = min(tf.x, MAX_TESSELLATION_FACTORS);
output.edge[1] = min(tf.y, MAX_TESSELLATION_FACTORS);
output.edge[2] = min(tf.z, MAX_TESSELLATION_FACTORS);
output.inside = min(tf.w, MAX_TESSELLATION_FACTORS);
[maxtessfactor(15.0)] // AMD recommand this value for GCN http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/05/GCNPerformanceTweets.pdf
PackedVaryingsToDS
[maxtessfactor(MAX_TESSELLATION_FACTORS)]
[domain("tri")]
[partitioning("fractional_odd")]
[outputtopology("triangle_cw")]

#endif
#if defined(_TESSELLATION_DISPLACEMENT) || defined(_TESSELLATION_DISPLACEMENT_PHONG)
varying.vmesh.positionWS += GetDisplacement(varying.vmesh);
varying.vmesh.positionWS += GetTessellationDisplacement(varying.vmesh);
#endif
return VertTesselation(varying);

15
Assets/ScriptableRenderLoop/ShaderLibrary/Common.hlsl


// Texture utilities
// ----------------------------------------------------------------------------
float ComputeTextureLOD(float2 uv)
{
float2 ddx_ = ddx(uv);
float2 ddy_ = ddy(uv);
float d = max(dot(ddx_, ddx_), dot(ddy_, ddy_));
return max(0.5 * log2(d), 0.0);
}
// texelSize is Unity XXX_TexelSize feature parameters
// x contains 1.0/width, y contains 1.0 / height, z contains width, w contains height
float ComputeTextureLOD(float2 uv, float4 texelSize)

float2 ddx_ = ddx(uv);
float2 ddy_ = ddy(uv);
float d = max(dot(ddx_, ddx_), dot(ddy_, ddy_));
return max(0.5 * log2(d), 0.0);
return ComputeTextureLOD(uv);
}
// ----------------------------------------------------------------------------

26
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)
// This function require that the caller define a callback for the height sampling name ComputePerPixelHeightDisplacement
// A PerPixelHeightDisplacementParam is used to provide all data necessary to calculate the heights to ComputePerPixelHeightDisplacement it doesn't need to be
// visible by the POM algorithm.
// This function is compatible with tiled uv.
// it return the offset to apply to the UVSet provide in PerPixelHeightDisplacementParam
// viewDirTS is view vector in texture space matching the UVSet
float2 ParallaxOcclusionMapping(float lod, float lodThreshold, int numSteps, float3 viewDirTS, float maxHeight, PerPixelHeightDisplacementParam ppdParam)
{
// Convention: 1.0 is top, 0.0 is bottom - POM is always inward, no extrusion
float stepSize = 1.0 / (float)numSteps;

// float2 parallaxDir = normalize(Out.viewDirTS.xy);
// float2 parallaxMaxOffsetTS = parallaxDir * parallaxLimit;
// Above code simplify to
float2 parallaxMaxOffsetTS = (viewDirTS.xy / -viewDirTS.z) * maximunHeight;
float2 parallaxMaxOffsetTS = (viewDirTS.xy / -viewDirTS.z) * maxHeight;
float prevHeight = ComputePerPixelHeightDisplacement(uv + texOffsetCurrent, lod, ppdParam);
float prevHeight = ComputePerPixelHeightDisplacement(texOffsetCurrent, lod, ppdParam);
float currHeight = ComputePerPixelHeightDisplacement(uv + texOffsetCurrent, lod, ppdParam);
float currHeight = ComputePerPixelHeightDisplacement(texOffsetCurrent, lod, ppdParam);
float rayHeight = 1.0 - stepSize; // Start at top less one sample
// Linear search

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);
currHeight = ComputePerPixelHeightDisplacement(texOffsetCurrent, lod, ppdParam);
}
// Found below and above points, now perform line interesection (ray) with piecewise linear heightfield approximation

float t = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);
offset = (1 - t) * texOffsetPerStep * numSteps;
currHeight = ComputePerPixelHeightDisplacement(uv + texOffsetCurrent, lod, ppdParam);
currHeight = ComputePerPixelHeightDisplacement(texOffsetCurrent, lod, ppdParam);
threshold = t - currHeight;

#endif
// TODO: expose LOD fading
//float lodThreshold = 0.0;
//offset *= (1.0 - saturate(lod - lodThreshold));
// Fade the effect with lod (allow to avoid pop when switching to a discrete LOD mesh)
offset *= (1.0 - saturate(lod - lodThreshold));
return offset;
}
正在加载...
取消
保存