Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
a8acc09
[6.4/URP] Restore RWTexture3D<half4> usage in probes shader on metal
alexey-unity Feb 24, 2026
5879a39
[Port] [6000.4] [Icons] Correct handling of IconAttribute in the Anno…
svc-reach-platform-support Feb 24, 2026
9860257
[Port] [6000.4] [UUM-134981] Make sure to declare output arrays with …
svc-reach-platform-support Feb 24, 2026
c15cb75
[Port] [6000.4] [URP] Implement Lazy initialisation for PlatformAutoD…
Ricky-James Feb 24, 2026
59e75ea
[Port] [6000.4] UUM-133550 : Fixed crash when using XAtlas with first…
svc-reach-platform-support Feb 26, 2026
3d83d2b
[Port] [6000.4] Fixed redefinition causing warning in UITK shader tem…
svc-reach-platform-support Feb 26, 2026
f7753ce
ENABLE_XR_MODULE -> ENABLE_VR_MODULE
Ricky-James Mar 3, 2026
e40a293
[Port] [6000.4] [UUM-133826] Initialize uv1 for Canvas shaders when n…
svc-reach-platform-support Mar 3, 2026
cb7c1df
[Port] [6000.4] RenderGraph - Add new operator == for the TextureHand…
svc-reach-platform-support Mar 4, 2026
91c981f
[Port] [6000.4] UUM-133557 Color texture is read twice in custom pass
svc-reach-platform-support Mar 4, 2026
3b2af98
[Port] [6000.4] [URP] Added OpenGL support checks for active build pr…
svc-reach-platform-support Mar 4, 2026
bcae17c
[Port] [6000.4] [VFX] Fix Sort.compute crash caused by OOB buffer access
svc-reach-platform-support Mar 5, 2026
a8bb55e
[Backport 6000.4] Correctly support UITKPreview without affecting oth…
ncerone-unity Mar 11, 2026
4935310
[Port] [6000.4] [HDRP] Fix volumetric clouds white flickering when ca…
svc-reach-platform-support Mar 11, 2026
09b9609
[Port] [6000.4] [UUM-130732][Switch2] Fix/workaround for GPU crash wh…
Wilfrid-Unity Mar 11, 2026
55e7615
[Port] UUM-116480: Updated SSAO pass to use Raster render passes
jenniferd-unity Mar 11, 2026
c0d8603
[Backport 6000.4] Fix gamma issue of Sample Element Texture node for …
ncerone-unity Mar 15, 2026
bce62e4
[Port][6000.4][UUM-134265] Fix `NullReferenceException` when deleting…
april-roszkowski Mar 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<float4> L0_L1Rx;
#else
RWTexture3D<half4> L0_L1Rx;
#endif
RWTexture3D<unorm float4> L1G_L1Ry;
RWTexture3D<unorm float4> L1B_L1Rz;
RWTexture3D<unorm float4> L2_0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,7 @@ Texture3D<float4> _State1_L0_L1Rx;
Texture3D<float4> _State1_L1G_L1Ry;
Texture3D<float4> _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<float4> _Out_L0_L1Rx;
#else
RWTexture3D<half4> _Out_L0_L1Rx;
#endif
RWTexture3D<unorm float4> _Out_L1G_L1Ry;
RWTexture3D<unorm float4> _Out_L1B_L1Rz;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<float4> _Out_L0_L1Rx;
#else
RWTexture3D<half4> _Out_L0_L1Rx;
#endif
RWTexture3D<unorm float4> _Out_L1G_L1Ry;
RWTexture3D<unorm float4> _Out_L1B_L1Rz;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,15 @@ 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;
IntegratorContext = new LightmapIntegratorContext();
ResourceCache = new LightmapIntegrationResourceCache();

ChartRasterizer = new ChartRasterizer(resources.SoftwareChartRasterizationShader, resources.HardwareChartRasterizationShader);
InitializeChartRasterizationBuffers(maxIndexCount);
InitializeChartRasterizationBuffers(maxIndexCount, maxVertexCount);

return SetOutputResolution(width, height);
}
Expand Down Expand Up @@ -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;
Expand All @@ -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<Vector2>());
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<Vector2>());
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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Shader "Hidden/ChartRasterizerSoftware"
#pragma fragment frag
#include "GeometryUtils.hlsl"

#define PARALLEL_EPS 1e-6f

struct v2f
{
float4 vertex : SV_POSITION;
Expand All @@ -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];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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++;
}
}
Expand All @@ -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] =
Expand All @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ internal enum TextureUVOriginSelection
/// </summary>
[DebuggerDisplay("Texture ({handle.index})")]
[MovedFrom(true, "UnityEngine.Experimental.Rendering.RenderGraphModule", "UnityEngine.Rendering.RenderGraphModule")]
public readonly struct TextureHandle
public readonly struct TextureHandle : IEquatable<TextureHandle>
{
private static TextureHandle s_NullHandle = new TextureHandle();

Expand Down Expand Up @@ -151,6 +151,52 @@ internal TextureHandle(int handle, bool shared = false, bool builtin = false)
/// <returns>Resource as a RTHandle.</returns>
public static implicit operator RTHandle(TextureHandle texture) => texture.IsValid() ? RenderGraphResourceRegistry.current.GetTexture(texture) : null;

/// <summary>
/// Determines whether this instance and another specified <see cref="TextureHandle"/> object have the same underlying resource handle.
/// </summary>
/// <param name="other">The texture handle to compare with the current instance.</param>
/// <returns>
/// True if both texture handles reference the same underlying resource; otherwise, false.
/// </returns>
public bool Equals(TextureHandle other) => handle.Equals(other.handle);

/// <summary>
/// Determines whether the specified object is equal to the current <see cref="TextureHandle"/>.
/// </summary>
/// <param name="obj">The object to compare with the current instance.</param>
/// <returns>
/// True if the specified object is a <see cref="TextureHandle"/> and references the same underlying resource; otherwise, false.
/// </returns>
public override bool Equals(object obj) => obj is TextureHandle other && Equals(other);

/// <summary>
/// Returns the hash code for this <see cref="TextureHandle"/>.
/// </summary>
/// <returns>
/// The hash code of the current <see cref="TextureHandle"/>.
/// </returns>
public override int GetHashCode() => handle.GetHashCode();

/// <summary>
/// Determines whether two <see cref="TextureHandle"/> instances reference the same underlying resource.
/// </summary>
/// <param name="lhs">The first texture handle to compare.</param>
/// <param name="rhs">The second texture handle to compare.</param>
/// <returns>
/// True if both handles reference the same underlying resource; otherwise, false.
/// </returns>
public static bool operator ==(TextureHandle lhs, TextureHandle rhs) => lhs.handle.Equals(rhs.handle);

/// <summary>
/// Determines whether two <see cref="TextureHandle"/> instances reference different underlying resources.
/// </summary>
/// <param name="lhs">The first texture handle to compare.</param>
/// <param name="rhs">The second texture handle to compare.</param>
/// <returns>
/// True if the handles reference different underlying resources; otherwise, false.
/// </returns>
public static bool operator !=(TextureHandle lhs, TextureHandle rhs) => !lhs.handle.Equals(rhs.handle);

/// <summary>
/// Return true if the handle is valid.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading
Loading