浏览代码

HDRenderPipeline: Another pass on adding surface gradient code

- miss the init of vT1/Vb1 etc...
/Branch_Batching2
Sebastien Lagarde 8 年前
当前提交
01072951
共有 10 个文件被更改,包括 253 次插入92 次删除
  1. 15
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  2. 31
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl
  3. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/MaterialUtilities.hlsl
  4. 39
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/SampleLayer.hlsl
  5. 88
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/SampleLayerInternal.hlsl
  6. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/CommonMaterial.hlsl
  7. 55
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/SampleLayerNormalInternal.hlsl
  8. 9
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/SampleLayerNormalInternal.hlsl.meta
  9. 88
      Assets/ScriptableRenderPipeline/ShaderLibrary/NormalSurfaceGradient.hlsl
  10. 9
      Assets/ScriptableRenderPipeline/ShaderLibrary/NormalSurfaceGradient.hlsl.meta

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


LayerUV blendMask;
#endif
// triplanar weight
float3 triplanarWeights;
CommonLayerUV common;
};
// To flip in case of double sided, we must flip the vertex normal and this will apply to the whole process either in surface gradient or not.

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

ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);
#if defined(_LAYER_MAPPING_TRIPLANAR_BLENDMASK) || defined(_LAYER_MAPPING_TRIPLANAR0) || defined(_LAYER_MAPPING_TRIPLANAR1) || defined(_LAYER_MAPPING_TRIPLANAR2) || defined(_LAYER_MAPPING_TRIPLANAR3)
// one weight for each direction XYZ - Use vertex normal for triplanar
layerTexCoord.triplanarWeights = ComputeTriplanarWeights(normalWS);
#ifdef SURFACE_GRADIENT
layerTexCoord.common.vertexNormalWS = normalWS;
#endif
layerTexCoord.common.triplanarWeights = ComputeTriplanarWeights(normalWS);
#endif
bool isTriplanar = false;

31
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl


ADD_IDX(layerTexCoord.details).uvXZ = TRANSFORM_TEX(uvXZ, ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvXY = TRANSFORM_TEX(uvXY, ADD_IDX(_DetailMap));
ADD_IDX(layerTexCoord.details).uvZY = TRANSFORM_TEX(uvZY, ADD_IDX(_DetailMap));
#ifdef SURFACE_GRADIENT
// TODO:... how to pass argument, how to deal with vertex level call (like tessellation)
ADD_IDX(layerTexCoord.base).vT = ADD_IDX(_UVMappingMask).x * worlToTangent[0] +
ADD_IDX(_UVMappingMask).y * vT1 +
ADD_IDX(_UVMappingMask).z * vT2 +
ADD_IDX(_UVMappingMask).w * vT3;
ADD_IDX(layerTexCoord.base).vB = ADD_IDX(_UVMappingMask).x * worlToTangent[1] +
ADD_IDX(_UVMappingMask).y * vB1 +
ADD_IDX(_UVMappingMask).z * vB2 +
ADD_IDX(_UVMappingMask).w * vB3;
ADD_IDX(layerTexCoord.details).vT = ADD_IDX(_UVMappingMask).x * worlToTangent[0] +
ADD_IDX(_UVMappingMask).y * vT1 +
ADD_IDX(_UVMappingMask).z * vT2 +
ADD_IDX(_UVMappingMask).w * vT3;
ADD_IDX(layerTexCoord.details).vB = ADD_IDX(_UVMappingMask).x * worlToTangent[1] +
ADD_IDX(_UVMappingMask).y * vB1 +
ADD_IDX(_UVMappingMask).z * vB2 +
ADD_IDX(_UVMappingMask).w * vB3;
#endif
}
float3 ADD_IDX(GetNormalTS)(FragInputs input, LayerTexCoord layerTexCoord, float3 detailNormalTS, float detailMask, bool useBias, float bias)

#ifdef SURFACE_GRADIENT
// /We need to decompress the normal ourselve here as UnpackNormalRGB will return a surface gradient
float3 normalOS = SAMPLE_TEXTURE2D_BIAS(layerTex, SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv, bias).xyz * 2.0 - 1.0;
// normalize(normalOS) // TO CHECK: surfgradFromPerturbedNormal doesn't require normalOS to be normalize, to check
normalTS = surfgradFromPerturbedNormal(input.worldToTangent[2], normalOS);
// normalize(normalOS) // TO CHECK: SurfaceGradientFromPerturbedNormal doesn't require normalOS to be normalize, to check
normalTS = SurfaceGradientFromPerturbedNormal(input.worldToTangent[2], normalOS);
normalTS *= ADD_IDX(_NormalScale);
#else
float3 normalOS = UnpackNormalRGB(SAMPLE_TEXTURE2D_BIAS(layerTex, SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv, bias), 1.0);

#ifdef SURFACE_GRADIENT
// /We need to decompress the normal ourselve here as UnpackNormalRGB will return a surface gradient
float3 normalOS = SAMPLE_TEXTURE2D(layerTex, SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv).xyz * 2.0 - 1.0;
// normalize(normalOS) // TO CHECK: surfgradFromPerturbedNormal doesn't require normalOS to be normalize, to check
normalTS = surfgradFromPerturbedNormal(input.worldToTangent[2], normalOS);
// normalize(normalOS) // TO CHECK: SurfaceGradientFromPerturbedNormal doesn't require normalOS to be normalize, to check
normalTS = SurfaceGradientFromPerturbedNormal(input.worldToTangent[2], normalOS);
normalTS *= ADD_IDX(_NormalScale);
#else
float3 normalOS = UnpackNormalRGB(SAMPLE_TEXTURE2D(layerTex, SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv), 1.0);

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/MaterialUtilities.hlsl


void GetNormalAndTangentWS(FragInputs input, float3 V, float3 normalTS, inout float3 normalWS, inout float3 tangentWS, bool wantNegativeNormal = false)
{
#ifdef SURFACE_GRADIENT
normalWS = resolveNormalFromSurfaceGradient(input.worldToTangent[2], normalTS);
normalWS = SurfaceGradientResolveNormal(input.worldToTangent[2], normalTS);
#else
normalWS = TransformTangentToWorld(normalTS, input.worldToTangent);
#endif

39
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/SampleLayer.hlsl


float2 uvZY;
float2 uvXZ;
float2 uvXY;
#ifdef SURFACE_GRADIENT
// tangent basis to use for this UV set
float3 vT, vB;
// vertex normal for planar/triplanar
float3 vertexNormalWS; // TODO: Should be part of LayerCoord but require to
#endif
};
struct CommonLayerUV
{
#ifdef SURFACE_GRADIENT
float3 vertexNormalWS;
#endif
float3 triplanarWeights;
};
// Multiple includes of the file to handle all variations of textures sampling for regular, lod and bias

#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.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_TEXTURE2D(textureName, samplerName, coord) SampleLayer(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.common, 0.0) // Last 0.0 is unused
#define SAMPLE_LAYER_TEXTURE2D_LOD(textureName, samplerName, coord, lod) SampleLayerLod(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.common, lod)
#define SAMPLE_LAYER_TEXTURE2D_BIAS(textureName, samplerName, coord, bias) SampleLayerBias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.common, 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(textureName, samplerName, coord, scale) SampleLayerNormal(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.common, scale, 0.0)
#define SAMPLE_LAYER_NORMALMAP_LOD(textureName, samplerName, coord, scale, lod) SampleLayerNormalLod(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.common, scale, lod)
#define SAMPLE_LAYER_NORMALMAP_BIAS(textureName, samplerName, coord, scale, bias) SampleLayerNormalBias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.common, 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_AG(textureName, samplerName, coord, scale) SampleLayerNormalAG(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.common, scale, 0.0)
#define SAMPLE_LAYER_NORMALMAP_AG_LOD(textureName, samplerName, coord, scale, lod) SampleLayerNormalAGLod(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.common, scale, lod)
#define SAMPLE_LAYER_NORMALMAP_AG_BIAS(textureName, samplerName, coord, scale, bias) SampleLayerNormalAGBias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.common, 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)
#define SAMPLE_LAYER_NORMALMAP_RGB(textureName, samplerName, coord, scale) SampleLayerNormalRGB(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.common, scale, 0.0)
#define SAMPLE_LAYER_NORMALMAP_RGB_LOD(textureName, samplerName, coord, scale, lod) SampleLayerNormalRGBLod(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.common, scale, lod)
#define SAMPLE_LAYER_NORMALMAP_RGB_BIAS(textureName, samplerName, coord, scale, bias) SampleLayerNormalRGBBias(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.common, scale, bias)

88
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/SampleLayerInternal.hlsl


// Also we use multiple inclusion to handle the various variation for lod and bias
// param can be unused, lod or bias
float4 ADD_FUNC_SUFFIX(SampleLayer)(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 triplanarWeights, float param)
float4 ADD_FUNC_SUFFIX(SampleLayer)(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, CommonLayerUV common, float param)
float3 triplanarWeights = common.triplanarWeights;
float4 val = float4(0.0, 0.0, 0.0, 0.0);
if (triplanarWeights.x > 0.0)

}
}
// Nested multiple includes of the file to handle all variations of normal map (AG, RG or RGB)
float3 ADD_FUNC_SUFFIX(SampleLayerNormal)(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 triplanarWeights, float scale, float param)
{
if (layerUV.isTriplanar)
{
float3 val = float3(0.0, 0.0, 0.0);
if (triplanarWeights.x > 0.0)
val += triplanarWeights.x * UnpackNormalAG(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvZY, param), scale);
if (triplanarWeights.y > 0.0)
val += triplanarWeights.y * UnpackNormalAG(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvXZ, param), scale);
if (triplanarWeights.z > 0.0)
val += triplanarWeights.z * UnpackNormalAG(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvXY, param), scale);
return normalize(val);
}
else
{
return UnpackNormalAG(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uv, param), scale);
}
}
#define ADD_NORMAL_FUNC_SUFFIX(Name) Name
#define UNPACK_NORMAL_FUNC UnpackNormalAG
#define UNPACK_DERIVATIVE_FUNC UnpackDerivativeNormalAG
#include "SampleLayerNormalInternal.hlsl"
#undef ADD_NORMAL_FUNC_SUFFIX
#undef UNPACK_NORMAL_FUNC
#undef UNPACK_DERIVATIVE_FUNC
float3 ADD_FUNC_SUFFIX(SampleLayerNormalAG)(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 triplanarWeights, float scale, float param)
{
if (layerUV.isTriplanar)
{
float3 val = float3(0.0, 0.0, 0.0);
if (triplanarWeights.x > 0.0)
val += triplanarWeights.x * UnpackNormalAG(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvZY, param), scale);
if (triplanarWeights.y > 0.0)
val += triplanarWeights.y * UnpackNormalAG(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvXZ, param), scale);
if (triplanarWeights.z > 0.0)
val += triplanarWeights.z * UnpackNormalAG(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvXY, param), scale);
return normalize(val);
}
else
{
return UnpackNormalAG(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uv, param), scale);
}
}
// This version is for normalmap with RGB encoding only, i.e uncompress or BC7. Mainly used for object space normal.
float3 ADD_FUNC_SUFFIX(SampleLayerNormalRGB)(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 triplanarWeights, float scale, float param)
{
if (layerUV.isTriplanar)
{
float3 val = float3(0.0, 0.0, 0.0);
if (triplanarWeights.x > 0.0)
val += triplanarWeights.x * UnpackNormalRGB(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvZY, param), scale);
if (triplanarWeights.y > 0.0)
val += triplanarWeights.y * UnpackNormalRGB(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvXZ, param), scale);
if (triplanarWeights.z > 0.0)
val += triplanarWeights.z * UnpackNormalRGB(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvXY, param), scale);
#define ADD_NORMAL_FUNC_SUFFIX(Name) Name##AG
#define UNPACK_NORMAL_FUNC UnpackNormalAG
#define UNPACK_DERIVATIVE_FUNC UnpackDerivativeNormalAG
#include "SampleLayerNormalInternal.hlsl"
#undef ADD_NORMAL_FUNC_SUFFIX
#undef UNPACK_NORMAL_FUNC
#undef UNPACK_DERIVATIVE_FUNC
return normalize(val);
}
else
{
return UnpackNormalRGB(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uv, param), scale);
}
}
// This version is for normalmap with RGB encoding only, i.e uncompress or BC7.
#define ADD_NORMAL_FUNC_SUFFIX(Name) Name##RGB
#define UNPACK_NORMAL_FUNC UnpackNormalRGB
#define UNPACK_DERIVATIVE_FUNC UnpackDerivativeNormalRGB
#include "SampleLayerNormalInternal.hlsl"
#undef ADD_NORMAL_FUNC_SUFFIX
#undef UNPACK_NORMAL_FUNC
#undef UNPACK_DERIVATIVE_FUNC

9
Assets/ScriptableRenderPipeline/ShaderLibrary/CommonMaterial.hlsl


// Parallax mapping
// ----------------------------------------------------------------------------
float2 ParallaxOffset(float3 viewDirTS, float height)
{
// Parallax mapping with offset limiting to reduce weird artifcat (i.e do not divide by z), also save performance
return viewDirTS.xy * height;
}
// ref https://www.gamedev.net/topic/678043-how-to-blend-world-space-normals/#entry5287707
// assume compositing in world space
// Note: Using vtxNormal = float3(0, 0, 1) give the BlendNormalRNM formulation.

return normalize(float3(n1.xy * n2.z + n2.xy * n1.z, n1.z * n2.z));
}
// Ref: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch01.html
// Ref: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch01.html / http://www.slideshare.net/icastano/cascades-demo-secrets
float3 ComputeTriplanarWeights(float3 normal)
{
// Determine the blend weights for the 3 planar projections.

blendWeights = blendWeights * blendWeights * blendWeights; // pow(blendWeights, 3);
// Force weights to sum to 1.0 (very important!)
blendWeights = max(blendWeights, float3(0.0, 0.0, 0.0));
blendWeights /= dot(blendWeights, 1.0);

55
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/SampleLayerNormalInternal.hlsl


float3 ADD_FUNC_SUFFIX(ADD_NORMAL_FUNC_SUFFIX(SampleLayerNormal))(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, CommonLayerUV common, float scale, float param)
{
if (layerUV.isTriplanar)
{
float3 triplanarWeights = common.triplanarWeights;
#ifdef SURFACE_GRADIENT
float2 derivXplane;
float2 derivYPlane;
float2 derivZPlane;
derivXplane = derivYPlane = derivZPlane = float2(0.0, 0.0);
if (triplanarWeights.x > 0.0)
derivXplane = triplanarWeights.x * UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvZY, param), scale);
if (triplanarWeights.y > 0.0)
derivYPlane = triplanarWeights.y * UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvXZ, param), scale);
if (triplanarWeights.z > 0.0)
derivZPlane = triplanarWeights.z * UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvXY, param), scale);
// Assume derivXplane, derivYPlane and derivZPlane sampled using (z,y), (z,x) and (x,y) respectively.
// TODO: Check with morten convention! Do it follow ours ?
float3 volumeGrad = float3(derivZPlane.x + derivYPlane.y, derivZPlane.y + derivXplane.y, derivXplane.x + derivYPlane.x);
return surfgradFromVolumeGradient(layerUV.vertexNormalWS, volumeGrad);
#else
float3 val = float3(0.0, 0.0, 0.0);
if (triplanarWeights.x > 0.0)
val += triplanarWeights.x * UNPACK_NORMAL_FUNC(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvZY, param), scale);
if (triplanarWeights.y > 0.0)
val += triplanarWeights.y * UNPACK_NORMAL_FUNC(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvXZ, param), scale);
if (triplanarWeights.z > 0.0)
val += triplanarWeights.z * UNPACK_NORMAL_FUNC(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvXY, param), scale);
return normalize(val);
#endif
}
#ifdef SURFACE_GRADIENT
else if (layerUV.isPlanar)
{
float2 derivYPlane = UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uvXZ, param), scale);
// See comment above
float3 volumeGrad = float3(derivYPlane.y, 0.0, derivYPlane.x);
return surfgradFromVolumeGradient(layerUV.vertexNormalWS, volumeGrad);
}
#endif
else
{
#ifdef SURFACE_GRADIENT
float2 deriv = UNPACK_DERIVATIVE_FUNC(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uv, param), scale);
return SurfaceGradientFromTBN(deriv, layerUV.vT, layerUV.vB);
#else
return UNPACK_NORMAL_FUNC(SAMPLE_TEXTURE_FUNC(layerTex, layerSampler, layerUV.uv, param), scale);
#endif
}
}

9
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/SampleLayerNormalInternal.hlsl.meta


fileFormatVersion: 2
guid: f941b2119184e624a8ecd126735c5ed0
timeCreated: 1487475828
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

88
Assets/ScriptableRenderPipeline/ShaderLibrary/NormalSurfaceGradient.hlsl


// this produces an orthonormal basis of the tangent and bitangent WITHOUT vertex level tangent/bitangent for any UV including procedurally generated
// method released with the demo for publication of "bump mapping unparametrized surfaces on the GPU"
// http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
void SurfaceGradientGenBasisTB(float3 nrmVertexNormal, float3 sigmaX, float3 sigmaY, float flip sign, out float3 vT, out float3 vB, float2 texST)
{
float2 dSTdx = ddx_fine(texST), dSTdy = ddy_fine(texST);
float det = dot(dSTdx, float2(dSTdy.y, -dSTdy.x));
float sign_det = det < 0 ? -1 : 1;
// invC0 represents (dXds, dYds); but we don't divide by determinant (scale by sign instead)
float2 invC0 = sign_det * float2(dSTdy.y, -dSTdx.y);
vT = sigmaX * invC0.x + sigmaY * invC0.y;
if (abs(det) > 0.0)
vT = normalize(vT);
vB = (sign_det * flip_sign) * cross(nrmVertexNormal, vT);
}
// surface gradient from an on the fly TBN (deriv obtained using tspaceNormalToDerivative()) or from conventional vertex level TBN (mikktspace compliant and deriv obtained using tspaceNormalToDerivative())
float3 SurfaceGradientFromTBN(float2 deriv, float3 vT, float3 vB)
{
return deriv.x * vT + deriv.y * vB;
}
// surface gradient from an already generated "normal" such as from an object space normal map
// this allows us to mix the contribution together with a series of other contributions including tangent space normals
// v does not need to be unit length as long as it establishes the direction.
float3 SurfaceGradientFromPerturbedNormal(float3 nrmVertexNormal, float3 v)
{
float3 n = nrmVertexNormal;
float s = 1.0 / max(FLT_EPSILON, abs(dot(n, v)));
return s * (dot(n, v) * n - v);
}
// used to produce a surface gradient from the gradient of a volume bump function such as a volume of perlin noise.
// equation 2. in "bump mapping unparametrized surfaces on the GPU".
// Observe the difference in figure 2. between using the gradient vs. the surface gradient to do bump mapping (the original method is proved wrong in the paper!).
float3 SurfaceGradientFromVolumeGradient(float3 nrmVertexNormal, float3 grad)
{
return grad - dot(nrmVertexNormal, grad) * nrmVertexNormal;
}
// triplanar projection considered special case of volume bump map
// described here: http://mmikkelsen3d.blogspot.com/2013/10/volume-height-maps-and-triplanar-bump.html
// derivs obtained using tspaceNormalToDerivative() and weights using computeTriplanarWeights().
float3 SurfaceGradientFromTriplanarProjection(float3 nrmVertexNormal, float3 triplanarWeights, float2 deriv_xplane, float2 deriv_yplane, float2 deriv_zplane)
{
const float w0 = triplanarWeights.x, w1 = triplanarWeights.y, w2 = triplanarWeights.z;
// assume deriv_xplane, deriv_yplane and deriv_zplane sampled using (z,y), (z,x) and (x,y) respectively.
// positive scales of the look-up coordinate will work as well but for negative scales the derivative components will need to be negated accordingly.
float3 volumeGrad = float3(w2 * deriv_zplane.x + w1 * deriv_yplane.y, w2 * deriv_zplane.y + w0 * deriv_xplane.y, w0 * deriv_xplane.x + w1 * deriv_yplane.x);
return SurfaceGradientFromVolumeGradient(nrmVertexNormal, volumeGrad);
}
float3 SurfaceGradientResolveNormal(float3 nrmVertexNormal, float3 surfGrad)
{
return normalize(nrmVertexNormal - surfGrad);
}
// The 128 means the derivative will come out no greater than 128 numerically (where 1 is 45 degrees so 128 is very steap). You can increase it if u like of course
// Basically tan(angle) limited to 128
// So a max angle of 89.55 degrees ;) id argue thats close enough to the vertical limit at 90 degrees
// vT is channels.xy of a tangent space normal in[-1; 1]
// out: convert vT to a derivative
float2 UnpackDerivativeNormalAG(float4 packedNormal, float scale = 1.0)
{
const float fS = 1.0 / (128.0 * 128.0);
float2 vT = packedNormal.wy * 2.0 - 1.0;
float2 vTsq = vT * vT;
float nz_sq = 1 - vTsq.x - vTsq.y;
float maxcompxy_sq = fS * max(vTsq.x, vTsq.y);
float z_inv = rsqrt(max(nz_sq, maxcompxy_sq));
float2 deriv = -z_inv * float2(vT.x, vT.y);
return deriv * scale;
}
float2 UnpackDerivativeNormalRGB(float4 packedNormal, float scale = 1.0)
{
const float fS = 1.0 / (128.0 * 128.0);
float3 vT = packedNormal.xyz * 2.0 - 1.0;
float3 vTsq = vT * vT;
float maxcompxy_sq = fS * max(vTsq.x, vTsq.y);
float z_inv = rsqrt(max(vTsq.z, maxcompxy_sq));
float2 deriv = -z_inv * float2(vT.x, vT.y);
return deriv * scale;
}

9
Assets/ScriptableRenderPipeline/ShaderLibrary/NormalSurfaceGradient.hlsl.meta


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