public class CustomRendererFeature : ScriptableRendererFeature
{
class CustomRenderPass : ScriptableRenderPass
{
private class PassData
{
public TextureHandle sourceTextureHandle;
}
...
}
...
}
C/C++
public class CustomRendererFeature : ScriptableRendererFeature
{
class CustomRenderPass : ScriptableRenderPass
{
...
// RecordRenderGraph 함수 정의
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
// Render pass 이름
const string passName = "CustomRenderPass";
// Render pass 정의, RasterPass
using (var builder = renderGraph.AddRasterRenderPass
{
// 사용할 리소스를 선언
// URP의 공용 리소스에 접근하여, 읽어 올 현재 CameraColor의 Handle을 선언
UniversalResourceData resourceData = frameData.Get
TextureHandle cameraColorTextureHandle = resourceData.activeColorTexture;
// 복사할 Custom Render Texture의 Handle 선언
UniversalCameraData cameraData = frameData.Get
RenderTextureDescriptor desc = cameraData.cameraTargetDescriptor;
desc.msaaSamples = 1;
desc.depthBufferBits = 0;
TextureHandle target = UniversalRenderer.CreateRenderGraphTexture(renderGraph, desc, "Target Texture", false);
// 리소스 접근 권한 지정
// CameraColor를 읽기 위해 Read로 지정
builder.UseTexture(cameraColorTextureHandle, AccessFlags.Read);
// Custom Render Texture에 값을 쓰기 위해 Write로 지정
// Custom Render Texture를 RasterPass의 Render Target으로 지정
// CommnadBuffer.SetRenderTarget과 비슷한 역할
builder.SetRenderAttachment(target, 0, AccessFlags.Write);
// Render pass 실행 중 CameraColor를 사용하기 위해 Handle을 passData에 등록
passData.sourceTextureHandle = cameraColorTextureHandle;
// Render pass 실행 함수 등록, 람다 함수도 가능
builder.SetRenderFunc((PassData data, RasterGraphContext context) => ExecutePass(data, context));
}
}
}
...
}
public class CustomRendererFeature : ScriptableRendererFeature
{
class CustomRenderPass : ScriptableRenderPass
{
...
static void ExecutePass(PassData data, RasterGraphContext context)
{
// 해당 Render pass는 RasterPass이므로 RasterCommandBuffer를 사용
RasterCommandBuffer cmd = context.cmd;
// 대상 Render Target에 CameraColor를 Blit
Blitter.BlitTexture(cmd, data.sourceTextureHandle, new Vector4(1, 1, 0, 0), 0, false);
}
}
...
}
public class CustomRendererFeature : ScriptableRendererFeature
{
class CustomRenderPass : ScriptableRenderPass
{
...
}
...
CustomRenderPass m_ScriptablePass;
// Render pass를 renderer에 등록
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
renderer.EnqueuePass(m_ScriptablePass);
}
}
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.Rendering.RenderGraphModule;
public class RedTintRenderPassFeature : ScriptableRendererFeature
{
class RedTintRenderPass : ScriptableRenderPass
{
Material _tintMaterial;
public RedTintRenderPass(Material material)
{
_tintMaterial = material;
}
private class PassData
{
// Render pass 실행 중 필요한 TextureHandle과 Material
public TextureHandle _soruceTextureHandle;
public Material _blitMaterial;
}
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
// 사용할 리소스를 선언
// URP의 공용 리소스에 접근하여, 현재 Camera Color의 Handle 선언
UniversalResourceData resourceData = frameData.Get
TextureHandle cameraColorTextureHandle = resourceData.activeColorTexture;
// 임시로 Blit할 Temp Render Texture의 Handle 선언
// 기존의 RenderTextureDescriptor 변수가 RecordRenderGraph로 이동
UniversalCameraData cameraData = frameData.Get
RenderTextureDescriptor desc = cameraData.cameraTargetDescriptor;
desc.msaaSamples = 1;
desc.depthBufferBits = 0;
TextureHandle tempTextureHandle = UniversalRenderer.CreateRenderGraphTexture(renderGraph, desc, "_tempRT", true);
// Camera color -> Temp Render Texture
using (var builder = renderGraph.AddRasterRenderPass
{
// 리소스 접근 권한 지정
// CameraColor를 읽기 위해 Read로 지정
builder.UseTexture(cameraColorTextureHandle, AccessFlags.Read);
// Temp Render Texture에 값을 쓰기 위해 Write로 지정
builder.SetRenderAttachment(tempTextureHandle, 0, AccessFlags.Write);
// Render pass 실행 중 필요한 handle과 material을 동록
passData._soruceTextureHandle = cameraColorTextureHandle;
passData._blitMaterial = _tintMaterial;
builder.SetRenderFunc((PassData data, RasterGraphContext context) =>
{
// CameraColor를 Temp Render Texture에 Blit
RasterCommandBuffer cmd = context.cmd;
Blitter.BlitTexture(cmd, data._soruceTextureHandle, new Vector4(1, 1, 0, 0), data._blitMaterial, 0);
});
}
// Temp Render Texture -> Camera color
using (var builder = renderGraph.AddRasterRenderPass
{
// 리소스 접근 권한 지정
// 위에서 Temp Render Texture에 Blit한 결과를 읽기 위해 Read로 지정
builder.UseTexture(tempTextureHandle, AccessFlags.Read);
// Camera color에 값을 쓰기 위해 Write로 지정
builder.SetRenderAttachment(cameraColorTextureHandle, 0, AccessFlags.Write);
// Render pass 실행 중 필요한 handle과 material을 동록
passData._soruceTextureHandle = tempTextureHandle;
passData._blitMaterial = _tintMaterial;
builder.SetRenderFunc((PassData data, RasterGraphContext context) =>
{
// Temp Render Texture를 Camera color에 Blit
RasterCommandBuffer cmd = context.cmd;
Blitter.BlitTexture(cmd, data._soruceTextureHandle, new Vector4(1, 1, 0, 0), data._blitMaterial, 1);
});
}
}
public void Dispose()
{
// Render Graph에서 리소스를 자동으로 관리하므로 명시적으로 리소스를 Dispose하지 않는다
}
}
RedTintRenderPass scriptablePass;
public Material _tintMaterial;
public override void Create()
{
scriptablePass = new RedTintRenderPass(_tintMaterial);
scriptablePass.renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
renderer.EnqueuePass(scriptablePass);
}
}