diff --git a/Packages/com.unity.render-pipelines.core/Editor/PathTracing/LightBakerStrangler.cs b/Packages/com.unity.render-pipelines.core/Editor/PathTracing/LightBakerStrangler.cs index a2b22365781..6c2c3fd88e9 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/PathTracing/LightBakerStrangler.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/PathTracing/LightBakerStrangler.cs @@ -940,16 +940,18 @@ internal static Result ExecuteLightmapRequests( bool debugDispatches = integrationSettings.DebugDispatches; bool doDirectionality = AnyLightmapRequestHasOutput(lightmapRequestData.requests, LightmapRequestOutputType.DirectionalityDirect) || AnyLightmapRequestHasOutput(lightmapRequestData.requests, LightmapRequestOutputType.DirectionalityIndirect); - // Find the max index count in any mesh, so we can pre-allocate various buffers based on it. + // Find the max index and vertex count in any mesh, so we can pre-allocate various buffers based on it. uint maxIndexCount = 1; + uint maxVertexCount = 1; for (int meshIdx = 0; meshIdx < world.Meshes.Length; ++meshIdx) { maxIndexCount = Math.Max(maxIndexCount, world.Meshes[meshIdx].GetTotalIndexCount()); + maxVertexCount = Math.Max(maxVertexCount, (uint)world.Meshes[meshIdx].vertexCount); } (int width, int height)[] atlasSizes = lightmapRequestData.atlassing.m_AtlasSizes; int initialLightmapResolution = atlasSizes.Length > 0 ? atlasSizes[0].width : 1024; - if (!lightmappingContext.Initialize(deviceContext, initialLightmapResolution, initialLightmapResolution, world, maxIndexCount, lightmapResourceLib)) + if (!lightmappingContext.Initialize(deviceContext, initialLightmapResolution, initialLightmapResolution, world, maxIndexCount, maxVertexCount, lightmapResourceLib)) return Result.InitializeFailure; lightmappingContext.IntegratorContext.Initialize(samplingResources, lightmapResourceLib, !useLegacyBakingBehavior); diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl index 226f979cfc1..065960fa325 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolume.hlsl @@ -77,13 +77,7 @@ struct APVResources struct APVResourcesRW { -#ifdef SHADER_API_METAL - // We need to use float4 on Metal, since HLSLcc will generate invalid MSL otherwise. - // See https://jira.unity3d.com/browse/UUM-127198 - RWTexture3D L0_L1Rx; -#else RWTexture3D L0_L1Rx; -#endif RWTexture3D L1G_L1Ry; RWTexture3D L1B_L1Rz; RWTexture3D L2_0; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBlendStates.compute b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBlendStates.compute index 75d333d3b4f..30f8252f1d0 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBlendStates.compute +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeBlendStates.compute @@ -15,13 +15,7 @@ Texture3D _State1_L0_L1Rx; Texture3D _State1_L1G_L1Ry; Texture3D _State1_L1B_L1Rz; -#ifdef SHADER_API_METAL -// We need to use float4 on Metal, since HLSLcc will generate invalid MSL otherwise. -// See https://jira.unity3d.com/browse/UUM-127198 -RWTexture3D _Out_L0_L1Rx; -#else RWTexture3D _Out_L0_L1Rx; -#endif RWTexture3D _Out_L1G_L1Ry; RWTexture3D _Out_L1B_L1Rz; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeUploadData.compute b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeUploadData.compute index e43d5d7767e..33418a71fe4 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeUploadData.compute +++ b/Packages/com.unity.render-pipelines.core/Runtime/Lighting/ProbeVolume/ProbeVolumeUploadData.compute @@ -9,13 +9,7 @@ #pragma multi_compile_local _ PROBE_VOLUMES_SKY_SHADING_DIRECTION #pragma multi_compile_local _ PROBE_VOLUMES_PROBE_OCCLUSION -#ifdef SHADER_API_METAL -// We need to use float4 on Metal, since HLSLcc will generate invalid MSL otherwise. -// See https://jira.unity3d.com/browse/UUM-127198 -RWTexture3D _Out_L0_L1Rx; -#else RWTexture3D _Out_L0_L1Rx; -#endif RWTexture3D _Out_L1G_L1Ry; RWTexture3D _Out_L1B_L1Rz; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmappingContext.cs b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmappingContext.cs index 5520402012f..491011d463f 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmappingContext.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/LightmappingContext.cs @@ -130,7 +130,7 @@ internal bool InitializeExpandedBuffer(UInt64 expandedSize) return true; } - internal bool Initialize(UnityComputeDeviceContext deviceContext, int width, int height, UnityComputeWorld world, uint maxIndexCount, LightmapResourceLibrary resources) + internal bool Initialize(UnityComputeDeviceContext deviceContext, int width, int height, UnityComputeWorld world, uint maxIndexCount, uint maxVertexCount, LightmapResourceLibrary resources) { _deviceContext = deviceContext; World = world; @@ -138,7 +138,7 @@ internal bool Initialize(UnityComputeDeviceContext deviceContext, int width, int ResourceCache = new LightmapIntegrationResourceCache(); ChartRasterizer = new ChartRasterizer(resources.SoftwareChartRasterizationShader, resources.HardwareChartRasterizationShader); - InitializeChartRasterizationBuffers(maxIndexCount); + InitializeChartRasterizationBuffers(maxIndexCount, maxVertexCount); return SetOutputResolution(width, height); } @@ -189,7 +189,7 @@ public void InitializeTraceScratchBuffer(uint width, uint height, uint expandedS } } - private void InitializeChartRasterizationBuffers(uint maxIndexCount) + private void InitializeChartRasterizationBuffers(uint maxIndexCount, uint maxVertexCount) { ChartRasterizerBuffers.vertex?.Dispose(); ChartRasterizerBuffers.vertex = null; @@ -198,10 +198,11 @@ private void InitializeChartRasterizationBuffers(uint maxIndexCount) ChartRasterizerBuffers.vertexToChartID?.Dispose(); ChartRasterizerBuffers.vertexToChartID = null; - // We base the size of the temporary buffers on the triangle count of the mesh with the most triangles, to avoid constant reallocations. - ChartRasterizerBuffers.vertex = new GraphicsBuffer(GraphicsBuffer.Target.Structured, (int)maxIndexCount, UnsafeUtility.SizeOf()); - ChartRasterizerBuffers.vertexToOriginalVertex = new GraphicsBuffer(GraphicsBuffer.Target.Structured, (int)maxIndexCount, sizeof(uint)); - ChartRasterizerBuffers.vertexToChartID = new GraphicsBuffer(GraphicsBuffer.Target.Structured, (int)maxIndexCount, sizeof(uint)); + // We base the size of the temporary buffers on the vertex count or index count of the mesh with the most vertices / indices, to avoid constant reallocations. + uint maxCount = Math.Max(maxIndexCount, maxVertexCount); + ChartRasterizerBuffers.vertex = new GraphicsBuffer(GraphicsBuffer.Target.Structured, (int)maxCount, UnsafeUtility.SizeOf()); + ChartRasterizerBuffers.vertexToOriginalVertex = new GraphicsBuffer(GraphicsBuffer.Target.Structured, (int)maxCount, sizeof(uint)); + ChartRasterizerBuffers.vertexToChartID = new GraphicsBuffer(GraphicsBuffer.Target.Structured, (int)maxCount, sizeof(uint)); } public CommandBuffer GetCommandBuffer() diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/Lightmapping/ChartRasterizerSoftware.shader b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/Lightmapping/ChartRasterizerSoftware.shader index d4a3af9887e..c4f95b542c3 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/Lightmapping/ChartRasterizerSoftware.shader +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/Lightmapping/ChartRasterizerSoftware.shader @@ -11,6 +11,8 @@ Shader "Hidden/ChartRasterizerSoftware" #pragma fragment frag #include "GeometryUtils.hlsl" + #define PARALLEL_EPS 1e-6f + struct v2f { float4 vertex : SV_POSITION; @@ -34,7 +36,7 @@ Shader "Hidden/ChartRasterizerSoftware" uint2 resolution = uint2(g_Width, g_Height); float2 tri[3]; ReadParentTriangle(g_VertexBuffer, vertexId, g_ScaleAndOffset, tri); - ExpandTriangleForConservativeRasterization(resolution, tri, vertexId, o.aabb, o.vertex); + ExpandTriangleForConservativeRasterization(resolution, tri, vertexId, o.aabb, o.vertex, PARALLEL_EPS); // Get the chart index. uint originalVertexId = g_VertexToOriginalVertex[vertexId]; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/Lightmapping/GeometryUtils.hlsl b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/Lightmapping/GeometryUtils.hlsl index a152f042ee2..06da9d25b62 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/Lightmapping/GeometryUtils.hlsl +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/Lightmapping/GeometryUtils.hlsl @@ -16,7 +16,7 @@ void OffsetEdge(float2 v1, float2 v2, float2 pixelSize, out float2 v1Offset, out } // Given 2 lines defined by 2 points each, find the intersection point. -float2 LineIntersect(float2 p1, float2 p2, float2 p3, float2 p4) +float2 LineIntersect(float2 p1, float2 p2, float2 p3, float2 p4, float eps = 0.0f) { // Line p1p2 represented as a1x + b1y = c1 float a1 = p2.y - p1.y; @@ -29,7 +29,7 @@ float2 LineIntersect(float2 p1, float2 p2, float2 p3, float2 p4) float c2 = a2 * p3.x + b2 * p3.y; float determinant = a1 * b2 - a2 * b1; - if (determinant == 0) // Parallel lines - return any valid point. + if (abs(determinant) <= eps) // Parallel lines - return any valid point. return p1; float x = b2 * c1 - b1 * c2; @@ -46,7 +46,7 @@ bool IsInside(float2 p, float2 cp1, float2 cp2, float eps = 0.0f) // Clip a polygon with a line defined by two points, in place. // https://en.wikipedia.org/wiki/Sutherland-Hodgman_algorithm -void ClipPolygonWithLine(inout float2 polygon[6], inout uint polygonLength, float2 cp1, float2 cp2) +void ClipPolygonWithLine(inout float2 polygon[6], inout uint polygonLength, float2 cp1, float2 cp2, float inside_eps = 0.0f, float parallel_eps = 0.0f) { float2 result[6]; uint resultLength = 0; @@ -56,19 +56,19 @@ void ClipPolygonWithLine(inout float2 polygon[6], inout uint polygonLength, floa float2 s = polygon[i]; float2 e = polygon[(i + 1) % polygonLength]; - if (IsInside(e, cp1, cp2)) // At least one endpoint is inside + if (IsInside(e, cp1, cp2, inside_eps)) // At least one endpoint is inside { - if (!IsInside(s, cp1, cp2)) // Only the end point is inside, add the intersection + if (!IsInside(s, cp1, cp2, inside_eps)) // Only the end point is inside, add the intersection { - result[resultLength] = LineIntersect(cp1, cp2, s, e); + result[resultLength] = LineIntersect(cp1, cp2, s, e, parallel_eps); resultLength++; } result[resultLength] = e; resultLength++; } - else if (IsInside(s, cp1, cp2)) // Only the start point is inside, add the intersection + else if (IsInside(s, cp1, cp2, inside_eps)) // Only the start point is inside, add the intersection { - result[resultLength] = LineIntersect(cp1, cp2, s, e); + result[resultLength] = LineIntersect(cp1, cp2, s, e, parallel_eps); resultLength++; } } @@ -79,7 +79,7 @@ void ClipPolygonWithLine(inout float2 polygon[6], inout uint polygonLength, floa } // Clip a polygon to the bounding box of a texel at the given position -bool ClipPolygonWithTexel(float2 texelPosition, inout float2 polygon[6], inout uint polygonLength) +bool ClipPolygonWithTexel(float2 texelPosition, inout float2 polygon[6], inout uint polygonLength, float inside_eps = 0.0f, float parallel_eps = 0.0f) { // Get the bounding box of the texel to clip with. float2 clipPolygon[4] = @@ -93,7 +93,7 @@ bool ClipPolygonWithTexel(float2 texelPosition, inout float2 polygon[6], inout u // Clip to each edge of the quad for (uint edge = 0; edge < 4; edge++) { - ClipPolygonWithLine(polygon, polygonLength, clipPolygon[edge], clipPolygon[(edge + 1) % 4]); + ClipPolygonWithLine(polygon, polygonLength, clipPolygon[edge], clipPolygon[(edge + 1) % 4], inside_eps, parallel_eps); } return polygonLength > 0; @@ -128,7 +128,8 @@ void ExpandTriangleForConservativeRasterization( float2 tri[3], uint vertexId, out float4 triangleAABB, - out float4 vertex) + out float4 vertex, + float eps = 0.0f) { float2 pixelSize = (1.0 / resolution); @@ -146,9 +147,9 @@ void ExpandTriangleForConservativeRasterization( OffsetEdge(tri[2], tri[0], pixelSize, v3Off3, v1Off3); // Find their intersections. This is the new triangle - tri[0] = LineIntersect(v1Off1, v2Off1, v3Off3, v1Off3); - tri[1] = LineIntersect(v2Off2, v3Off2, v1Off1, v2Off1); - tri[2] = LineIntersect(v3Off3, v1Off3, v2Off2, v3Off2); + tri[0] = LineIntersect(v1Off1, v2Off1, v3Off3, v1Off3, eps); + tri[1] = LineIntersect(v2Off2, v3Off2, v1Off1, v2Off1, eps); + tri[2] = LineIntersect(v3Off3, v1Off3, v2Off2, v3Off2, eps); vertex = float4(tri[vertexId % 3]*2-1, 0, 1); #if UNITY_UV_STARTS_AT_TOP vertex.y = -vertex.y; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/Lightmapping/UVFallbackBufferGeneration.shader b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/Lightmapping/UVFallbackBufferGeneration.shader index 0d66d5ce48c..863bcb4420c 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/Lightmapping/UVFallbackBufferGeneration.shader +++ b/Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/Lightmapping/UVFallbackBufferGeneration.shader @@ -12,6 +12,10 @@ Shader "Hidden/UVFallbackBufferGeneration" #pragma target 5.0 #include "GeometryUtils.hlsl" + #define INSIDE_EPS 0.01f // Epsilon chosen to be 1 order of magnitude larger than the maximum + // distance between subsequent floats in range [0; 8192] + #define PARALLEL_EPS 1e-6f + struct v2f { float4 vertex : SV_POSITION; @@ -32,8 +36,9 @@ Shader "Hidden/UVFallbackBufferGeneration" uint2 resolution = uint2(g_Width, g_Height); float2 tri[3]; float4 unusedAABB; + const float eps = 0.01f; ReadParentTriangle(g_VertexBuffer, vertexId, float4(g_WidthScale, g_HeightScale, 0, 0), tri); - ExpandTriangleForConservativeRasterization(resolution, tri, vertexId, unusedAABB, o.vertex); + ExpandTriangleForConservativeRasterization(resolution, tri, vertexId, unusedAABB, o.vertex, PARALLEL_EPS); // Scale the triangle to screen coordinates, pass it to fragment shader. o.vertices[0] = tri[0] * resolution; @@ -54,8 +59,7 @@ Shader "Hidden/UVFallbackBufferGeneration" // as our intersector cannot handle such points. Epsilon chosen to be 1 order of magnitude larger than the maximum // distance between subsequent floats in range [0; 8192] float2 texelCenter = i.vertex.xy; - const float eps = 0.01f; - if (IsInside(texelCenter, c, b, eps) && IsInside(texelCenter, b, a, eps) && IsInside(texelCenter, a, c, eps)) + if (IsInside(texelCenter, c, b, INSIDE_EPS) && IsInside(texelCenter, b, a, INSIDE_EPS) && IsInside(texelCenter, a, c, INSIDE_EPS)) { #if UNITY_REVERSED_Z depth = 1.0; @@ -70,7 +74,7 @@ Shader "Hidden/UVFallbackBufferGeneration" uint resultSize = 3; // Clip to the texel. - ClipPolygonWithTexel(texelCenter, result, resultSize); + ClipPolygonWithTexel(texelCenter, result, resultSize, INSIDE_EPS, PARALLEL_EPS); // Discard removed triangles. if (resultSize <= 0) diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceTexture.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceTexture.cs index cd63545cf4a..ad0c471b356 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceTexture.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResourceTexture.cs @@ -97,7 +97,7 @@ internal enum TextureUVOriginSelection /// [DebuggerDisplay("Texture ({handle.index})")] [MovedFrom(true, "UnityEngine.Experimental.Rendering.RenderGraphModule", "UnityEngine.Rendering.RenderGraphModule")] - public readonly struct TextureHandle + public readonly struct TextureHandle : IEquatable { private static TextureHandle s_NullHandle = new TextureHandle(); @@ -151,6 +151,52 @@ internal TextureHandle(int handle, bool shared = false, bool builtin = false) /// Resource as a RTHandle. public static implicit operator RTHandle(TextureHandle texture) => texture.IsValid() ? RenderGraphResourceRegistry.current.GetTexture(texture) : null; + /// + /// Determines whether this instance and another specified object have the same underlying resource handle. + /// + /// The texture handle to compare with the current instance. + /// + /// True if both texture handles reference the same underlying resource; otherwise, false. + /// + public bool Equals(TextureHandle other) => handle.Equals(other.handle); + + /// + /// Determines whether the specified object is equal to the current . + /// + /// The object to compare with the current instance. + /// + /// True if the specified object is a and references the same underlying resource; otherwise, false. + /// + public override bool Equals(object obj) => obj is TextureHandle other && Equals(other); + + /// + /// Returns the hash code for this . + /// + /// + /// The hash code of the current . + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + /// Determines whether two instances reference the same underlying resource. + /// + /// The first texture handle to compare. + /// The second texture handle to compare. + /// + /// True if both handles reference the same underlying resource; otherwise, false. + /// + public static bool operator ==(TextureHandle lhs, TextureHandle rhs) => lhs.handle.Equals(rhs.handle); + + /// + /// Determines whether two instances reference different underlying resources. + /// + /// The first texture handle to compare. + /// The second texture handle to compare. + /// + /// True if the handles reference different underlying resources; otherwise, false. + /// + public static bool operator !=(TextureHandle lhs, TextureHandle rhs) => !lhs.handle.Equals(rhs.handle); + /// /// Return true if the handle is valid. /// diff --git a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs index 14f0589f409..27b3a51cc65 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphResources.cs @@ -123,6 +123,21 @@ public bool Equals(ResourceHandle hdl) { return hdl.m_Value == this.m_Value && hdl.m_Version == this.m_Version && hdl.type == this.type; } + + public static bool operator ==(ResourceHandle lhs, ResourceHandle rhs) => lhs.Equals(rhs); + + public static bool operator !=(ResourceHandle lhs, ResourceHandle rhs) => !lhs.Equals(rhs); + + public override bool Equals(object obj) => obj is ResourceHandle other && Equals(other); + + public override int GetHashCode() + { + var hashCode = HashFNV1A32.Create(); + hashCode.Append(m_Value); + hashCode.Append(m_Version); + hashCode.Append(m_Type); + return hashCode.value; + } } class IRenderGraphResource diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/PathTracing/UVFallbackBufferTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/PathTracing/UVFallbackBufferTests.cs index c4f6fddc894..29c33e1413c 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/PathTracing/UVFallbackBufferTests.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/PathTracing/UVFallbackBufferTests.cs @@ -422,9 +422,9 @@ public void Build_QuadWithNonSquareUVs_AllCoveredTexelsAreOccupied([ValueSource( mesh.uv = new[] { new Vector2(0, 0), - new Vector2(0.501f, 0), // Cover the 2 rightmost texels by only a tiny amount + new Vector2(0.51f, 0), // Cover the 2 rightmost texels by only a tiny amount (must exceed INSIDE_EPS in screen-space units) new Vector2(0, 1), - new Vector2(0.501f, 1) + new Vector2(0.51f, 1) }; UVFallbackBufferResources.GetUVFallbackBuffer(_resources, mesh, buildFlags, width, height, out Color[] fallbackData); diff --git a/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs index 6df299a2d62..3389eb7540f 100644 --- a/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs +++ b/Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs @@ -6,7 +6,7 @@ using UnityEngine.TestTools; using Unity.Collections; using UnityEngine.Rendering.RendererUtils; -using System.Text.RegularExpressions; +using UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler; #if UNITY_EDITOR using UnityEditor; @@ -1489,7 +1489,7 @@ public void ImportedTexturesAreClearedOnFirstUse() m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => { - var redTexture = CreateRedTexture(kWidth, kHeight); + var redTexture = CreateColorTexture(kWidth, kHeight, Color.red); ImportResourceParams importParams = new ImportResourceParams() { clearColor = Color.blue, clearOnFirstUse = true @@ -1533,6 +1533,128 @@ public void ImportedTexturesAreClearedOnFirstUse() pixels.Dispose(); } + [Test] + public void ImportedTexturesOperatorEqualAndNotEqual() + { + const int kWidth = 4; + const int kHeight = 4; + + m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => + { + var importParams = new ImportResourceParams() + { + clearColor = Color.black, + clearOnFirstUse = true + }; + + var redTexture = CreateColorTexture(kWidth, kHeight, Color.red); + var red2Texture = CreateColorTexture(kWidth, kHeight, Color.red); + var blackTexture = CreateColorTexture(kWidth, kHeight, Color.black); + + var importedTextureRed = m_RenderGraph.ImportTexture(redTexture, importParams); + var importedTextureRed2 = m_RenderGraph.ImportTexture(red2Texture, importParams); + var importedTextureRedSame = m_RenderGraph.ImportTexture(redTexture, importParams); + var importedTextureBlack = m_RenderGraph.ImportTexture(blackTexture, importParams); + + // Different textures, different handles. + Assert.True(importedTextureRed != importedTextureBlack); + + // Different textures, different handles. + Assert.True(importedTextureRed != importedTextureRed2); + + // Same texture, different handles. + Assert.False(importedTextureRed == importedTextureRedSame); + + importedTextureRedSame = importedTextureRed; + + // Same texture, same handle. + Assert.True(importedTextureRed == importedTextureRedSame); + }; + + m_Camera.Render(); + } + + [Test] + public void CreatedTexturesOperatorEqualAndNotEqual() + { + m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => + { + const int kWidth = 4; + const int kHeight = 4; + + var texture0 = m_RenderGraph.CreateTexture(new TextureDesc(kWidth, kHeight) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, name = "Texture0" }); + var texture1 = m_RenderGraph.CreateTexture(new TextureDesc(kWidth, kHeight) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, name = "Texture1" }); + + // Different textures, different handles. + Assert.True(texture0 != texture1); + + // Different textures, different handles. + Assert.False(texture0 == texture1); + + texture1 = texture0; + + // Same texture, same handles. + Assert.True(texture0 == texture1); + + // Same texture, same handles. + Assert.False(texture0 != texture1); + }; + + m_Camera.Render(); + } + + [Test] + public void TexturesOperatorWorksInList() + { + m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => + { + const int kWidth = 4; + const int kHeight = 4; + + var texture0 = m_RenderGraph.CreateTexture(new TextureDesc(kWidth, kHeight) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, name = "Texture0" }); + var texture1 = m_RenderGraph.CreateTexture(new TextureDesc(kWidth, kHeight) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, name = "Texture1" }); + + var listHandles = new List(); + listHandles.Add(texture0); + + Assert.True(listHandles.Contains(texture0)); + Assert.True(!listHandles.Contains(texture1)); + + listHandles.Add(texture1); + + Assert.True(listHandles.Contains(texture1)); + }; + + m_Camera.Render(); + } + + [Test] + public void TexturesOperatorWorksInDictionary() + { + m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) => + { + const int kWidth = 4; + const int kHeight = 4; + + var texture0 = m_RenderGraph.CreateTexture(new TextureDesc(kWidth, kHeight) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, name = "Texture0" }); + var texture1 = m_RenderGraph.CreateTexture(new TextureDesc(kWidth, kHeight) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm, name = "Texture1" }); + + var dictionaryHandles = new Dictionary(); + dictionaryHandles.Add(texture0, 0); + + Assert.True(dictionaryHandles.ContainsKey(texture0)); + Assert.True(dictionaryHandles.TryGetValue(texture0, out var value0) && value0 == 0); + Assert.True(!dictionaryHandles.ContainsKey(texture1)); + + dictionaryHandles.Add(texture1, 1); + + Assert.True(dictionaryHandles.ContainsKey(texture1)); + Assert.True(dictionaryHandles.TryGetValue(texture1, out var value1) && value1 == 1); + }; + + m_Camera.Render(); + } + [Test] public void RequestAsyncReadbackIntoNativeArrayWorks() { @@ -1552,7 +1674,7 @@ public void RequestAsyncReadbackIntoNativeArrayWorks() passExecuted = true; - var redTexture = CreateRedTexture(kWidth, kHeight); + var redTexture = CreateColorTexture(kWidth, kHeight, Color.red); var texture0 = m_RenderGraph.ImportTexture(redTexture); pixels = new NativeArray(kWidth * kHeight * 4, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); @@ -1603,11 +1725,8 @@ void RenderGraphTest_AsyncReadbackCallback(AsyncGPUReadbackRequest request, ref } } - RTHandle CreateRedTexture(int width, int height) + RTHandle CreateColorTexture(int width, int height, Color color) { - // Create a red color - Color redColor = Color.red; - // Initialize the RTHandle system if necessary RTHandles.Initialize(width, height); @@ -1625,7 +1744,7 @@ RTHandle CreateRedTexture(int width, int height) { for (int x = 0; x < tempTexture.width; x++) { - tempTexture.SetPixel(x, y, redColor); + tempTexture.SetPixel(x, y, color); } } tempTexture.Apply(); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.hlsl index 2bb3d1c340c..1bdffcc9c14 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.hlsl @@ -124,7 +124,8 @@ void BilUpColor3x3(float highDepth, in NeighborhoodUpsampleData3x3 data, out flo float TotalWeight = combinedWeightsA.x + combinedWeightsA.y + combinedWeightsA.z + combinedWeightsA.w + combinedWeightsB.x + combinedWeightsB.y + combinedWeightsB.z + combinedWeightsB.w - + combinedWeightsC; + + combinedWeightsC + + _NoiseFilterStrength; float4 WeightedSum = data.lowValue0 * combinedWeightsA.x + data.lowValue1 * combinedWeightsA.y @@ -134,25 +135,15 @@ void BilUpColor3x3(float highDepth, in NeighborhoodUpsampleData3x3 data, out flo + data.lowValue5 * combinedWeightsB.y + data.lowValue6 * combinedWeightsB.z + data.lowValue7 * combinedWeightsB.w - + data.lowValue8 * combinedWeightsC - + float4(_NoiseFilterStrength.xxx, 0.0f); + + data.lowValue8 * combinedWeightsC; float WeightedDepth = dot(data.lowDepthValueA, combinedWeightsA) + dot(data.lowDepthValueB, combinedWeightsB) + data.lowDepthValueC * combinedWeightsC + _NoiseFilterStrength; - // This branch shouldn't be needed if we do the neighbor analysis mentionned in BuildRay - if (TotalWeight == 0.0f) - { - outColor = float4(0, 0, 0, 1); - outDepth = UNITY_NEAR_CLIP_VALUE; - } - else - { - outColor = WeightedSum / (TotalWeight + _NoiseFilterStrength); - outDepth = WeightedDepth / (TotalWeight + _NoiseFilterStrength); - } + outColor = WeightedSum / TotalWeight; + outDepth = WeightedDepth / TotalWeight; } // Due to compiler issues, it is not possible to use arrays to store the neighborhood values, we then store them in this structure diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFog.cs.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFog.cs.meta index f03ddda2af1..177c9533c47 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFog.cs.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/VolumetricLighting/LocalVolumetricFog.cs.meta @@ -5,6 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 + icon: {fileID: 2800000, guid: a51c08ea4f8a47641a38f14eff7be3db, type: 2} userData: assetBundleName: assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Canvas/HDCanvasPass.hlsl b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Canvas/HDCanvasPass.hlsl index d688c00468e..ce526019b65 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Canvas/HDCanvasPass.hlsl +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Canvas/HDCanvasPass.hlsl @@ -91,6 +91,8 @@ Varyings BuildVaryings(Attributes input) float4 clampedRect = clamp(_ClipRect, -2e10, 2e10); float2 maskUV = (input.positionOS.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy); output.texCoord1 = float4(input.positionOS.xy * 2 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * half2(_UIMaskSoftnessX, _UIMaskSoftnessY) + abs(pixelSize.xy))); + #else + output.texCoord1 = input.uv1; #endif #endif diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.cs.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.cs.meta index 369590cb415..292a4bcd018 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.cs.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Decal/DecalProjector.cs.meta @@ -5,6 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 + icon: {fileID: 2800000, guid: 340b2e8f8761e254d8ee52bc663cedbd, type: 2} userData: assetBundleName: assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPass.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPass.cs index a0a82bf4cc1..ffb4289aecb 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPass.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPass.cs @@ -227,7 +227,7 @@ RenderTargets ReadRenderTargets(in IUnsafeRenderGraphBuilder builder, in RenderT output.colorBufferRG = targets.colorBufferRG; builder.UseTexture(output.colorBufferRG, AccessFlags.ReadWrite); } - if (targets.nonMSAAColorBufferRG.IsValid()) + if (targets.nonMSAAColorBufferRG.IsValid() && targets.nonMSAAColorBufferRG != targets.colorBufferRG) { output.nonMSAAColorBufferRG = targets.nonMSAAColorBufferRG; builder.UseTexture(output.nonMSAAColorBufferRG, AccessFlags.ReadWrite); diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/Legacy/WaterDeformer.cs.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/Legacy/WaterDeformer.cs.meta index 97092193dfc..f2bc3d8db89 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/Legacy/WaterDeformer.cs.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/Legacy/WaterDeformer.cs.meta @@ -5,7 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {fileID: 2800000, guid: b057b73ec5a603e4aa80ccf4b34db0d3, type: 3} + icon: {fileID: 2800000, guid: 340b2e8f8761e254d8ee52bc663cedbd, type: 2} userData: assetBundleName: assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/Legacy/WaterFoamGenerator.cs.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/Legacy/WaterFoamGenerator.cs.meta index 7e8cc867259..da48c021a3c 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/Legacy/WaterFoamGenerator.cs.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/Legacy/WaterFoamGenerator.cs.meta @@ -5,7 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {fileID: 2800000, guid: b057b73ec5a603e4aa80ccf4b34db0d3, type: 3} + icon: {fileID: 2800000, guid: 340b2e8f8761e254d8ee52bc663cedbd, type: 2} userData: assetBundleName: assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs index c40e463a9aa..c60fba01840 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs @@ -8,6 +8,7 @@ namespace UnityEngine.Rendering.HighDefinition /// [HDRPHelpURL("water-decals-and-masking-in-the-water-system")] [ExecuteInEditMode] + [Icon("Packages/com.unity.render-pipelines.core/Editor/Icons/Processed/DecalProjector Icon.asset")] public partial class WaterDecal : MonoBehaviour { internal enum PassType diff --git a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs.meta b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs.meta index bd89e58cab4..87978e31764 100644 --- a/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs.meta +++ b/Packages/com.unity.render-pipelines.high-definition/Runtime/Water/WaterDecal/WaterDecal.cs.meta @@ -5,7 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {fileID: 2800000, guid: b057b73ec5a603e4aa80ccf4b34db0d3, type: 3} + icon: {fileID: 2800000, guid: 340b2e8f8761e254d8ee52bc663cedbd, type: 2} userData: assetBundleName: - assetBundleVariant: \ No newline at end of file + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Editor/RendererFeatures/DecalRendererFeatureEditor.cs b/Packages/com.unity.render-pipelines.universal/Editor/RendererFeatures/DecalRendererFeatureEditor.cs index ba16ae93864..5e8ac49fbdf 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/RendererFeatures/DecalRendererFeatureEditor.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/RendererFeatures/DecalRendererFeatureEditor.cs @@ -14,6 +14,7 @@ private struct Styles public static GUIContent UseRenderingLayers = EditorGUIUtility.TrTextContent("Use Rendering Layers", "When enabled, you can configure specific Decal Projectors to affect only specific objects. The number of Rendering Layers affects the performance."); public static GUIContent SurfaceData = EditorGUIUtility.TrTextContent("Surface Data", "Allows specifying which decals surface data should be blended with surfaces."); public static GUIContent NormalBlend = EditorGUIUtility.TrTextContent("Normal Blend", "Controls the quality of normal reconstruction. The higher the value the more accurate normal reconstruction and the cost on performance."); + public static readonly GUIContent OpenGlSupportWarning = EditorGUIUtility.TrTextContentWithIcon("Rendering Layers are not supported on OpenGL.", "This feature is incompatible with OpenGL. Disable 'Auto Graphics API' in Player Settings and remove OpenGL from the list.", MessageType.Warning); } private SerializedProperty m_Technique; @@ -45,7 +46,18 @@ public override void OnInspectorGUI() { Init(); - var isGLDevice = SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES3 || SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLCore; + var gfxTypes = PlayerSettings.GetGraphicsAPIs(EditorUserBuildSettings.activeBuildTarget); + + var isGLDevice = false; + + foreach (var type in gfxTypes) + { + if (type == GraphicsDeviceType.OpenGLES3 || type == GraphicsDeviceType.OpenGLCore) + { + isGLDevice = true; + break; + } + } EditorGUILayout.PropertyField(m_Technique, Styles.Technique); @@ -89,7 +101,7 @@ public override void OnInspectorGUI() if (isGLDevice) { GUI.enabled = true; - EditorGUILayout.HelpBox("Rendering Layers are not supported on OpenGL.", MessageType.Warning); + EditorGUILayout.HelpBox(Styles.OpenGlSupportWarning); } } } diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/CanvasPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/CanvasPass.hlsl index d3f261d1c6b..82128033643 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/CanvasPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/CanvasPass.hlsl @@ -80,6 +80,8 @@ Varyings BuildVaryings(Attributes input) float4 clampedRect = clamp(_ClipRect, -2e10, 2e10); float2 maskUV = (input.positionOS.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy); output.texCoord1 = float4(input.positionOS.xy * 2 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * half2(_UIMaskSoftnessX, _UIMaskSoftnessY) + abs(pixelSize.xy))); + #else + output.texCoord1 = input.uv1; #endif #endif diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UITKPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UITKPass.hlsl index e1f5bcf34dc..03f675a2799 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UITKPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UITKPass.hlsl @@ -2,9 +2,6 @@ #error SHADERPASS_CUSTOM_UI_is_not_correctly_defined #endif - -#define UIE_NOINTERPOLATION nointerpolation - PackedVaryings uie_custom_vert(Attributes input) { appdata_t uieInput = (appdata_t)0; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Decal/DecalProjector.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Decal/DecalProjector.cs index 97ba722c212..b136f041e9d 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Decal/DecalProjector.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Decal/DecalProjector.cs @@ -23,6 +23,7 @@ public enum DecalScaleMode [CanEditMultipleObjects] #endif [AddComponentMenu("Rendering/URP Decal Projector")] + [Icon("Packages/com.unity.render-pipelines.core/Editor/Icons/Processed/DecalProjector Icon.asset")] public partial class DecalProjector : MonoBehaviour, ISerializationCallbackReceiver { internal delegate void DecalProjectorAction(DecalProjector decalProjector); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Decal/DecalProjector.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/Decal/DecalProjector.cs.meta index 664d9b5ed37..ac0b996ac82 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Decal/DecalProjector.cs.meta +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Decal/DecalProjector.cs.meta @@ -5,7 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {fileID: 2800000, guid: 9ba98ca4f0fc0754caca09e38af0cc0a, type: 3} + icon: {fileID: 2800000, guid: 340b2e8f8761e254d8ee52bc663cedbd, type: 2} userData: assetBundleName: assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/ScreenSpaceAmbientOcclusionPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/ScreenSpaceAmbientOcclusionPass.cs index d8b1a6a16fa..9f4842c867b 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/ScreenSpaceAmbientOcclusionPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/ScreenSpaceAmbientOcclusionPass.cs @@ -67,21 +67,21 @@ private enum ShaderPasses } // Structs - private struct SSAOMaterialParams + private readonly struct SSAOMaterialParams { - internal bool orthographicCamera; - internal bool aoBlueNoise; - internal bool aoInterleavedGradient; - internal bool sampleCountHigh; - internal bool sampleCountMedium; - internal bool sampleCountLow; - internal bool sourceDepthNormals; - internal bool sourceDepthHigh; - internal bool sourceDepthMedium; - internal bool sourceDepthLow; - internal Vector4 ssaoParams; - - internal SSAOMaterialParams(ref ScreenSpaceAmbientOcclusionSettings settings, bool isOrthographic) + internal readonly bool orthographicCamera; + internal readonly bool aoBlueNoise; + internal readonly bool aoInterleavedGradient; + internal readonly bool sampleCountHigh; + internal readonly bool sampleCountMedium; + internal readonly bool sampleCountLow; + internal readonly bool sourceDepthNormals; + internal readonly bool sourceDepthHigh; + internal readonly bool sourceDepthMedium; + internal readonly bool sourceDepthLow; + internal readonly Vector4 ssaoParams; + + internal SSAOMaterialParams(ScreenSpaceAmbientOcclusionSettings settings, bool isOrthographic) { bool isUsingDepthNormals = settings.Source == ScreenSpaceAmbientOcclusionSettings.DepthSource.DepthNormals; float radiusMultiplier = settings.AOMethod == ScreenSpaceAmbientOcclusionSettings.AOMethodOptions.BlueNoise ? 1.5f : 1; @@ -103,7 +103,7 @@ internal SSAOMaterialParams(ref ScreenSpaceAmbientOcclusionSettings settings, bo ); } - internal bool Equals(ref SSAOMaterialParams other) + internal bool Equals(in SSAOMaterialParams other) { return orthographicCamera == other.orthographicCamera && aoBlueNoise == other.aoBlueNoise @@ -126,7 +126,7 @@ internal ScreenSpaceAmbientOcclusionPass() m_CurrentSettings = new ScreenSpaceAmbientOcclusionSettings(); } - internal bool Setup(ref ScreenSpaceAmbientOcclusionSettings featureSettings, ref ScriptableRenderer renderer, ref Material material, ref Texture2D[] blueNoiseTextures) + internal bool Setup(ScreenSpaceAmbientOcclusionSettings featureSettings, ScriptableRenderer renderer, Material material, Texture2D[] blueNoiseTextures) { m_BlueNoiseTextures = blueNoiseTextures; m_Material = material; @@ -135,7 +135,7 @@ internal bool Setup(ref ScreenSpaceAmbientOcclusionSettings featureSettings, ref // RenderPass Event + Source Settings (Depth / Depth&Normals if (renderer is UniversalRenderer { usesDeferredLighting: true }) { - renderPassEvent = m_CurrentSettings.AfterOpaque ? RenderPassEvent.AfterRenderingOpaques : RenderPassEvent.AfterRenderingGbuffer; + renderPassEvent = m_CurrentSettings.AfterOpaque ? RenderPassEvent.AfterRenderingOpaques : RenderPassEvent.AfterRenderingPrePasses; m_CurrentSettings.Source = ScreenSpaceAmbientOcclusionSettings.DepthSource.DepthNormals; } @@ -243,8 +243,8 @@ private void SetupKeywordsAndParameters(ref ScreenSpaceAmbientOcclusionSettings // Setting keywords can be somewhat expensive on low-end platforms. // Previous params are cached to avoid setting the same keywords every frame. - SSAOMaterialParams matParams = new SSAOMaterialParams(ref settings, cameraData.camera.orthographic); - bool ssaoParamsDirty = !m_SSAOParamsPrev.Equals(ref matParams); // Checks if the parameters have changed. + SSAOMaterialParams matParams = new SSAOMaterialParams(settings, cameraData.camera.orthographic); + bool ssaoParamsDirty = !m_SSAOParamsPrev.Equals(in matParams); // Checks if the parameters have changed. bool isParamsPropertySet = m_Material.HasProperty(s_SSAOParamsID); // Checks if the parameters have been set on the material. if (!ssaoParamsDirty && isParamsPropertySet) return; @@ -271,6 +271,7 @@ private class SSAOPassData { internal bool afterOpaque; internal ScreenSpaceAmbientOcclusionSettings.BlurQualityOptions BlurQuality; + internal MaterialPropertyBlock materialPropertyBlock; internal Material material; internal float directLightingStrength; internal TextureHandle cameraColor; @@ -281,7 +282,24 @@ private class SSAOPassData internal UniversalCameraData cameraData; } - private void InitSSAOPassData(ref SSAOPassData data) + private class SSAOBlurPassData + { + internal TextureHandle srcTexture; + internal TextureHandle dstTexture; + internal MaterialPropertyBlock materialPropertyBlock; + internal Material material; + internal UniversalCameraData cameraData; + internal int pass; + internal ScreenSpaceAmbientOcclusionSettings.BlurQualityOptions BlurQuality; + internal bool afterOpaque; + } + + private class SSAOFinalPassData + { + internal float directLightingStrength; + } + + private void InitSSAOPassData(SSAOPassData data) { data.material = m_Material; data.BlurQuality = m_CurrentSettings.BlurQuality; @@ -289,27 +307,67 @@ private void InitSSAOPassData(ref SSAOPassData data) data.directLightingStrength = m_CurrentSettings.DirectLightingStrength; } - private static Vector4 ComputeScaleBias(in UnsafeGraphContext context, in TextureHandle source, in TextureHandle destination) + private void InitSSAOBlurPassData(SSAOBlurPassData data) + { + data.material = m_Material; + data.BlurQuality = m_CurrentSettings.BlurQuality; + data.afterOpaque = m_CurrentSettings.AfterOpaque; + } + + private static Vector4 ComputeScaleBias(in TextureHandle source, bool yFlip) { RTHandle srcRTHandle = source; Vector2 viewportScale; if (srcRTHandle is { useScaling: true }) { - viewportScale.x = srcRTHandle.rtHandleProperties.rtHandleScale.x; - viewportScale.y = srcRTHandle.rtHandleProperties.rtHandleScale.y; + var scale = srcRTHandle.rtHandleProperties.rtHandleScale; + viewportScale.x = scale.x; + viewportScale.y = scale.y; } else { viewportScale = Vector2.one; } - bool yFlip = context.GetTextureUVOrigin(in source) != context.GetTextureUVOrigin(in destination); if (yFlip) return new Vector4(viewportScale.x, -viewportScale.y, 0, viewportScale.y); else return new Vector4(viewportScale.x, viewportScale.y, 0, 0); } + private static readonly int _BlitScaleBias = Shader.PropertyToID(nameof(_BlitScaleBias)); + private static readonly int _BlitTexture = Shader.PropertyToID(nameof(_BlitTexture)); + + private void RecordBlurStep(RenderGraph renderGraph, UniversalCameraData cameraData, string blurPassName, in TextureHandle src, in TextureHandle dst, int pass, bool isLastPass) + { + using (var builder = renderGraph.AddRasterRenderPass(blurPassName, out var passData, m_ProfilingSampler)) + { + // Fill in the Pass data... + InitSSAOBlurPassData(passData); + passData.srcTexture = src; + passData.dstTexture = dst; + passData.cameraData = cameraData; + passData.pass = pass; + passData.materialPropertyBlock ??= new(); + + builder.UseTexture(passData.srcTexture); + + AccessFlags finalDstAccess = passData.afterOpaque && isLastPass ? AccessFlags.Write : AccessFlags.WriteAll; + builder.SetRenderAttachment(passData.dstTexture, 0, finalDstAccess); + + builder.SetRenderFunc(static (SSAOBlurPassData data, RasterGraphContext ctx) => + { + bool yFlip = ctx.GetTextureUVOrigin(in data.srcTexture) != ctx.GetTextureUVOrigin(in data.dstTexture); + Vector4 viewScaleBias = ComputeScaleBias(data.srcTexture, yFlip); + + data.materialPropertyBlock.Clear(); + data.materialPropertyBlock.SetVector(_BlitScaleBias, viewScaleBias); + data.materialPropertyBlock.SetTexture(_BlitTexture, data.srcTexture); + CoreUtils.DrawFullScreen(ctx.cmd, data.material, data.materialPropertyBlock, data.pass); + }); + } + } + /// public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { @@ -331,31 +389,29 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer // Update keywords and other shader params SetupKeywordsAndParameters(ref m_CurrentSettings, ref cameraData); - using (IUnsafeRenderGraphBuilder builder = renderGraph.AddUnsafePass("Blit SSAO", out var passData, m_ProfilingSampler)) + using (var builder = renderGraph.AddRasterRenderPass("Blit SSAO", out var passData, m_ProfilingSampler)) { // Shader keyword changes are considered as global state modifications builder.AllowGlobalStateModification(true); // Fill in the Pass data... - InitSSAOPassData(ref passData); + InitSSAOPassData(passData); passData.cameraColor = resourceData.cameraColor; passData.AOTexture = aoTexture; passData.finalTexture = finalTexture; passData.blurTexture = blurTexture; passData.cameraData = cameraData; + passData.materialPropertyBlock ??= new(); // Declare input textures - builder.UseTexture(passData.AOTexture, AccessFlags.ReadWrite); + builder.SetRenderAttachment(passData.AOTexture, 0, AccessFlags.WriteAll); // TODO: Refactor to eliminate the need for 'UseTexture'. // Currently required only because 'PostProcessUtils.SetSourceSize' allocates an RTHandle, // which expects a valid graphicsResource. Without this call, 'cameraColor.graphicsResource' // may be null if it wasn't initialized in an earlier pass (e.g., DrawOpaque). - if (resourceData.cameraColor.IsValid()) - builder.UseTexture(resourceData.cameraColor, AccessFlags.Read); - - if (passData.BlurQuality != ScreenSpaceAmbientOcclusionSettings.BlurQualityOptions.Low) - builder.UseTexture(passData.blurTexture, AccessFlags.ReadWrite); + if (passData.cameraColor.IsValid()) + builder.UseTexture(passData.cameraColor, AccessFlags.Read); if (cameraDepthTexture.IsValid()) builder.UseTexture(cameraDepthTexture, AccessFlags.Read); @@ -366,64 +422,64 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer passData.cameraNormalsTexture = cameraNormalsTexture; } - // The global SSAO texture only needs to be set if After Opaque is disabled... - if (!passData.afterOpaque && finalTexture.IsValid()) + builder.SetRenderFunc(static (SSAOPassData data, RasterGraphContext ctx) => { - builder.UseTexture(passData.finalTexture, AccessFlags.Write); - builder.SetGlobalTextureAfterPass(finalTexture, s_SSAOFinalTextureID); - } - - builder.SetRenderFunc(static (SSAOPassData data, UnsafeGraphContext rgContext) => - { - CommandBuffer cmd = CommandBufferHelpers.GetNativeCommandBuffer(rgContext.cmd); - RenderBufferLoadAction finalLoadAction = data.afterOpaque ? RenderBufferLoadAction.Load : RenderBufferLoadAction.DontCare; - // Setup - PostProcessUtils.SetGlobalShaderSourceSize(cmd, data.cameraData.cameraTargetDescriptor.width, data.cameraData.cameraTargetDescriptor.height, data.cameraColor); + PostProcessUtils.SetGlobalShaderSourceSize(ctx.cmd, data.cameraData.cameraTargetDescriptor.width, data.cameraData.cameraTargetDescriptor.height, data.cameraColor); + + data.materialPropertyBlock.Clear(); if (data.cameraNormalsTexture.IsValid()) - data.material.SetTexture(s_CameraNormalsTextureID, data.cameraNormalsTexture); + data.materialPropertyBlock.SetTexture(s_CameraNormalsTextureID, data.cameraNormalsTexture); - // AO Pass - Blitter.BlitCameraTexture(cmd, data.AOTexture, data.AOTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, data.material, (int) ShaderPasses.AmbientOcclusion); + Vector4 viewScaleBias = new(1, 1, 0, 0); + data.materialPropertyBlock.SetVector(_BlitScaleBias, viewScaleBias); - // Blur passes - Vector4 viewScaleBias; - switch (data.BlurQuality) - { - // Bilateral - case ScreenSpaceAmbientOcclusionSettings.BlurQualityOptions.High: - Blitter.BlitCameraTexture(cmd, data.AOTexture, data.blurTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, data.material, (int) ShaderPasses.BilateralBlurHorizontal); - Blitter.BlitCameraTexture(cmd, data.blurTexture, data.AOTexture, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, data.material, (int) ShaderPasses.BilateralBlurVertical); - viewScaleBias = ComputeScaleBias(in rgContext, in data.AOTexture, in data.finalTexture); - Blitter.BlitCameraTexture(cmd, data.AOTexture, data.finalTexture, viewScaleBias, finalLoadAction, RenderBufferStoreAction.Store, data.material, (int) (data.afterOpaque ? ShaderPasses.BilateralAfterOpaque : ShaderPasses.BilateralBlurFinal)); - break; - - // Gaussian - case ScreenSpaceAmbientOcclusionSettings.BlurQualityOptions.Medium: - Blitter.BlitCameraTexture(cmd, data.AOTexture, data.blurTexture, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store, data.material, (int) ShaderPasses.GaussianBlurHorizontal); - viewScaleBias = ComputeScaleBias(in rgContext, in data.blurTexture, in data.finalTexture); - Blitter.BlitCameraTexture(cmd, data.blurTexture, data.finalTexture, viewScaleBias, finalLoadAction, RenderBufferStoreAction.Store, data.material, (int) (data.afterOpaque ? ShaderPasses.GaussianAfterOpaque : ShaderPasses.GaussianBlurVertical)); - break; - - // Kawase - case ScreenSpaceAmbientOcclusionSettings.BlurQualityOptions.Low: - viewScaleBias = ComputeScaleBias(in rgContext, in data.AOTexture, in data.finalTexture); - Blitter.BlitCameraTexture(cmd, data.AOTexture, data.finalTexture, viewScaleBias, finalLoadAction, RenderBufferStoreAction.Store, data.material, (int) (data.afterOpaque ? ShaderPasses.KawaseAfterOpaque : ShaderPasses.KawaseBlur)); - break; - - default: - throw new ArgumentOutOfRangeException(); - } - - // We only want URP shaders to sample SSAO if After Opaque is disabled... - if (!data.afterOpaque) - { - rgContext.cmd.SetKeyword(ShaderGlobalKeywords.ScreenSpaceOcclusion, true); - rgContext.cmd.SetGlobalVector(s_AmbientOcclusionParamID, new Vector4(1f, 0f, 0f, data.directLightingStrength)); - } + CoreUtils.DrawFullScreen(ctx.cmd, data.material, data.materialPropertyBlock, (int)ShaderPasses.AmbientOcclusion); }); } + + switch (m_CurrentSettings.BlurQuality) + { + case ScreenSpaceAmbientOcclusionSettings.BlurQualityOptions.High: + RecordBlurStep(renderGraph, cameraData, "Blur SSAO Horizontal (High)", aoTexture, blurTexture, (int)ShaderPasses.BilateralBlurHorizontal, false); + RecordBlurStep(renderGraph, cameraData, "Blur SSAO Vertical (High)", blurTexture, aoTexture, (int)ShaderPasses.BilateralBlurVertical, false); + RecordBlurStep(renderGraph, cameraData, "Blur SSAO Final (High)", aoTexture, finalTexture, (int)(m_CurrentSettings.AfterOpaque ? ShaderPasses.BilateralAfterOpaque : ShaderPasses.BilateralBlurFinal), true); + break; + case ScreenSpaceAmbientOcclusionSettings.BlurQualityOptions.Medium: + RecordBlurStep(renderGraph, cameraData, "Blur SSAO Horizontal (Medium)", aoTexture, blurTexture, (int)ShaderPasses.GaussianBlurHorizontal, false); + RecordBlurStep(renderGraph, cameraData, "Blur SSAO Final (Medium)", blurTexture, finalTexture, (int)(m_CurrentSettings.AfterOpaque ? ShaderPasses.GaussianAfterOpaque : ShaderPasses.GaussianBlurVertical), true); + break; + case ScreenSpaceAmbientOcclusionSettings.BlurQualityOptions.Low: + RecordBlurStep(renderGraph, cameraData, "Blur SSAO (Low)", aoTexture, finalTexture, (int)(m_CurrentSettings.AfterOpaque ? ShaderPasses.KawaseAfterOpaque : ShaderPasses.KawaseBlur), true); + break; + default: + throw new ArgumentOutOfRangeException(); + } + + if (!m_CurrentSettings.AfterOpaque) + { + // Add cleanup pass to: + // - Set global keywords for next passes + // - Set global texture as there is a limitation in Render Graph where an input texture cannot be set as a global texture after the pass runs + // A Raster pass is used so it can be merged easily with the blur passes. + using (var builder = renderGraph.AddRasterRenderPass("Cleanup SSAO", out var passData, m_ProfilingSampler)) + { + passData.directLightingStrength = m_CurrentSettings.DirectLightingStrength; + + builder.AllowGlobalStateModification(true); + + builder.UseTexture(finalTexture, AccessFlags.Read); + builder.SetGlobalTextureAfterPass(finalTexture, s_SSAOFinalTextureID); + + builder.SetRenderFunc(static (SSAOFinalPassData data, RasterGraphContext ctx) => + { + // We only want URP shaders to sample SSAO if After Opaque is disabled... + ctx.cmd.SetKeyword(ShaderGlobalKeywords.ScreenSpaceOcclusion, true); + ctx.cmd.SetGlobalVector(s_AmbientOcclusionParamID, new Vector4(1f, 0f, 0f, data.directLightingStrength)); + }); + } + } } private void CreateRenderTextureHandles(RenderGraph renderGraph, UniversalResourceData resourceData, diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DecalRendererFeature.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DecalRendererFeature.cs index f2d5cb60480..e76c707e270 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DecalRendererFeature.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DecalRendererFeature.cs @@ -179,6 +179,7 @@ private void OnDecalMaterialChange(DecalProjector decalProjector) [DisallowMultipleRendererFeature("Decal")] [Tooltip("With this Renderer Feature, Unity can project specific Materials (decals) onto other objects in the Scene.")] [URPHelpURL("renderer-feature-decal")] + [Icon("Packages/com.unity.render-pipelines.core/Editor/Icons/Processed/DecalProjector Icon.asset")] public partial class DecalRendererFeature : ScriptableRendererFeature { private static SharedDecalEntityManager sharedDecalEntityManager { get; } = new SharedDecalEntityManager(); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DecalRendererFeature.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DecalRendererFeature.cs.meta index d7eb64cb212..c2a1d425131 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DecalRendererFeature.cs.meta +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/DecalRendererFeature.cs.meta @@ -5,7 +5,7 @@ MonoImporter: serializedVersion: 2 defaultReferences: [] executionOrder: 0 - icon: {fileID: 2800000, guid: 9ba98ca4f0fc0754caca09e38af0cc0a, type: 3} + icon: {fileID: 2800000, guid: 340b2e8f8761e254d8ee52bc663cedbd, type: 2} userData: assetBundleName: assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceAmbientOcclusion.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceAmbientOcclusion.cs index 8ba3d62d8ef..aeb93976adf 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceAmbientOcclusion.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceAmbientOcclusion.cs @@ -58,7 +58,7 @@ internal enum BlurQualityOptions Low, // Kawase } } - + [Serializable] [SupportedOnRenderPipeline(typeof(UniversalRenderPipelineAsset))] [Categorization.CategoryInfo(Name = "R: SSAO Shader", Order = 1000)] @@ -68,12 +68,12 @@ class ScreenSpaceAmbientOcclusionPersistentResources : IRenderPipelineResources [SerializeField] [ResourcePath("Shaders/Utils/ScreenSpaceAmbientOcclusion.shader")] Shader m_Shader; - + public Shader Shader { get => m_Shader; set => this.SetValueAndNotify(ref m_Shader, value); - } + } public bool isAvailableInPlayerBuild => true; @@ -92,13 +92,13 @@ class ScreenSpaceAmbientOcclusionDynamicResources : IRenderPipelineResources [SerializeField] [ResourceFormattedPaths("Textures/BlueNoise256/LDR_LLL1_{0}.png", 0, 7)] Texture2D[] m_BlueNoise256Textures; - + public Texture2D[] BlueNoise256Textures { get => m_BlueNoise256Textures; set => this.SetValueAndNotify(ref m_BlueNoise256Textures, value); - } - + } + public bool isAvailableInPlayerBuild => true; [SerializeField][HideInInspector] private int m_Version = 0; @@ -138,7 +138,7 @@ public class ScreenSpaceAmbientOcclusion : ScriptableRendererFeature internal const string k_SampleCountLowKeyword = "_SAMPLE_COUNT_LOW"; internal const string k_SampleCountMediumKeyword = "_SAMPLE_COUNT_MEDIUM"; internal const string k_SampleCountHighKeyword = "_SAMPLE_COUNT_HIGH"; - + /// public override void Create() { @@ -171,8 +171,8 @@ public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingD if (!TryPrepareResources()) return; - bool shouldAdd = m_SSAOPass.Setup(ref m_Settings, ref renderer, ref m_Material, ref m_BlueNoise256Textures); - if (shouldAdd) + bool shouldAdd = m_SSAOPass.Setup(m_Settings, renderer, m_Material, m_BlueNoise256Textures); + if (shouldAdd) renderer.EnqueuePass(m_SSAOPass); } @@ -194,7 +194,7 @@ bool TryPrepareResources() $"Couldn't find the required resources for the {nameof(ScreenSpaceAmbientOcclusion)} render feature. If this exception appears in the Player, make sure at least one {nameof(ScreenSpaceAmbientOcclusion)} render feature is enabled or adjust your stripping settings."); return false; } - + m_Shader = ssaoPersistentResources.Shader; } @@ -208,7 +208,7 @@ bool TryPrepareResources() m_BlueNoise256Textures = ssaoDynamicResources.BlueNoise256Textures; } - + if (m_Material == null && m_Shader != null) m_Material = CoreUtils.CreateEngineMaterial(m_Shader); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs b/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs index 434c647acd4..2a2b613a5e1 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs @@ -1139,6 +1139,7 @@ static void ClearRenderingState(IBaseCommandBuffer cmd) cmd.SetKeyword(ShaderGlobalKeywords.ShadowsShadowMask, false); cmd.SetKeyword(ShaderGlobalKeywords.LinearToSRGBConversion, false); cmd.SetKeyword(ShaderGlobalKeywords.LightLayers, false); + cmd.SetKeyword(ShaderGlobalKeywords.ScreenSpaceOcclusion, false); cmd.SetGlobalVector(ScreenSpaceAmbientOcclusionPass.s_AmbientOcclusionParamID, Vector4.zero); } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs index 9764508ea7e..af908009a8e 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs @@ -1951,21 +1951,39 @@ internal enum URPProfileId internal static class PlatformAutoDetect { /// - /// Detect and cache runtime platform information. This function should only be called once when creating the URP. + /// Detect and cache runtime platform information. + /// Lazy initialized for situations where platform detection is required before URP is initialized (UUM-134298) /// - internal static void Initialize() + private sealed class PlatformDetectionCache { - bool isRunningMobile = false; - #if ENABLE_VR && ENABLE_VR_MODULE - #if PLATFORM_WINRT || PLATFORM_ANDROID - isRunningMobile = IsRunningXRMobile(); + public readonly bool isXRMobile; + public readonly bool isShaderAPIMobileDefined; + public readonly bool isSwitch; + public readonly bool isSwitch2; + public readonly bool isRunningOnPowerVRGPU; + + public PlatformDetectionCache() + { + bool isRunningMobile = false; + #if ENABLE_VR && ENABLE_VR_MODULE + #if PLATFORM_WINRT || PLATFORM_ANDROID + isRunningMobile = IsRunningXRMobile(); + #endif #endif - #endif - isXRMobile = isRunningMobile; - isShaderAPIMobileDefined = GraphicsSettings.HasShaderDefine(BuiltinShaderDefine.SHADER_API_MOBILE); - isSwitch = Application.platform == RuntimePlatform.Switch; - isSwitch2 = Application.platform == RuntimePlatform.Switch2; + isXRMobile = isRunningMobile; + isShaderAPIMobileDefined = GraphicsSettings.HasShaderDefine(BuiltinShaderDefine.SHADER_API_MOBILE); + isSwitch = Application.platform == RuntimePlatform.Switch; + isSwitch2 = Application.platform == RuntimePlatform.Switch2; + isRunningOnPowerVRGPU = SystemInfo.graphicsDeviceName.Contains("PowerVR"); + } + } + + private static readonly Lazy platformCache = new(() => new PlatformDetectionCache(), true); + + internal static void Initialize() + { + _ = platformCache.Value; } #if ENABLE_VR && ENABLE_VR_MODULE @@ -1994,19 +2012,21 @@ private static bool IsRunningXRMobile() /// /// If true, the runtime platform is an XR mobile platform. /// - internal static bool isXRMobile { get; private set; } = false; + internal static bool isXRMobile => platformCache.Value.isXRMobile; /// /// If true, then SHADER_API_MOBILE has been defined in URP Shaders. /// - internal static bool isShaderAPIMobileDefined { get; private set; } = false; + internal static bool isShaderAPIMobileDefined => platformCache.Value.isShaderAPIMobileDefined; /// /// If true, then the runtime platform is set to Switch. /// - internal static bool isSwitch { get; private set; } = false; + internal static bool isSwitch => platformCache.Value.isSwitch; - internal static bool isSwitch2 { get; private set; } = false; + internal static bool isSwitch2 => platformCache.Value.isSwitch2; + + internal static bool isRunningOnPowerVRGPU => platformCache.Value.isRunningOnPowerVRGPU; /// /// Gives the SH evaluation mode when set to automatically detect. @@ -2025,7 +2045,5 @@ internal static ShEvalMode ShAutoDetect(ShEvalMode mode) return mode; } - - internal static bool isRunningOnPowerVRGPU = SystemInfo.graphicsDeviceName.Contains("PowerVR"); } } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs b/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs index 9dad1c3c532..dfedb3e34ac 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs @@ -887,6 +887,17 @@ public List GetActiveBlocksForAllActiveTargets() return context.activeBlocks; } + public void RefreshBadgesAndPreviews() + { + foreach (var node in this.m_Nodes) + { + if (node.value != null) + { + node.value.Dirty(ModificationScope.Graph); + } + } + } + public void UpdateActiveBlocks(List activeBlockDescriptors) { // Set Blocks as active based on supported Block list @@ -1660,40 +1671,49 @@ public ShaderInput AddCopyOfShaderInput(ShaderInput source, int insertIndex = -1 return copy; } - public void RemoveGraphInput(ShaderInput input) + // Removes a collection of shader inputs, deferring graph validation until all inputs have been removed + public void RemoveGraphInputs(IEnumerable inputs) { - switch (input) + foreach (ShaderInput input in inputs) { - case AbstractShaderProperty property: - var propertyNodes = GetNodes().Where(x => x.property == input).ToList(); - foreach (var propertyNode in propertyNodes) - ReplacePropertyNodeWithConcreteNodeNoValidate(propertyNode); - break; - } + switch (input) + { + case AbstractShaderProperty property: + var propertyNodes = GetNodes().Where(x => x.property == input).ToList(); + foreach (var propertyNode in propertyNodes) + ReplacePropertyNodeWithConcreteNodeNoValidate(propertyNode); + break; + } - // Also remove this input from any category it existed in - foreach (var categoryData in categories) - { - if (categoryData.IsItemInCategory(input)) + // Also remove this input from any category it existed in + foreach (var categoryData in categories) { - categoryData.RemoveItemFromCategory(input); - break; + if (categoryData.IsItemInCategory(input)) + { + categoryData.RemoveItemFromCategory(input); + break; + } } - } - foreach(var node in GetNodes()) - { - if (node.UsedReferenceNames().Contains(input.referenceName)) + foreach (var node in GetNodes()) { - node.ValidateNode(); - node.Dirty(ModificationScope.Graph); + if (node.UsedReferenceNames().Contains(input.referenceName)) + { + node.ValidateNode(); + node.Dirty(ModificationScope.Graph); + } } - } - RemoveGraphInputNoValidate(input); + RemoveGraphInputNoValidate(input); + } ValidateGraph(); } + public void RemoveGraphInput(ShaderInput input) + { + RemoveGraphInputs(new ShaderInput[] { input }); + } + public void MoveCategory(CategoryData category, int newIndex) { if (newIndex > m_CategoryData.Count || newIndex < 0) @@ -1878,8 +1898,7 @@ public void RemoveCategory(string categoryGUID) m_RemovedCategories.Add(existingCategory); // Whenever a category is removed, also remove any inputs within that category - foreach (var shaderInput in existingCategory.Children) - RemoveGraphInput(shaderInput); + RemoveGraphInputs(existingCategory.Children); } else AssertHelpers.Fail("Attempted to remove a category that does not exist in the graph."); diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/SampleElementTextureNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/SampleElementTextureNode.cs index 24f2be454ac..88709249532 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/SampleElementTextureNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/SampleElementTextureNode.cs @@ -99,6 +99,13 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo GetVariableNameForSlot(Color1SlotId), GetVariableNameForSlot(Color2SlotId), GetVariableNameForSlot(Color3SlotId)); + + sb.AppendLine("#if _UIE_FORCE_GAMMA"); + sb.AppendLine("{0}.rgb = uie_linear_to_gamma({1}.rgb);", GetVariableNameForSlot(Color0SlotId), GetVariableNameForSlot(Color0SlotId)); + sb.AppendLine("{0}.rgb = uie_linear_to_gamma({1}.rgb);", GetVariableNameForSlot(Color1SlotId), GetVariableNameForSlot(Color1SlotId)); + sb.AppendLine("{0}.rgb = uie_linear_to_gamma({1}.rgb);", GetVariableNameForSlot(Color2SlotId), GetVariableNameForSlot(Color2SlotId)); + sb.AppendLine("{0}.rgb = uie_linear_to_gamma({1}.rgb);", GetVariableNameForSlot(Color3SlotId), GetVariableNameForSlot(Color3SlotId)); + sb.AppendLine("#endif"); } } diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialGraphView.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialGraphView.cs index 0ce96188f94..c8160a7917e 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialGraphView.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialGraphView.cs @@ -131,6 +131,7 @@ void ChangeTargetSettings() graph.AddRemoveBlocksFromActiveList(activeBlocks); } + graph.RefreshBadgesAndPreviews(); graph.UpdateActiveBlocks(activeBlocks); this.m_PreviewManagerUpdateDelegate(); this.m_InspectorUpdateDelegate(); diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs b/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs index 3d0b2919f94..0c57fa8aec6 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs @@ -12,6 +12,7 @@ using UnityEngine.Assertions; using Pool = UnityEngine.Pool; using UnityEngine.Profiling; +using UnityEditor.Rendering.UITK.ShaderGraph; namespace UnityEditor.ShaderGraph { @@ -192,6 +193,14 @@ Target[] GetTargetImplementations() } else { + var targets = m_GraphData.activeTargets.ToList(); + foreach (var target in targets) + { + if (target.activeSubTarget is IUISubTarget) + { + return new Target[] { new PreviewTarget(true) }; + } + } return new Target[] { new PreviewTarget() }; } } diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Includes/BuiltInCanvasPass.hlsl b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Includes/BuiltInCanvasPass.hlsl index 7d326cef6d9..1edf07826d8 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Includes/BuiltInCanvasPass.hlsl +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Includes/BuiltInCanvasPass.hlsl @@ -77,6 +77,8 @@ Varyings BuildVaryings(Attributes input) float4 clampedRect = clamp(_ClipRect, -2e10, 2e10); float2 maskUV = (input.positionOS.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy); output.texCoord1 = float4(input.positionOS.xy * 2 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * half2(_UIMaskSoftnessX, _UIMaskSoftnessY) + abs(pixelSize.xy))); + #else + output.texCoord1 = input.uv1; #endif #endif diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shadows.hlsl b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shadows.hlsl index 7ed9e206705..6ac285ffcc4 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shadows.hlsl +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shadows.hlsl @@ -218,8 +218,8 @@ real SampleShadowmapFiltered(TEXTURE2D_SHADOW_PARAM(ShadowMap, sampler_ShadowMap attenuation4.w = SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, shadowCoord.xyz + samplingData.shadowOffset3.xyz); attenuation = dot(attenuation4, 0.25); #else - float fetchesWeights[9]; - float2 fetchesUV[9]; + real fetchesWeights[9]; + real2 fetchesUV[9]; SampleShadow_ComputeSamples_Tent_5x5(samplingData.shadowmapSize, shadowCoord.xy, fetchesWeights, fetchesUV); attenuation = fetchesWeights[0] * SAMPLE_TEXTURE2D_SHADOW(ShadowMap, sampler_ShadowMap, float3(fetchesUV[0].xy, shadowCoord.z)); diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShimPreview.hlsl b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShimPreview.hlsl new file mode 100644 index 00000000000..5a1bca85b00 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShimPreview.hlsl @@ -0,0 +1,3 @@ +#ifdef UITK_PREVIEW +#include "UIShim.hlsl" +#endif diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShimPreview.hlsl.meta b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShimPreview.hlsl.meta new file mode 100644 index 00000000000..021fe44fc02 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShimPreview.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9f12249d09c77224c8a6d6fad6e252b5 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/PreviewTarget.cs b/Packages/com.unity.shadergraph/Editor/Generation/Targets/PreviewTarget.cs index 89efef4d16b..8a65dac3ad6 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Targets/PreviewTarget.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/PreviewTarget.cs @@ -10,10 +10,17 @@ sealed class PreviewTarget : Target { static readonly GUID kSourceCodeGuid = new GUID("7464b9fcde08e5645a16b9b8ae1e573c"); // PreviewTarget.cs - public PreviewTarget() + private bool isUITKPreview = false; + + public PreviewTarget() : this(false) + { + } + + public PreviewTarget(bool isUITKPreview) { displayName = "Preview"; isHidden = true; + this.isUITKPreview = isUITKPreview; } public override bool IsActive() => false; @@ -22,7 +29,7 @@ public PreviewTarget() public override void Setup(ref TargetSetupContext context) { context.AddAssetDependency(kSourceCodeGuid, AssetCollection.Flags.SourceDependency); - context.AddSubShader(SubShaders.Preview); + context.AddSubShader(SubShaders.GetPreview(isUITKPreview)); } public override void GetFields(ref TargetFieldContext context) @@ -41,66 +48,77 @@ public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Acti static class SubShaders { - public static SubShaderDescriptor Preview = new SubShaderDescriptor() + public static SubShaderDescriptor GetPreview(bool isUITKPreview) { - renderQueue = "Geometry", - renderType = "Opaque", - generatesPreview = true, - passes = new PassCollection { Passes.Preview }, - }; + var preview = new SubShaderDescriptor() + { + renderQueue = "Geometry", + renderType = "Opaque", + generatesPreview = true, + passes = new PassCollection { Passes.GetPreview(isUITKPreview) }, + }; + + return preview; + } } static class Passes { - public static PassDescriptor Preview = new PassDescriptor() + public static PassDescriptor GetPreview(bool isUITKPreview) { - // Definition - referenceName = "SHADERPASS_PREVIEW", - useInPreview = true, + var pass = new PassDescriptor() + { + // Definition + referenceName = "SHADERPASS_PREVIEW", + useInPreview = true, - // Templates - passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), - sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), + // Templates + passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), + sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), - // Collections - structs = new StructCollection - { - { Structs.Attributes }, - { StructDescriptors.PreviewVaryings }, - { Structs.SurfaceDescriptionInputs }, - { Structs.VertexDescriptionInputs }, - }, - fieldDependencies = FieldDependencies.Default, - pragmas = new PragmaCollection - { - { Pragma.Vertex("vert") }, - { Pragma.Fragment("frag") }, - }, - defines = new DefineCollection - { - { KeywordDescriptors.PreviewKeyword, 1 }, - }, - includes = new IncludeCollection - { - // Pre-graph - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl", IncludeLocation.Pregraph }, // TODO: put this on a conditional - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariables.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShim.hlsl", IncludeLocation.Pregraph }, - - // Post-graph - { "Packages/com.unity.shadergraph/ShaderGraphLibrary/PreviewVaryings.hlsl", IncludeLocation.Postgraph }, - { "Packages/com.unity.shadergraph/ShaderGraphLibrary/PreviewPass.hlsl", IncludeLocation.Postgraph }, - } - }; + // Collections + structs = new StructCollection + { + { Structs.Attributes }, + { StructDescriptors.PreviewVaryings }, + { Structs.SurfaceDescriptionInputs }, + { Structs.VertexDescriptionInputs }, + }, + fieldDependencies = FieldDependencies.Default, + pragmas = new PragmaCollection + { + { Pragma.Vertex("vert") }, + { Pragma.Fragment("frag") }, + }, + defines = new DefineCollection + { + { KeywordDescriptors.PreviewKeyword, 1 }, + { KeywordDescriptors.UITKPreviewKeyword, isUITKPreview ? 1 : 0 } + }, + includes = new IncludeCollection + { + // Pre-graph + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl", IncludeLocation.Pregraph }, // TODO: put this on a conditional + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariables.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShimPreview.hlsl", IncludeLocation.Pregraph }, + + // Post-graph + { "Packages/com.unity.shadergraph/ShaderGraphLibrary/PreviewVaryings.hlsl", IncludeLocation.Postgraph }, + { "Packages/com.unity.shadergraph/ShaderGraphLibrary/PreviewPass.hlsl", IncludeLocation.Postgraph }, + } + }; + + return pass; + } } static class StructDescriptors @@ -144,6 +162,15 @@ static class KeywordDescriptors scope = KeywordScope.Global, stages = KeywordShaderStage.All, }; + public static KeywordDescriptor UITKPreviewKeyword = new KeywordDescriptor() + { + displayName = "UITK Preview", + referenceName = "UITK_PREVIEW", + type = KeywordType.Boolean, + definition = KeywordDefinition.MultiCompile, + scope = KeywordScope.Global, + stages = KeywordShaderStage.All, + }; } } } diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/UITK/UISubTarget.cs b/Packages/com.unity.shadergraph/Editor/Generation/Targets/UITK/UISubTarget.cs index 321ad95f8be..d69a5deb115 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Targets/UITK/UISubTarget.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/UITK/UISubTarget.cs @@ -218,6 +218,9 @@ public string GetValidatorKey() return "UISubTarget"; } + const string kUVErrorMessageNode = "UI Material does not support UV1-7. Consider using 'UV0'."; + const string kUVErrorMessageSubGraph = "UI Material does not support UV1-7. Consider using 'UV0' in the subgraph."; + public INodeValidationExtension.Status GetValidationStatus(AbstractMaterialNode node, out string msg) { // Make sure node is in our graph first @@ -227,6 +230,12 @@ public INodeValidationExtension.Status GetValidationStatus(AbstractMaterialNode return INodeValidationExtension.Status.None; } + // Clear all Warning/Error message from other providers. + // The message from the graph (when loading the graph) will not be removed + // since it's not the same provider as the UISubTarget. It then stays present + // even if the UV0 is selected. + node.owner.messageManager.ClearNodeFromOtherProvider(this, new[] { node }); + foreach (var item in node.owner.activeTargets) { if (item.prefersUITKPreview) @@ -235,16 +244,6 @@ public INodeValidationExtension.Status GetValidationStatus(AbstractMaterialNode { return INodeValidationExtension.Status.Warning; } - - UVNode uvNode = node as UVNode; - if (uvNode != null) - { - if (uvNode.uvChannel != UnityEditor.ShaderGraph.Internal.UVChannel.UV0) - { - msg = "UI Material does not support UV1-7. Consider using 'UV0'."; - return INodeValidationExtension.Status.Warning; - } - } } } @@ -261,7 +260,17 @@ private bool ValidateUV(AbstractMaterialNode node, out string warningMessage) { if (uvSlot.channel != UnityEditor.ShaderGraph.Internal.UVChannel.UV0) { - warningMessage = "UI Material does not support UV1-7. Consider using 'UV0'."; + warningMessage = kUVErrorMessageNode; + return true; + } + } + + UVNode uvNode = node as UVNode; + if (uvNode != null) + { + if (uvNode.uvChannel != UnityEditor.ShaderGraph.Internal.UVChannel.UV0) + { + warningMessage = kUVErrorMessageNode; return true; } } @@ -283,7 +292,7 @@ public override bool ValidateNodeCompatibility(AbstractMaterialNode node, out st { if (uvSlot.channel != UnityEditor.ShaderGraph.Internal.UVChannel.UV0) { - warningMessage = "UI Material does not support UV1-7. Consider using 'UV0'."; + warningMessage = kUVErrorMessageNode; return true; } } @@ -303,7 +312,7 @@ public override bool ValidateNodeCompatibility(AbstractMaterialNode node, out st { if (item != UnityEditor.ShaderGraph.Internal.UVChannel.UV0) { - warningMessage = "UI Material does not support UV1-7. Consider using 'UV0' in the subgraph."; + warningMessage = kUVErrorMessageSubGraph; return true; } } diff --git a/Packages/com.unity.shadergraph/Editor/Util/MessageManager.cs b/Packages/com.unity.shadergraph/Editor/Util/MessageManager.cs index 2878744ae55..90d75b39bb4 100644 --- a/Packages/com.unity.shadergraph/Editor/Util/MessageManager.cs +++ b/Packages/com.unity.shadergraph/Editor/Util/MessageManager.cs @@ -124,6 +124,24 @@ public void ClearNodesFromProvider(object messageProvider, IEnumerable nodes) + { + foreach (var key in m_Messages.Keys) + { + if (key != messageProvider) + { + foreach (var node in nodes) + { + if (m_Messages[key].TryGetValue(node.objectId, out var messages)) + { + nodeMessagesChanged |= messages.Count > 0; + messages.Clear(); + } + } + } + } + } + public void ClearAll() { m_Messages.Clear(); diff --git a/Packages/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs b/Packages/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs index 9ff8a425902..98d777c11a5 100644 --- a/Packages/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs +++ b/Packages/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs @@ -320,6 +320,27 @@ public void ReportAnyErrors_EmptyManager_ErrorOneProvider() var ret = m_EmptyMgr.HasSeverity(); Assert.IsTrue(ret); } + + [Test] + public void ClearNodesFromOtherProvider() + { + m_ComplexMgr.ClearNodeFromOtherProvider(p0, new List { node1 }); + + // Verify node1 is still in provider0 + Assert.IsTrue(m_ComplexMgr.Messages.ContainsKey(p0)); + Assert.IsTrue(m_ComplexMgr.Messages[p0].ContainsKey(node1.objectId)); + Assert.AreEqual(1, m_ComplexMgr.Messages[p0][node1.objectId].Count); + Assert.AreEqual(e2, m_ComplexMgr.Messages[p0][node1.objectId][0]); + + // Verify node1 is cleared from provider1 + Assert.IsTrue(m_ComplexMgr.Messages.ContainsKey(p1)); + Assert.IsTrue(m_ComplexMgr.Messages[p1].ContainsKey(node1.objectId)); + Assert.AreEqual(0, m_ComplexMgr.Messages[p1][node1.objectId].Count); + + // Verify other nodes in provider1 are unchanged + Assert.AreEqual(1, m_ComplexMgr.Messages[p1][node0.objectId].Count); + Assert.AreEqual(1, m_ComplexMgr.Messages[p1][node2.objectId].Count); + } } } diff --git a/Packages/com.unity.visualeffectgraph/Editor/Models/Operators/Implementations/SampleMesh.cs b/Packages/com.unity.visualeffectgraph/Editor/Models/Operators/Implementations/SampleMesh.cs index 6dc495661cd..921f478b3e9 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Models/Operators/Implementations/SampleMesh.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Models/Operators/Implementations/SampleMesh.cs @@ -445,6 +445,7 @@ private static VFXExpression SampleVertexAttribute(VFXExpression source, VFXExpr var outputType = GetSampledType(vertexAttribute); VFXExpression sampled = null; + vertexIndex = new VFXExpressionMin(vertexIndex, new VFXExpressionMeshVertexCount(mesh)); var meshChannelFormatAndDimension = new VFXExpressionMeshChannelInfos(mesh, channelIndex); var vertexOffset = vertexIndex * meshVertexStride + meshChannelOffset; diff --git a/Packages/com.unity.visualeffectgraph/Shaders/Sort.compute b/Packages/com.unity.visualeffectgraph/Shaders/Sort.compute index e4fe54c210a..419fea2b19e 100644 --- a/Packages/com.unity.visualeffectgraph/Shaders/Sort.compute +++ b/Packages/com.unity.visualeffectgraph/Shaders/Sort.compute @@ -112,6 +112,8 @@ void LoadFromMemory(uint3 groupId, uint ldsIndex) uint memIndex = DST_INDEX(groupId, ldsIndex); KVP kvp = { REJECTED_VALUE, 0xFFFFFFFF }; + + UNITY_BRANCH if (instanceDstIndex < GetElementCount(groupId.z)) kvp = inputSequence[totalInstanceCount + memIndex]; @@ -245,6 +247,7 @@ void MERGE_PASS(uint3 groupId : SV_GroupID, const int arrayStart = arraySize * (id / arraySize); // If the current array considered is less than one half filled (due to element count), we can copy it directly as it is already sorted + UNITY_BRANCH if (GetElementCount(groupId.z) - (uint)arrayStart <= subArraySize) { #if FINAL_PASS diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_URP/ProjectSettings/ProjectSettings.asset b/Tests/SRPTests/Projects/VisualEffectGraph_URP/ProjectSettings/ProjectSettings.asset index 391570a6f26..c485e60474f 100644 --- a/Tests/SRPTests/Projects/VisualEffectGraph_URP/ProjectSettings/ProjectSettings.asset +++ b/Tests/SRPTests/Projects/VisualEffectGraph_URP/ProjectSettings/ProjectSettings.asset @@ -120,15 +120,15 @@ PlayerSettings: xboxOneEnableTypeOptimization: 0 xboxOnePresentImmediateThreshold: 0 switchQueueCommandMemory: 1048576 - switchQueueControlMemory: 65536 + switchQueueControlMemory: 1048576 switchQueueComputeMemory: 262144 switchNVNShaderPoolsGranularity: 33554432 switchNVNDefaultPoolsGranularity: 16777216 switchNVNOtherPoolsGranularity: 16777216 switchGpuScratchPoolGranularity: 2097152 switchAllowGpuScratchShrinking: 0 - switchNVNMaxPublicTextureIDCount: 0 - switchNVNMaxPublicSamplerIDCount: 0 + switchNVNMaxPublicTextureIDCount: 65536 + switchNVNMaxPublicSamplerIDCount: 65536 switchMaxWorkerMultiple: 8 switchNVNGraphicsFirmwareMemory: 32 vulkanNumSwapchainBuffers: 3 diff --git a/Tests/SRPTests/Projects/VisualEffectGraph_URP/ProjectSettings/Switch2PlayerSettings.asset b/Tests/SRPTests/Projects/VisualEffectGraph_URP/ProjectSettings/Switch2PlayerSettings.asset new file mode 100644 index 00000000000..54affd997d4 --- /dev/null +++ b/Tests/SRPTests/Projects/VisualEffectGraph_URP/ProjectSettings/Switch2PlayerSettings.asset @@ -0,0 +1,64 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 21014, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEditor.Switch2.Extensions.dll::UnityEditor.Switch2.Switch2PlayerSettings + m_SocketConfigEnabled: 0 + m_SocketMemoryPoolSize: 6144 + m_SocketAllocatorPoolSize: 128 + m_SocketConcurrencyLimit: 14 + m_TcpInitialSendBufferSize: 32 + m_TcpInitialReceiveBufferSize: 64 + m_TcpAutoSendBufferSizeMax: 256 + m_TcpAutoReceiveBufferSizeMax: 256 + m_UdpSendBufferSize: 9 + m_UdpReceiveBufferSize: 42 + m_SocketBufferEfficiency: 4 + m_SocketInitializeEnabled: 1 + m_NetworkInterfaceManagerInitializeEnabled: 1 + m_HTCSForPlayerConnectionDisabled: 0 + m_LTOSetting: 0 + m_UseCPUProfiler: 0 + m_EnableFileSystemTrace: 0 + m_PrimaryQueueCommandMemory: 4194304 + m_PrimaryQueueControlMemory: 65536 + m_PrimaryQueueComputeMemory: 262144 + m_ComputeQueueCommandMemory: 4194304 + m_ComputeQueueControlMemory: 16384 + m_ComputeQueueComputeMemory: 262144 + m_NVNShaderPoolsGranularity: 33554432 + m_NVNDefaultPoolsGranularity: 16777216 + m_NVNOtherPoolsGranularity: 16777216 + m_GpuScratchPoolGranularity: 2097152 + m_AllowGpuScratchShrinking: 0 + m_NVNMaxPublicTextureIDCount: 65536 + m_NVNMaxPublicSamplerIDCount: 65536 + m_KMaxWorkerMultiple: 8 + m_DisableAsyncCompute: 0 + m_EnableNxLegacyTextureLayout: 0 + m_ExperimentalNvnDeviceInitializeDlssFlag: 0 + m_CompilerFlags: + - + m_NMETAOverride: + m_ScreenResolutionBehavior: 2 + m_NativeFsCacheSize: 32 + m_IsHoldTypeHorizontal: 1 + m_SupportedNpadCount: 8 + m_EnableTouchScreen: 1 + m_NSODependencies: + m_MicroSleepForYieldTime: 25 + m_EnableRamDiskSupport: 0 + m_RamDiskSpaceSize: 12 + m_DockedResolution: 1 + m_HandheldResolution: 1 + m_SupportedNpadStyles: 22 + m_ExtendedStructuredBufferBindings: 0