Skip to content

Commit 6acf80f

Browse files
adrien-de-tocquevilleEvergreen
authored andcommitted
[HDRP][Water] Various fixes and samples improvements
Several improvements to water samples: - Reorg of gameobjects into prefabs for clarity - Added link to Global Settings from the helper window - Small rework of meshes and textures to reduce sample size Improved test coverage: - Test water mask - Test water decals - Test cpu readback Improved system usability and workflows Various fixes, mostly minor bugs see release notes
1 parent 8e3c705 commit 6acf80f

File tree

221 files changed

+36712
-23642
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

221 files changed

+36712
-23642
lines changed

Packages/com.unity.render-pipelines.core/Runtime/Textures/Texture2DAtlas.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,32 @@ public virtual bool NeedsUpdate(Texture texture, bool needMips = false)
638638
return false;
639639
}
640640

641+
/// <summary>
642+
/// Check if a slot needs to be updated in the atlas.
643+
/// </summary>
644+
/// <param name="id">The id.</param>
645+
/// <param name="updateCount">The update count.</param>
646+
/// <param name="needMips">Texture uses mips.</param>
647+
/// <returns>True if slot needs update, false otherwise.</returns>
648+
public virtual bool NeedsUpdate(int id, int updateCount, bool needMips = false)
649+
{
650+
int atlasUpdateCount;
651+
if (m_IsGPUTextureUpToDate.TryGetValue(id, out atlasUpdateCount))
652+
{
653+
if (updateCount != atlasUpdateCount)
654+
{
655+
m_IsGPUTextureUpToDate[id] = updateCount;
656+
return true;
657+
}
658+
}
659+
else
660+
{
661+
m_IsGPUTextureUpToDate[id] = updateCount;
662+
}
663+
664+
return false;
665+
}
666+
641667
/// <summary>
642668
/// Check if contents of a texture needs to be updated in the atlas.
643669
/// </summary>

Packages/com.unity.render-pipelines.core/Samples~/Common/Scripts/Editor/SamplesShowcaseEditor.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Collections;
1111
using System.Reflection;
1212
using UnityEngine.Rendering;
13+
using UnityEditor.Inspector.GraphicsSettingsInspectors;
1314

1415
[InitializeOnLoad]
1516
[CustomEditor(typeof(SamplesShowcase))]
@@ -174,6 +175,11 @@ public override VisualElement CreateInspectorGUI()
174175
{
175176
RequiredSettingBase.showSettingCallback(setting);
176177
}
178+
else if (!string.IsNullOrEmpty(setting.globalSettingsType))
179+
{
180+
var type = Type.GetType(setting.globalSettingsType);
181+
GraphicsSettingsInspectorUtility.OpenAndScrollTo(type);
182+
}
177183
else
178184
{
179185
SettingsService.OpenProjectSettings(setting.projectSettingsPath);

Packages/com.unity.render-pipelines.core/Samples~/Common/Scripts/RequiredSettings/RequiredSettingBase.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using UnityEditor;
77
using UnityEngine;
88
using UnityEngine.Rendering;
9+
using System.Reflection;
910

1011
namespace UnityEngine.Rendering
1112
{
@@ -21,6 +22,8 @@ public class RequiredSettingBase : IRequiredSetting
2122
public string name => m_name;
2223
public string description => m_description;
2324

25+
public string globalSettingsType;
26+
2427
public ValueType valueType = ValueType.Bool;
2528
public float targetValue = 1f;
2629
public ValidationType validationType = ValidationType.Equal;
@@ -71,6 +74,15 @@ public virtual bool state
7174
{
7275
get
7376
{
77+
if (!string.IsNullOrEmpty(globalSettingsType))
78+
{
79+
var type = Type.GetType(globalSettingsType);
80+
var field = type.GetField(propertyPath, BindingFlags.NonPublic | BindingFlags.Instance);
81+
var getSettings = typeof(GraphicsSettings).GetMethod("GetRenderPipelineSettings").MakeGenericMethod(type);
82+
object settings = getSettings.Invoke(null, null);
83+
return (bool)field.GetValue(settings);
84+
}
85+
7486
if (property == null)
7587
return false;
7688

Packages/com.unity.render-pipelines.high-definition/Editor/AssetProcessors/ShaderGraphMaterialsUpdater.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ static ShaderGraphMaterialsUpdater()
1919

2020
static void OnShaderGraphSaved(Shader shader, object saveContext)
2121
{
22+
#if UNITY_EDITOR
23+
// Water decals don't have an HDSaveContext, but this call has no effect if the shader is not a WaterDecal
24+
HDRenderPipeline.currentPipeline?.waterSystem?.UpdateWaterDecalAtlas(shader);
25+
#endif
26+
2227
// In case the shader is not HDRP
2328
if (!(saveContext is HDSaveContext hdSaveContext))
2429
return;

Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPBuildData.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ internal class HDRPBuildData : IDisposable
1616
public List<HDRenderPipelineAsset> renderPipelineAssets { get; private set; } = new List<HDRenderPipelineAsset>();
1717
public bool playerNeedRaytracing { get; private set; }
1818
public bool stripDebugVariants { get; private set; } = true;
19+
public bool waterDecalMaskAndCurrent { get; private set; }
1920
public Dictionary<int, ComputeShader> rayTracingComputeShaderCache { get; private set; } = new();
2021
public Dictionary<int, ComputeShader> computeShaderCache { get; private set; } = new();
2122

@@ -59,6 +60,10 @@ public HDRPBuildData(BuildTarget buildTarget, bool isDevelopmentBuild)
5960

6061
stripDebugVariants = !isDevelopmentBuild || GraphicsSettings.GetRenderPipelineSettings<ShaderStrippingSetting>().stripRuntimeDebugShaders;
6162
}
63+
64+
var waterSettings = GraphicsSettings.GetRenderPipelineSettings<WaterSystemGlobalSettings>();
65+
if (waterSettings != null)
66+
waterDecalMaskAndCurrent = waterSettings.waterDecalMaskAndCurrent;
6267
}
6368

6469
m_Instance = this;
@@ -71,6 +76,7 @@ public void Dispose()
7176
computeShaderCache?.Clear();
7277
playerNeedRaytracing = false;
7378
stripDebugVariants = true;
79+
waterDecalMaskAndCurrent = false;
7480
buildingPlayerForHDRenderPipeline = false;
7581
runtimeShaders = null;
7682
materialResources = null;

Packages/com.unity.render-pipelines.high-definition/Editor/BuildProcessors/HDRPPreprocessShaders.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ protected override bool DoShadersStripper(HDRenderPipelineAsset hdrpAsset, Shade
4242
if (stripDebugVariants && snippet.passName.StartsWith(WaterSystem.k_WaterMaskPass))
4343
return true;
4444
}
45+
if (HDRPBuildData.instance.waterDecalMaskAndCurrent)
46+
{
47+
if (inputData.shaderKeywordSet.IsEnabled(m_WaterDecalPartial))
48+
return true;
49+
}
50+
else
51+
{
52+
if (inputData.shaderKeywordSet.IsEnabled(m_WaterDecalComplete))
53+
return true;
54+
}
4555

4656
// If Screen Space Lens Flare is disabled, strip all the shaders
4757
if (!settings.supportScreenSpaceLensFlare)

Packages/com.unity.render-pipelines.high-definition/Editor/Material/BaseShaderPreprocessor.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ abstract class BaseShaderPreprocessor
8888
protected ShaderKeyword m_DecalSurfaceGradient;
8989
protected ShaderKeyword m_EditorVisualization;
9090
protected ShaderKeyword m_SupportWater;
91+
protected ShaderKeyword m_WaterDecalPartial;
92+
protected ShaderKeyword m_WaterDecalComplete;
9193
protected ShaderKeyword m_SupportWaterCaustics;
9294
protected ShaderKeyword m_SupportWaterCausticsShadow;
9395
protected ShaderKeyword m_SupportWaterAbsorption;
@@ -133,6 +135,8 @@ public BaseShaderPreprocessor()
133135
m_DecalSurfaceGradient = new ShaderKeyword("DECAL_SURFACE_GRADIENT");
134136
m_EditorVisualization = new ShaderKeyword("EDITOR_VISUALIZATION");
135137
m_SupportWater = new ShaderKeyword("SUPPORT_WATER");
138+
m_WaterDecalPartial = new ShaderKeyword("WATER_DECAL_PARTIAL");
139+
m_WaterDecalComplete = new ShaderKeyword("WATER_DECAL_COMPLETE");
136140
m_SupportWaterCaustics = new ShaderKeyword("SUPPORT_WATER_CAUSTICS");
137141
m_SupportWaterCausticsShadow = new ShaderKeyword("SUPPORT_WATER_CAUSTICS_SHADOW");
138142
m_SupportWaterAbsorption = new ShaderKeyword("SUPPORT_WATER_ABSORPTION");

Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Node/UnpackData_Water.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,18 @@ public sealed override void UpdateNodeAfterDeserialization()
4545

4646
public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode)
4747
{
48-
sb.AppendLine("$precision {1} = saturate(IN.{0}.x); $precision {2} = IN.{0}.y;",
49-
ShaderGeneratorNames.GetUVName(UVChannel.UV1),
48+
// See PackWaterVertexData
49+
50+
// Low Frequency Height
51+
sb.AppendLine("$precision {0} = saturate(IN.{1}.w);",
5052
GetVariableNameForSlot(kLowFrequencyHeightOutputSlotId),
51-
GetVariableNameForSlot(kHorizontalDisplacementOutputSlotId)
53+
ShaderGeneratorNames.GetUVName(UVChannel.UV1)
54+
);
55+
56+
// Horizontal Displacement
57+
sb.AppendLine("$precision {0} = IN.{1}.w;",
58+
GetVariableNameForSlot(kHorizontalDisplacementOutputSlotId),
59+
ShaderGeneratorNames.GetUVName(UVChannel.UV0)
5260
);
5361
}
5462

Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Tessellation.template.hlsl

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ VaryingsMeshToDS InterpolateWithBaryCoordsMeshToDS(VaryingsMeshToDS input0, Vary
1212
TESSELLATION_INTERPOLATE_BARY(normalWS, baryCoords);
1313
TESSELLATION_INTERPOLATE_BARY(texCoord0, baryCoords);
1414
TESSELLATION_INTERPOLATE_BARY(texCoord1, baryCoords);
15-
output.positionPredisplacementRWS = output.positionRWS;
1615

1716
// Pass-Through for custom interpolator
1817
$splice(CustomInterpolatorInterpolateWithBaryCoordsMeshToDS)
@@ -42,8 +41,7 @@ VertexDescriptionInputs VaryingsMeshToDSToVertexDescriptionInputs(VaryingsMeshTo
4241
// y - 2->0 edge
4342
// z - 0->1 edge
4443
// w - inside tessellation factor
45-
// The water shader graph required these four fields to be fed (not an option)
46-
VaryingsMeshToDS ApplyTessellationModification(VaryingsMeshToDS input, float3 timeParameters)
44+
void ApplyTessellationModification(VaryingsMeshToDS input, float3 timeParameters, inout VaryingsMeshToPS output, out VertexDescription vertexDescription)
4745
{
4846
// HACK: As there is no specific tessellation stage for now in shadergraph, we reuse the vertex description mechanism.
4947
// It mean we store TessellationFactor inside vertex description causing extra read on both vertex and hull stage, but unused parameters are optimize out by the shader compiler, so no impact.
@@ -53,28 +51,14 @@ VaryingsMeshToDS ApplyTessellationModification(VaryingsMeshToDS input, float3 ti
5351
$VertexDescriptionInputs.TimeParameters: vertexDescriptionInputs.TimeParameters = timeParameters;
5452

5553
// evaluate vertex graph
56-
VertexDescription vertexDescription = VertexDescriptionFunction(vertexDescriptionInputs);
54+
vertexDescription = VertexDescriptionFunction(vertexDescriptionInputs);
5755

5856
// Backward compatibility with old graphs
5957
$VertexDescriptionInputs.uv0: vertexDescription.Displacement = vertexDescription.uv0.xyz;
6058
$VertexDescriptionInputs.uv1: vertexDescription.LowFrequencyHeight = vertexDescription.uv1.x;
6159

62-
// Export for the following stage
63-
input.positionRWS = TransformObjectToWorld(vertexDescription.Position + vertexDescription.Displacement);
64-
input.normalWS = vertexDescription.Normal;
65-
PackWaterVertexData(vertexDescription, input.texCoord0, input.texCoord1);
66-
67-
return input;
68-
}
69-
70-
#ifdef USE_CUSTOMINTERP_SUBSTRUCT
71-
72-
// This will evaluate the custom interpolator and update the varying structure
73-
void VertMeshTesselationCustomInterpolation(VaryingsMeshToDS input, inout VaryingsMeshToPS output)
74-
{
60+
// Custom interpolators
7561
$splice(CustomInterpolatorVertMeshTesselationCustomInterpolation)
7662
}
7763

78-
#endif // USE_CUSTOMINTERP_SUBSTRUCT
79-
8064
#endif // TESSELLATION_ON

Packages/com.unity.render-pipelines.high-definition/Editor/Material/Water/ShaderGraph/Vertex.template.hlsl

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,30 @@ VertexDescriptionInputs AttributesMeshToVertexDescriptionInputs(AttributesMesh i
1919
return output;
2020
}
2121

22-
void PackWaterVertexData(VertexDescription vertexDescription, out float4 uv0, out float4 uv1)
22+
void PackWaterVertexData(VertexDescription vertex, out float4 uv0, out float4 uv1)
2323
{
24-
float3 displacement = vertexDescription.Displacement;
25-
26-
#if defined(SHADER_STAGE_VERTEX) && defined(TESSELLATION_ON)
27-
uv0 = float4(vertexDescription.Displacement, 1.0);
28-
uv1 = float4(vertexDescription.Position, 1.0);
29-
#else
30-
uv0 = float4(vertexDescription.Position.x, vertexDescription.Position.z, displacement.y, 0.0);
31-
uv1 = float4(vertexDescription.LowFrequencyHeight, length(float2(displacement.x, displacement.z)), 0.0, 0.0);
32-
#endif
24+
#if defined(SHADER_STAGE_VERTEX) && defined(TESSELLATION_ON)
25+
uv0 = float4(vertex.Displacement, 1.0);
26+
uv1 = float4(vertex.Position, 1.0);
27+
#else
28+
uv0.xy = vertex.Position.xz;
29+
uv0.z = vertex.Displacement.y;
30+
uv0.w = length(vertex.Displacement.xz);
31+
32+
if (_GridSize.x >= 0)
33+
uv1.xyz = TransformObjectToWorld(vertex.Position + vertex.Displacement);
34+
uv1.w = vertex.LowFrequencyHeight;
35+
#endif
3336
}
3437

35-
// The water shader graph required these four fields to be fed (not an option)
38+
#if defined(TESSELLATION_ON)
39+
#define VaryingsMeshType VaryingsMeshToDS
40+
#else
41+
#define VaryingsMeshType VaryingsMeshToPS
42+
#endif
43+
3644
// Modifications should probably be replicated to ApplyTessellationModification
37-
AttributesMesh ApplyMeshModification(AttributesMesh input, float3 timeParameters
38-
#ifdef USE_CUSTOMINTERP_SUBSTRUCT
39-
#ifdef TESSELLATION_ON
40-
, inout VaryingsMeshToDS varyings
41-
#else
42-
, inout VaryingsMeshToPS varyings
43-
#endif
44-
#endif
45-
)
45+
void ApplyMeshModification(AttributesMesh input, float3 timeParameters, inout VaryingsMeshType varyings, out VertexDescription vertexDescription)
4646
{
4747
// build graph inputs
4848
VertexDescriptionInputs vertexDescriptionInputs = AttributesMeshToVertexDescriptionInputs(input);
@@ -51,21 +51,18 @@ AttributesMesh ApplyMeshModification(AttributesMesh input, float3 timeParameters
5151
$VertexDescriptionInputs.TimeParameters: vertexDescriptionInputs.TimeParameters = timeParameters;
5252

5353
// evaluate vertex graph
54-
VertexDescription vertexDescription = VertexDescriptionFunction(vertexDescriptionInputs);
54+
vertexDescription = VertexDescriptionFunction(vertexDescriptionInputs);
5555

5656
// Backward compatibility with old graphs
5757
$VertexDescriptionInputs.uv0: vertexDescription.Displacement = vertexDescription.uv0.xyz;
5858
$VertexDescriptionInputs.uv1: vertexDescription.LowFrequencyHeight = vertexDescription.uv1.x;
5959

60-
input.positionOS = vertexDescription.Position + vertexDescription.Displacement;
61-
input.normalOS = vertexDescription.Normal;
62-
PackWaterVertexData(vertexDescription, input.uv0, input.uv1);
63-
60+
// Custom interpolators
6461
$splice(CustomInterpolatorVertMeshCustomInterpolation)
65-
66-
return input;
6762
}
6863

64+
#undef VaryingsMeshType
65+
6966
FragInputs BuildFragInputs(VaryingsMeshToPS input)
7067
{
7168
FragInputs output;
@@ -77,7 +74,7 @@ FragInputs BuildFragInputs(VaryingsMeshToPS input)
7774
output.tangentToWorld = k_identity3x3;
7875
output.positionSS = input.positionCS; // input.positionCS is SV_Position
7976

80-
$FragInputs.positionRWS: output.positionRWS = input.positionRWS;
77+
$FragInputs.positionRWS: output.positionRWS = input.texCoord1.xyz;
8178
$FragInputs.positionPixel: output.positionPixel = input.positionCS.xy; // NOTE: this is not actually in clip space, it is the VPOS pixel coordinate value
8279
$FragInputs.positionPredisplacementRWS: output.positionPredisplacementRWS = input.positionPredisplacementRWS;
8380
$FragInputs.tangentToWorld: output.tangentToWorld = GetLocalFrame(input.normalWS);

0 commit comments

Comments
 (0)