study/first_study/Library/PackageCache/com.unity.render-pipelines.universal@d10049dfa479/Tests/Editor/RenderGraphTests.HelperPasses.cs
jh04010421 739d49f1a0 Unity | 2026.01.20
수업 실습 파일
2026-01-20 11:01:57 +09:00

197 lines
8.0 KiB
C#

using NUnit.Framework;
using UnityEngine.Experimental.Rendering;
using Unity.Collections;
using UnityEngine.Rendering.RenderGraphModule.Util;
using UnityEngine.Rendering.Universal;
using static UnityEngine.Rendering.RenderGraphModule.Util.RenderGraphUtils;
#if UNITY_EDITOR
using UnityEditor.Rendering;
#endif
namespace UnityEngine.Rendering.Tests
{
internal partial class RenderGraphTests : RenderGraphTestsCore
{
static GraphicsFormat[] depthBlitTestFormats =
{
GraphicsFormat.D32_SFloat,
GraphicsFormat.D24_UNorm,
GraphicsFormat.D16_UNorm,
};
public enum MSAAState
{
MSAA_None,
MSAA_4X,
}
static MSAAState[] depthBlitTestMSAA = { MSAAState.MSAA_None, MSAAState.MSAA_4X, };
RTHandle CreateDepthTexture(int width, int height, float depthValue, GraphicsFormat depthFormat, bool msaa = false, bool force2D = false)
{
// Create a new RTHandle texture
var depthHandle = RTHandles.Alloc(width, height,
depthFormat,
dimension: force2D ? TextureDimension.Tex2D : TextureXR.dimension,
useMipMap: false,
autoGenerateMips: false,
msaaSamples: (msaa) ? MSAASamples.MSAA4x : MSAASamples.None,
bindTextureMS: msaa,
name: "Depth Texture 32 bit");
var cmd = new CommandBuffer();
cmd.name = "Clear Depth RT";
cmd.SetRenderTarget(depthHandle);
cmd.ClearRenderTarget(true, true, Color.black, depthValue);
Graphics.ExecuteCommandBuffer(cmd);
return depthHandle;
}
[Test]
public void UtilityPasses_CopyDepth(
[ValueSource(nameof(depthBlitTestFormats))] GraphicsFormat depthFormat,
[ValueSource(nameof(depthBlitTestMSAA))] MSAAState msaa
)
{
const int kWidth = 4;
const int kHeight = 4;
// Verify if the test is being executed in a non-URP project (e.g pipeline asset set to null)
if (!EditorGraphicsSettings.TryGetRenderPipelineSettingsForPipeline<UniversalRenderPipelineRuntimeShaders, UniversalRenderPipeline>(out var shaders))
return;
if (Blitter.GetBlitMaterial(TextureDimension.Tex2D) == null && shaders != null)
{
Blitter.Initialize(shaders.coreBlitPS, shaders.coreBlitColorAndDepthPS);
}
float expectedDepthValue = 0.20f;
float gpuDepthValue = expectedDepthValue;
if (SystemInfo.usesReversedZBuffer)
gpuDepthValue = 1 - expectedDepthValue;
var sourceDepth = CreateDepthTexture(kWidth, kHeight, gpuDepthValue, depthFormat, msaa != MSAAState.MSAA_None);
var destinationDepth = CreateDepthTexture(kWidth, kHeight, 0.0f, depthFormat);
var depthAsColor = RTHandles.Alloc(kWidth, kHeight,
GraphicsFormat.R32_SFloat,
dimension: TextureXR.dimension,
useMipMap: false,
autoGenerateMips: false,
name: "Depth As Color Texture 32 bit");
m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) =>
{
// Initialize the RTHandle system if necessary
RTHandles.Initialize(kWidth, kHeight);
var source = m_RenderGraph.ImportTexture(sourceDepth);
var intermediate = m_RenderGraph.ImportTexture(destinationDepth);
var destination = m_RenderGraph.ImportTexture(depthAsColor);
// First do a copy from depth to depth, moving the value of 0.25 depth to the intermediate buffer.
m_RenderGraph.AddBlitPass(source, intermediate, Vector2.one, Vector2.zero);
// Then we move the depth value from the intermediate buffer to a color buffer to allow reading back its data to the CPU.
m_RenderGraph.AddBlitPass(intermediate, destination, Vector2.one, Vector2.zero);
};
RenderReadbackAndAssert(depthAsColor, expectedDepthValue);
sourceDepth.Release();
destinationDepth.Release();
depthAsColor.Release();
Blitter.Cleanup();
}
[Test]
public void UtilityPasses_CopyDepthWithMaterial([ValueSource(nameof(depthBlitTestFormats))] GraphicsFormat depthFormat)
{
const int kWidth = 4;
const int kHeight = 4;
// Verify if the test is being executed in a non-URP project (e.g pipeline asset set to null)
if (!EditorGraphicsSettings.TryGetRenderPipelineSettingsForPipeline<UniversalRenderPipelineRuntimeShaders, UniversalRenderPipeline>(out var shaders))
return;
if (Blitter.GetBlitMaterial(TextureDimension.Tex2D) == null && shaders != null)
{
Blitter.Initialize(shaders.coreBlitPS, shaders.coreBlitColorAndDepthPS);
}
float expectedDepthValue = 0.20f;
float gpuDepthValue = expectedDepthValue;
if (SystemInfo.usesReversedZBuffer)
gpuDepthValue = 1 - expectedDepthValue;
var sourceDepth = CreateDepthTexture(kWidth, kHeight, gpuDepthValue, depthFormat, false, true);
var destinationDepth = CreateDepthTexture(kWidth, kHeight, 0.0f, depthFormat, false, true);
var depthAsColor = RTHandles.Alloc(kWidth, kHeight,
GraphicsFormat.R32_SFloat,
dimension: TextureXR.dimension,
useMipMap: false,
autoGenerateMips: false,
name: "Depth As Color Texture 32 bit");
var shader = Shader.Find("Hidden/Core/CustomDepthBlit");
Assert.IsNotNull(shader);
var customDepthToColorMaterial = new Material(shader);
m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) =>
{
// Initialize the RTHandle system if necessary
RTHandles.Initialize(kWidth, kHeight);
var source = m_RenderGraph.ImportTexture(sourceDepth);
var intermediate = m_RenderGraph.ImportTexture(destinationDepth);
var destination = m_RenderGraph.ImportTexture(depthAsColor);
// First do a copy from depth to depth, moving the value of 0.25 depth to the intermediate buffer.
m_RenderGraph.AddBlitPass(new BlitMaterialParameters(source, intermediate, customDepthToColorMaterial, 0));
m_RenderGraph.AddBlitPass(new BlitMaterialParameters(intermediate, destination, customDepthToColorMaterial, 1));
};
RenderReadbackAndAssert(depthAsColor, expectedDepthValue);
CoreUtils.Destroy(customDepthToColorMaterial);
sourceDepth.Release();
depthAsColor.Release();
Blitter.Cleanup();
}
void RenderReadbackAndAssert(RTHandle colorBuffer, float expectedDepthValue)
{
ExternalGPUProfiler.BeginGPUCapture();
m_Camera.Render();
NativeArray<float> data = default;
AsyncGPUReadback.Request(colorBuffer, 0, (res) =>
{
Assert.That(!res.hasError, "GPU readback failed");
Assert.That(res.done, "GPU readback not done");
data = res.GetData<float>();
});
AsyncGPUReadback.WaitAllRequests();
ExternalGPUProfiler.EndGPUCapture();
Assert.That(data.Length, Is.EqualTo(colorBuffer.rt.width * colorBuffer.rt.height));
for (int i = 0; i < colorBuffer.rt.width * colorBuffer.rt.height; i++)
{
const float tolerance = 0.02f;
float e = Mathf.Abs(data[i] - expectedDepthValue);
Assert.True(e < tolerance, $"Depth Data does not match: actual = {data[i]}, expected = {expectedDepthValue}, error = {e}, tolerance = {tolerance}");
}
data.Dispose();
}
}
}