浏览代码

Fix POM using the primitive size

/stochastic_alpha_test
Evgenii Golubev 7 年前
当前提交
84d9b5a3
共有 10 个文件被更改,包括 91 次插入33 次删除
  1. 9
      SampleScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Wood.mat
  2. 5
      SampleScenes/HDTest/GraphicTest/Tessellation/Material/Tessellation - Wood.mat
  3. 3
      ScriptableRenderPipeline/Core/ShaderLibrary/PerPixelDisplacement.hlsl
  4. 6
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader
  5. 4
      ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader
  6. 33
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Editor/BaseLitUI.cs
  7. 4
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader
  8. 53
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  9. 3
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl
  10. 4
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader

9
SampleScenes/HDTest/GraphicTest/Parallax Occlusion Mapping/Material/POM - Wood.mat


m_Name: POM - Wood
m_Shader: {fileID: 4800000, guid: 6e4ae4064600d784cac1e41a9e6f2e59, type: 3}
m_ShaderKeywords: _DEPTHOFFSET_ON _HEIGHTMAP _NORMALMAP _NORMALMAP_TANGENT_SPACE
_PER_PIXEL_DISPLACEMENT _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
_PER_PIXEL_DISPLACEMENT _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE _PER_PIXEL_DISPLACEMENT_TILING_SCALE
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0

m_Offset: {x: 0, y: 0}
- _BaseColorMap:
m_Texture: {fileID: 2800000, guid: 927434958f610214aa6a4179f134f5fd, type: 3}
m_Scale: {x: 2, y: 2}
m_Scale: {x: 3, y: 2}
m_Offset: {x: 0, y: 0}
- _BentNormalMap:
m_Texture: {fileID: 0}

- _NormalScale: 1
- _OcclusionStrength: 1
- _PPDLodThreshold: 5
- _PPDMaxSamples: 15
- _PPDMaxSamples: 64
- _PPDPrimitiveLength: 10
- _PPDPrimitiveWidth: 10
- _PerPixelDisplacementTilingScale: 1
- _ShiverDirectionality: 0.5
- _ShiverDrag: 0.2
- _Smoothness: 0.5

5
SampleScenes/HDTest/GraphicTest/Tessellation/Material/Tessellation - Wood.mat


m_Offset: {x: 0, y: 0}
- _BaseColorMap:
m_Texture: {fileID: 2800000, guid: 927434958f610214aa6a4179f134f5fd, type: 3}
m_Scale: {x: 2, y: 2}
m_Scale: {x: 3, y: 2}
m_Offset: {x: 0, y: 0}
- _BentNormalMap:
m_Texture: {fileID: 0}

- _PPDLodThreshold: 5
- _PPDMaxSamples: 64
- _PPDMinSamples: 1
- _PPDPrimitiveLength: 1
- _PPDPrimitiveWidth: 1
- _PerPixelDisplacementTilingScale: 1
- _ShiverDirectionality: 0.5
- _ShiverDrag: 0.2
- _Smoothness: 0.5

3
ScriptableRenderPipeline/Core/ShaderLibrary/PerPixelDisplacement.hlsl


// ref: https://www.gamedev.net/resources/_/technical/graphics-programming-and-theory/a-closer-look-at-parallax-occlusion-mapping-r3262
float2 ParallaxOcclusionMapping(float lod, float lodThreshold, int numSteps, float3 viewDirTS, float maxHeight, PerPixelHeightDisplacementParam ppdParam, out float outHeight)
{
// TODO: explain this factor! Necessary to achieve parity between tessellation and POM w.r.t. height.
maxHeight *= 0.1;
// Convention: 1.0 is top, 0.0 is bottom - POM is always inward, no extrusion
float stepSize = 1.0 / (float)numSteps;

6
ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLit.shader


_PPDMinSamples("Min sample for POM", Range(1.0, 64.0)) = 5
_PPDMaxSamples("Max sample for POM", Range(1.0, 64.0)) = 15
_PPDLodThreshold("Start lod to fade out the POM effect", Range(0.0, 16.0)) = 5
_PPDPrimitiveLength("Primitive length for POM", Float) = 1
_PPDPrimitiveWidth("Primitive width for POM", Float) = 1
[ToggleOff] _PerPixelDisplacementTilingScale("Per pixel displacement tiling scale", Float) = 1.0
[Enum(Use Emissive Color, 0, Use Emissive Mask, 1)] _EmissiveColorMode("Emissive color mode", Float) = 1

#pragma shader_feature _DEPTHOFFSET_ON
#pragma shader_feature _DOUBLESIDED_ON
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_TILING_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT_TILING_SCALE

4
ScriptableRenderPipeline/HDRenderPipeline/Material/LayeredLit/LayeredLitTessellation.shader


_PPDMinSamples("Min sample for POM", Range(1.0, 64.0)) = 5
_PPDMaxSamples("Max sample for POM", Range(1.0, 64.0)) = 15
_PPDLodThreshold("Start lod to fade out the POM effect", Range(0.0, 16.0)) = 5
_PPDPrimitiveLength("Primitive length for POM", Float) = 1
_PPDPrimitiveWidth("Primitive width for POM", Float) = 1
[ToggleOff] _PerPixelDisplacementTilingScale("Per pixel displacement tiling scale", Float) = 1.0
[Enum(Use Emissive Color, 0, Use Emissive Mask, 1)] _EmissiveColorMode("Emissive color mode", Float) = 1

#pragma shader_feature _DOUBLESIDED_ON
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_TILING_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT_TILING_SCALE

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


// Material ID
public static GUIContent materialIDText = new GUIContent("Material type", "Subsurface Scattering: enable for translucent materials such as skin, vegetation, fruit, marble, wax and milk.");
// Displacement mapping (POM, tessellation, per vertex)
public static GUIContent lockWithObjectScaleText = new GUIContent("Lock with object scale", "Displacement mapping will take the absolute value of the scale of the object into account.");
public static GUIContent lockWithTilingRateText = new GUIContent("Lock with height map tiling rate", "Displacement mapping will take the absolute value of the tiling rate of the height map into account.");
public static GUIContent perPixelDisplacementObjectScaleText = new GUIContent("Lock with object scale", "Per Pixel displacement will take into account the tiling scale - Only work with uniform positive scale");
public static GUIContent ppdPrimitiveLength = new GUIContent("Primitive length", "Dimensions of the primitive (with the scale of 1) to which the per-pixel displacement mapping is being applied. For example, the standard quad is 1 x 1 meter, while the standard plane is 10 x 10 meters.");
public static GUIContent ppdPrimitiveWidth = new GUIContent("Primitive width", "Dimensions of the primitive (with the scale of 1) to which the per-pixel displacement mapping is being applied. For example, the standard quad is 1 x 1 meter, while the standard plane is 10 x 10 meters.");
public static GUIContent vertexDisplacementObjectScaleText = new GUIContent("Lock with object scale", "Vertex displacement will take into account the object scale - Only work with uniform positive scale");
public static GUIContent vertexDisplacementTilingScaleText = new GUIContent("Lock with heightmap tiling", "Vertex displacement will take into account the tiling scale - Only work with uniform positive scale");
// Tessellation
public static string tessellationModeText = "Tessellation Mode";

protected const string kPpdMaxSamples = "_PPDMaxSamples";
protected MaterialProperty ppdLodThreshold = null;
protected const string kPpdLodThreshold = "_PPDLodThreshold";
protected MaterialProperty ppdPrimitiveLength = null;
protected const string kPpdPrimitiveLength = "_PPDPrimitiveLength";
protected MaterialProperty ppdPrimitiveWidth = null;
protected const string kPpdPrimitiveWidth = "_PPDPrimitiveWidth";
protected MaterialProperty perPixelDisplacementTilingScale = null;
protected const string kPerPixelDisplacementTilingScale = "_PerPixelDisplacementTilingScale";
// Vertex displacement
protected MaterialProperty enableVertexDisplacement = null;

ppdMinSamples = FindProperty(kPpdMinSamples, props);
ppdMaxSamples = FindProperty(kPpdMaxSamples, props);
ppdLodThreshold = FindProperty(kPpdLodThreshold, props);
ppdPrimitiveLength = FindProperty(kPpdPrimitiveLength, props);
ppdPrimitiveWidth = FindProperty(kPpdPrimitiveWidth, props);
perPixelDisplacementTilingScale = FindProperty(kPerPixelDisplacementTilingScale, props);
// vertex displacement
enableVertexDisplacement = FindProperty(kEnableVertexDisplacement, props);

m_MaterialEditor.ShaderProperty(ppdMaxSamples, StylesBaseLit.ppdMaxSamplesText);
ppdMinSamples.floatValue = Mathf.Min(ppdMinSamples.floatValue, ppdMaxSamples.floatValue);
m_MaterialEditor.ShaderProperty(ppdLodThreshold, StylesBaseLit.ppdLodThresholdText);
m_MaterialEditor.ShaderProperty(perPixelDisplacementObjectScale, StylesBaseLit.perPixelDisplacementObjectScaleText);
m_MaterialEditor.ShaderProperty(ppdPrimitiveLength, StylesBaseLit.ppdPrimitiveLength);
ppdPrimitiveLength.floatValue = Mathf.Max(0.01f, ppdPrimitiveLength.floatValue);
m_MaterialEditor.ShaderProperty(ppdPrimitiveWidth, StylesBaseLit.ppdPrimitiveWidth);
ppdPrimitiveWidth.floatValue = Mathf.Max(0.01f, ppdPrimitiveWidth.floatValue);
m_MaterialEditor.ShaderProperty(perPixelDisplacementObjectScale, StylesBaseLit.lockWithObjectScaleText);
m_MaterialEditor.ShaderProperty(perPixelDisplacementTilingScale, StylesBaseLit.lockWithTilingRateText);
m_MaterialEditor.ShaderProperty(depthOffsetEnable, StylesBaseLit.depthOffsetEnableText);
EditorGUI.indentLevel--;
}

if (enableVertexDisplacement.floatValue > 0.0f)
{
EditorGUI.indentLevel++;
m_MaterialEditor.ShaderProperty(vertexDisplacementObjectScale, StylesBaseLit.vertexDisplacementObjectScaleText);
m_MaterialEditor.ShaderProperty(vertexDisplacementTilingScale, StylesBaseLit.vertexDisplacementTilingScaleText);
m_MaterialEditor.ShaderProperty(vertexDisplacementObjectScale, StylesBaseLit.lockWithObjectScaleText);
m_MaterialEditor.ShaderProperty(vertexDisplacementTilingScale, StylesBaseLit.lockWithTilingRateText);
EditorGUI.indentLevel--;
}

bool perPixelDisplacementObjectScale = material.GetFloat(kPerPixelDisplacementObjectScale) > 0.0;
SetKeyword(material, "_PER_PIXEL_DISPLACEMENT_OBJECT_SCALE", perPixelDisplacementObjectScale && enablePerPixelDisplacement);
bool perPixelDisplacementTilingScale = material.GetFloat(kPerPixelDisplacementTilingScale) > 0.0;
SetKeyword(material, "_PER_PIXEL_DISPLACEMENT_TILING_SCALE", perPixelDisplacementTilingScale && enablePerPixelDisplacement);
bool enableVertexDisplacement = material.GetFloat(kEnableVertexDisplacement) > 0.0f;
SetKeyword(material, "_VERTEX_DISPLACEMENT", enableVertexDisplacement);

4
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.shader


_PPDMinSamples("Min sample for POM", Range(1.0, 64.0)) = 5
_PPDMaxSamples("Max sample for POM", Range(1.0, 64.0)) = 15
_PPDLodThreshold("Start lod to fade out the POM effect", Range(0.0, 16.0)) = 5
_PPDPrimitiveLength("Primitive length for POM", Float) = 1
_PPDPrimitiveWidth("Primitive width for POM", Float) = 1
[ToggleOff] _PerPixelDisplacementTilingScale("Per pixel displacement tiling scale", Float) = 1.0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _UVDetail("UV Set for detail", Float) = 0
[HideInInspector] _UVDetailsMappingMask("_UVDetailsMappingMask", Color) = (1, 0, 0, 0)

#pragma shader_feature _DOUBLESIDED_ON
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_TILING_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT_TILING_SCALE

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


float2 minUvSize = GetMinUvSize(layerTexCoord);
float lod = ComputeTextureLOD(minUvSize);
#ifdef _PER_PIXEL_DISPLACEMENT_TILING_SCALE
float tilingScale = rcp(0.5 * abs(_BaseColorMap_ST.x) + 0.5 * abs(_BaseColorMap_ST.y));
maxHeight *= tilingScale;
#endif
float3 invObjectScale;
invObjectScale.x = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
float3 invObjectScale;
invObjectScale.z = length(float3(worldTransform._m20, worldTransform._m21, worldTransform._m22));
if (isPlanar)
{
invObjectScale.xz = 1;
}
else
{
invObjectScale.x = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
invObjectScale.z = length(float3(worldTransform._m20, worldTransform._m21, worldTransform._m22));
}
#endif
PerPixelHeightDisplacementParam ppdParam;

float3 viewDirTS = isPlanar ? float3(uvXZ, V.y) : TransformWorldToTangent(V, worldToTangent);
#ifdef _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
viewDirTS *= invObjectScale.xyz; // Switch from Y-up to Z-up
viewDirTS *= invObjectScale.xzy; // Switch from Y-up to Z-up
int numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, saturate(viewDirTS.z));
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam, height);
// Transform the view vector into the UV space.
float2 primitiveSize = 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));
int numSteps = (int)lerp(_PPDMinSamples, _PPDMaxSamples, saturate(FastACos(viewDirUV.z) * INV_HALF_PI));
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirUV, 1, ppdParam, height);
// Apply offset to all UVSet0 / planar
layerTexCoord.base.uv += offset;

// 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.
float verticalDisplacement = maxHeight - height * maxHeight;
// IDEA: precompute the tiling scale? MOV-MUL vs MOV-MOV-MAX-RCP-MUL.
float tilingScale = rcp(max(_BaseColorMap_ST.x, _BaseColorMap_ST.y));
return tilingScale * verticalDisplacement / NdotV;
return verticalDisplacement / NdotV;
}
return 0.0;

{
float height = (SAMPLE_UVMAPPING_TEXTURE2D_LOD(_HeightMap, sampler_HeightMap, layerTexCoord.base, lod).r - _HeightCenter) * _HeightAmplitude;
#ifdef _VERTEX_DISPLACEMENT_TILING_SCALE
// When we change the tiling, we have want to conserve the ratio with the displacement (and this is consistent with per pixel displacement)
// IDEA: precompute the tiling scale? MOV-MUL vs MOV-MOV-MAX-RCP-MUL.
float tilingScale = rcp(max(_BaseColorMap_ST.x, _BaseColorMap_ST.y));
height *= tilingScale;
// TODO: precompute this scaling factor!
float tilingScale = rcp(0.5 * abs(_BaseColorMap_ST.x) + 0.5 * abs(_BaseColorMap_ST.y));
height *= tilingScale * _TexWorldScale;
#endif
return height;
}

tileObjectScale = length(float3(worldTransform._m00, worldTransform._m01, worldTransform._m02));
#endif
height0 /= max(_BaseColorMap0_ST.x, _BaseColorMap0_ST.y);
// TODO: precompute all these scaling factors!
height0 /= max(_BaseColorMap0_ST.x, _BaseColorMap0_ST.y) * _TexWorldScale0;
height1 /= tileObjectScale * max(_BaseColorMap1_ST.x, _BaseColorMap1_ST.y);
height2 /= tileObjectScale * max(_BaseColorMap2_ST.x, _BaseColorMap2_ST.y);
height3 /= tileObjectScale * max(_BaseColorMap3_ST.x, _BaseColorMap3_ST.y);
height1 /= tileObjectScale * max(_BaseColorMap1_ST.x, _BaseColorMap1_ST.y) * _TexWorldScale1;
height2 /= tileObjectScale * max(_BaseColorMap2_ST.x, _BaseColorMap2_ST.y) * _TexWorldScale2;
height3 /= tileObjectScale * max(_BaseColorMap3_ST.x, _BaseColorMap3_ST.y) * _TexWorldScale3;
#endif
}

3
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitProperties.hlsl


// TODO: Fix the code in legacy unity so we can customize the beahvior for GI
float3 _EmissionColor;
float _PPDPrimitiveLength;
float _PPDPrimitiveWidth;
// Wind
float _InitialBend;
float _Stiffness;

4
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.shader


_PPDMinSamples("Min sample for POM", Range(1.0, 64.0)) = 5
_PPDMaxSamples("Max sample for POM", Range(1.0, 64.0)) = 15
_PPDLodThreshold("Start lod to fade out the POM effect", Range(0.0, 16.0)) = 5
_PPDPrimitiveLength("Primitive length for POM", Float) = 1
_PPDPrimitiveWidth("Primitive width for POM", Float) = 1
[ToggleOff] _PerPixelDisplacementTilingScale("Per pixel displacement tiling scale", Float) = 1.0
[Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3)] _UVDetail("UV Set for detail", Float) = 0
[HideInInspector] _UVDetailsMappingMask("_UVDetailsMappingMask", Color) = (1, 0, 0, 0)

#pragma shader_feature _DOUBLESIDED_ON
#pragma shader_feature _PER_PIXEL_DISPLACEMENT
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _PER_PIXEL_DISPLACEMENT_TILING_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT
#pragma shader_feature _VERTEX_DISPLACEMENT_OBJECT_SCALE
#pragma shader_feature _VERTEX_DISPLACEMENT_TILING_SCALE

正在加载...
取消
保存