Version: Unity 6.0 (6000.0)
언어 : 한국어
URP의 이전 프레임에서 데이터 가져오기
URP의 프레임버퍼 페치를 통해 현재 프레임버퍼 가져오기

카메라 내역에 텍스처 추가

카메라 내역에 자체 텍스처를 추가하고 이후의 프레임에서 해당 데이터를 읽으려면 카메라 내역 유형을 생성하여 프레임 사이의 텍스처를 저장하십시오.

카메라 내역 유형 생성

다음 과정을 따르십시오.

  1. CameraHistoryItem에서 상속하는 클래스를 생성합니다. 예시:

    public class ExampleHistoryType : CameraHistoryItem {
        ...
    }
    
  2. 클래스에서 카메라 내역 시스템의 ID를 추가합니다. 예시:

        private int uniqueId;
    

    ID는 한 텍스처의 전체 내역을 나타냅니다(현재 프레임과 이전 프레임을 포함).

    프레임 사이에 저장해야 하는 텍스처 기술자(descriptor)와 같이 필요한 다른 데이터도 추가할 수 있습니다.

  3. OnCreate 메서드를 오버라이드합니다. 메서드에서 부모 클래스의 OnCreate 메서드를 호출하고 고유 ID를 생성합니다. 예시:

    public override void OnCreate(BufferedRTHandleSystem owner, uint typeId)
    {
        // Call the OnCreate method of the parent class
        base.OnCreate(owner, typeId);
    
        // Generate the unique id
        uniqueId = MakeId(0);
    }
    
  4. 렌더 패스가 액세스할 수 있도록 현재 및 이전 텍스처에 대한 퍼블릭 프로퍼티를 생성합니다. 예시:

    public RTHandle currentTexture => GetCurrentFrameRT(uniqueId);
    public RTHandle previousTexture => GetPreviousFrameRT(uniqueId);
    
  5. 텍스처에 대해 메모리를 할당합니다. 예시:

    // Allocate 2 textures using a texture descriptor, assign them to the uniqueId, and give them a name.
    AllocHistoryFrameRT(uniqueId, 2, ref textureDescriptor, "ExampleHistoryTexture");
    

렌더 패스가 다른 크기 또는 포맷의 텍스처를 작성하는 경우 프레임마다 메모리를 재할당해야 할 수도 있습니다.

텍스처에 쓰기

생성한 텍스처에 쓰기를 수행하려면 다음 과정을 따르십시오.

  1. ScriptableRenderPass 클래스에서 텍스처에 대한 액세스를 요청하려면 카메라 내역 유형에 대해 RequestAccess API를 사용하십시오. 예시:

    cameraData.historyManager.RequestAccess<ExampleHistoryType>();
    
  2. 쓰기를 수행할 현재 프레임의 텍스처를 가져와서 렌더 그래프 시스템이 사용할 수 있는 핸들로 전환합니다. 예시:

    // Get the textures 
    ExampleHistoryType history = cameraData.historyManager.GetHistoryForWrite<ExampleHistoryType>();
    
    // Get the texture for the current frame, using the unique id
    RTHandle historyTexture = history?.currentTexture(theUniqueid);
    
    // Convert the texture into a handle the render graph system can use
    historyTexture = renderGraph.ImportTexture(historyTexture);
    

이후에 렌더 패스에서 텍스처에 쓰기를 수행할 수 있습니다. 자세한 내용은 텍스처 사용하기를 참조하십시오.

텍스처에서 읽기

텍스처에서 읽기를 수행하려면 생성한 카메라 유형에 대해 RequestAccess API를 사용하십시오.

텍스처에서 읽기를 수행하려면 먼저 텍스처에 쓰기를 수행해야 합니다.

자세한 내용은 이전 프레임에서 데이터 가져오기를 참조하십시오.

예제

다음은 카메라 내역 유형의 예시입니다.

public class ExampleHistoryType : CameraHistoryItem
{
    private int m_Id;
    
    // Add a descriptor for the size and format of the texture.
    private RenderTextureDescriptor m_Descriptor;

    // Add a hash key to track changes to the descriptor.
    private Hash128 m_DescKey;
    
    public override void OnCreate(BufferedRTHandleSystem owner, uint typeId)
    {
        base.OnCreate(owner, typeId);
        m_Id = MakeId(0);
    }
    
    public RTHandle currentTexture => return GetCurrentFrameRT(m_Id);
    public RTHandle previousTexture => return GetPreviousFrameRT(m_Id);

    // The render pass calls the Update method every frame, to initialize, update, or dispose of the textures.
    public void Update(RenderTextureDescriptor textureDescriptor)
    {
        // Dispose of the textures if the memory needs to be reallocated.
        if (m_DescKey != Hash128.Compute(ref textureDescriptor))
            ReleaseHistoryFrameRT(m_Id);

        // Allocate the memory for the textures if it's not already allocated.
        if (currentTexture == null)
        {
            AllocHistoryFrameRT(m_Id, 2, ref textureDescriptor, "HistoryTexture");
    
            // Store the descriptor and hash key for future changes.
            m_Descriptor = textureDescriptor;
            m_DescKey = Hash128.Compute(ref textureDescriptor);
        }
    }
}

다음은 텍스처에 쓰기를 수행하는 렌더 패스의 예시입니다.

class WriteToHistoryTexture : ScriptableRenderPass
{
    private class PassData
    {
        internal Material material;
    }

    public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
    {
        var cameraData = frameData.Get<UniversalCameraData>();

        cameraData.historyManager.RequestAccess<ExampleHistory>();
        var history = cameraData.historyManager.GetHistoryForWrite<ExampleHistory>();

        if (history != null)
        {
            // Call the Update method of the camera history type.
            history.Update(cameraData.cameraTargetDescriptor);

            using (var builder = renderGraph.AddRasterRenderPass<PassData>("Write to history texture", out var passData))
            {
                UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
                RTHandle historyTexture = history?.currentTexture(multipassId);

                // Set the render graph to render to the history texture.
                builder.SetRenderAttachment(renderGraph.ImportTexture(historyTexture), 0, AccessFlags.Write);

                passData.material = m_Material;

                builder.SetRenderFunc(static (PassData data, RasterGraphContext context) =>
                {
                    // Draw a triangle to the history texture
                    context.cmd.DrawProcedural(Matrix4x4.identity, data.material, 0, MeshTopology.Triangles, 3, 1);
                });
            }
        }
    }
}
URP의 이전 프레임에서 데이터 가져오기
URP의 프레임버퍼 페치를 통해 현재 프레임버퍼 가져오기