浏览代码

Factor out GetInverseTilingScale()

/stochastic_alpha_test
Evgenii Golubev 7 年前
当前提交
a38309ba
共有 1 个文件被更改,包括 39 次插入35 次删除
  1. 74
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl

74
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl


#include "../../../Core/ShaderLibrary/PerPixelDisplacement.hlsl"
float3 GetInverseObjectScale(bool isPlanar)
// TODO: share this function with tessellation code.
float3 GetInverseObjectScale()
if (!isPlanar)
{
// TODO: This should be an uniform for the object, this code should be remove (and is specific to Lit.shader) once we have it. - Workaround for now
// Extract scaling from world transform
// To handle object scaling with PPD we need to multiply the view vector by the inverse scale.
// Currently we extract the inverse scale directly by taking worldToObject matrix (instead of ObjectToWorld)
float4x4 worldTransform = GetWorldToObjectMatrix(); // Note that we take WorldToObject to get inverse scale
#ifndef _MAPPING_PLANAR
// TODO: This should be an uniform for the object, this code should be remove (and is specific to Lit.shader) once we have it. - Workaround for now
// Extract scaling from world transform
// To handle object scaling with PPD we need to multiply the view vector by the inverse scale.
// Currently we extract the inverse scale directly by taking worldToObject matrix (instead of ObjectToWorld)
float4x4 worldTransform = GetWorldToObjectMatrix(); // Note that we take WorldToObject to get inverse scale
invObjectScale.x = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
#ifdef _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
invObjectScale.y = length(float3(worldTransform._m10, worldTransform._m11, worldTransform._m12));
#endif
invObjectScale.z = length(float3(worldTransform._m20, worldTransform._m21, worldTransform._m22));
}
invObjectScale.x = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
#ifdef _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
invObjectScale.y = length(float3(worldTransform._m10, worldTransform._m11, worldTransform._m12));
#endif // _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
invObjectScale.z = length(float3(worldTransform._m20, worldTransform._m21, worldTransform._m22));
#endif // _MAPPING_PLANAR
// TODO: share this function with tessellation code.
float GetInverseTilingScale()
{
#ifdef _PER_PIXEL_DISPLACEMENT_TILING_SCALE
return rcp(0.5 * abs(_BaseColorMap_ST.x) + 0.5 * abs(_BaseColorMap_ST.y)); // TODO: precompute
#else
return 1;
#endif
}
float ApplyPerPixelDisplacement(FragInputs input, float3 V, inout LayerTexCoord layerTexCoord)
{
bool ppdEnable = false;

if (ppdEnable)
{
// See comment in layered version for details
float maxHeight = GetMaxDisplacement();
float2 minUvSize = GetMinUvSize(layerTexCoord);
float lod = ComputeTextureLOD(minUvSize);
if (isPlanar) maxHeight *= _TexWorldScale;
#ifdef _PER_PIXEL_DISPLACEMENT_TILING_SCALE
float tilingScale = rcp(0.5 * abs(_BaseColorMap_ST.x) + 0.5 * abs(_BaseColorMap_ST.y));
maxHeight *= tilingScale;
#endif
float2 worldScales = isPlanar ? float2(_TexWorldScale, rcp(_TexWorldScale)) : 1; // TODO: precompute
float2 invPrimScale = isPlanar ? 1 : rcp(float2(_PPDPrimitiveLength, _PPDPrimitiveWidth)); // TODO: precompute
float maxHeight = GetMaxDisplacement() * GetInverseTilingScale() * worldScales.x;
float2 minUvSize = GetMinUvSize(layerTexCoord);
float lod = ComputeTextureLOD(minUvSize);
PerPixelHeightDisplacementParam ppdParam;

{
ppdParam.uv = layerTexCoord.base.uv; // For planar it is uv too, not uvXZ
float3x3 worldToTangent = input.worldToTangent;
float3 viewDirTS = isPlanar ? float3(uvXZ, V.y) : TransformWorldToTangent(V, worldToTangent);
float3 viewDirTS = isPlanar ? float3(uvXZ, V.y) : TransformWorldToTangent(V, input.worldToTangent);
viewDirTS *= GetInverseObjectScale().xzy; // Switch from Y-up to Z-up
viewDirTS *= GetInverseObjectScale(isPlanar).xzy; // Switch from Y-up to Z-up
float2 primitiveSize = isPlanar ? 1 : float2(_PPDPrimitiveLength, _PPDPrimitiveWidth);
float2 primitiveScale = rcp(primitiveSize);
float2 uvSpaceScale = primitiveScale * _BaseColorMap_ST.xy; // This could be precomputed
float3 viewDirUV = normalize(float3(viewDirTS.xy * uvSpaceScale, viewDirTS.z / maxHeight));
float2 uvSpaceScale = invPrimScale * _BaseColorMap_ST.xy;
float3 viewDirUV = normalize(float3(viewDirTS.xy * uvSpaceScale, viewDirTS.z / maxHeight));
float unitAngle = saturate(FastACos(viewDirUV.z) * INV_HALF_PI); // TODO: optimize
int numSteps = (int)lerp(_PPDMinSamples, _PPDMaxSamples, unitAngle);
int numSteps = (int)lerp(_PPDMinSamples, _PPDMaxSamples, saturate(FastACos(viewDirUV.z) * INV_HALF_PI));
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirUV, 1, ppdParam, height);
// POM uses a normalized view vector in the UV space to intersect the heightmap within a 1x1x1 box.
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirUV, 1, ppdParam, height);
// Apply offset to all UVSet0 / planar
layerTexCoord.base.uv += offset;

if (isPlanar) maxHeight *= rcp(_TexWorldScale);
maxHeight *= worldScales.y;
// Since POM "pushes" geometry inwards (rather than extrude it), { height = height - 1 }.
// Since the result is used as a 'depthOffsetVS', it needs to be positive, so we flip the sign.

正在加载...
取消
保存