Skip to content

Commit d6fffaf

Browse files
alex-vazquez-unity3dEvergreen
authored andcommitted
[URP] [Native Render Pass]Fix incorrect RenderTextureDescriptor when rendering into a texture and having a renderScale.
When Render scale != 1 and we are rendering to a Render Texture. The NativeRender pass was creating the RenderTextureDescriptor with an invalid dimensions. Make sure that Attachements sizes are the same as pass sizes. https://jira.unity3d.com/browse/UUM-61468
1 parent da09cf2 commit d6fffaf

File tree

6 files changed

+152
-18
lines changed

6 files changed

+152
-18
lines changed

Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalCameraData.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,20 @@ internal Matrix4x4 GetGPUProjectionMatrix(bool renderIntoTexture, int viewIndex
145145
/// </summary>
146146
public Camera camera;
147147

148+
/// <summary>
149+
/// Returns the scaled width of the Camera
150+
/// By obtaining the pixelWidth of the camera and taking into account the render scale
151+
/// The min dimension is 1.
152+
/// </summary>
153+
public int scaledWidth => Mathf.Max(1, (int)(camera.pixelWidth * renderScale));
154+
155+
/// <summary>
156+
/// Returns the scaled height of the Camera
157+
/// By obtaining the pixelHeight of the camera and taking into account the render scale
158+
/// The min dimension is 1.
159+
/// </summary>
160+
public int scaledHeight => Mathf.Max(1, (int)(camera.pixelHeight * renderScale));
161+
148162

149163
// NOTE: This is internal instead of private to allow ref return in the old CameraData compatibility property.
150164
// We can make this private when it is removed.

Packages/com.unity.render-pipelines.universal/Runtime/NativeRenderPass.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -669,9 +669,8 @@ internal static Hash128 CreateRenderPassHash(RenderPassDescriptor desc, uint has
669669
return CreateRenderPassHash(desc.w, desc.h, desc.depthID, desc.samples, hashIndex);
670670
}
671671

672-
private RenderPassDescriptor InitializeRenderPassDescriptor(UniversalCameraData cameraData, ScriptableRenderPass renderPass)
672+
internal static void GetRenderTextureDescriptor(UniversalCameraData cameraData, ScriptableRenderPass renderPass, out RenderTextureDescriptor targetRT)
673673
{
674-
RenderTextureDescriptor targetRT;
675674
if (!renderPass.overrideCameraTarget || (renderPass.colorAttachmentHandle.rt == null && renderPass.depthAttachmentHandle.rt == null))
676675
{
677676
targetRT = cameraData.cameraTargetDescriptor;
@@ -680,15 +679,20 @@ private RenderPassDescriptor InitializeRenderPassDescriptor(UniversalCameraData
680679
// and it's new dimensions might not be reflected on the targetTexture. This also applies to camera stacks rendering to a target texture.
681680
if (cameraData.targetTexture != null)
682681
{
683-
targetRT.width = cameraData.pixelWidth;
684-
targetRT.height = cameraData.pixelHeight;
682+
targetRT.width = cameraData.scaledWidth;
683+
targetRT.height = cameraData.scaledHeight;
685684
}
686685
}
687686
else
688687
{
689688
var handle = GetFirstAllocatedRTHandle(renderPass);
690689
targetRT = handle.rt != null ? handle.rt.descriptor : renderPass.depthAttachmentHandle.rt.descriptor;
691690
}
691+
}
692+
693+
private RenderPassDescriptor InitializeRenderPassDescriptor(UniversalCameraData cameraData, ScriptableRenderPass renderPass)
694+
{
695+
GetRenderTextureDescriptor(cameraData, renderPass, out RenderTextureDescriptor targetRT);
692696

693697
// Disable obsolete warning for internal usage
694698
#pragma warning disable CS0618

Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1280,7 +1280,7 @@ static UniversalCameraData CreateCameraData(ContextContainer frameData, Camera c
12801280
bool needsAlphaChannel = Graphics.preserveFramebufferAlpha;
12811281

12821282
cameraData.hdrColorBufferPrecision = asset ? asset.hdrColorBufferPrecision : HDRColorBufferPrecision._32Bits;
1283-
cameraData.cameraTargetDescriptor = CreateRenderTextureDescriptor(camera, cameraData.renderScale,
1283+
cameraData.cameraTargetDescriptor = CreateRenderTextureDescriptor(camera, cameraData,
12841284
cameraData.isHdrEnabled, cameraData.hdrColorBufferPrecision, msaaSamples, needsAlphaChannel, cameraData.requiresOpaqueTexture);
12851285

12861286
uint count = GraphicsFormatUtility.GetAlphaComponentCount(cameraData.cameraTargetDescriptor.graphicsFormat);

Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,19 +1525,14 @@ internal static GraphicsFormat MakeUnormRenderTextureGraphicsFormat()
15251525
return GraphicsFormat.R8G8B8A8_UNorm;
15261526
}
15271527

1528-
static RenderTextureDescriptor CreateRenderTextureDescriptor(Camera camera, float renderScale,
1528+
internal static RenderTextureDescriptor CreateRenderTextureDescriptor(Camera camera, UniversalCameraData cameraData,
15291529
bool isHdrEnabled, HDRColorBufferPrecision requestHDRColorBufferPrecision, int msaaSamples, bool needsAlpha, bool requiresOpaqueTexture)
15301530
{
1531-
int scaledWidth = (int)((float)camera.pixelWidth * renderScale);
1532-
int scaledHeight = (int)((float)camera.pixelHeight * renderScale);
1533-
15341531
RenderTextureDescriptor desc;
15351532

15361533
if (camera.targetTexture == null)
15371534
{
1538-
desc = new RenderTextureDescriptor(camera.pixelWidth, camera.pixelHeight);
1539-
desc.width = scaledWidth;
1540-
desc.height = scaledHeight;
1535+
desc = new RenderTextureDescriptor(cameraData.scaledWidth, cameraData.scaledHeight);
15411536
desc.graphicsFormat = MakeRenderTextureGraphicsFormat(isHdrEnabled, requestHDRColorBufferPrecision, needsAlpha);
15421537
desc.depthBufferBits = 32;
15431538
desc.msaaSamples = msaaSamples;
@@ -1547,8 +1542,8 @@ static RenderTextureDescriptor CreateRenderTextureDescriptor(Camera camera, floa
15471542
{
15481543
desc = camera.targetTexture.descriptor;
15491544
desc.msaaSamples = msaaSamples;
1550-
desc.width = scaledWidth;
1551-
desc.height = scaledHeight;
1545+
desc.width = cameraData.scaledWidth;
1546+
desc.height = cameraData.scaledHeight;
15521547

15531548
if (camera.cameraType == CameraType.SceneView && !isHdrEnabled)
15541549
{
@@ -1561,10 +1556,6 @@ static RenderTextureDescriptor CreateRenderTextureDescriptor(Camera camera, floa
15611556
// is given.
15621557
}
15631558

1564-
// Make sure dimension is non zero
1565-
desc.width = Mathf.Max(1, desc.width);
1566-
desc.height = Mathf.Max(1, desc.height);
1567-
15681559
desc.enableRandomWrite = false;
15691560
desc.bindMS = false;
15701561
desc.useDynamicScale = camera.allowDynamicResolution;
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
using System.Collections.Generic;
2+
using NUnit.Framework;
3+
using UnityEngine;
4+
using UnityEngine.Rendering.Universal;
5+
6+
namespace UnityEditor.Rendering.Universal.Tests
7+
{
8+
[TestFixture]
9+
class RenderTextureDescriptorDimensionsTests
10+
{
11+
private Camera m_Camera;
12+
private UniversalCameraData m_CameraData;
13+
public RenderTexture m_RT;
14+
15+
public class RenderScaleTestCase
16+
{
17+
public float renderScale { get; }
18+
public bool cameraTargetIsRenderTexture { get; }
19+
20+
public RenderScaleTestCase(float renderScale, bool cameraTargetIsRenderTexture)
21+
{
22+
this.renderScale = renderScale;
23+
this.cameraTargetIsRenderTexture = cameraTargetIsRenderTexture;
24+
}
25+
26+
public override string ToString()
27+
{
28+
return $"Render Scale : {renderScale}, Rendering To Texture : {cameraTargetIsRenderTexture}";
29+
}
30+
}
31+
32+
[OneTimeSetUp]
33+
public void GlobalSetup()
34+
{
35+
var go = new GameObject(nameof(RenderTextureDescriptorDimensionsTests));
36+
m_Camera = go.AddComponent<Camera>();
37+
38+
m_CameraData = new UniversalCameraData
39+
{
40+
camera = m_Camera
41+
};
42+
43+
m_RT = new RenderTexture(256, 256, 16, RenderTextureFormat.ARGB32);
44+
m_RT.Create();
45+
}
46+
47+
[OneTimeTearDown]
48+
public void GlobalCleanup()
49+
{
50+
Object.DestroyImmediate(m_Camera.gameObject);
51+
m_RT.Release();
52+
}
53+
54+
public RenderTextureDescriptor CreateRenderTextureDescriptor()
55+
{
56+
bool isHdrEnabled = false;
57+
HDRColorBufferPrecision requestHDRColorBufferPrecision = HDRColorBufferPrecision._64Bits;
58+
int msaaSamples = 1;
59+
bool needsAlpha = false;
60+
bool requiresOpaqueTexture = false;
61+
62+
return UniversalRenderPipeline.CreateRenderTextureDescriptor(
63+
m_Camera,
64+
m_CameraData,
65+
isHdrEnabled,
66+
requestHDRColorBufferPrecision,
67+
msaaSamples,
68+
needsAlpha,
69+
requiresOpaqueTexture);
70+
}
71+
72+
public void CheckDimensions(RenderTextureDescriptor desc, RenderScaleTestCase testCase)
73+
{
74+
var expectedWidth = Mathf.Max(1, (int)(m_Camera.pixelWidth * testCase.renderScale));
75+
var expectedHeight = Mathf.Max(1, (int)(m_Camera.pixelHeight * testCase.renderScale));
76+
77+
Assert.AreEqual(expectedWidth, desc.width);
78+
Assert.AreEqual(expectedHeight, desc.height);
79+
}
80+
81+
public static IEnumerable<RenderScaleTestCase> TestCasesTextureDimension()
82+
{
83+
// Texture target
84+
yield return new RenderScaleTestCase(0f, true);
85+
yield return new RenderScaleTestCase(0.5f, true);
86+
yield return new RenderScaleTestCase(1f, true);
87+
yield return new RenderScaleTestCase(2f, true);
88+
89+
// Backbuffer target
90+
yield return new RenderScaleTestCase(0f, false);
91+
yield return new RenderScaleTestCase(0.5f, false);
92+
yield return new RenderScaleTestCase(1f, false);
93+
yield return new RenderScaleTestCase(2f, false);
94+
}
95+
96+
[TestCaseSource(nameof(TestCasesTextureDimension))]
97+
public void TextureDescriptor_FromCameraData(RenderScaleTestCase testCase)
98+
{
99+
// Setup needed data for the test
100+
m_CameraData.renderScale = testCase.renderScale;
101+
m_Camera.targetTexture = (testCase.cameraTargetIsRenderTexture) ? m_RT : null;
102+
103+
var desc = CreateRenderTextureDescriptor();
104+
CheckDimensions(desc, testCase);
105+
}
106+
107+
public class TestRTDimensionNativeRenderPass : ScriptableRenderPass {}
108+
109+
[TestCaseSource(nameof(TestCasesTextureDimension))]
110+
public void TextureDescriptor_FromNativeRenderPass(RenderScaleTestCase testCase)
111+
{
112+
// Setup needed data for the test
113+
m_CameraData.renderScale = testCase.renderScale;
114+
m_Camera.targetTexture = (testCase.cameraTargetIsRenderTexture) ? m_RT : null;
115+
116+
m_CameraData.cameraTargetDescriptor = CreateRenderTextureDescriptor();
117+
118+
var nativeRenderPass = new TestRTDimensionNativeRenderPass();
119+
ScriptableRenderer.GetRenderTextureDescriptor(m_CameraData, nativeRenderPass, out var desc);
120+
CheckDimensions(desc, testCase);
121+
}
122+
}
123+
}

Packages/com.unity.render-pipelines.universal/Tests/Editor/RenderTextureDescriptorDimensionsTests.cs.meta

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)