浏览代码

Remove object scale from attribute/interpolator of tessellation

/stochastic_alpha_test
sebastienlagarde 7 年前
当前提交
af8794d4
共有 6 个文件被更改,包括 53 次插入76 次删除
  1. 4
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs
  2. 51
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  3. 28
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.hlsl
  4. 9
      ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/TessellationShare.hlsl
  5. 19
      ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VaryingMesh.hlsl
  6. 18
      ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VertMesh.hlsl

4
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs


bool enableDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) != DisplacementMode.None;
bool enableVertexDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Vertex;
bool enablePixelDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Pixel;
bool enableTessellationDisplacement = (DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Tessellation;
bool enableTessellationDisplacement = ((DisplacementMode)material.GetFloat(kDisplacementMode) == DisplacementMode.Tessellation) && material.HasProperty(kTessellationMode);
SetKeyword(material, "_TESSELLATION_DISPLACEMENT", enableTessellationDisplacement && material.HasProperty(kTessellationMode));
SetKeyword(material, "_TESSELLATION_DISPLACEMENT", enableTessellationDisplacement);
bool displacementLockObjectScale = material.GetFloat(kDisplacementLockObjectScale) > 0.0;
bool displacementLockTilingScale = material.GetFloat(kDisplacementLockTilingScale) > 0.0;

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


#include "../../../Core/ShaderLibrary/PerPixelDisplacement.hlsl"
// Displacement with lock object scale require to take into account object scaling except for planar and triplanar that are done in world space in Lit and thus are independent of object scale.
float3 GetInverseObjectScale()
float3 GetDisplacementInverseObjectScale(bool vertexDisplacement)
float3 invObjectScale = 1;
float3 objectScale = float3(1.0, 1.0, 1.0);
// Displacement with lock object scale require to take into account object scaling except for planar and triplanar that are done in world space in Lit and thus are independent of object scale.
// 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();
// TODO: This should be an uniform for the object, this code should be remove once we have it. - Workaround for now
// To handle object scaling with pixel displacement we need to multiply the view vector by the inverse scale.
// To Handle object scaling with vertex/tessellation displacement we must multiply displacement by object scale
// Currently we extract either the scale (ObjectToWorld) or the inverse scale (worldToObject) directly by taking the transform matrix
float4x4 worldTransform;
if (vertexDisplacement)
{
worldTransform = GetObjectToWorldMatrix();
}
else
{
worldTransform = GetWorldToObjectMatrix();
}
invObjectScale.x = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
#ifdef _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE
invObjectScale.y = length(float3(worldTransform._m10, worldTransform._m11, worldTransform._m12));
#endif // _PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE
invObjectScale.z = length(float3(worldTransform._m20, worldTransform._m21, worldTransform._m22));
#endif // _MAPPING_PLANAR
objectScale.x = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
// In the specific case of pixel displacement mapping, to get a consistent behavior compare to tessellation we require to not take into account y scale if lock object scale is not enabled
#if !defined(_PIXEL_DISPLACEMENT) || (defined(_PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE))
objectScale.y = length(float3(worldTransform._m10, worldTransform._m11, worldTransform._m12));
#endif
objectScale.z = length(float3(worldTransform._m20, worldTransform._m21, worldTransform._m22));
#endif
return invObjectScale;
return objectScale;
float GetHeightmapInverseTilingScale()
float GetDisplacementInverseTilingScale()
#if _MAPPING_PLANAR
#if defined(_MAPPING_PLANAR) || defined(_MAPPING_TRIPLANAR)
* rcp(_TexWorldScale)
#endif
;

bool isTriplanar = layerTexCoord.base.mappingType == UV_MAPPING_TRIPLANAR;
// See comment in layered version for details
float maxHeight = GetMaxDisplacement() * GetHeightmapInverseTilingScale();
float maxHeight = GetMaxDisplacement() * GetDisplacementInverseTilingScale();
float2 minUvSize = GetMinUvSize(layerTexCoord);
float lod = ComputeTextureLOD(minUvSize);

ppdParam.uv = layerTexCoord.base.uv; // For planar it is uv too, not uvXZ
// Note: The TBN is not normalize as it is based on mikkt. We should normalize it, but POM is always use on simple enough surfarce that mean it is not required (save 2 normalize). Tag: SURFACE_GRADIENT
float3 viewDirTS = isPlanar ? float3(uvXZ, V.y) : TransformWorldToTangent(V, input.worldToTangent) * GetInverseObjectScale().xzy; // Switch from Y-up to Z-up (as we move to tangent space)
float3 viewDirTS = isPlanar ? float3(uvXZ, V.y) : TransformWorldToTangent(V, input.worldToTangent) * GetDisplacementInverseObjectScale(false).xzy; // Switch from Y-up to Z-up (as we move to tangent space)
NdotV = viewDirTS.z;
// Transform the view vector into the UV space.

float ComputePerVertexDisplacement(LayerTexCoord layerTexCoord, float4 vertexColor, float lod)
{
float height = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap, sampler_HeightMap, layerTexCoord.base, lod).r - _HeightCenter) * _HeightAmplitude;
return height * GetHeightmapInverseTilingScale();
return height * GetDisplacementInverseTilingScale();
}
void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)

28
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.hlsl


float3 GetVertexDisplacement(float3 positionWS, float3 normalWS, float2 texCoord0, float2 texCoord1, float2 texCoord2, float2 texCoord3, float4 vertexColor, float3 objectScale)
float3 GetVertexDisplacement(float3 positionWS, float3 normalWS, float2 texCoord0, float2 texCoord1, float2 texCoord2, float2 texCoord3, float4 vertexColor)
{
// This call will work for both LayeredLit and Lit shader
LayerTexCoord layerTexCoord;

// Applying scaling of the object if requested
// Note: In case of planar mapping there is no object scale as we do world space planar mapping (not object space planar mapping)
#ifndef _MAPPING_PLANAR
displ *= objectScale;
#ifdef _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
float3 objectScale = GetDisplacementInverseObjectScale(true);
#else
float3 objectScale = float3(1.0, 1.0, 1.0);
displ *= objectScale;
void ApplyVertexModification(AttributesMesh input, float3 normalWS, float3 objectScale, inout float3 positionWS)
void ApplyVertexModification(AttributesMesh input, float3 normalWS, inout float3 positionWS)
positionWS += GetVertexDisplacement(positionWS, normalWS,
#ifdef ATTRIBUTES_NEED_TEXCOORD0
input.uv0,

float2(0.0, 0.0),
#endif
#ifdef ATTRIBUTES_NEED_COLOR
input.color,
input.color
float4(0.0, 0.0, 0.0, 0.0),
float4(0.0, 0.0, 0.0, 0.0)
objectScale);
);
#endif
#ifdef _VERTEX_WIND

// y - 2->0 edge
// z - 0->1 edge
// w - inside tessellation factor
void ApplyTessellationModification(VaryingsMeshToDS input, float3 normalWS, float3 objectScale, inout float3 positionWS)
void ApplyTessellationModification(VaryingsMeshToDS input, float3 normalWS, inout float3 positionWS)
positionWS += GetVertexDisplacement(positionWS, normalWS,
#ifdef VARYINGS_DS_NEED_TEXCOORD0
input.texCoord0,

float2(0.0, 0.0),
#endif
#ifdef VARYINGS_DS_NEED_COLOR
input.color,
input.color
float4(0.0, 0.0, 0.0, 0.0),
float4(0.0, 0.0, 0.0, 0.0)
objectScale);
);
#endif // _TESSELLATION_DISPLACEMENT
}

9
ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/TessellationShare.hlsl


#endif
#ifdef HAVE_TESSELLATION_MODIFICATION
// 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
#ifdef _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
float3 objectScale = varying.vmesh.objectScale;
#else
float3 objectScale = float3(1.0, 1.0, 1.0);
#endif
ApplyTessellationModification(varying.vmesh, varying.vmesh.normalWS, objectScale, varying.vmesh.positionWS);
ApplyTessellationModification(varying.vmesh, varying.vmesh.normalWS, varying.vmesh.positionWS);
#endif
return VertTesselation(varying);

19
ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VaryingMesh.hlsl


#ifdef VARYINGS_DS_NEED_COLOR
float4 color;
#endif
#ifdef _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
float3 objectScale;
#endif
};
struct PackedVaryingsMeshToDS

#ifdef VARYINGS_DS_NEED_COLOR
float4 interpolators5 : TEXCOORD2;
#endif
#ifdef _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
float3 interpolators6 : TEXCOORD3;
#endif
};
// Functions to pack data to use as few interpolator as possible, the ShaderGraph should generate these functions

#endif
#ifdef VARYINGS_DS_NEED_COLOR
output.interpolators5 = input.color;
#endif
#ifdef _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
output.interpolators6 = input.objectScale;
#endif
return output;

#ifdef VARYINGS_DS_NEED_COLOR
output.color = input.interpolators5;
#endif
#ifdef _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
output.objectScale = input.interpolators6;
#endif
return output;
}

#endif
#ifdef VARYINGS_DS_NEED_COLOR
TESSELLATION_INTERPOLATE_BARY(color, baryCoords);
#endif
#ifdef _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
// objectScale doesn't change for the whole object.
ouput.objectScale = input0.objectScale;
#endif
return ouput;

18
ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VertMesh.hlsl


float4 tangentWS = float4(TransformObjectToWorldDir(input.tangentOS.xyz), input.tangentOS.w);
#endif
// 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
#ifdef _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
float3 objectScale;
float4x4 worldTransform = GetObjectToWorldMatrix();
objectScale.x = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
objectScale.y = length(float3(worldTransform._m10, worldTransform._m11, worldTransform._m12));
objectScale.z = length(float3(worldTransform._m20, worldTransform._m21, worldTransform._m22));
#else
float3 objectScale = float3(1.0, 1.0, 1.0);
#endif
ApplyVertexModification(input, normalWS, objectScale, positionWS);
ApplyVertexModification(input, normalWS, positionWS);
#endif
positionWS = GetCameraRelativePositionWS(positionWS);

#ifdef _VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE
// 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
output.objectScale = objectScale;
#endif
// TODO: TEMP: Velocity has a flow as it doens't have normal. This need to be fix. In the mean time, generate fix normal so compiler doesn't complain - When fix, think to also enable ATTRIBUTES_NEED_NORMAL in LitVelocityPass.hlsl
#if (SHADERPASS == SHADERPASS_VELOCITY)
output.normalWS = float3(0.0, 0.0, 1.0);

正在加载...
取消
保存