SRP (Scriptable Render Pipeline)
RenderPipelineAsset.asset
- 유니티에서 그래픽스 파이프 라인을 관리한다. 여러
Renderer
를 가질 수 있다.
// 런타임 렌더파이프라인에셋 교체
// Edit> Project Settings> Scriptable Render Pipeline Settings
// 혹은, 이하 스크립트
public RenderPipelineAsset _renderPipelineAsset;
GraphicsSettings.renderPipelineAsset = _renderPipelineAsset;
// 클래스를 만들어서 사용자 렌더파이프라인에셋 만들기
[CreateAssetMenu(menuName = "Rendering/CustomRenderPipelineAsset")]
public class CustomRenderPipelineAsset : RenderPipelineAsset
{
protected override RenderPipeline CreatePipeline()
{
return new CustomRenderPipeline();
}
}
public class CustomRenderPipeline : RenderPipeline
{
protected override void Render(ScriptableRenderContext context, Camera[] cameras);
}
RenderGraph
TODO
RTHandles | class | RenderTexture API 감싼것 | https://docs.unity3d.com/Packages/com.unity.render-pipelines.core@12.0/api/UnityEngine.Rendering.RTHandles.html |
ComputeBuffers | class | Compute Shader를 위한 GPU data buffer | https://docs.unity3d.com/ScriptReference/ComputeBuffer.html |
RendererLists | struct | 렌더링에 사용하는 셋팅같은 정보들 모아둔것 | https://docs.unity3d.com/Packages/com.unity.render-pipelines.core@12.0/api/UnityEngine.Experimental.Rendering.RendererList.html |
RenderGraph - cont
- https://github.com/alexuhui/MySRP/blob/main/Assets/Custom%20RP/ShaderLibrary/Common.hlsl
- https://catlikecoding.com/unity/custom-srp/2-0-0/
using UnityEngine.Experimental.Rendering.RenderGraphModule;
readonly RenderGraph renderGraph = new("Custom SRP Render Graph");
protected override void Dispose(bool disposing)
{
…
renderGraph.Cleanup();
}
var renderGraphParameters = new RenderGraphParameters
{
commandBuffer = CommandBufferPool.Get(),
currentFrameIndex = Time.frameCount,
executionName = "Render Camera",
scriptableRenderContext = context
};
using (renderGraph.RecordAndExecute(renderGraphParameters))
{
}
CommandBufferPool.Release(renderGraphParameters.commandBuffer);
renderGraph.EndFrame();
Example
RenderPipeline
Pass
{
Tags
{
// LightMode 태그는 라이팅 파이프 라인에서 패스의 역할을 정의.
"LightMode" = "CustomLightMode"
}
}
[CreateAssetMenu(menuName = "Rendering/CustomRenderPipelineAsset")]
public class CustomRenderPipelineAsset : RenderPipelineAsset
{
protected override RenderPipeline CreatePipeline()
{
return new CustomRenderPipeline();
}
}
// ==========================================================================
public class CustomRenderPipeline : RenderPipeline
{
CustomRenderer _renderer = new CustomRenderer();
protected override void Render(ScriptableRenderContext context, Camera[] cameras)
{
foreach (Camera cam in cameras)
{
_renderer.Render(ref context, cam);
}
}
}
// ==========================================================================
public class CustomRenderer
{
readonly static ShaderTagId unlitShaderTagId = new ShaderTagId("CustomLightMode");
public void Render(ref ScriptableRenderContext context, Camera cam)
{
// ...
context.Submit(); // 실행
}
}
context.SetupCameraProperties(camera); // cmd전에 설정해주자(빠른 지우기)
var cmd = new CommandBuffer();
cmd.ClearRenderTarget
context.ExecuteCommandBuffer(cmd); // enqueue cmd
cmd.Release();
context.Submit(); // 실행
var cmd = new CommandBuffer();
cmd.BeginSample(string sampleName); // profiler begin
cmd.EndSample(string sampleName); // profiler end
// 컬링
if (!CulllResults.GetCullingParameters(camera, out ScriptableCullingParameters cullingParams))
{
continue;
}
CullResults cullingResults = context.Cull(ref cullingParams);
SortingSettings sortingSettings = new SortingSettings(cam);
DrawingSettings drawingSettings = new DrawingSettings(unlitShaderTagId, sortingSettings);
FilteringSettings filteringSettings = new FilteringSettings(RenderQueueRange.opaque);
context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
context.DrawRenderers // 렌더링
context.DrawSkybox(camera) // Skybox
// cs
var cmd = new CommandBuffer();
cmd.SetGlobalVector("_LightDir", new Vector4(0, 1, 0, 0));
context.ExecuteCommandBuffer(cmd);
cmd.Release();
// shader
CBUFFER_START(_Light) // CommandBuffer에서 전송됨
float4 _LightDir;
CBUFFER_END
- CBUFFER_START(UnityPerMaterial) // 메터리얼별
- CBUFFER_START(UnityPerDraw) // draw별
- https://blogs.unity3d.com/kr/2019/02/28/srp-batcher-speed-up-your-rendering/
/// Render Texture 사용.
// RenderTarget Id가 필요
int _TmpShaderProperty = Shader.PropertyToID("_TmpShaderProperty");
{
var cmd = new CommandBuffer();
// https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.GetTemporaryRT.html
// GetTemporaryRT(int nameID, int width, int height, int depthBuffer, FilterMode filter, RenderTextureFormat format, RenderTextureReadWrite readWrite, int antiAliasing, bool enableRandomWrite);
// GetTemporaryRT(int nameID, RenderTextureDescriptor desc, FilterMode filter);
cmd.GetTemporaryRT(_TmpShaderProperty, )
cmd.SetRenderTarget(RTID);
cmd.ClearRenderTarget;
context.ExecuteCommandBuffer(cmd);
cmd.Release();
}
{
var cmd = new CommandBuffer();
cmd.Blit(RTID, BuiltinRenderTextureType.CameraTarget);
cmd.ReleaseTemporaryRT(TemporaryRTID);
context.ExecuteCommandBuffer(cmd);
cmd.Release();
}
ScriptableRenderPass
...
CullResults cr = CullResults.Cull(ref cullingParams, context);
InitializeRenderingData(settings, ref cameraData, ref cullResults, out var renderingData);
renderer.Setup(context, ref renderingData); // RenderPass 쌓기.
renderer.Execute(context, ref renderingData);
public struct RenderingData
{
public CullingResults cullResults;
public CameraData cameraData;
public LightData lightData;
public ShadowData shadowData;
public PostProcessingData postProcessingData;
public bool supportsDynamicBatching;
public PerObjectData perObjectData;
public bool postProcessingEnabled;
}
- ScriptableRenderContext
- ScriptableRenderer (abstract class)
- public abstract void Setup(ScriptableRenderContext context, ref RenderingData renderingData);
- ScriptableRendererFeature
RenderingData
RenderPassEvent
RenderTargetHandle
Ref
-
https://blogs.unity3d.com/kr/2019/02/28/srp-batcher-speed-up-your-rendering/
-
https://docs.unity3d.com/Manual/ScriptableRenderPipeline.html
-
https://docs.unity3d.com/Manual/srp-creating-render-pipeline-asset-and-render-pipeline-instance.html
-
2020 - Universal RenderPipeline의 Custom RenderPass를 활용하여 렌더링 기능을 구현해보자 Track1-2